{"file_path":"contracts/bridge/SecuritizeBridge.sol","creation_status":"success","source_code":"//SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.20;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol\";\nimport \"@securitize/digital_securities/contracts/token/IDSToken.sol\";\nimport \"@securitize/digital_securities/contracts/registry/IDSRegistryService.sol\";\nimport \"@securitize/digital_securities/contracts/issuance/TokenIssuer.sol\";\nimport \"@securitize/digital_securities/contracts/utils/BaseDSContract.sol\";\nimport \"wormhole-solidity-sdk/interfaces/IWormholeReceiver.sol\";\nimport \"wormhole-solidity-sdk/interfaces/IWormholeRelayer.sol\";\nimport \"../utils/BaseContract.sol\";\nimport \"./ISecuritizeBridge.sol\";\n\ncontract SecuritizeBridge is IWormholeReceiver, ISecuritizeBridge, BaseContract {\n    string private constant BRIDGE_REASON = 'bridge';\n    uint256 internal constant US = 1;\n\n    IWormholeRelayer public wormholeRelayer;\n    IDSToken public dsToken;\n    IDSServiceConsumer public dsServiceConsumer;\n    uint256 public gasLimit;\n    uint16 public whChainId;\n\n    mapping(uint16 => address) public bridgeAddresses;\n\n    function initialize(uint16 _whChainId, address _wormholeRelayer, address _dsToken, address _owner) public override onlyProxy initializer {\n        __BaseDSContract_init(_owner);\n        whChainId = _whChainId;\n        wormholeRelayer = IWormholeRelayer(_wormholeRelayer);\n        dsToken = IDSToken(_dsToken);\n        dsServiceConsumer = IDSServiceConsumer(_dsToken);\n        gasLimit = 2_500_000;\n    }\n\n    function setBridgeAddress(uint16 chainId, address bridgeAddress) external override onlyOwner {\n        bridgeAddresses[chainId] = bridgeAddress;\n        emit BridgeAddressAdd(chainId, bridgeAddress);\n    }\n\n    function removeBridgeAddress(uint16 chainId) external override onlyOwner {\n        delete bridgeAddresses[chainId];\n        emit BridgeAddressRemove(chainId);\n    }\n\n    function updateGasLimit(uint256 _gasLimit) external override onlyOwner {\n        emit GasLimitUpdate(gasLimit, _gasLimit);\n        gasLimit = _gasLimit;\n    }\n\n    function quoteBridge(uint16 targetChain) public override view returns (uint256 cost) {\n        (cost, ) = wormholeRelayer.quoteEVMDeliveryPrice(targetChain, 0, gasLimit);\n    }\n\n    function bridgeDSTokens(uint16 targetChain, uint256 value) external override payable whenNotPaused {\n        uint256 cost = quoteBridge(targetChain);\n        require(msg.value >= cost, \"Transaction value should be equal or greater than quoteBridge response\");\n        require(dsToken.balanceOf(msg.sender) >= value, \"Not enough balance in source chain to bridge\");\n        address targetAddress = bridgeAddresses[targetChain];\n        require(bridgeAddresses[targetChain] != address(0), \"No bridge address available\");\n\n        IDSRegistryService registryService = IDSRegistryService(dsServiceConsumer.getDSService(dsServiceConsumer.REGISTRY_SERVICE()));\n        require(registryService.isWallet(msg.sender), \"Investor not registered\");\n        require(value > 0, \"DSToken value must be greater than 0\");\n\n        string memory investorId = registryService.getInvestor(msg.sender);\n\n        validateLockedTokens(investorId, value, registryService);\n\n        InvestorDetail memory investorDetail = getInvestorData(investorId, registryService);\n\n        // Perform DSToken burn on source chain\n        dsToken.burn(msg.sender, value, BRIDGE_REASON);\n\n        // Send Relayer message\n        wormholeRelayer.sendPayloadToEvm{value: msg.value} (\n            targetChain,\n            targetAddress,\n            abi.encode(\n                investorDetail.investorId,\n                value,\n                msg.sender,\n                investorDetail.country,\n                investorDetail.attributeValues,\n                investorDetail.attributeExpirations\n            ), // payload\n            0, // no receiver value needed since we\"re just passing a message\n            gasLimit,\n            whChainId,\n            msg.sender\n        );\n\n        emit DSTokenBridgeSend(targetChain, address(dsToken), msg.sender, value);\n    }\n\n    function receiveWormholeMessages(\n        bytes memory payload,\n        bytes[] memory, // additionalVaas\n        bytes32 sourceBridge, // address that called \"sendPayloadToEvm\" (DSTokenBridge contract)\n        uint16 sourceChain,\n        bytes32 // unique identifier of delivery\n    ) public override payable whenNotPaused {\n        require(msg.sender == address(wormholeRelayer), \"Only an authorized relayer can call this method\");\n        require(address(uint160(uint256(sourceBridge))) == bridgeAddresses[sourceChain], \"Wrong bridge initiator\");\n\n        // Parse the payload and do the corresponding actions\n        (\n            string memory investorId,\n            uint256 value,\n            address investorWallet,\n            string memory country,\n            uint256[] memory attributeValues,\n            uint256[] memory attributeExpirations\n        ) = abi.decode(payload, (string, uint256, address, string, uint256[], uint256[]));\n\n        // Perform DSToken operation\n        IDSRegistryService registryService = IDSRegistryService(dsServiceConsumer.getDSService(dsServiceConsumer.REGISTRY_SERVICE()));\n\n        uint8[] memory attributeIds = new uint8[](4);\n        attributeIds[0] = 1;  // KYC\n        attributeIds[1] = 2;  // Accredited\n        attributeIds[2] = 4;  // Qualified\n        attributeIds[3] = 8;  // Professional\n\n        address[] memory investorWallets = new address[](1);\n        investorWallets[0] = investorWallet;\n\n        registryService.updateInvestor(investorId, investorId, country, investorWallets, attributeIds, attributeValues, attributeExpirations);\n        dsToken.issueTokens(investorWallet, value);\n\n        emit DSTokenBridgeReceive(sourceChain, address(dsToken), investorWallet, value);\n    }\n\n    /////// private methods ////////\n    function getInvestorData(string memory investorId, IDSRegistryService registryService) private view returns (InvestorDetail memory) {\n        (string memory country, uint256[] memory attributeValues, uint256[] memory attributeExpirations, , , , ) = registryService.getInvestorDetailsFull(investorId);\n\n        InvestorDetail memory detail = InvestorDetail({\n            investorId: investorId,\n            country: country,\n            attributeValues: attributeValues,\n            attributeExpirations: attributeExpirations\n        });\n\n        return detail;\n    }\n\n    function validateLockedTokens(string memory investorId, uint256 value, IDSRegistryService registryService) private view {\n        IDSComplianceService complianceService = IDSComplianceService(dsServiceConsumer.getDSService(dsServiceConsumer.COMPLIANCE_SERVICE()));\n        IDSComplianceConfigurationService complianceConfigurationService = IDSComplianceConfigurationService(dsServiceConsumer.getDSService(dsServiceConsumer.COMPLIANCE_CONFIGURATION_SERVICE()));\n\n        string memory country = registryService.getCountry(investorId);\n        uint256 region = complianceConfigurationService.getCountryCompliance(country);\n\n        // lock/hold up validation\n        uint256 lockPeriod = (region == US) ? complianceConfigurationService.getUSLockPeriod() : complianceConfigurationService.getNonUSLockPeriod();\n        uint256 availableBalanceForTransfer = complianceService.getComplianceTransferableTokens(msg.sender, block.timestamp, uint64(lockPeriod));\n        require(availableBalanceForTransfer >= value, \"Not enough unlocked balance in source chain to bridge\");\n    }\n}\n","deployed_bytecode":"0x60806040526004361061014a5760003560e01c80637d97bf40116100b6578063b3c650151161006f578063b3c65015146103b7578063da25b725146103e4578063e93b582f14610404578063f2fde38b1461043a578063f68016b71461045a578063f687d12a1461047057600080fd5b80637d97bf40146102b95780638456cb59146102d95780638a60c3e5146102ee5780638da5cb5b1461031c578063aaea536314610359578063ad3cb1cc1461037957600080fd5b8063529dca3211610108578063529dca32146101fe57806352d1902d146102115780635c975abb1461023457806364a8c00b1461026457806369eb0b1b14610284578063715018a6146102a457600080fd5b80622d2fda1461014f57806306fc6687146101715780630cbcae70146101845780633f4ba83a146101b65780634f1ef286146101cb578063504ce999146101de575b600080fd5b34801561015b57600080fd5b5061016f61016a366004611e6b565b610490565b005b61016f61017f366004611ec5565b6105fc565b34801561019057600080fd5b50610199610bfa565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156101c257600080fd5b5061016f610c20565b61016f6101d9366004611fb2565b610c32565b3480156101ea57600080fd5b5061016f6101f9366004612001565b610c51565b61016f61020c36600461205b565b610cc4565b34801561021d57600080fd5b50610226611115565b6040519081526020016101ad565b34801561024057600080fd5b506000805160206127ef8339815191525460ff1660405190151581526020016101ad565b34801561027057600080fd5b50600254610199906001600160a01b031681565b34801561029057600080fd5b50600154610199906001600160a01b031681565b3480156102b057600080fd5b5061016f611132565b3480156102c557600080fd5b5061016f6102d4366004612150565b611144565b3480156102e557600080fd5b5061016f6111a5565b3480156102fa57600080fd5b506004546103099061ffff1681565b60405161ffff90911681526020016101ad565b34801561032857600080fd5b507f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b0316610199565b34801561036557600080fd5b50610226610374366004612150565b6111b5565b34801561038557600080fd5b506103aa604051806040016040528060058152602001640352e302e360dc1b81525081565b6040516101ad91906121bb565b3480156103c357600080fd5b506103cc61123e565b6040516001600160401b0390911681526020016101ad565b3480156103f057600080fd5b50600054610199906001600160a01b031681565b34801561041057600080fd5b5061019961041f366004612150565b6005602052600090815260409020546001600160a01b031681565b34801561044657600080fd5b5061016f6104553660046121ce565b611271565b34801561046657600080fd5b5061022660035481565b34801561047c57600080fd5b5061016f61048b3660046121eb565b6112af565b6104986112f8565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03166000811580156104dd5750825b90506000826001600160401b031660011480156104f95750303b155b905081158015610507575080155b156105255760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561054f57845460ff60401b1916600160401b1785555b6105588661139d565b6004805461ffff8b1661ffff19909116179055600080546001600160a01b03808b166001600160a01b03199283161790925560018054928a1692821683179055600280549091169091179055622625a060035583156105f157845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050565b6106046113be565b600061060f836111b5565b90508034101561069b5760405162461bcd60e51b815260206004820152604660248201527f5472616e73616374696f6e2076616c75652073686f756c64206265206571756160448201527f6c206f722067726561746572207468616e2071756f746542726964676520726560648201526573706f6e736560d01b608482015260a4015b60405180910390fd5b6001546040516370a0823160e01b815233600482015283916001600160a01b0316906370a0823190602401602060405180830381865afa1580156106e3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107079190612204565b101561076a5760405162461bcd60e51b815260206004820152602c60248201527f4e6f7420656e6f7567682062616c616e636520696e20736f757263652063686160448201526b696e20746f2062726964676560a01b6064820152608401610692565b61ffff83166000908152600560205260409020546001600160a01b0316806107d45760405162461bcd60e51b815260206004820152601b60248201527f4e6f20627269646765206164647265737320617661696c61626c6500000000006044820152606401610692565b600254604080516344be001760e11b815290516000926001600160a01b031691630e5324be91839163897c002e9160048083019260209291908290030181865afa158015610826573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061084a9190612204565b6040518263ffffffff1660e01b815260040161086891815260200190565b602060405180830381865afa158015610885573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108a9919061221d565b6040516333955c3b60e21b81523360048201529091506001600160a01b0382169063ce5570ec90602401602060405180830381865afa1580156108f0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610914919061223a565b6109605760405162461bcd60e51b815260206004820152601760248201527f496e766573746f72206e6f7420726567697374657265640000000000000000006044820152606401610692565b600084116109bc5760405162461bcd60e51b8152602060048201526024808201527f4453546f6b656e2076616c7565206d75737420626520677265617465722074686044820152630616e20360e41b6064820152608401610692565b60405163479ad3af60e11b81523360048201526000906001600160a01b03831690638f35a75e90602401600060405180830381865afa158015610a03573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610a2b91908101906122a9565b9050610a388186846113ef565b6000610a44828461184d565b600154604080518082018252600681526562726964676560d01b6020820152905163057d5c3760e21b81529293506001600160a01b03909116916315f570dc91610a949133918b916004016122dd565b600060405180830381600087803b158015610aae57600080fd5b505af1158015610ac2573d6000803e3d6000fd5b5050505060008054906101000a90046001600160a01b03166001600160a01b0316634b5ca6f434898785600001518b33886020015189604001518a60600151604051602001610b169695949392919061233f565b60408051601f1981840301815290829052600354600480546001600160e01b031960e08a901b168552610b589695946000939261ffff909216913391016123af565b60206040518083038185885af1158015610b76573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610b9b9190612408565b506001546040805161ffff8a1681526001600160a01b039092166020830152338282015260608201889052517f4351f6706a6389b725bcb6eeeef18d35b0a46729b615d322eeadc477ddae4cdc9181900360800190a150505050505050565b6000610c1b6000805160206127cf833981519152546001600160a01b031690565b905090565b610c2861191a565b610c30611975565b565b610c3a6112f8565b610c43826119cf565b610c4d82826119d7565b5050565b610c5961191a565b61ffff821660008181526005602090815260409182902080546001600160a01b0319166001600160a01b0386169081179091558251938452908301527f3e3a3092b9a40b2f57754dae00a7ba88b71ce0b0dc8362a46f4f20caf83b268a910160405180910390a15050565b610ccc6113be565b6000546001600160a01b03163314610d3e5760405162461bcd60e51b815260206004820152602f60248201527f4f6e6c7920616e20617574686f72697a65642072656c617965722063616e206360448201526e185b1b081d1a1a5cc81b595d1a1bd9608a1b6064820152608401610692565b61ffff82166000908152600560205260409020546001600160a01b03848116911614610da55760405162461bcd60e51b81526020600482015260166024820152752bb937b73390313934b233b29034b734ba34b0ba37b960511b6044820152606401610692565b6000806000806000808a806020019051810190610dc291906124a2565b600254604080516344be001760e11b81529051979d50959b50939950919750955093506000926001600160a01b0390911691630e5324be91839163897c002e9160048083019260209291908290030181865afa158015610e26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e4a9190612204565b6040518263ffffffff1660e01b8152600401610e6891815260200190565b602060405180830381865afa158015610e85573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ea9919061221d565b60408051600480825260a082019092529192506000919060208201608080368337019050509050600181600081518110610ee557610ee5612567565b602002602001019060ff16908160ff1681525050600281600181518110610f0e57610f0e612567565b602002602001019060ff16908160ff1681525050600481600281518110610f3757610f37612567565b602002602001019060ff16908160ff1681525050600881600381518110610f6057610f60612567565b60ff92909216602092830291909101909101526040805160018082528183019092526000918160200160208202803683370190505090508681600081518110610fab57610fab612567565b6001600160a01b03928316602091820292909201015260405163ba9be7ed60e01b81529084169063ba9be7ed90610ff2908c9081908b90879089908d908d906004016125b0565b6020604051808303816000875af1158015611011573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611035919061223a565b5060015460405163475a9fa960e01b81526001600160a01b038981166004830152602482018b90529091169063475a9fa9906044016020604051808303816000875af1158015611089573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ad919061223a565b506001546040805161ffff8e1681526001600160a01b03928316602082015291891682820152606082018a9052517f15e282eb9531b9cf86d564e700c0ad57d504676d5efda43e10a2533489ead4ed9181900360800190a15050505050505050505050505050565b600061111f611a99565b506000805160206127cf83398151915290565b61113a61191a565b610c306000611ae2565b61114c61191a565b61ffff811660008181526005602090815260409182902080546001600160a01b031916905590519182527fb17e2688fc934a3a73f34eb86cc52f2d4b001229874b0db62fd10b6516fbffd591015b60405180910390a150565b6111ad61191a565b610c30611b53565b6000805460035460405163c23ee3c360e01b815261ffff851660048201526024810184905260448101919091526001600160a01b039091169063c23ee3c3906064016040805180830381865afa158015611213573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112379190612674565b5092915050565b6000610c1b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00546001600160401b031690565b61127961191a565b6001600160a01b0381166112a357604051631e4fbdf760e01b815260006004820152602401610692565b6112ac81611ae2565b50565b6112b761191a565b60035460408051918252602082018390527fc1d450c3bb55eba5a02505c12a824cfebfb8692b2d3a5ad2b23b3c32c068d56e910160405180910390a1600355565b306001600160a01b037f000000000000000000000000a42a23db258666ade7a40f52ea55819da4fa985316148061137f57507f000000000000000000000000a42a23db258666ade7a40f52ea55819da4fa98536001600160a01b03166113736000805160206127cf833981519152546001600160a01b031690565b6001600160a01b031614155b15610c305760405163703e46dd60e11b815260040160405180910390fd5b6113a5611b9c565b6113ad611be5565b6113b5611bed565b6112ac81611bfd565b6000805160206127ef8339815191525460ff1615610c305760405163d93c066560e01b815260040160405180910390fd5b60025460408051632e18ca8160e21b815290516000926001600160a01b031691630e5324be91839163b8632a049160048083019260209291908290030181865afa158015611441573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114659190612204565b6040518263ffffffff1660e01b815260040161148391815260200190565b602060405180830381865afa1580156114a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114c4919061221d565b60025460408051630c75401560e41b815290519293506000926001600160a01b0390921691630e5324be91839163c7540150916004808201926020929091908290030181865afa15801561151c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115409190612204565b6040518263ffffffff1660e01b815260040161155e91815260200190565b602060405180830381865afa15801561157b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061159f919061221d565b90506000836001600160a01b031663848924cb876040518263ffffffff1660e01b81526004016115cf91906121bb565b600060405180830381865afa1580156115ec573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261161491908101906122a9565b90506000826001600160a01b0316636a528307836040518263ffffffff1660e01b815260040161164491906121bb565b602060405180830381865afa158015611661573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116859190612204565b90506000600182146116f857836001600160a01b0316639f9b9a816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116f39190612204565b61175a565b836001600160a01b031663295a217d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611736573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061175a9190612204565b60405163c67016d760e01b81523360048201524260248201526001600160401b03821660448201529091506000906001600160a01b0387169063c67016d790606401602060405180830381865afa1580156117b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117dd9190612204565b9050878110156105f15760405162461bcd60e51b815260206004820152603560248201527f4e6f7420656e6f75676820756e6c6f636b65642062616c616e636520696e20736044820152746f7572636520636861696e20746f2062726964676560581b6064820152608401610692565b6118786040518060800160405280606081526020016060815260200160608152602001606081525090565b6000806000846001600160a01b031663a9796bd1876040518263ffffffff1660e01b81526004016118a991906121bb565b600060405180830381865afa1580156118c6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526118ee9190810190612698565b5050604080516080810182529b8c5260208c019590955250509188015260608701525093949350505050565b3361194c7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b031614610c305760405163118cdaa760e01b8152336004820152602401610692565b61197d611c0e565b6000805160206127ef833981519152805460ff191681557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200161119a565b6112ac61191a565b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611a31575060408051601f3d908101601f19168201909252611a2e91810190612204565b60015b611a5957604051634c9c8ce360e01b81526001600160a01b0383166004820152602401610692565b6000805160206127cf8339815191528114611a8a57604051632a87526960e21b815260048101829052602401610692565b611a948383611c3e565b505050565b306001600160a01b037f000000000000000000000000a42a23db258666ade7a40f52ea55819da4fa98531614610c305760405163703e46dd60e11b815260040160405180910390fd5b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b611b5b6113be565b6000805160206127ef833981519152805460ff191660011781557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258336119b7565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff16610c3057604051631afcd79f60e31b815260040160405180910390fd5b610c30611b9c565b611bf5611b9c565b610c30611c94565b611c05611b9c565b6112ac81611cb5565b6000805160206127ef8339815191525460ff16610c3057604051638dfc202b60e01b815260040160405180910390fd5b611c4782611cbd565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a2805115611c8c57611a948282611d22565b610c4d611d98565b611c9c611b9c565b6000805160206127ef833981519152805460ff19169055565b611279611b9c565b806001600160a01b03163b600003611cf357604051634c9c8ce360e01b81526001600160a01b0382166004820152602401610692565b6000805160206127cf83398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b6060600080846001600160a01b031684604051611d3f91906127b2565b600060405180830381855af49150503d8060008114611d7a576040519150601f19603f3d011682016040523d82523d6000602084013e611d7f565b606091505b5091509150611d8f858383611db7565b95945050505050565b3415610c305760405163b398979f60e01b815260040160405180910390fd5b606082611dcc57611dc782611e16565b611e0f565b8151158015611de357506001600160a01b0384163b155b15611e0c57604051639996b31560e01b81526001600160a01b0385166004820152602401610692565b50805b9392505050565b805115611e265780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b803561ffff81168114611e5157600080fd5b919050565b6001600160a01b03811681146112ac57600080fd5b60008060008060808587031215611e8157600080fd5b611e8a85611e3f565b93506020850135611e9a81611e56565b92506040850135611eaa81611e56565b91506060850135611eba81611e56565b939692955090935050565b60008060408385031215611ed857600080fd5b611ee183611e3f565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715611f2d57611f2d611eef565b604052919050565b60006001600160401b03821115611f4e57611f4e611eef565b50601f01601f191660200190565b600082601f830112611f6d57600080fd5b8135611f80611f7b82611f35565b611f05565b818152846020838601011115611f9557600080fd5b816020850160208301376000918101602001919091529392505050565b60008060408385031215611fc557600080fd5b8235611fd081611e56565b915060208301356001600160401b03811115611feb57600080fd5b611ff785828601611f5c565b9150509250929050565b6000806040838503121561201457600080fd5b61201d83611e3f565b9150602083013561202d81611e56565b809150509250929050565b60006001600160401b0382111561205157612051611eef565b5060051b60200190565b600080600080600060a0868803121561207357600080fd5b85356001600160401b038082111561208a57600080fd5b61209689838a01611f5c565b96506020915081880135818111156120ad57600080fd5b8801601f81018a136120be57600080fd5b80356120cc611f7b82612038565b81815260059190911b8201840190848101908c8311156120eb57600080fd5b8584015b83811015612123578035868111156121075760008081fd5b6121158f8983890101611f5c565b8452509186019186016120ef565b5098505050506040880135945061213f91505060608701611e3f565b949793965091946080013592915050565b60006020828403121561216257600080fd5b611e0f82611e3f565b60005b8381101561218657818101518382015260200161216e565b50506000910152565b600081518084526121a781602086016020860161216b565b601f01601f19169290920160200192915050565b602081526000611e0f602083018461218f565b6000602082840312156121e057600080fd5b8135611e0f81611e56565b6000602082840312156121fd57600080fd5b5035919050565b60006020828403121561221657600080fd5b5051919050565b60006020828403121561222f57600080fd5b8151611e0f81611e56565b60006020828403121561224c57600080fd5b81518015158114611e0f57600080fd5b600082601f83011261226d57600080fd5b815161227b611f7b82611f35565b81815284602083860101111561229057600080fd5b6122a182602083016020870161216b565b949350505050565b6000602082840312156122bb57600080fd5b81516001600160401b038111156122d157600080fd5b6122a18482850161225c565b60018060a01b0384168152826020820152606060408201526000611d8f606083018461218f565b600081518084526020808501945080840160005b8381101561233457815187529582019590820190600101612318565b509495945050505050565b60c08152600061235260c083018961218f565b602083018890526001600160a01b0387166040840152828103606084015261237a818761218f565b9050828103608084015261238e8186612304565b905082810360a08401526123a28185612304565b9998505050505050505050565b600061ffff808a16835260018060a01b03808a16602085015260e060408501526123dc60e085018a61218f565b925087606085015286608085015281861660a085015280851660c0850152505098975050505050505050565b60006020828403121561241a57600080fd5b81516001600160401b0381168114611e0f57600080fd5b8051611e5181611e56565b600082601f83011261244d57600080fd5b8151602061245d611f7b83612038565b82815260059290921b8401810191818101908684111561247c57600080fd5b8286015b848110156124975780518352918301918301612480565b509695505050505050565b60008060008060008060c087890312156124bb57600080fd5b86516001600160401b03808211156124d257600080fd5b6124de8a838b0161225c565b9750602089015196506124f360408a01612431565b9550606089015191508082111561250957600080fd5b6125158a838b0161225c565b9450608089015191508082111561252b57600080fd5b6125378a838b0161243c565b935060a089015191508082111561254d57600080fd5b5061255a89828a0161243c565b9150509295509295509295565b634e487b7160e01b600052603260045260246000fd5b600081518084526020808501945080840160005b8381101561233457815160ff1687529582019590820190600101612591565b60e0815260006125c360e083018a61218f565b6020838203818501526125d6828b61218f565b915083820360408501526125ea828a61218f565b84810360608601528851808252828a0193509082019060005b818110156126285784516001600160a01b031683529383019391830191600101612603565b5050848103608086015261263c818961257d565b9250505082810360a08401526126528186612304565b905082810360c08401526126668185612304565b9a9950505050505050505050565b6000806040838503121561268757600080fd5b505080516020909101519092909150565b600080600080600080600060e0888a0312156126b357600080fd5b87516001600160401b03808211156126ca57600080fd5b6126d68b838c0161225c565b985060208a01519150808211156126ec57600080fd5b6126f88b838c0161243c565b975060408a015191508082111561270e57600080fd5b61271a8b838c0161243c565b965060608a015191508082111561273057600080fd5b61273c8b838c0161225c565b955060808a015191508082111561275257600080fd5b61275e8b838c0161225c565b945060a08a015191508082111561277457600080fd5b6127808b838c0161225c565b935060c08a015191508082111561279657600080fd5b506127a38a828b0161225c565b91505092959891949750929550565b600082516127c481846020870161216b565b919091019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbccd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f03300a264697066735822122098add5d8d3695cd991807680c4eaf911268653408ac39716528e87995f9bdc3b64736f6c63430008140033","optimization_enabled":true,"verified_twin_address_hash":null,"is_verified":true,"compiler_settings":{"evmVersion":"paris","libraries":{},"optimizer":{"enabled":true,"runs":200},"outputSelection":{"*":{"":["ast"],"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers","metadata"]}}},"optimization_runs":200,"sourcify_repo_url":null,"decoded_constructor_args":null,"compiler_version":"v0.8.20+commit.a1b79de6","is_verified_via_verifier_alliance":false,"verified_at":"2025-06-11T05:19:48.119669Z","implementations":[],"proxy_type":null,"external_libraries":[],"creation_bytecode":"0x60a06040523060805234801561001457600080fd5b5060805161284461003e600039600081816113030152818161132c0152611aa401526128446000f3fe60806040526004361061014a5760003560e01c80637d97bf40116100b6578063b3c650151161006f578063b3c65015146103b7578063da25b725146103e4578063e93b582f14610404578063f2fde38b1461043a578063f68016b71461045a578063f687d12a1461047057600080fd5b80637d97bf40146102b95780638456cb59146102d95780638a60c3e5146102ee5780638da5cb5b1461031c578063aaea536314610359578063ad3cb1cc1461037957600080fd5b8063529dca3211610108578063529dca32146101fe57806352d1902d146102115780635c975abb1461023457806364a8c00b1461026457806369eb0b1b14610284578063715018a6146102a457600080fd5b80622d2fda1461014f57806306fc6687146101715780630cbcae70146101845780633f4ba83a146101b65780634f1ef286146101cb578063504ce999146101de575b600080fd5b34801561015b57600080fd5b5061016f61016a366004611e6b565b610490565b005b61016f61017f366004611ec5565b6105fc565b34801561019057600080fd5b50610199610bfa565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156101c257600080fd5b5061016f610c20565b61016f6101d9366004611fb2565b610c32565b3480156101ea57600080fd5b5061016f6101f9366004612001565b610c51565b61016f61020c36600461205b565b610cc4565b34801561021d57600080fd5b50610226611115565b6040519081526020016101ad565b34801561024057600080fd5b506000805160206127ef8339815191525460ff1660405190151581526020016101ad565b34801561027057600080fd5b50600254610199906001600160a01b031681565b34801561029057600080fd5b50600154610199906001600160a01b031681565b3480156102b057600080fd5b5061016f611132565b3480156102c557600080fd5b5061016f6102d4366004612150565b611144565b3480156102e557600080fd5b5061016f6111a5565b3480156102fa57600080fd5b506004546103099061ffff1681565b60405161ffff90911681526020016101ad565b34801561032857600080fd5b507f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b0316610199565b34801561036557600080fd5b50610226610374366004612150565b6111b5565b34801561038557600080fd5b506103aa604051806040016040528060058152602001640352e302e360dc1b81525081565b6040516101ad91906121bb565b3480156103c357600080fd5b506103cc61123e565b6040516001600160401b0390911681526020016101ad565b3480156103f057600080fd5b50600054610199906001600160a01b031681565b34801561041057600080fd5b5061019961041f366004612150565b6005602052600090815260409020546001600160a01b031681565b34801561044657600080fd5b5061016f6104553660046121ce565b611271565b34801561046657600080fd5b5061022660035481565b34801561047c57600080fd5b5061016f61048b3660046121eb565b6112af565b6104986112f8565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03166000811580156104dd5750825b90506000826001600160401b031660011480156104f95750303b155b905081158015610507575080155b156105255760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561054f57845460ff60401b1916600160401b1785555b6105588661139d565b6004805461ffff8b1661ffff19909116179055600080546001600160a01b03808b166001600160a01b03199283161790925560018054928a1692821683179055600280549091169091179055622625a060035583156105f157845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050565b6106046113be565b600061060f836111b5565b90508034101561069b5760405162461bcd60e51b815260206004820152604660248201527f5472616e73616374696f6e2076616c75652073686f756c64206265206571756160448201527f6c206f722067726561746572207468616e2071756f746542726964676520726560648201526573706f6e736560d01b608482015260a4015b60405180910390fd5b6001546040516370a0823160e01b815233600482015283916001600160a01b0316906370a0823190602401602060405180830381865afa1580156106e3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107079190612204565b101561076a5760405162461bcd60e51b815260206004820152602c60248201527f4e6f7420656e6f7567682062616c616e636520696e20736f757263652063686160448201526b696e20746f2062726964676560a01b6064820152608401610692565b61ffff83166000908152600560205260409020546001600160a01b0316806107d45760405162461bcd60e51b815260206004820152601b60248201527f4e6f20627269646765206164647265737320617661696c61626c6500000000006044820152606401610692565b600254604080516344be001760e11b815290516000926001600160a01b031691630e5324be91839163897c002e9160048083019260209291908290030181865afa158015610826573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061084a9190612204565b6040518263ffffffff1660e01b815260040161086891815260200190565b602060405180830381865afa158015610885573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108a9919061221d565b6040516333955c3b60e21b81523360048201529091506001600160a01b0382169063ce5570ec90602401602060405180830381865afa1580156108f0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610914919061223a565b6109605760405162461bcd60e51b815260206004820152601760248201527f496e766573746f72206e6f7420726567697374657265640000000000000000006044820152606401610692565b600084116109bc5760405162461bcd60e51b8152602060048201526024808201527f4453546f6b656e2076616c7565206d75737420626520677265617465722074686044820152630616e20360e41b6064820152608401610692565b60405163479ad3af60e11b81523360048201526000906001600160a01b03831690638f35a75e90602401600060405180830381865afa158015610a03573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610a2b91908101906122a9565b9050610a388186846113ef565b6000610a44828461184d565b600154604080518082018252600681526562726964676560d01b6020820152905163057d5c3760e21b81529293506001600160a01b03909116916315f570dc91610a949133918b916004016122dd565b600060405180830381600087803b158015610aae57600080fd5b505af1158015610ac2573d6000803e3d6000fd5b5050505060008054906101000a90046001600160a01b03166001600160a01b0316634b5ca6f434898785600001518b33886020015189604001518a60600151604051602001610b169695949392919061233f565b60408051601f1981840301815290829052600354600480546001600160e01b031960e08a901b168552610b589695946000939261ffff909216913391016123af565b60206040518083038185885af1158015610b76573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610b9b9190612408565b506001546040805161ffff8a1681526001600160a01b039092166020830152338282015260608201889052517f4351f6706a6389b725bcb6eeeef18d35b0a46729b615d322eeadc477ddae4cdc9181900360800190a150505050505050565b6000610c1b6000805160206127cf833981519152546001600160a01b031690565b905090565b610c2861191a565b610c30611975565b565b610c3a6112f8565b610c43826119cf565b610c4d82826119d7565b5050565b610c5961191a565b61ffff821660008181526005602090815260409182902080546001600160a01b0319166001600160a01b0386169081179091558251938452908301527f3e3a3092b9a40b2f57754dae00a7ba88b71ce0b0dc8362a46f4f20caf83b268a910160405180910390a15050565b610ccc6113be565b6000546001600160a01b03163314610d3e5760405162461bcd60e51b815260206004820152602f60248201527f4f6e6c7920616e20617574686f72697a65642072656c617965722063616e206360448201526e185b1b081d1a1a5cc81b595d1a1bd9608a1b6064820152608401610692565b61ffff82166000908152600560205260409020546001600160a01b03848116911614610da55760405162461bcd60e51b81526020600482015260166024820152752bb937b73390313934b233b29034b734ba34b0ba37b960511b6044820152606401610692565b6000806000806000808a806020019051810190610dc291906124a2565b600254604080516344be001760e11b81529051979d50959b50939950919750955093506000926001600160a01b0390911691630e5324be91839163897c002e9160048083019260209291908290030181865afa158015610e26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e4a9190612204565b6040518263ffffffff1660e01b8152600401610e6891815260200190565b602060405180830381865afa158015610e85573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ea9919061221d565b60408051600480825260a082019092529192506000919060208201608080368337019050509050600181600081518110610ee557610ee5612567565b602002602001019060ff16908160ff1681525050600281600181518110610f0e57610f0e612567565b602002602001019060ff16908160ff1681525050600481600281518110610f3757610f37612567565b602002602001019060ff16908160ff1681525050600881600381518110610f6057610f60612567565b60ff92909216602092830291909101909101526040805160018082528183019092526000918160200160208202803683370190505090508681600081518110610fab57610fab612567565b6001600160a01b03928316602091820292909201015260405163ba9be7ed60e01b81529084169063ba9be7ed90610ff2908c9081908b90879089908d908d906004016125b0565b6020604051808303816000875af1158015611011573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611035919061223a565b5060015460405163475a9fa960e01b81526001600160a01b038981166004830152602482018b90529091169063475a9fa9906044016020604051808303816000875af1158015611089573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ad919061223a565b506001546040805161ffff8e1681526001600160a01b03928316602082015291891682820152606082018a9052517f15e282eb9531b9cf86d564e700c0ad57d504676d5efda43e10a2533489ead4ed9181900360800190a15050505050505050505050505050565b600061111f611a99565b506000805160206127cf83398151915290565b61113a61191a565b610c306000611ae2565b61114c61191a565b61ffff811660008181526005602090815260409182902080546001600160a01b031916905590519182527fb17e2688fc934a3a73f34eb86cc52f2d4b001229874b0db62fd10b6516fbffd591015b60405180910390a150565b6111ad61191a565b610c30611b53565b6000805460035460405163c23ee3c360e01b815261ffff851660048201526024810184905260448101919091526001600160a01b039091169063c23ee3c3906064016040805180830381865afa158015611213573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112379190612674565b5092915050565b6000610c1b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00546001600160401b031690565b61127961191a565b6001600160a01b0381166112a357604051631e4fbdf760e01b815260006004820152602401610692565b6112ac81611ae2565b50565b6112b761191a565b60035460408051918252602082018390527fc1d450c3bb55eba5a02505c12a824cfebfb8692b2d3a5ad2b23b3c32c068d56e910160405180910390a1600355565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148061137f57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166113736000805160206127cf833981519152546001600160a01b031690565b6001600160a01b031614155b15610c305760405163703e46dd60e11b815260040160405180910390fd5b6113a5611b9c565b6113ad611be5565b6113b5611bed565b6112ac81611bfd565b6000805160206127ef8339815191525460ff1615610c305760405163d93c066560e01b815260040160405180910390fd5b60025460408051632e18ca8160e21b815290516000926001600160a01b031691630e5324be91839163b8632a049160048083019260209291908290030181865afa158015611441573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114659190612204565b6040518263ffffffff1660e01b815260040161148391815260200190565b602060405180830381865afa1580156114a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114c4919061221d565b60025460408051630c75401560e41b815290519293506000926001600160a01b0390921691630e5324be91839163c7540150916004808201926020929091908290030181865afa15801561151c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115409190612204565b6040518263ffffffff1660e01b815260040161155e91815260200190565b602060405180830381865afa15801561157b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061159f919061221d565b90506000836001600160a01b031663848924cb876040518263ffffffff1660e01b81526004016115cf91906121bb565b600060405180830381865afa1580156115ec573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261161491908101906122a9565b90506000826001600160a01b0316636a528307836040518263ffffffff1660e01b815260040161164491906121bb565b602060405180830381865afa158015611661573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116859190612204565b90506000600182146116f857836001600160a01b0316639f9b9a816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116f39190612204565b61175a565b836001600160a01b031663295a217d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611736573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061175a9190612204565b60405163c67016d760e01b81523360048201524260248201526001600160401b03821660448201529091506000906001600160a01b0387169063c67016d790606401602060405180830381865afa1580156117b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117dd9190612204565b9050878110156105f15760405162461bcd60e51b815260206004820152603560248201527f4e6f7420656e6f75676820756e6c6f636b65642062616c616e636520696e20736044820152746f7572636520636861696e20746f2062726964676560581b6064820152608401610692565b6118786040518060800160405280606081526020016060815260200160608152602001606081525090565b6000806000846001600160a01b031663a9796bd1876040518263ffffffff1660e01b81526004016118a991906121bb565b600060405180830381865afa1580156118c6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526118ee9190810190612698565b5050604080516080810182529b8c5260208c019590955250509188015260608701525093949350505050565b3361194c7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b031614610c305760405163118cdaa760e01b8152336004820152602401610692565b61197d611c0e565b6000805160206127ef833981519152805460ff191681557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200161119a565b6112ac61191a565b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611a31575060408051601f3d908101601f19168201909252611a2e91810190612204565b60015b611a5957604051634c9c8ce360e01b81526001600160a01b0383166004820152602401610692565b6000805160206127cf8339815191528114611a8a57604051632a87526960e21b815260048101829052602401610692565b611a948383611c3e565b505050565b306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610c305760405163703e46dd60e11b815260040160405180910390fd5b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b611b5b6113be565b6000805160206127ef833981519152805460ff191660011781557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258336119b7565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff16610c3057604051631afcd79f60e31b815260040160405180910390fd5b610c30611b9c565b611bf5611b9c565b610c30611c94565b611c05611b9c565b6112ac81611cb5565b6000805160206127ef8339815191525460ff16610c3057604051638dfc202b60e01b815260040160405180910390fd5b611c4782611cbd565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a2805115611c8c57611a948282611d22565b610c4d611d98565b611c9c611b9c565b6000805160206127ef833981519152805460ff19169055565b611279611b9c565b806001600160a01b03163b600003611cf357604051634c9c8ce360e01b81526001600160a01b0382166004820152602401610692565b6000805160206127cf83398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b6060600080846001600160a01b031684604051611d3f91906127b2565b600060405180830381855af49150503d8060008114611d7a576040519150601f19603f3d011682016040523d82523d6000602084013e611d7f565b606091505b5091509150611d8f858383611db7565b95945050505050565b3415610c305760405163b398979f60e01b815260040160405180910390fd5b606082611dcc57611dc782611e16565b611e0f565b8151158015611de357506001600160a01b0384163b155b15611e0c57604051639996b31560e01b81526001600160a01b0385166004820152602401610692565b50805b9392505050565b805115611e265780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b803561ffff81168114611e5157600080fd5b919050565b6001600160a01b03811681146112ac57600080fd5b60008060008060808587031215611e8157600080fd5b611e8a85611e3f565b93506020850135611e9a81611e56565b92506040850135611eaa81611e56565b91506060850135611eba81611e56565b939692955090935050565b60008060408385031215611ed857600080fd5b611ee183611e3f565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715611f2d57611f2d611eef565b604052919050565b60006001600160401b03821115611f4e57611f4e611eef565b50601f01601f191660200190565b600082601f830112611f6d57600080fd5b8135611f80611f7b82611f35565b611f05565b818152846020838601011115611f9557600080fd5b816020850160208301376000918101602001919091529392505050565b60008060408385031215611fc557600080fd5b8235611fd081611e56565b915060208301356001600160401b03811115611feb57600080fd5b611ff785828601611f5c565b9150509250929050565b6000806040838503121561201457600080fd5b61201d83611e3f565b9150602083013561202d81611e56565b809150509250929050565b60006001600160401b0382111561205157612051611eef565b5060051b60200190565b600080600080600060a0868803121561207357600080fd5b85356001600160401b038082111561208a57600080fd5b61209689838a01611f5c565b96506020915081880135818111156120ad57600080fd5b8801601f81018a136120be57600080fd5b80356120cc611f7b82612038565b81815260059190911b8201840190848101908c8311156120eb57600080fd5b8584015b83811015612123578035868111156121075760008081fd5b6121158f8983890101611f5c565b8452509186019186016120ef565b5098505050506040880135945061213f91505060608701611e3f565b949793965091946080013592915050565b60006020828403121561216257600080fd5b611e0f82611e3f565b60005b8381101561218657818101518382015260200161216e565b50506000910152565b600081518084526121a781602086016020860161216b565b601f01601f19169290920160200192915050565b602081526000611e0f602083018461218f565b6000602082840312156121e057600080fd5b8135611e0f81611e56565b6000602082840312156121fd57600080fd5b5035919050565b60006020828403121561221657600080fd5b5051919050565b60006020828403121561222f57600080fd5b8151611e0f81611e56565b60006020828403121561224c57600080fd5b81518015158114611e0f57600080fd5b600082601f83011261226d57600080fd5b815161227b611f7b82611f35565b81815284602083860101111561229057600080fd5b6122a182602083016020870161216b565b949350505050565b6000602082840312156122bb57600080fd5b81516001600160401b038111156122d157600080fd5b6122a18482850161225c565b60018060a01b0384168152826020820152606060408201526000611d8f606083018461218f565b600081518084526020808501945080840160005b8381101561233457815187529582019590820190600101612318565b509495945050505050565b60c08152600061235260c083018961218f565b602083018890526001600160a01b0387166040840152828103606084015261237a818761218f565b9050828103608084015261238e8186612304565b905082810360a08401526123a28185612304565b9998505050505050505050565b600061ffff808a16835260018060a01b03808a16602085015260e060408501526123dc60e085018a61218f565b925087606085015286608085015281861660a085015280851660c0850152505098975050505050505050565b60006020828403121561241a57600080fd5b81516001600160401b0381168114611e0f57600080fd5b8051611e5181611e56565b600082601f83011261244d57600080fd5b8151602061245d611f7b83612038565b82815260059290921b8401810191818101908684111561247c57600080fd5b8286015b848110156124975780518352918301918301612480565b509695505050505050565b60008060008060008060c087890312156124bb57600080fd5b86516001600160401b03808211156124d257600080fd5b6124de8a838b0161225c565b9750602089015196506124f360408a01612431565b9550606089015191508082111561250957600080fd5b6125158a838b0161225c565b9450608089015191508082111561252b57600080fd5b6125378a838b0161243c565b935060a089015191508082111561254d57600080fd5b5061255a89828a0161243c565b9150509295509295509295565b634e487b7160e01b600052603260045260246000fd5b600081518084526020808501945080840160005b8381101561233457815160ff1687529582019590820190600101612591565b60e0815260006125c360e083018a61218f565b6020838203818501526125d6828b61218f565b915083820360408501526125ea828a61218f565b84810360608601528851808252828a0193509082019060005b818110156126285784516001600160a01b031683529383019391830191600101612603565b5050848103608086015261263c818961257d565b9250505082810360a08401526126528186612304565b905082810360c08401526126668185612304565b9a9950505050505050505050565b6000806040838503121561268757600080fd5b505080516020909101519092909150565b600080600080600080600060e0888a0312156126b357600080fd5b87516001600160401b03808211156126ca57600080fd5b6126d68b838c0161225c565b985060208a01519150808211156126ec57600080fd5b6126f88b838c0161243c565b975060408a015191508082111561270e57600080fd5b61271a8b838c0161243c565b965060608a015191508082111561273057600080fd5b61273c8b838c0161225c565b955060808a015191508082111561275257600080fd5b61275e8b838c0161225c565b945060a08a015191508082111561277457600080fd5b6127808b838c0161225c565b935060c08a015191508082111561279657600080fd5b506127a38a828b0161225c565b91505092959891949750929550565b600082516127c481846020870161216b565b919091019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbccd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f03300a264697066735822122098add5d8d3695cd991807680c4eaf911268653408ac39716528e87995f9bdc3b64736f6c63430008140033","name":"SecuritizeBridge","is_blueprint":false,"license_type":"none","is_fully_verified":true,"is_verified_via_eth_bytecode_db":true,"language":"solidity","evm_version":"paris","can_be_visualized_via_sol2uml":true,"is_verified_via_sourcify":false,"additional_sources":[{"file_path":"@openzeppelin/contracts/interfaces/IERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../token/ERC20/IERC20.sol\";\n"},{"file_path":"@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/ERC1967/ERC1967Utils.sol)\n\npragma solidity ^0.8.20;\n\nimport {IBeacon} from \"../beacon/IBeacon.sol\";\nimport {Address} from \"../../utils/Address.sol\";\nimport {StorageSlot} from \"../../utils/StorageSlot.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n */\nlibrary ERC1967Utils {\n    // We re-declare ERC-1967 events here because they can't be used directly from IERC1967.\n    // This will be fixed in Solidity 0.8.21. At that point we should remove these events.\n    /**\n     * @dev Emitted when the implementation is upgraded.\n     */\n    event Upgraded(address indexed implementation);\n\n    /**\n     * @dev Emitted when the admin account has changed.\n     */\n    event AdminChanged(address previousAdmin, address newAdmin);\n\n    /**\n     * @dev Emitted when the beacon is changed.\n     */\n    event BeaconUpgraded(address indexed beacon);\n\n    /**\n     * @dev Storage slot with the address of the current implementation.\n     * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1.\n     */\n    // solhint-disable-next-line private-vars-leading-underscore\n    bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n    /**\n     * @dev The `implementation` of the proxy is invalid.\n     */\n    error ERC1967InvalidImplementation(address implementation);\n\n    /**\n     * @dev The `admin` of the proxy is invalid.\n     */\n    error ERC1967InvalidAdmin(address admin);\n\n    /**\n     * @dev The `beacon` of the proxy is invalid.\n     */\n    error ERC1967InvalidBeacon(address beacon);\n\n    /**\n     * @dev An upgrade function sees `msg.value > 0` that may be lost.\n     */\n    error ERC1967NonPayable();\n\n    /**\n     * @dev Returns the current implementation address.\n     */\n    function getImplementation() internal view returns (address) {\n        return StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new address in the EIP1967 implementation slot.\n     */\n    function _setImplementation(address newImplementation) private {\n        if (newImplementation.code.length == 0) {\n            revert ERC1967InvalidImplementation(newImplementation);\n        }\n        StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value = newImplementation;\n    }\n\n    /**\n     * @dev Performs implementation upgrade with additional setup call if data is nonempty.\n     * This function is payable only if the setup call is performed, otherwise `msg.value` is rejected\n     * to avoid stuck value in the contract.\n     *\n     * Emits an {IERC1967-Upgraded} event.\n     */\n    function upgradeToAndCall(address newImplementation, bytes memory data) internal {\n        _setImplementation(newImplementation);\n        emit Upgraded(newImplementation);\n\n        if (data.length > 0) {\n            Address.functionDelegateCall(newImplementation, data);\n        } else {\n            _checkNonPayable();\n        }\n    }\n\n    /**\n     * @dev Storage slot with the admin of the contract.\n     * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1.\n     */\n    // solhint-disable-next-line private-vars-leading-underscore\n    bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n    /**\n     * @dev Returns the current admin.\n     *\n     * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using\n     * the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n     * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n     */\n    function getAdmin() internal view returns (address) {\n        return StorageSlot.getAddressSlot(ADMIN_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new address in the EIP1967 admin slot.\n     */\n    function _setAdmin(address newAdmin) private {\n        if (newAdmin == address(0)) {\n            revert ERC1967InvalidAdmin(address(0));\n        }\n        StorageSlot.getAddressSlot(ADMIN_SLOT).value = newAdmin;\n    }\n\n    /**\n     * @dev Changes the admin of the proxy.\n     *\n     * Emits an {IERC1967-AdminChanged} event.\n     */\n    function changeAdmin(address newAdmin) internal {\n        emit AdminChanged(getAdmin(), newAdmin);\n        _setAdmin(newAdmin);\n    }\n\n    /**\n     * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n     * This is the keccak-256 hash of \"eip1967.proxy.beacon\" subtracted by 1.\n     */\n    // solhint-disable-next-line private-vars-leading-underscore\n    bytes32 internal constant BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n    /**\n     * @dev Returns the current beacon.\n     */\n    function getBeacon() internal view returns (address) {\n        return StorageSlot.getAddressSlot(BEACON_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new beacon in the EIP1967 beacon slot.\n     */\n    function _setBeacon(address newBeacon) private {\n        if (newBeacon.code.length == 0) {\n            revert ERC1967InvalidBeacon(newBeacon);\n        }\n\n        StorageSlot.getAddressSlot(BEACON_SLOT).value = newBeacon;\n\n        address beaconImplementation = IBeacon(newBeacon).implementation();\n        if (beaconImplementation.code.length == 0) {\n            revert ERC1967InvalidImplementation(beaconImplementation);\n        }\n    }\n\n    /**\n     * @dev Change the beacon and trigger a setup call if data is nonempty.\n     * This function is payable only if the setup call is performed, otherwise `msg.value` is rejected\n     * to avoid stuck value in the contract.\n     *\n     * Emits an {IERC1967-BeaconUpgraded} event.\n     *\n     * CAUTION: Invoking this function has no effect on an instance of {BeaconProxy} since v5, since\n     * it uses an immutable beacon without looking at the value of the ERC-1967 beacon slot for\n     * efficiency.\n     */\n    function upgradeBeaconToAndCall(address newBeacon, bytes memory data) internal {\n        _setBeacon(newBeacon);\n        emit BeaconUpgraded(newBeacon);\n\n        if (data.length > 0) {\n            Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\n        } else {\n            _checkNonPayable();\n        }\n    }\n\n    /**\n     * @dev Reverts if `msg.value` is not zero. It can be used to avoid `msg.value` stuck in the contract\n     * if an upgrade doesn't perform an initialization call.\n     */\n    function _checkNonPayable() private {\n        if (msg.value > 0) {\n            revert ERC1967NonPayable();\n        }\n    }\n}\n"},{"file_path":"@securitize/digital_securities/contracts/compliance/IDSPartitionsManager.sol","source_code":"pragma solidity ^0.8.20;\n\n//SPDX-License-Identifier: GPL-3.0\nabstract contract IDSPartitionsManager {\n\n    event PartitionCreated(uint256 _date, uint256 _region, bytes32 _partition);\n\n    function initialize() public virtual;\n\n    function ensurePartition(\n        uint256 _issuanceDate,\n        uint256 _region /*onlyIssuerOrAboveOrToken*/\n    ) public virtual returns (bytes32 partition);\n\n    function getPartition(bytes32 _partition) public view virtual returns (uint256 date, uint256 region);\n\n    function getPartitionIssuanceDate(bytes32 _partition) public view virtual returns (uint256);\n\n    function getPartitionRegion(bytes32 _partition) public view virtual returns (uint256);\n}\n"},{"file_path":"@securitize/digital_securities/contracts/service/IDSServiceConsumer.sol","source_code":"pragma solidity ^0.8.20;\n\nimport \"../omnibus/IDSOmnibusWalletController.sol\";\n\n//SPDX-License-Identifier: GPL-3.0\nabstract contract IDSServiceConsumer {\n\n    uint256 public constant TRUST_SERVICE = 1;\n    uint256 public constant DS_TOKEN = 2;\n    uint256 public constant REGISTRY_SERVICE = 4;\n    uint256 public constant COMPLIANCE_SERVICE = 8;\n    uint256 public constant UNUSED_1 = 16;\n    uint256 public constant WALLET_MANAGER = 32;\n    uint256 public constant LOCK_MANAGER = 64;\n    uint256 public constant PARTITIONS_MANAGER = 128;\n    uint256 public constant COMPLIANCE_CONFIGURATION_SERVICE = 256;\n    uint256 public constant TOKEN_ISSUER = 512;\n    uint256 public constant WALLET_REGISTRAR = 1024;\n    uint256 public constant OMNIBUS_TBE_CONTROLLER = 2048;\n    uint256 public constant TRANSACTION_RELAYER = 4096;\n    uint256 public constant TOKEN_REALLOCATOR = 8192;\n    uint256 public constant ISSUER_MULTICALL = 8194;\n    uint256 public constant TA_MULTICALL = 8195;\n    uint256 public constant SECURITIZE_SWAP = 16384;\n    \n    function getDSService(uint256 _serviceId) public view virtual returns (address);\n\n    function setDSService(\n        uint256 _serviceId,\n        address _address /*onlyMaster*/\n    ) public virtual returns (bool);\n\n    event DSServiceSet(uint256 serviceId, address serviceAddress);\n}\n"},{"file_path":"@openzeppelin/contracts/utils/Address.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n    /**\n     * @dev The ETH balance of the account is not enough to perform the operation.\n     */\n    error AddressInsufficientBalance(address account);\n\n    /**\n     * @dev There's no code at `target` (it is not a contract).\n     */\n    error AddressEmptyCode(address target);\n\n    /**\n     * @dev A call to an address target failed. The target may have reverted.\n     */\n    error FailedInnerCall();\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        if (address(this).balance < amount) {\n            revert AddressInsufficientBalance(address(this));\n        }\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        if (!success) {\n            revert FailedInnerCall();\n        }\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason or custom error, it is bubbled\n     * up by this function (like regular Solidity function calls). However, if\n     * the call reverted with no returned reason, this function reverts with a\n     * {FailedInnerCall} error.\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     */\n    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n        if (address(this).balance < value) {\n            revert AddressInsufficientBalance(address(this));\n        }\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResultFromTarget(target, success, returndata);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResultFromTarget(target, success, returndata);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResultFromTarget(target, success, returndata);\n    }\n\n    /**\n     * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target\n     * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an\n     * unsuccessful call.\n     */\n    function verifyCallResultFromTarget(\n        address target,\n        bool success,\n        bytes memory returndata\n    ) internal view returns (bytes memory) {\n        if (!success) {\n            _revert(returndata);\n        } else {\n            // only check if target is a contract if the call was successful and the return data is empty\n            // otherwise we already know that it was a contract\n            if (returndata.length == 0 && target.code.length == 0) {\n                revert AddressEmptyCode(target);\n            }\n            return returndata;\n        }\n    }\n\n    /**\n     * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the\n     * revert reason or with a default {FailedInnerCall} error.\n     */\n    function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {\n        if (!success) {\n            _revert(returndata);\n        } else {\n            return returndata;\n        }\n    }\n\n    /**\n     * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.\n     */\n    function _revert(bytes memory returndata) private pure {\n        // Look for revert reason and bubble it up if present\n        if (returndata.length > 0) {\n            // The easiest way to bubble the revert reason is using memory via assembly\n            /// @solidity memory-safe-assembly\n            assembly {\n                let returndata_size := mload(returndata)\n                revert(add(32, returndata), returndata_size)\n            }\n        } else {\n            revert FailedInnerCall();\n        }\n    }\n}\n"},{"file_path":"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n    function __Context_init() internal onlyInitializing {\n    }\n\n    function __Context_init_unchained() internal onlyInitializing {\n    }\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    function _contextSuffixLength() internal view virtual returns (uint256) {\n        return 0;\n    }\n}\n"},{"file_path":"contracts/bridge/ISecuritizeBridge.sol","source_code":"//SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.20;\n\ninterface ISecuritizeBridge {\n\n    struct InvestorDetail {\n        string investorId;\n        string country;\n        uint256[] attributeValues;\n        uint256[] attributeExpirations;\n    }\n\n    /**\n    * @notice UUPSUpgradeable initiator method\n    * @param _whChainId wormhole chain id\n    * @param _wormholeRelayer bridge relayer address\n    * @param _dsToken ds token address\n    * @param _owner contract owner\n    */\n    function initialize(uint16 _whChainId, address _wormholeRelayer, address _dsToken, address _owner) external;\n\n    /**\n     * @notice Emitted when tokens are burnt and sent from source blockchain\n     * @dev chain Id is not EVM chain id, please refer to https://wormhole.com/docs/build/reference/chain-ids/\n     * @param targetChainId chain id\n     * @param dsToken token address\n     * @param investorWallet holder wallet\n     * @param value amount bridged\n     */\n    event DSTokenBridgeSend(uint16 targetChainId, address dsToken, address investorWallet, uint256 value);\n\n    /**\n     * @notice Emitted when tokens are received and issued in target blockchain\n     * @dev chain Id is not EVM chain id, please refer to https://wormhole.com/docs/build/reference/chain-ids/\n     * @param sourceChainId chain id\n     * @param dsToken token address\n     * @param investorWallet holder wallet\n     * @param value amount bridged\n     */\n    event DSTokenBridgeReceive(uint16 sourceChainId, address dsToken, address investorWallet, uint256 value);\n\n    /**\n     * @notice Emitted when a new bridge address is set\n     * @dev chain Id is not EVM chain id, please refer to https://wormhole.com/docs/build/reference/chain-ids/\n     * @param chainId Bridge chain id\n     * @param bridgeAddress bridge address\n     */\n    event BridgeAddressAdd(uint16 chainId, address bridgeAddress);\n\n    /**\n     * @notice Emitted when a new bridge address is removed\n     * @dev chain Id is not EVM chain id, please refer to https://wormhole.com/docs/build/reference/chain-ids/\n     * @param chainId Bridge chain id\n     */\n    event BridgeAddressRemove(uint16 chainId);\n\n    /**\n     * @notice Emitted when a gas limit value is updated\n     * @param oldGasLimit old gas limit value\n     * @param newGasLimit new gas limit value\n     */\n    event GasLimitUpdate(uint256 oldGasLimit, uint256 newGasLimit);\n\n    /**\n    * @notice Set a mapping with available bridges per chain\n    * @dev chain Id is not EVM chain id, please refer to https://wormhole.com/docs/build/reference/chain-ids/\n    * @param chainId Bridge chain id\n    * @param bridgeAddress brdige address\n    */\n    function setBridgeAddress(uint16 chainId, address bridgeAddress) external;\n\n    /**\n    * @notice Remove a chain bridge address\n    * @dev chain Id is not EVM chain id, please refer to https://wormhole.com/docs/build/reference/chain-ids/\n    * @param chainId Bridge chain id\n    */\n    function removeBridgeAddress(uint16 chainId) external;\n\n    /**\n    * @notice Update gas limit value\n    * @param _gasLimit new gas limit value\n    */\n    function updateGasLimit(uint256 _gasLimit) external;\n\n    /**\n    * @notice Get total cost of bridge operation\n    * @dev targetChainId is not EVM chain id, please refer to https://wormhole.com/docs/build/reference/chain-ids/\n    * @param targetChainId chain id\n    */\n    function quoteBridge(uint16 targetChainId) external view returns (uint256);\n\n    /**\n    * @notice Bridge dsTokens between blockchain\n    * @dev chain Id is not EVM chain id, please refer to https://wormhole.com/docs/build/reference/chain-ids/\n    * @param targetChainId chain id\n    * @param value - Amount to be bridged\n    */\n    function bridgeDSTokens(uint16 targetChainId, uint256 value) external payable;\n}\n"},{"file_path":"wormhole-solidity-sdk/interfaces/IWormholeReceiver.sol","source_code":"// SPDX-License-Identifier: Apache 2\n\npragma solidity ^0.8.0;\n\n/**\n * @notice Interface for a contract which can receive Wormhole messages.\n */\ninterface IWormholeReceiver {\n    /**\n     * @notice When a `send` is performed with this contract as the target, this function will be\n     *     invoked by the WormholeRelayer contract\n     *\n     * NOTE: This function should be restricted such that only the Wormhole Relayer contract can call it.\n     *\n     * We also recommend that this function checks that `sourceChain` and `sourceAddress` are indeed who\n     *       you expect to have requested the calling of `send` on the source chain\n     *\n     * The invocation of this function corresponding to the `send` request will have msg.value equal\n     *   to the receiverValue specified in the send request.\n     *\n     * If the invocation of this function reverts or exceeds the gas limit\n     *   specified by the send requester, this delivery will result in a `ReceiverFailure`.\n     *\n     * @param payload - an arbitrary message which was included in the delivery by the\n     *     requester. This message's signature will already have been verified (as long as msg.sender is the Wormhole Relayer contract)\n     * @param additionalMessages - Additional messages which were requested to be included in this delivery.\n     *      Note: There are no contract-level guarantees that the messages in this array are what was requested\n     *      so **you should verify any sensitive information given here!**\n     *\n     *      For example, if a 'VaaKey' was specified on the source chain, then MAKE SURE the corresponding message here\n     *      has valid signatures (by calling `parseAndVerifyVM(message)` on the Wormhole core contract)\n     *\n     *      This field can be used to perform and relay TokenBridge or CCTP transfers, and there are example\n     *      usages of this at\n     *         https://github.com/wormhole-foundation/hello-token\n     *         https://github.com/wormhole-foundation/hello-cctp\n     *\n     * @param sourceAddress - the (wormhole format) address on the sending chain which requested\n     *     this delivery.\n     * @param sourceChain - the wormhole chain ID where this delivery was requested.\n     * @param deliveryHash - the VAA hash of the deliveryVAA.\n     *\n     */\n    function receiveWormholeMessages(\n        bytes memory payload,\n        bytes[] memory additionalMessages,\n        bytes32 sourceAddress,\n        uint16 sourceChain,\n        bytes32 deliveryHash\n    ) external payable;\n}\n"},{"file_path":"@securitize/digital_securities/contracts/compliance/IDSWalletManager.sol","source_code":"pragma solidity ^0.8.20;\n\n//SPDX-License-Identifier: GPL-3.0\nabstract contract IDSWalletManager {\n\n    function initialize() public virtual;\n\n    // Special wallets constants\n    uint8 public constant NONE = 0;\n    uint8 public constant ISSUER = 1;\n    uint8 public constant PLATFORM = 2;\n    uint8 public constant EXCHANGE = 4;\n\n    /**\n     * @dev should be emitted when a special wallet is added.\n     */\n    event DSWalletManagerSpecialWalletAdded(address wallet, uint8 walletType, address sender);\n    /**\n     * @dev should be emitted when a special wallet is removed.\n     */\n    event DSWalletManagerSpecialWalletRemoved(address wallet, uint8 walletType, address sender);\n    /**\n     * @dev should be emitted when the number of reserved slots is set for a wallet.\n     */\n    event DSWalletManagerReservedSlotsSet(address wallet, string country, uint8 accreditationStatus, uint256 slots, address sender);\n\n    /**\n     * @dev Sets a wallet to be an special wallet. (internal)\n     * @param _wallet The address of the wallet.\n     * @param _type The type of the wallet.\n     * @return A boolean that indicates if the operation was successful.\n     */\n    function setSpecialWallet(address _wallet, uint8 _type) internal virtual returns (bool);\n\n    /**\n     * @dev gets a wallet type\n     * @param _wallet the address of the wallet to check.\n     */\n    function getWalletType(address _wallet) public view virtual returns (uint8);\n\n    /**\n     * @dev Returns true if it is platform wallet\n     * @param _wallet the address of the wallet to check.\n     */\n    function isPlatformWallet(address _wallet) external view virtual returns (bool);\n\n    /**\n     * @dev Returns true if it is special wallet\n     * @param _wallet the address of the wallet to check.\n     */\n    function isSpecialWallet(address _wallet) external view virtual returns (bool);\n\n    /**\n     * @dev Returns true if it is issuer special wallet\n     * @param _wallet the address of the wallet to check.\n     */\n    function isIssuerSpecialWallet(address _wallet) external view virtual returns (bool);\n\n    /**\n     * @dev Sets a wallet to be an issuer wallet.\n     * @param _wallet The address of the wallet.\n     * @return A boolean that indicates if the operation was successful.\n     */\n    function addIssuerWallet(\n        address _wallet /*onlyIssuerOrAbove*/\n    ) public virtual returns (bool);\n\n    /**\n     * @dev Sets an array of wallets to be issuer wallets.\n     * @param _wallets The address of the wallets.\n     * @return A boolean that indicates if the operation was successful.\n     */\n    function addIssuerWallets(address[] memory _wallets) public virtual returns (bool);\n\n    /**\n     * @dev Sets a wallet to be a platform wallet.\n     * @param _wallet The address of the wallet.\n     * @return A boolean that indicates if the operation was successful.\n     */\n    function addPlatformWallet(\n        address _wallet /*onlyIssuerOrAbove*/\n    ) public virtual returns (bool);\n\n    /**\n     * @dev Sets an array of wallets to be platforms wallet.\n     * @param _wallets The address of the wallets.\n     * @return A boolean that indicates if the operation was successful.\n     */\n    function addPlatformWallets(address[] memory _wallets) public virtual returns (bool);\n\n    /**\n     * @dev Sets a wallet to be an exchange wallet.\n     * @param _wallet The address of the wallet.\n     * @param _owner The address of the owner.\n     * @return A boolean that indicates if the operation was successful.\n     */\n    function addExchangeWallet(address _wallet, address _owner) public virtual returns (bool);\n\n    /**\n     * @dev Removes a special wallet.\n     * @param _wallet The address of the wallet.\n     * @return A boolean that indicates if the operation was successful.\n     */\n    function removeSpecialWallet(\n        address _wallet /*onlyIssuerOrAbove*/\n    ) public virtual returns (bool);\n}\n"},{"file_path":"@securitize/digital_securities/contracts/compliance/IDSComplianceConfigurationService.sol","source_code":"pragma solidity ^0.8.20;\n\n//SPDX-License-Identifier: GPL-3.0\nabstract contract IDSComplianceConfigurationService {\n\n    function initialize() public virtual;\n\n    event DSComplianceUIntRuleSet(string ruleName, uint256 prevValue, uint256 newValue);\n    event DSComplianceBoolRuleSet(string ruleName, bool prevValue, bool newValue);\n    event DSComplianceStringToUIntMapRuleSet(string ruleName, string keyValue, uint256 prevValue, uint256 newValue);\n\n    function getCountryCompliance(string memory _country) public view virtual returns (uint256);\n\n    function setCountriesCompliance(string[] calldata _countries, uint256[] calldata _values) public virtual;\n\n    function setCountryCompliance(\n        string calldata _country,\n        uint256 _value /*onlyTransferAgentOrAbove*/\n    ) public virtual;\n\n    function getTotalInvestorsLimit() public view virtual returns (uint256);\n\n    function setTotalInvestorsLimit(\n        uint256 _value /*onlyTransferAgentOrAbove*/\n    ) public virtual;\n\n    function getMinUSTokens() public view virtual returns (uint256);\n\n    function setMinUSTokens(\n        uint256 _value /*onlyTransferAgentOrAbove*/\n    ) public virtual;\n\n    function getMinEUTokens() public view virtual returns (uint256);\n\n    function setMinEUTokens(\n        uint256 _value /*onlyTransferAgentOrAbove*/\n    ) public virtual;\n\n    function getUSInvestorsLimit() public view virtual returns (uint256);\n\n    function setUSInvestorsLimit(\n        uint256 _value /*onlyTransferAgentOrAbove*/\n    ) public virtual;\n\n    function getJPInvestorsLimit() public view virtual returns (uint256);\n\n    function setJPInvestorsLimit(\n        uint256 _value /*onlyTransferAgentOrAbove*/\n    ) public virtual;\n\n    function getUSAccreditedInvestorsLimit() public view virtual returns (uint256);\n\n    function setUSAccreditedInvestorsLimit(\n        uint256 _value /*onlyTransferAgentOrAbove*/\n    ) public virtual;\n\n    function getNonAccreditedInvestorsLimit() public view virtual returns (uint256);\n\n    function setNonAccreditedInvestorsLimit(\n        uint256 _value /*onlyTransferAgentOrAbove*/\n    ) public virtual;\n\n    function getMaxUSInvestorsPercentage() public view virtual returns (uint256);\n\n    function setMaxUSInvestorsPercentage(\n        uint256 _value /*onlyTransferAgentOrAbove*/\n    ) public virtual;\n\n    function getBlockFlowbackEndTime() public view virtual returns (uint256);\n\n    function setBlockFlowbackEndTime(\n        uint256 _value /*onlyTransferAgentOrAbove*/\n    ) public virtual;\n\n    function getNonUSLockPeriod() public view virtual returns (uint256);\n\n    function setNonUSLockPeriod(\n        uint256 _value /*onlyTransferAgentOrAbove*/\n    ) public virtual;\n\n    function getMinimumTotalInvestors() public view virtual returns (uint256);\n\n    function setMinimumTotalInvestors(\n        uint256 _value /*onlyTransferAgentOrAbove*/\n    ) public virtual;\n\n    function getMinimumHoldingsPerInvestor() public view virtual returns (uint256);\n\n    function setMinimumHoldingsPerInvestor(\n        uint256 _value /*onlyTransferAgentOrAbove*/\n    ) public virtual;\n\n    function getMaximumHoldingsPerInvestor() public view virtual returns (uint256);\n\n    function setMaximumHoldingsPerInvestor(\n        uint256 _value /*onlyTransferAgentOrAbove*/\n    ) public virtual;\n\n    function getEURetailInvestorsLimit() public view virtual returns (uint256);\n\n    function setEURetailInvestorsLimit(\n        uint256 _value /*onlyTransferAgentOrAbove*/\n    ) public virtual;\n\n    function getUSLockPeriod() public view virtual returns (uint256);\n\n    function setUSLockPeriod(\n        uint256 _value /*onlyTransferAgentOrAbove*/\n    ) public virtual;\n\n    function getForceFullTransfer() public view virtual returns (bool);\n\n    function setForceFullTransfer(\n        bool _value /*onlyTransferAgentOrAbove*/\n    ) public virtual;\n\n    function getForceAccredited() public view virtual returns (bool);\n\n    function setForceAccredited(\n        bool _value /*onlyTransferAgentOrAbove*/\n    ) public virtual;\n\n    function setForceAccreditedUS(\n        bool _value /*onlyTransferAgentOrAbove*/\n    ) public virtual;\n\n    function getForceAccreditedUS() public view virtual returns (bool);\n\n    function setWorldWideForceFullTransfer(\n        bool _value /*onlyTransferAgentOrAbove*/\n    ) public virtual;\n\n    function getWorldWideForceFullTransfer() public view virtual returns (bool);\n\n    function getAuthorizedSecurities() public view virtual returns (uint256);\n\n    function setAuthorizedSecurities(\n        uint256 _value /*onlyTransferAgentOrAbove*/\n    ) public virtual;\n\n    function getDisallowBackDating() public view virtual returns (bool);\n\n    function setDisallowBackDating(\n        bool _value /*onlyTransferAgentOrAbove*/\n    ) public virtual;\n\n    function setAll(\n        uint256[] calldata _uint_values,\n        bool[] calldata _bool_values /*onlyTransferAgentOrAbove*/\n    ) public virtual;\n\n    function getAll() public view virtual returns (uint256[] memory, bool[] memory);\n}\n"},{"file_path":"@securitize/digital_securities/contracts/issuance/TokenIssuer.sol","source_code":"pragma solidity ^0.8.20;\n\nimport \"./IDSTokenIssuer.sol\";\nimport \"../utils/BaseDSContract.sol\";\n\n//SPDX-License-Identifier: GPL-3.0\ncontract TokenIssuer is IDSTokenIssuer, BaseDSContract {\n    function initialize() public override onlyProxy initializer {\n        __BaseDSContract_init();\n    }\n\n    function issueTokens(\n        string memory _id,\n        address _to,\n        uint256[] memory _issuanceValues,\n        string calldata _reason,\n        uint256[] memory _locksValues,\n        uint64[] memory _lockReleaseTimes,\n        string memory _collisionHash,\n        string memory _country,\n        uint256[] memory _attributeValues,\n        uint256[] memory _attributeExpirations\n    ) public override onlyIssuerOrAbove returns (bool) {\n        require(_issuanceValues.length == 2, \"Wrong length of parameters\");\n        require(_attributeValues.length == _attributeExpirations.length, \"Wrong length of parameters\");\n        require(_locksValues.length == _lockReleaseTimes.length, \"Wrong length of parameters\");\n        if (getRegistryService().isWallet(_to)) {\n            require(CommonUtils.isEqualString(getRegistryService().getInvestor(_to), _id), \"Wallet does not belong to investor\");\n        } else {\n            registerInvestor(_id, _to, _collisionHash, _country, _attributeValues, _attributeExpirations);\n        }\n\n        getToken().issueTokensWithMultipleLocks(_to, _issuanceValues[0], _issuanceValues[1], _locksValues, _reason, _lockReleaseTimes);\n\n        return true;\n    }\n\n    function registerInvestor(\n        string memory _id,\n        address _wallet,\n        string memory _collisionHash,\n        string memory _country,\n        uint256[] memory _attributeValues,\n        uint256[] memory _attributeExpirations\n    ) private {\n        if (!getRegistryService().isInvestor(_id)) {\n            getRegistryService().registerInvestor(_id, _collisionHash);\n            getRegistryService().setCountry(_id, _country);\n\n            if (_attributeValues.length > 0) {\n                require(_attributeValues.length == 3, \"Wrong length of parameters\");\n                getRegistryService().setAttribute(_id, KYC_APPROVED, _attributeValues[0], _attributeExpirations[0], \"\");\n                getRegistryService().setAttribute(_id, ACCREDITED, _attributeValues[1], _attributeExpirations[1], \"\");\n                getRegistryService().setAttribute(_id, QUALIFIED, _attributeValues[2], _attributeExpirations[2], \"\");\n            }\n\n        }\n        getRegistryService().addWallet(_wallet, _id);\n    }\n}\n"},{"file_path":"@securitize/digital_securities/contracts/compliance/IDSComplianceService.sol","source_code":"pragma solidity ^0.8.20;\n\n//SPDX-License-Identifier: GPL-3.0\nabstract contract IDSComplianceService {\n\n    uint256 internal constant NONE = 0;\n    uint256 internal constant US = 1;\n    uint256 internal constant EU = 2;\n    uint256 internal constant FORBIDDEN = 4;\n    uint256 internal constant JP = 8;\n    string internal constant TOKEN_PAUSED = \"Token Paused\";\n    string internal constant NOT_ENOUGH_TOKENS = \"Not Enough Tokens\";\n    string internal constant TOKENS_LOCKED = \"Tokens Locked\";\n    string internal constant WALLET_NOT_IN_REGISTRY_SERVICE = \"Wallet not in registry Service\";\n    string internal constant DESTINATION_RESTRICTED = \"Destination restricted\";\n    string internal constant VALID = \"Valid\";\n    string internal constant HOLD_UP = \"Under lock-up\";\n    string internal constant ONLY_FULL_TRANSFER = \"Only Full Transfer\";\n    string internal constant FLOWBACK = \"Flowback\";\n    string internal constant MAX_INVESTORS_IN_CATEGORY = \"Max Investors in category\";\n    string internal constant AMOUNT_OF_TOKENS_UNDER_MIN = \"Amount of tokens under min\";\n    string internal constant AMOUNT_OF_TOKENS_ABOVE_MAX = \"Amount of tokens above max\";\n    string internal constant ONLY_ACCREDITED = \"Only accredited\";\n    string internal constant ONLY_US_ACCREDITED = \"Only us accredited\";\n    string internal constant NOT_ENOUGH_INVESTORS = \"Not enough investors\";\n    string internal constant MAX_AUTHORIZED_SECURITIES_EXCEEDED = \"Max authorized securities exceeded\";\n\n    function initialize() public virtual;\n\n    function adjustInvestorCountsAfterCountryChange(\n        string memory _id,\n        string memory _country,\n        string memory _prevCountry\n    ) public virtual returns (bool);\n\n    //*****************************************\n    // TOKEN ACTION VALIDATIONS\n    //*****************************************\n\n    function validateTransfer(\n        address _from,\n        address _to,\n        uint256 _value /*onlyToken*/\n    ) public virtual returns (bool);\n\n    function validateTransfer(\n        address _from,\n        address _to,\n        uint256 _value, /*onlyToken*/\n        bool _pausedToken,\n        uint256 _balanceFrom\n    ) public virtual returns (bool);\n\n    function validateIssuance(\n        address _to,\n        uint256 _value,\n        uint256 _issuanceTime /*onlyToken*/\n    ) public virtual returns (bool);\n\n    function validateIssuanceWithNoCompliance(\n        address _to,\n        uint256 _value,\n        uint256 _issuanceTime /*onlyToken*/\n    ) public virtual returns (bool);\n\n    function validateBurn(\n        address _who,\n        uint256 _value /*onlyToken*/\n    ) public virtual returns (bool);\n\n    function validateSeize(\n        address _from,\n        address _to,\n        uint256 _value /*onlyToken*/\n    ) public virtual returns (bool);\n\n    function preIssuanceCheck(address _to, uint256 _value) public view virtual returns (uint256 code, string memory reason);\n\n    function preTransferCheck(\n        address _from,\n        address _to,\n        uint256 _value\n    ) public view virtual returns (uint256 code, string memory reason);\n\n    function newPreTransferCheck(\n        address _from,\n        address _to,\n        uint256 _value,\n        uint256 _balanceFrom,\n        bool _pausedToken\n    ) public view virtual returns (uint256 code, string memory reason);\n\n    function preInternalTransferCheck(\n        address _from,\n        address _to,\n        uint256 _value\n    ) public view virtual returns (uint256 code, string memory reason);\n\n    function validateIssuanceTime(uint256 _issuanceTime) public view virtual returns (uint256 issuanceTime);\n\n    function getComplianceTransferableTokens(\n        address _who,\n        uint256 _time,\n        uint64 _lockTime\n    ) public view virtual returns (uint256);\n}\n"},{"file_path":"@openzeppelin/contracts/proxy/beacon/IBeacon.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeacon {\n    /**\n     * @dev Must return an address that can be used as a delegate call target.\n     *\n     * {UpgradeableBeacon} will check that this address is a contract.\n     */\n    function implementation() external view returns (address);\n}\n"},{"file_path":"wormhole-solidity-sdk/interfaces/IWormholeRelayer.sol","source_code":"// SPDX-License-Identifier: Apache 2\n\npragma solidity ^0.8.0;\n\nimport {NotAnEvmAddress} from \"../Utils.sol\";\n\n/**\n * @title WormholeRelayer\n * @author\n * @notice This project allows developers to build cross-chain applications powered by Wormhole without needing to\n * write and run their own relaying infrastructure\n *\n * We implement the IWormholeRelayer interface that allows users to request a delivery provider to relay a payload (and/or additional messages)\n * to a chain and address of their choice.\n */\n\n/**\n * @notice VaaKey identifies a wormhole message\n *\n * @custom:member chainId Wormhole chain ID of the chain where this VAA was emitted from\n * @custom:member emitterAddress Address of the emitter of the VAA, in Wormhole bytes32 format\n * @custom:member sequence Sequence number of the VAA\n */\nstruct VaaKey {\n    uint16 chainId;\n    bytes32 emitterAddress;\n    uint64 sequence;\n}\n\n// 0-127 are reserved for standardized KeyTypes, 128-255 are for custom use\nuint8 constant VAA_KEY_TYPE = 1;\n\nstruct MessageKey {\n    uint8 keyType; // 0-127 are reserved for standardized KeyTypes, 128-255 are for custom use\n    bytes encodedKey;\n}\n\ninterface IWormholeRelayerBase {\n    event SendEvent(\n        uint64 indexed sequence,\n        uint256 deliveryQuote,\n        uint256 paymentForExtraReceiverValue\n    );\n\n    function getRegisteredWormholeRelayerContract(\n        uint16 chainId\n    ) external view returns (bytes32);\n\n    /**\n     * @notice Returns true if a delivery has been attempted for the given deliveryHash\n     * Note: invalid deliveries where the tx reverts are not considered attempted\n     */\n    function deliveryAttempted(\n        bytes32 deliveryHash\n    ) external view returns (bool attempted);\n\n    /**\n     * @notice block number at which a delivery was successfully executed\n     */\n    function deliverySuccessBlock(\n        bytes32 deliveryHash\n    ) external view returns (uint256 blockNumber);\n\n    /**\n     * @notice block number of the latest attempt to execute a delivery that failed\n     */\n    function deliveryFailureBlock(\n        bytes32 deliveryHash\n    ) external view returns (uint256 blockNumber);\n}\n\n/**\n * @title IWormholeRelayerSend\n * @notice The interface to request deliveries\n */\ninterface IWormholeRelayerSend is IWormholeRelayerBase {\n    /**\n     * @notice Publishes an instruction for the default delivery provider\n     * to relay a payload to the address `targetAddress` on chain `targetChain`\n     * with gas limit `gasLimit` and `msg.value` equal to `receiverValue`\n     *\n     * `targetAddress` must implement the IWormholeReceiver interface\n     *\n     * This function must be called with `msg.value` equal to `quoteEVMDeliveryPrice(targetChain, receiverValue, gasLimit)`\n     *\n     * Any refunds (from leftover gas) will be paid to the delivery provider. In order to receive the refunds, use the `sendPayloadToEvm` function\n     * with `refundChain` and `refundAddress` as parameters\n     *\n     * @param targetChain in Wormhole Chain ID format\n     * @param targetAddress address to call on targetChain (that implements IWormholeReceiver)\n     * @param payload arbitrary bytes to pass in as parameter in call to `targetAddress`\n     * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units)\n     * @param gasLimit gas limit with which to call `targetAddress`.\n     * @return sequence sequence number of published VAA containing delivery instructions\n     */\n    function sendPayloadToEvm(\n        uint16 targetChain,\n        address targetAddress,\n        bytes memory payload,\n        uint256 receiverValue,\n        uint256 gasLimit\n    ) external payable returns (uint64 sequence);\n\n    /**\n     * @notice Publishes an instruction for the default delivery provider\n     * to relay a payload to the address `targetAddress` on chain `targetChain`\n     * with gas limit `gasLimit` and `msg.value` equal to `receiverValue`\n     *\n     * Any refunds (from leftover gas) will be sent to `refundAddress` on chain `refundChain`\n     * `targetAddress` must implement the IWormholeReceiver interface\n     *\n     * This function must be called with `msg.value` equal to `quoteEVMDeliveryPrice(targetChain, receiverValue, gasLimit)`\n     *\n     * @param targetChain in Wormhole Chain ID format\n     * @param targetAddress address to call on targetChain (that implements IWormholeReceiver)\n     * @param payload arbitrary bytes to pass in as parameter in call to `targetAddress`\n     * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units)\n     * @param gasLimit gas limit with which to call `targetAddress`. Any units of gas unused will be refunded according to the\n     *        `targetChainRefundPerGasUnused` rate quoted by the delivery provider\n     * @param refundChain The chain to deliver any refund to, in Wormhole Chain ID format\n     * @param refundAddress The address on `refundChain` to deliver any refund to\n     * @return sequence sequence number of published VAA containing delivery instructions\n     */\n    function sendPayloadToEvm(\n        uint16 targetChain,\n        address targetAddress,\n        bytes memory payload,\n        uint256 receiverValue,\n        uint256 gasLimit,\n        uint16 refundChain,\n        address refundAddress\n    ) external payable returns (uint64 sequence);\n\n    /**\n     * @notice Publishes an instruction for the default delivery provider\n     * to relay a payload and VAAs specified by `vaaKeys` to the address `targetAddress` on chain `targetChain`\n     * with gas limit `gasLimit` and `msg.value` equal to `receiverValue`\n     *\n     * `targetAddress` must implement the IWormholeReceiver interface\n     *\n     * This function must be called with `msg.value` equal to `quoteEVMDeliveryPrice(targetChain, receiverValue, gasLimit)`\n     *\n     * Any refunds (from leftover gas) will be paid to the delivery provider. In order to receive the refunds, use the `sendVaasToEvm` function\n     * with `refundChain` and `refundAddress` as parameters\n     *\n     * @param targetChain in Wormhole Chain ID format\n     * @param targetAddress address to call on targetChain (that implements IWormholeReceiver)\n     * @param payload arbitrary bytes to pass in as parameter in call to `targetAddress`\n     * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units)\n     * @param gasLimit gas limit with which to call `targetAddress`.\n     * @param vaaKeys Additional VAAs to pass in as parameter in call to `targetAddress`\n     * @return sequence sequence number of published VAA containing delivery instructions\n     */\n    function sendVaasToEvm(\n        uint16 targetChain,\n        address targetAddress,\n        bytes memory payload,\n        uint256 receiverValue,\n        uint256 gasLimit,\n        VaaKey[] memory vaaKeys\n    ) external payable returns (uint64 sequence);\n\n    /**\n     * @notice Publishes an instruction for the default delivery provider\n     * to relay a payload and VAAs specified by `vaaKeys` to the address `targetAddress` on chain `targetChain`\n     * with gas limit `gasLimit` and `msg.value` equal to `receiverValue`\n     *\n     * Any refunds (from leftover gas) will be sent to `refundAddress` on chain `refundChain`\n     * `targetAddress` must implement the IWormholeReceiver interface\n     *\n     * This function must be called with `msg.value` equal to `quoteEVMDeliveryPrice(targetChain, receiverValue, gasLimit)`\n     *\n     * @param targetChain in Wormhole Chain ID format\n     * @param targetAddress address to call on targetChain (that implements IWormholeReceiver)\n     * @param payload arbitrary bytes to pass in as parameter in call to `targetAddress`\n     * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units)\n     * @param gasLimit gas limit with which to call `targetAddress`. Any units of gas unused will be refunded according to the\n     *        `targetChainRefundPerGasUnused` rate quoted by the delivery provider\n     * @param vaaKeys Additional VAAs to pass in as parameter in call to `targetAddress`\n     * @param refundChain The chain to deliver any refund to, in Wormhole Chain ID format\n     * @param refundAddress The address on `refundChain` to deliver any refund to\n     * @return sequence sequence number of published VAA containing delivery instructions\n     */\n    function sendVaasToEvm(\n        uint16 targetChain,\n        address targetAddress,\n        bytes memory payload,\n        uint256 receiverValue,\n        uint256 gasLimit,\n        VaaKey[] memory vaaKeys,\n        uint16 refundChain,\n        address refundAddress\n    ) external payable returns (uint64 sequence);\n\n    /**\n     * @notice Publishes an instruction for the delivery provider at `deliveryProviderAddress`\n     * to relay a payload and VAAs specified by `vaaKeys` to the address `targetAddress` on chain `targetChain`\n     * with gas limit `gasLimit` and `msg.value` equal to\n     * receiverValue + (arbitrary amount that is paid for by paymentForExtraReceiverValue of this chain's wei) in targetChain wei.\n     *\n     * Any refunds (from leftover gas) will be sent to `refundAddress` on chain `refundChain`\n     * `targetAddress` must implement the IWormholeReceiver interface\n     *\n     * This function must be called with `msg.value` equal to\n     * quoteEVMDeliveryPrice(targetChain, receiverValue, gasLimit, deliveryProviderAddress) + paymentForExtraReceiverValue\n     *\n     * @param targetChain in Wormhole Chain ID format\n     * @param targetAddress address to call on targetChain (that implements IWormholeReceiver)\n     * @param payload arbitrary bytes to pass in as parameter in call to `targetAddress`\n     * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units)\n     * @param paymentForExtraReceiverValue amount (in current chain currency units) to spend on extra receiverValue\n     *        (in addition to the `receiverValue` specified)\n     * @param gasLimit gas limit with which to call `targetAddress`. Any units of gas unused will be refunded according to the\n     *        `targetChainRefundPerGasUnused` rate quoted by the delivery provider\n     * @param refundChain The chain to deliver any refund to, in Wormhole Chain ID format\n     * @param refundAddress The address on `refundChain` to deliver any refund to\n     * @param deliveryProviderAddress The address of the desired delivery provider's implementation of IDeliveryProvider\n     * @param vaaKeys Additional VAAs to pass in as parameter in call to `targetAddress`\n     * @param consistencyLevel Consistency level with which to publish the delivery instructions - see\n     *        https://book.wormhole.com/wormhole/3_coreLayerContracts.html?highlight=consistency#consistency-levels\n     * @return sequence sequence number of published VAA containing delivery instructions\n     */\n    function sendToEvm(\n        uint16 targetChain,\n        address targetAddress,\n        bytes memory payload,\n        uint256 receiverValue,\n        uint256 paymentForExtraReceiverValue,\n        uint256 gasLimit,\n        uint16 refundChain,\n        address refundAddress,\n        address deliveryProviderAddress,\n        VaaKey[] memory vaaKeys,\n        uint8 consistencyLevel\n    ) external payable returns (uint64 sequence);\n\n    /**\n     * @notice Publishes an instruction for the delivery provider at `deliveryProviderAddress`\n     * to relay a payload and external messages specified by `messageKeys` to the address `targetAddress` on chain `targetChain`\n     * with gas limit `gasLimit` and `msg.value` equal to\n     * receiverValue + (arbitrary amount that is paid for by paymentForExtraReceiverValue of this chain's wei) in targetChain wei.\n     *\n     * Any refunds (from leftover gas) will be sent to `refundAddress` on chain `refundChain`\n     * `targetAddress` must implement the IWormholeReceiver interface\n     *\n     * This function must be called with `msg.value` equal to\n     * quoteEVMDeliveryPrice(targetChain, receiverValue, gasLimit, deliveryProviderAddress) + paymentForExtraReceiverValue\n     *\n     * Note: MessageKeys can specify wormhole messages (VaaKeys) or other types of messages (ex. USDC CCTP attestations). Ensure the selected\n     * DeliveryProvider supports all the MessageKey.keyType values specified or it will not be delivered!\n     *\n     * @param targetChain in Wormhole Chain ID format\n     * @param targetAddress address to call on targetChain (that implements IWormholeReceiver)\n     * @param payload arbitrary bytes to pass in as parameter in call to `targetAddress`\n     * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units)\n     * @param paymentForExtraReceiverValue amount (in current chain currency units) to spend on extra receiverValue\n     *        (in addition to the `receiverValue` specified)\n     * @param gasLimit gas limit with which to call `targetAddress`. Any units of gas unused will be refunded according to the\n     *        `targetChainRefundPerGasUnused` rate quoted by the delivery provider\n     * @param refundChain The chain to deliver any refund to, in Wormhole Chain ID format\n     * @param refundAddress The address on `refundChain` to deliver any refund to\n     * @param deliveryProviderAddress The address of the desired delivery provider's implementation of IDeliveryProvider\n     * @param messageKeys Additional messagess to pass in as parameter in call to `targetAddress`\n     * @param consistencyLevel Consistency level with which to publish the delivery instructions - see\n     *        https://book.wormhole.com/wormhole/3_coreLayerContracts.html?highlight=consistency#consistency-levels\n     * @return sequence sequence number of published VAA containing delivery instructions\n     */\n    function sendToEvm(\n        uint16 targetChain,\n        address targetAddress,\n        bytes memory payload,\n        uint256 receiverValue,\n        uint256 paymentForExtraReceiverValue,\n        uint256 gasLimit,\n        uint16 refundChain,\n        address refundAddress,\n        address deliveryProviderAddress,\n        MessageKey[] memory messageKeys,\n        uint8 consistencyLevel\n    ) external payable returns (uint64 sequence);\n\n    /**\n     * @notice Publishes an instruction for the delivery provider at `deliveryProviderAddress`\n     * to relay a payload and VAAs specified by `vaaKeys` to the address `targetAddress` on chain `targetChain`\n     * with `msg.value` equal to\n     * receiverValue + (arbitrary amount that is paid for by paymentForExtraReceiverValue of this chain's wei) in targetChain wei.\n     *\n     * Any refunds (from leftover gas) will be sent to `refundAddress` on chain `refundChain`\n     * `targetAddress` must implement the IWormholeReceiver interface\n     *\n     * This function must be called with `msg.value` equal to\n     * quoteDeliveryPrice(targetChain, receiverValue, encodedExecutionParameters, deliveryProviderAddress) + paymentForExtraReceiverValue\n     *\n     * @param targetChain in Wormhole Chain ID format\n     * @param targetAddress address to call on targetChain (that implements IWormholeReceiver), in Wormhole bytes32 format\n     * @param payload arbitrary bytes to pass in as parameter in call to `targetAddress`\n     * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units)\n     * @param paymentForExtraReceiverValue amount (in current chain currency units) to spend on extra receiverValue\n     *        (in addition to the `receiverValue` specified)\n     * @param encodedExecutionParameters encoded information on how to execute delivery that may impact pricing\n     *        e.g. for version EVM_V1, this is a struct that encodes the `gasLimit` with which to call `targetAddress`\n     * @param refundChain The chain to deliver any refund to, in Wormhole Chain ID format\n     * @param refundAddress The address on `refundChain` to deliver any refund to, in Wormhole bytes32 format\n     * @param deliveryProviderAddress The address of the desired delivery provider's implementation of IDeliveryProvider\n     * @param vaaKeys Additional VAAs to pass in as parameter in call to `targetAddress`\n     * @param consistencyLevel Consistency level with which to publish the delivery instructions - see\n     *        https://book.wormhole.com/wormhole/3_coreLayerContracts.html?highlight=consistency#consistency-levels\n     * @return sequence sequence number of published VAA containing delivery instructions\n     */\n    function send(\n        uint16 targetChain,\n        bytes32 targetAddress,\n        bytes memory payload,\n        uint256 receiverValue,\n        uint256 paymentForExtraReceiverValue,\n        bytes memory encodedExecutionParameters,\n        uint16 refundChain,\n        bytes32 refundAddress,\n        address deliveryProviderAddress,\n        VaaKey[] memory vaaKeys,\n        uint8 consistencyLevel\n    ) external payable returns (uint64 sequence);\n\n    /**\n     * @notice Publishes an instruction for the delivery provider at `deliveryProviderAddress`\n     * to relay a payload and VAAs specified by `vaaKeys` to the address `targetAddress` on chain `targetChain`\n     * with `msg.value` equal to\n     * receiverValue + (arbitrary amount that is paid for by paymentForExtraReceiverValue of this chain's wei) in targetChain wei.\n     *\n     * Any refunds (from leftover gas) will be sent to `refundAddress` on chain `refundChain`\n     * `targetAddress` must implement the IWormholeReceiver interface\n     *\n     * This function must be called with `msg.value` equal to\n     * quoteDeliveryPrice(targetChain, receiverValue, encodedExecutionParameters, deliveryProviderAddress) + paymentForExtraReceiverValue\n     *\n     * Note: MessageKeys can specify wormhole messages (VaaKeys) or other types of messages (ex. USDC CCTP attestations). Ensure the selected\n     * DeliveryProvider supports all the MessageKey.keyType values specified or it will not be delivered!\n     *\n     * @param targetChain in Wormhole Chain ID format\n     * @param targetAddress address to call on targetChain (that implements IWormholeReceiver), in Wormhole bytes32 format\n     * @param payload arbitrary bytes to pass in as parameter in call to `targetAddress`\n     * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units)\n     * @param paymentForExtraReceiverValue amount (in current chain currency units) to spend on extra receiverValue\n     *        (in addition to the `receiverValue` specified)\n     * @param encodedExecutionParameters encoded information on how to execute delivery that may impact pricing\n     *        e.g. for version EVM_V1, this is a struct that encodes the `gasLimit` with which to call `targetAddress`\n     * @param refundChain The chain to deliver any refund to, in Wormhole Chain ID format\n     * @param refundAddress The address on `refundChain` to deliver any refund to, in Wormhole bytes32 format\n     * @param deliveryProviderAddress The address of the desired delivery provider's implementation of IDeliveryProvider\n     * @param messageKeys Additional messagess to pass in as parameter in call to `targetAddress`\n     * @param consistencyLevel Consistency level with which to publish the delivery instructions - see\n     *        https://book.wormhole.com/wormhole/3_coreLayerContracts.html?highlight=consistency#consistency-levels\n     * @return sequence sequence number of published VAA containing delivery instructions\n     */\n    function send(\n        uint16 targetChain,\n        bytes32 targetAddress,\n        bytes memory payload,\n        uint256 receiverValue,\n        uint256 paymentForExtraReceiverValue,\n        bytes memory encodedExecutionParameters,\n        uint16 refundChain,\n        bytes32 refundAddress,\n        address deliveryProviderAddress,\n        MessageKey[] memory messageKeys,\n        uint8 consistencyLevel\n    ) external payable returns (uint64 sequence);\n\n    /**\n     * @notice Requests a previously published delivery instruction to be redelivered\n     * (e.g. with a different delivery provider)\n     *\n     * This function must be called with `msg.value` equal to\n     * quoteEVMDeliveryPrice(targetChain, newReceiverValue, newGasLimit, newDeliveryProviderAddress)\n     *\n     *  @notice *** This will only be able to succeed if the following is true **\n     *         - newGasLimit >= gas limit of the old instruction\n     *         - newReceiverValue >= receiver value of the old instruction\n     *         - newDeliveryProvider's `targetChainRefundPerGasUnused` >= old relay provider's `targetChainRefundPerGasUnused`\n     *\n     * @param deliveryVaaKey VaaKey identifying the wormhole message containing the\n     *        previously published delivery instructions\n     * @param targetChain The target chain that the original delivery targeted. Must match targetChain from original delivery instructions\n     * @param newReceiverValue new msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units)\n     * @param newGasLimit gas limit with which to call `targetAddress`. Any units of gas unused will be refunded according to the\n     *        `targetChainRefundPerGasUnused` rate quoted by the delivery provider, to the refund chain and address specified in the original request\n     * @param newDeliveryProviderAddress The address of the desired delivery provider's implementation of IDeliveryProvider\n     * @return sequence sequence number of published VAA containing redelivery instructions\n     *\n     * @notice *** This will only be able to succeed if the following is true **\n     *         - newGasLimit >= gas limit of the old instruction\n     *         - newReceiverValue >= receiver value of the old instruction\n     */\n    function resendToEvm(\n        VaaKey memory deliveryVaaKey,\n        uint16 targetChain,\n        uint256 newReceiverValue,\n        uint256 newGasLimit,\n        address newDeliveryProviderAddress\n    ) external payable returns (uint64 sequence);\n\n    /**\n     * @notice Requests a previously published delivery instruction to be redelivered\n     *\n     *\n     * This function must be called with `msg.value` equal to\n     * quoteDeliveryPrice(targetChain, newReceiverValue, newEncodedExecutionParameters, newDeliveryProviderAddress)\n     *\n     * @param deliveryVaaKey VaaKey identifying the wormhole message containing the\n     *        previously published delivery instructions\n     * @param targetChain The target chain that the original delivery targeted. Must match targetChain from original delivery instructions\n     * @param newReceiverValue new msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units)\n     * @param newEncodedExecutionParameters new encoded information on how to execute delivery that may impact pricing\n     *        e.g. for version EVM_V1, this is a struct that encodes the `gasLimit` with which to call `targetAddress`\n     * @param newDeliveryProviderAddress The address of the desired delivery provider's implementation of IDeliveryProvider\n     * @return sequence sequence number of published VAA containing redelivery instructions\n     *\n     *  @notice *** This will only be able to succeed if the following is true **\n     *         - (For EVM_V1) newGasLimit >= gas limit of the old instruction\n     *         - newReceiverValue >= receiver value of the old instruction\n     *         - (For EVM_V1) newDeliveryProvider's `targetChainRefundPerGasUnused` >= old relay provider's `targetChainRefundPerGasUnused`\n     */\n    function resend(\n        VaaKey memory deliveryVaaKey,\n        uint16 targetChain,\n        uint256 newReceiverValue,\n        bytes memory newEncodedExecutionParameters,\n        address newDeliveryProviderAddress\n    ) external payable returns (uint64 sequence);\n\n    /**\n     * @notice Returns the price to request a relay to chain `targetChain`, using the default delivery provider\n     *\n     * @param targetChain in Wormhole Chain ID format\n     * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units)\n     * @param gasLimit gas limit with which to call `targetAddress`.\n     * @return nativePriceQuote Price, in units of current chain currency, that the delivery provider charges to perform the relay\n     * @return targetChainRefundPerGasUnused amount of target chain currency that will be refunded per unit of gas unused,\n     *         if a refundAddress is specified.\n     *         Note: This value can be overridden by the delivery provider on the target chain. The returned value here should be considered to be a\n     *         promise by the delivery provider of the amount of refund per gas unused that will be returned to the refundAddress at the target chain.\n     *         If a delivery provider decides to override, this will be visible as part of the emitted Delivery event on the target chain.\n     */\n    function quoteEVMDeliveryPrice(\n        uint16 targetChain,\n        uint256 receiverValue,\n        uint256 gasLimit\n    )\n        external\n        view\n        returns (\n            uint256 nativePriceQuote,\n            uint256 targetChainRefundPerGasUnused\n        );\n\n    /**\n     * @notice Returns the price to request a relay to chain `targetChain`, using delivery provider `deliveryProviderAddress`\n     *\n     * @param targetChain in Wormhole Chain ID format\n     * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units)\n     * @param gasLimit gas limit with which to call `targetAddress`.\n     * @param deliveryProviderAddress The address of the desired delivery provider's implementation of IDeliveryProvider\n     * @return nativePriceQuote Price, in units of current chain currency, that the delivery provider charges to perform the relay\n     * @return targetChainRefundPerGasUnused amount of target chain currency that will be refunded per unit of gas unused,\n     *         if a refundAddress is specified\n     *         Note: This value can be overridden by the delivery provider on the target chain. The returned value here should be considered to be a\n     *         promise by the delivery provider of the amount of refund per gas unused that will be returned to the refundAddress at the target chain.\n     *         If a delivery provider decides to override, this will be visible as part of the emitted Delivery event on the target chain.\n     */\n    function quoteEVMDeliveryPrice(\n        uint16 targetChain,\n        uint256 receiverValue,\n        uint256 gasLimit,\n        address deliveryProviderAddress\n    )\n        external\n        view\n        returns (\n            uint256 nativePriceQuote,\n            uint256 targetChainRefundPerGasUnused\n        );\n\n    /**\n     * @notice Returns the price to request a relay to chain `targetChain`, using delivery provider `deliveryProviderAddress`\n     *\n     * @param targetChain in Wormhole Chain ID format\n     * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units)\n     * @param encodedExecutionParameters encoded information on how to execute delivery that may impact pricing\n     *        e.g. for version EVM_V1, this is a struct that encodes the `gasLimit` with which to call `targetAddress`\n     * @param deliveryProviderAddress The address of the desired delivery provider's implementation of IDeliveryProvider\n     * @return nativePriceQuote Price, in units of current chain currency, that the delivery provider charges to perform the relay\n     * @return encodedExecutionInfo encoded information on how the delivery will be executed\n     *        e.g. for version EVM_V1, this is a struct that encodes the `gasLimit` and `targetChainRefundPerGasUnused`\n     *             (which is the amount of target chain currency that will be refunded per unit of gas unused,\n     *              if a refundAddress is specified)\n     */\n    function quoteDeliveryPrice(\n        uint16 targetChain,\n        uint256 receiverValue,\n        bytes memory encodedExecutionParameters,\n        address deliveryProviderAddress\n    )\n        external\n        view\n        returns (uint256 nativePriceQuote, bytes memory encodedExecutionInfo);\n\n    /**\n     * @notice Returns the (extra) amount of target chain currency that `targetAddress`\n     * will be called with, if the `paymentForExtraReceiverValue` field is set to `currentChainAmount`\n     *\n     * @param targetChain in Wormhole Chain ID format\n     * @param currentChainAmount The value that `paymentForExtraReceiverValue` will be set to\n     * @param deliveryProviderAddress The address of the desired delivery provider's implementation of IDeliveryProvider\n     * @return targetChainAmount The amount such that if `targetAddress` will be called with `msg.value` equal to\n     *         receiverValue + targetChainAmount\n     */\n    function quoteNativeForChain(\n        uint16 targetChain,\n        uint256 currentChainAmount,\n        address deliveryProviderAddress\n    ) external view returns (uint256 targetChainAmount);\n\n    /**\n     * @notice Returns the address of the current default delivery provider\n     * @return deliveryProvider The address of (the default delivery provider)'s contract on this source\n     *   chain. This must be a contract that implements IDeliveryProvider.\n     */\n    function getDefaultDeliveryProvider()\n        external\n        view\n        returns (address deliveryProvider);\n}\n\n/**\n * @title IWormholeRelayerDelivery\n * @notice The interface to execute deliveries. Only relevant for Delivery Providers\n */\ninterface IWormholeRelayerDelivery is IWormholeRelayerBase {\n    enum DeliveryStatus {\n        SUCCESS,\n        RECEIVER_FAILURE\n    }\n\n    enum RefundStatus {\n        REFUND_SENT,\n        REFUND_FAIL,\n        CROSS_CHAIN_REFUND_SENT,\n        CROSS_CHAIN_REFUND_FAIL_PROVIDER_NOT_SUPPORTED,\n        CROSS_CHAIN_REFUND_FAIL_NOT_ENOUGH,\n        NO_REFUND_REQUESTED\n    }\n\n    /**\n     * @custom:member recipientContract - The target contract address\n     * @custom:member sourceChain - The chain which this delivery was requested from (in wormhole\n     *     ChainID format)\n     * @custom:member sequence - The wormhole sequence number of the delivery VAA on the source chain\n     *     corresponding to this delivery request\n     * @custom:member deliveryVaaHash - The hash of the delivery VAA corresponding to this delivery\n     *     request\n     * @custom:member gasUsed - The amount of gas that was used to call your target contract\n     * @custom:member status:\n     *   - RECEIVER_FAILURE, if the target contract reverts\n     *   - SUCCESS, if the target contract doesn't revert\n     * @custom:member additionalStatusInfo:\n     *   - If status is SUCCESS, then this is empty.\n     *   - If status is RECEIVER_FAILURE, this is `RETURNDATA_TRUNCATION_THRESHOLD` bytes of the\n     *       return data (i.e. potentially truncated revert reason information).\n     * @custom:member refundStatus - Result of the refund. REFUND_SUCCESS or REFUND_FAIL are for\n     *     refunds where targetChain=refundChain; the others are for targetChain!=refundChain,\n     *     where a cross chain refund is necessary, or if the default code path is used where no refund is requested (NO_REFUND_REQUESTED)\n     * @custom:member overridesInfo:\n     *   - If not an override: empty bytes array\n     *   - Otherwise: An encoded `DeliveryOverride`\n     */\n    event Delivery(\n        address indexed recipientContract,\n        uint16 indexed sourceChain,\n        uint64 indexed sequence,\n        bytes32 deliveryVaaHash,\n        DeliveryStatus status,\n        uint256 gasUsed,\n        RefundStatus refundStatus,\n        bytes additionalStatusInfo,\n        bytes overridesInfo\n    );\n\n    /**\n     * @notice The delivery provider calls `deliver` to relay messages as described by one delivery instruction\n     *\n     * The delivery provider must pass in the specified (by VaaKeys[]) signed wormhole messages (VAAs) from the source chain\n     * as well as the signed wormhole message with the delivery instructions (the delivery VAA)\n     *\n     * The messages will be relayed to the target address (with the specified gas limit and receiver value) iff the following checks are met:\n     * - the delivery VAA has a valid signature\n     * - the delivery VAA's emitter is one of these WormholeRelayer contracts\n     * - the delivery provider passed in at least enough of this chain's currency as msg.value (enough meaning the maximum possible refund)\n     * - the instruction's target chain is this chain\n     * - the relayed signed VAAs match the descriptions in container.messages (the VAA hashes match, or the emitter address, sequence number pair matches, depending on the description given)\n     *\n     * @param encodedVMs - An array of signed wormhole messages (all from the same source chain\n     *     transaction)\n     * @param encodedDeliveryVAA - Signed wormhole message from the source chain's WormholeRelayer\n     *     contract with payload being the encoded delivery instruction container\n     * @param relayerRefundAddress - The address to which any refunds to the delivery provider\n     *     should be sent\n     * @param deliveryOverrides - Optional overrides field which must be either an empty bytes array or\n     *     an encoded DeliveryOverride struct\n     */\n    function deliver(\n        bytes[] memory encodedVMs,\n        bytes memory encodedDeliveryVAA,\n        address payable relayerRefundAddress,\n        bytes memory deliveryOverrides\n    ) external payable;\n}\n\ninterface IWormholeRelayer is IWormholeRelayerDelivery, IWormholeRelayerSend {}\n\n/*\n *  Errors thrown by IWormholeRelayer contract\n */\n\n// Bound chosen by the following formula: `memoryWord * 4 + selectorSize`.\n// This means that an error identifier plus four fixed size arguments should be available to developers.\n// In the case of a `require` revert with error message, this should provide 2 memory word's worth of data.\nuint256 constant RETURNDATA_TRUNCATION_THRESHOLD = 132;\n\n//When msg.value was not equal to `delivery provider's quoted delivery price` + `paymentForExtraReceiverValue`\nerror InvalidMsgValue(uint256 msgValue, uint256 totalFee);\n\nerror RequestedGasLimitTooLow();\n\nerror DeliveryProviderDoesNotSupportTargetChain(\n    address relayer,\n    uint16 chainId\n);\nerror DeliveryProviderCannotReceivePayment();\nerror DeliveryProviderDoesNotSupportMessageKeyType(uint8 keyType);\n\n//When calling `delivery()` a second time even though a delivery is already in progress\nerror ReentrantDelivery(address msgSender, address lockedBy);\n\nerror InvalidPayloadId(uint8 parsed, uint8 expected);\nerror InvalidPayloadLength(uint256 received, uint256 expected);\nerror InvalidVaaKeyType(uint8 parsed);\nerror TooManyMessageKeys(uint256 numMessageKeys);\n\nerror InvalidDeliveryVaa(string reason);\n//When the delivery VAA (signed wormhole message with delivery instructions) was not emitted by the\n//  registered WormholeRelayer contract\nerror InvalidEmitter(bytes32 emitter, bytes32 registered, uint16 chainId);\nerror MessageKeysLengthDoesNotMatchMessagesLength(uint256 keys, uint256 vaas);\nerror VaaKeysDoNotMatchVaas(uint8 index);\n//When someone tries to call an external function of the WormholeRelayer that is only intended to be\n//  called by the WormholeRelayer itself (to allow retroactive reverts for atomicity)\nerror RequesterNotWormholeRelayer();\n\n//When trying to relay a `DeliveryInstruction` to any other chain but the one it was specified for\nerror TargetChainIsNotThisChain(uint16 targetChain);\n//When a `DeliveryOverride` contains a gas limit that's less than the original\nerror InvalidOverrideGasLimit();\n//When a `DeliveryOverride` contains a receiver value that's less than the original\nerror InvalidOverrideReceiverValue();\n//When a `DeliveryOverride` contains a 'refund per unit of gas unused' that's less than the original\nerror InvalidOverrideRefundPerGasUnused();\n\n//When the delivery provider doesn't pass in sufficient funds (i.e. msg.value does not cover the\n// maximum possible refund to the user)\nerror InsufficientRelayerFunds(uint256 msgValue, uint256 minimum);\n\n//When a bytes32 field can't be converted into a 20 byte EVM address, because the 12 padding bytes\n//  are non-zero (see Utils.sol)\n//error NotAnEvmAddress(bytes32);\n"},{"file_path":"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)\n\npragma solidity ^0.8.20;\n\nimport {ContextUpgradeable} from \"../utils/ContextUpgradeable.sol\";\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * The initial owner is set to the address provided by the deployer. This can\n * later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n    /// @custom:storage-location erc7201:openzeppelin.storage.Ownable\n    struct OwnableStorage {\n        address _owner;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.Ownable\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant OwnableStorageLocation = 0x9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300;\n\n    function _getOwnableStorage() private pure returns (OwnableStorage storage $) {\n        assembly {\n            $.slot := OwnableStorageLocation\n        }\n    }\n\n    /**\n     * @dev The caller account is not authorized to perform an operation.\n     */\n    error OwnableUnauthorizedAccount(address account);\n\n    /**\n     * @dev The owner is not a valid owner account. (eg. `address(0)`)\n     */\n    error OwnableInvalidOwner(address owner);\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.\n     */\n    function __Ownable_init(address initialOwner) internal onlyInitializing {\n        __Ownable_init_unchained(initialOwner);\n    }\n\n    function __Ownable_init_unchained(address initialOwner) internal onlyInitializing {\n        if (initialOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(initialOwner);\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        _checkOwner();\n        _;\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        OwnableStorage storage $ = _getOwnableStorage();\n        return $._owner;\n    }\n\n    /**\n     * @dev Throws if the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        if (owner() != _msgSender()) {\n            revert OwnableUnauthorizedAccount(_msgSender());\n        }\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby disabling any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        if (newOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        OwnableStorage storage $ = _getOwnableStorage();\n        address oldOwner = $._owner;\n        $._owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n"},{"file_path":"wormhole-solidity-sdk/Utils.sol","source_code":"\n// SPDX-License-Identifier: Apache 2\npragma solidity ^0.8.19;\n\nerror NotAnEvmAddress(bytes32);\n\nfunction toUniversalAddress(address addr) pure returns (bytes32 universalAddr) {\n    universalAddr = bytes32(uint256(uint160(addr)));\n}\n\nfunction fromUniversalAddress(bytes32 universalAddr) pure returns (address addr) {\n    if (bytes12(universalAddr) != 0)\n        revert NotAnEvmAddress(universalAddr);\n\n    assembly (\"memory-safe\") {\n        addr := universalAddr\n    }\n}\n"},{"file_path":"@securitize/digital_securities/contracts/utils/BaseDSContract.sol","source_code":"pragma solidity ^0.8.20;\n\nimport \"../service/ServiceConsumer.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\";\n\n//SPDX-License-Identifier: GPL-3.0\nabstract contract BaseDSContract is UUPSUpgradeable, ServiceConsumer {\n\n    function __BaseDSContract_init() public onlyProxy onlyInitializing {\n        __UUPSUpgradeable_init();\n        __ServiceConsumer_init();\n    }\n\n    /**\n     * @dev required by the OZ UUPS module\n     */\n    function _authorizeUpgrade(address) internal override onlyMaster {}\n\n    /**\n     * @dev returns proxy ERC1967 implementation address\n     */\n    function getImplementationAddress() external view returns (address) {\n        return ERC1967Utils.getImplementation();\n    }\n\n    /**\n     * @dev Returns the highest version that has been initialized. See {reinitializer}.\n     */\n    function getInitializedVersion() external view returns (uint64) {\n        return _getInitializedVersion();\n    }\n\n}\n"},{"file_path":"@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/Pausable.sol)\n\npragma solidity ^0.8.20;\n\nimport {ContextUpgradeable} from \"../utils/ContextUpgradeable.sol\";\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\n    /// @custom:storage-location erc7201:openzeppelin.storage.Pausable\n    struct PausableStorage {\n        bool _paused;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.Pausable\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant PausableStorageLocation = 0xcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f03300;\n\n    function _getPausableStorage() private pure returns (PausableStorage storage $) {\n        assembly {\n            $.slot := PausableStorageLocation\n        }\n    }\n\n    /**\n     * @dev Emitted when the pause is triggered by `account`.\n     */\n    event Paused(address account);\n\n    /**\n     * @dev Emitted when the pause is lifted by `account`.\n     */\n    event Unpaused(address account);\n\n    /**\n     * @dev The operation failed because the contract is paused.\n     */\n    error EnforcedPause();\n\n    /**\n     * @dev The operation failed because the contract is not paused.\n     */\n    error ExpectedPause();\n\n    /**\n     * @dev Initializes the contract in unpaused state.\n     */\n    function __Pausable_init() internal onlyInitializing {\n        __Pausable_init_unchained();\n    }\n\n    function __Pausable_init_unchained() internal onlyInitializing {\n        PausableStorage storage $ = _getPausableStorage();\n        $._paused = false;\n    }\n\n    /**\n     * @dev Modifier to make a function callable only when the contract is not paused.\n     *\n     * Requirements:\n     *\n     * - The contract must not be paused.\n     */\n    modifier whenNotPaused() {\n        _requireNotPaused();\n        _;\n    }\n\n    /**\n     * @dev Modifier to make a function callable only when the contract is paused.\n     *\n     * Requirements:\n     *\n     * - The contract must be paused.\n     */\n    modifier whenPaused() {\n        _requirePaused();\n        _;\n    }\n\n    /**\n     * @dev Returns true if the contract is paused, and false otherwise.\n     */\n    function paused() public view virtual returns (bool) {\n        PausableStorage storage $ = _getPausableStorage();\n        return $._paused;\n    }\n\n    /**\n     * @dev Throws if the contract is paused.\n     */\n    function _requireNotPaused() internal view virtual {\n        if (paused()) {\n            revert EnforcedPause();\n        }\n    }\n\n    /**\n     * @dev Throws if the contract is not paused.\n     */\n    function _requirePaused() internal view virtual {\n        if (!paused()) {\n            revert ExpectedPause();\n        }\n    }\n\n    /**\n     * @dev Triggers stopped state.\n     *\n     * Requirements:\n     *\n     * - The contract must not be paused.\n     */\n    function _pause() internal virtual whenNotPaused {\n        PausableStorage storage $ = _getPausableStorage();\n        $._paused = true;\n        emit Paused(_msgSender());\n    }\n\n    /**\n     * @dev Returns to normal state.\n     *\n     * Requirements:\n     *\n     * - The contract must be paused.\n     */\n    function _unpause() internal virtual whenPaused {\n        PausableStorage storage $ = _getPausableStorage();\n        $._paused = false;\n        emit Unpaused(_msgSender());\n    }\n}\n"},{"file_path":"@securitize/digital_securities/contracts/omnibus/IDSOmnibusWalletController.sol","source_code":"pragma solidity ^0.8.20;\n\n//SPDX-License-Identifier: GPL-3.0\nabstract contract IDSOmnibusWalletController {\n    uint8 public constant BENEFICIARY = 0;\n    uint8 public constant HOLDER_OF_RECORD = 1;\n\n    function initialize(address _omnibusWallet) public virtual;\n\n    function setAssetTrackingMode(uint8 _assetTrackingMode) public virtual;\n\n    function getAssetTrackingMode() public view virtual returns (uint8);\n\n    function isHolderOfRecord() public view virtual returns (bool);\n\n    function balanceOf(address _who) public view virtual returns (uint256);\n\n    function transfer(\n        address _from,\n        address _to,\n        uint256 _value /*onlyOperator*/\n    ) public virtual;\n\n    function deposit(\n        address _to,\n        uint256 _value /*onlyToken*/\n    ) public virtual;\n\n    function withdraw(\n        address _from,\n        uint256 _value /*onlyToken*/\n    ) public virtual;\n\n    function seize(\n        address _from,\n        uint256 _value /*onlyToken*/\n    ) public virtual;\n\n    function burn(\n        address _from,\n        uint256 _value /*onlyToken*/\n    ) public virtual;\n}\n"},{"file_path":"@openzeppelin/contracts/utils/StorageSlot.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/StorageSlot.sol)\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```solidity\n * contract ERC1967 {\n *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n *     function _getImplementation() internal view returns (address) {\n *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n *     }\n *\n *     function _setImplementation(address newImplementation) internal {\n *         require(newImplementation.code.length > 0);\n *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n *     }\n * }\n * ```\n */\nlibrary StorageSlot {\n    struct AddressSlot {\n        address value;\n    }\n\n    struct BooleanSlot {\n        bool value;\n    }\n\n    struct Bytes32Slot {\n        bytes32 value;\n    }\n\n    struct Uint256Slot {\n        uint256 value;\n    }\n\n    struct StringSlot {\n        string value;\n    }\n\n    struct BytesSlot {\n        bytes value;\n    }\n\n    /**\n     * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n     */\n    function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n     */\n    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n     */\n    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n     */\n    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `StringSlot` with member `value` located at `slot`.\n     */\n    function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\n     */\n    function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := store.slot\n        }\n    }\n\n    /**\n     * @dev Returns an `BytesSlot` with member `value` located at `slot`.\n     */\n    function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\n     */\n    function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := store.slot\n        }\n    }\n}\n"},{"file_path":"@securitize/digital_securities/contracts/compliance/IDSLockManager.sol","source_code":"pragma solidity ^0.8.20;\n\n//SPDX-License-Identifier: GPL-3.0\nabstract contract IDSLockManager {\n\n    function initialize() public virtual;\n\n    modifier validLock(uint256 _valueLocked, uint256 _releaseTime) {\n        require(_valueLocked > 0, \"Value is zero\");\n        require(_releaseTime == 0 || _releaseTime > uint256(block.timestamp), \"Release time is in the past\");\n        _;\n    }\n\n    event Locked(address indexed who, uint256 value, uint256 indexed reason, string reasonString, uint256 releaseTime);\n    event Unlocked(address indexed who, uint256 value, uint256 indexed reason, string reasonString, uint256 releaseTime);\n\n    event HolderLocked(string holderId, uint256 value, uint256 indexed reason, string reasonString, uint256 releaseTime);\n    event HolderUnlocked(string holderId, uint256 value, uint256 indexed reason, string reasonString, uint256 releaseTime);\n    /**\n     * @dev creates a lock record for wallet address\n     * @param _to address to lock the tokens at\n     * @param _valueLocked value of tokens to lock\n     * @param _reason reason for lock\n     * @param _releaseTime timestamp to release the lock (or 0 for locks which can only released by an unlockTokens call)\n     * Note: The user MAY have at a certain time more locked tokens than actual tokens\n     */\n\n    function addManualLockRecord(\n        address _to,\n        uint256 _valueLocked,\n        string calldata _reason,\n        uint256 _releaseTime /*issuerOrAboveOrToken*/\n    ) public virtual;\n\n    /**\n     * @dev creates a lock record for investor Id\n     * @param _investor investor id to lock the tokens at\n     * @param _valueLocked value of tokens to lock\n     * @param _reasonCode reason code for lock\n     * @param _reasonString reason for lock\n     * @param _releaseTime timestamp to release the lock (or 0 for locks which can only released by an unlockTokens call)\n     * Note: The user MAY have at a certain time more locked tokens than actual tokens\n     */\n\n    function createLockForInvestor(\n        string memory _investor,\n        uint256 _valueLocked,\n        uint256 _reasonCode,\n        string calldata _reasonString,\n        uint256 _releaseTime /*onlyIssuerOrAboveOrToken*/\n    ) public virtual;\n\n    /**\n     * @dev Releases a specific lock record for a wallet\n     * @param _to address to release the tokens for\n     * @param _lockIndex the index of the lock to remove\n     *\n     * note - this may change the order of the locks on an address, so if iterating the iteration should be restarted.\n     * @return true on success\n     */\n    function removeLockRecord(\n        address _to,\n        uint256 _lockIndex /*issuerOrAbove*/\n    ) public virtual returns (bool);\n\n    /**\n     * @dev Releases a specific lock record for a investor\n     * @param _investorId investor id to release the tokens for\n     * @param _lockIndex the index of the lock to remove\n     *\n     * note - this may change the order of the locks on an address, so if iterating the iteration should be restarted.\n     * @return true on success\n     */\n    function removeLockRecordForInvestor(\n        string memory _investorId,\n        uint256 _lockIndex /*onlyIssuerOrAbove*/\n    ) public virtual returns (bool);\n\n    /**\n     * @dev Get number of locks currently associated with an address\n     * @param _who address to get count for\n     *\n     * @return number of locks\n     *\n     * Note - a lock can be inactive (due to its time expired) but still exists for a specific address\n     */\n    function lockCount(address _who) public view virtual returns (uint256);\n\n    /**\n     * @dev Get number of locks currently associated with a investor\n     * @param _investorId investor id to get count for\n     *\n     * @return number of locks\n     *\n     * Note - a lock can be inactive (due to its time expired) but still exists for a specific address\n     */\n\n    function lockCountForInvestor(string memory _investorId) public view virtual returns (uint256);\n\n    /**\n     * @dev Get details of a specific lock associated with an address\n     * can be used to iterate through the locks of a user\n     * @param _who address to get token lock for\n     * @param _lockIndex the 0 based index of the lock.\n     * @return reasonCode the reason code\n     * @return reasonString the reason for the lock\n     * @return value the value of tokens locked\n     * @return autoReleaseTime the timestamp in which the lock will be inactive (or 0 if it's always active until removed)\n     *\n     * Note - a lock can be inactive (due to its time expired) but still exists for a specific address\n     */\n    function lockInfo(address _who, uint256 _lockIndex) public view virtual returns (uint256 reasonCode, string memory reasonString, uint256 value, uint256 autoReleaseTime);\n\n    /**\n     * @dev Get details of a specific lock associated with a investor\n     * can be used to iterate through the locks of a user\n     * @param _investorId investorId to get token lock for\n     * @param _lockIndex the 0 based index of the lock.\n     * @return reasonCode the reason code\n     * @return reasonString the reason for the lock\n     * @return value the value of tokens locked\n     * @return autoReleaseTime the timestamp in which the lock will be inactive (or 0 if it's always active until removed)\n     *\n     * Note - a lock can be inactive (due to its time expired) but still exists for a specific address\n     */\n    function lockInfoForInvestor(\n        string memory _investorId,\n        uint256 _lockIndex\n    ) public view virtual  returns (uint256 reasonCode, string memory reasonString, uint256 value, uint256 autoReleaseTime);\n\n    /**\n     * @dev get total number of transferable tokens for a wallet, at a certain time\n     * @param _who address to get number of transferable tokens for\n     * @param _time time to calculate for\n     */\n    function getTransferableTokens(address _who, uint256 _time) public view virtual returns (uint256);\n\n    /**\n     * @dev get total number of transferable tokens for a investor, at a certain time\n     * @param _investorId investor id\n     * @param _time time to calculate for\n     */\n    function getTransferableTokensForInvestor(string memory _investorId, uint256 _time) public view virtual returns (uint256);\n\n    /**\n     * @dev pause investor\n     * @param _investorId investor id\n     */\n    function lockInvestor(\n        string memory _investorId /*issuerOrAbove*/\n    ) public virtual returns (bool);\n\n    /**\n     * @dev unpauses investor\n     * @param _investorId investor id\n     */\n    function unlockInvestor(\n        string memory _investorId /*issuerOrAbove*/\n    ) public virtual returns (bool);\n\n    /**\n     * @dev Returns true if paused, otherwise false\n     * @param _investorId investor id\n     */\n    function isInvestorLocked(string memory _investorId) public view virtual returns (bool);\n}\n"},{"file_path":"@securitize/digital_securities/contracts/issuance/IDSTokenIssuer.sol","source_code":"pragma solidity ^0.8.20;\n\n//SPDX-License-Identifier: GPL-3.0\nabstract contract IDSTokenIssuer {\n\n    function initialize() public virtual;\n\n    //Same values as IDSRegistryService\n    uint8 public constant KYC_APPROVED = 1;\n    uint8 public constant ACCREDITED = 2;\n    uint8 public constant QUALIFIED = 4;\n\n\n    function issueTokens(\n        string memory _id,\n        address _to,\n        uint256[] memory _issuanceValues,\n        string calldata _reason,\n        uint256[] memory _locksValues,\n        uint64[] memory _lockReleaseTimes,\n        string memory _collisionHash,\n        string memory _country,\n        uint256[] memory attributeValues,\n        uint256[] memory attributeExpirations /*onlyIssuerOrAbove*/\n    ) public virtual returns (bool);\n}\n"},{"file_path":"contracts/utils/BaseContract.sol","source_code":"//SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.20;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\";\n\nabstract contract BaseContract is UUPSUpgradeable, PausableUpgradeable, OwnableUpgradeable {\n\n    function __BaseDSContract_init(address owner) internal onlyInitializing {\n        __UUPSUpgradeable_init();\n        __Pausable_init();\n        __Ownable_init(owner);\n    }\n\n    /**\n     * @dev required by the OZ UUPS module\n     */\n    function _authorizeUpgrade(address) internal override onlyOwner {}\n\n    /**\n     * @dev returns proxy ERC1967 implementation address\n     */\n    function getImplementationAddress() external view returns (address) {\n        return ERC1967Utils.getImplementation();\n    }\n\n    /**\n     * @dev Returns the highest version that has been initialized. See {reinitializer}.\n     */\n    function getInitializedVersion() external view returns (uint64) {\n        return _getInitializedVersion();\n    }\n\n    function pause() onlyOwner external {\n        _pause();\n    }\n\n    function unpause() onlyOwner external {\n        _unpause();\n    }\n}\n"},{"file_path":"@openzeppelin/contracts/interfaces/draft-IERC1822.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822Proxiable {\n    /**\n     * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n     * address.\n     *\n     * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n     * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n     * function revert if invoked through a proxy.\n     */\n    function proxiableUUID() external view returns (bytes32);\n}\n"},{"file_path":"@securitize/digital_securities/contracts/trust/IDSTrustService.sol","source_code":"pragma solidity ^0.8.20;\n\n/**\n * @title IDSTrustService\n * @dev An interface for a trust service which allows role-based access control for other contracts.\n */\n//SPDX-License-Identifier: GPL-3.0\nabstract contract IDSTrustService {\n\n    function initialize() public virtual;\n\n    /**\n     * @dev Should be emitted when a role is set for a user.\n     */\n    event DSTrustServiceRoleAdded(address targetAddress, uint8 role, address sender);\n    /**\n     * @dev Should be emitted when a role is removed for a user.\n     */\n    event DSTrustServiceRoleRemoved(address targetAddress, uint8 role, address sender);\n\n    // Role constants\n    uint8 public constant NONE = 0;\n    uint8 public constant MASTER = 1;\n    uint8 public constant ISSUER = 2;\n    uint8 public constant EXCHANGE = 4;\n    uint8 public constant TRANSFER_AGENT = 8;\n\n    /**\n     * @dev Transfers the ownership (MASTER role) of the contract.\n     * @param _address The address which the ownership needs to be transferred to.\n     * @return A boolean that indicates if the operation was successful.\n     */\n    function setServiceOwner(\n        address _address /*onlyMaster*/\n    ) public virtual returns (bool);\n\n    /**\n     * @dev Sets a role for an array of wallets.\n     * @dev Should not be used for setting MASTER (use setServiceOwner) or role removal (use removeRole).\n     * @param _addresses The array of wallet whose role needs to be set.\n     * @param _roles The array of role to be set. The length and order must match with _addresses\n     * @return A boolean that indicates if the operation was successful.\n     */\n    function setRoles(address[] calldata _addresses, uint8[] calldata _roles) public virtual returns (bool);\n\n    /**\n     * @dev Sets a role for a wallet.\n     * @dev Should not be used for setting MASTER (use setServiceOwner) or role removal (use removeRole).\n     * @param _address The wallet whose role needs to be set.\n     * @param _role The role to be set.\n     * @return A boolean that indicates if the operation was successful.\n     */\n    function setRole(\n        address _address,\n        uint8 _role /*onlyMasterOrIssuer*/\n    ) public virtual returns (bool);\n\n    /**\n     * @dev Removes the role for a wallet.\n     * @dev Should not be used to remove MASTER (use setServiceOwner).\n     * @param _address The wallet whose role needs to be removed.\n     * @return A boolean that indicates if the operation was successful.\n     */\n    function removeRole(\n        address _address /*onlyMasterOrIssuer*/\n    ) public virtual returns (bool);\n\n    /**\n     * @dev Gets the role for a wallet.\n     * @param _address The wallet whose role needs to be fetched.\n     * @return A boolean that indicates if the operation was successful.\n     */\n    function getRole(address _address) public view virtual returns (uint8);\n\n    function addEntity(\n        string calldata _name,\n        address _owner /*onlyMasterOrIssuer onlyNewEntity onlyNewEntityOwner*/\n    ) public virtual;\n\n    function changeEntityOwner(\n        string calldata _name,\n        address _oldOwner,\n        address _newOwner /*onlyMasterOrIssuer onlyExistingEntityOwner*/\n    ) public virtual;\n\n    function addOperator(\n        string calldata _name,\n        address _operator /*onlyEntityOwnerOrAbove onlyNewOperator*/\n    ) public virtual;\n\n    function removeOperator(\n        string calldata _name,\n        address _operator /*onlyEntityOwnerOrAbove onlyExistingOperator*/\n    ) public virtual;\n\n    function addResource(\n        string calldata _name,\n        address _resource /*onlyMasterOrIssuer onlyExistingEntity onlyNewResource*/\n    ) public virtual;\n\n    function removeResource(\n        string calldata _name,\n        address _resource /*onlyMasterOrIssuer onlyExistingResource*/\n    ) public virtual;\n\n    function getEntityByOwner(address _owner) public view virtual returns (string memory);\n\n    function getEntityByOperator(address _operator) public view virtual returns (string memory);\n\n    function getEntityByResource(address _resource) public view virtual returns (string memory);\n\n    function isResourceOwner(address _resource, address _owner) public view virtual returns (bool);\n\n    function isResourceOperator(address _resource, address _operator) public view virtual returns (bool);\n}\n"},{"file_path":"@openzeppelin/contracts/token/ERC20/IERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the value of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the value of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the\n     * allowance mechanism. `value` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 value) external returns (bool);\n}\n"},{"file_path":"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/UUPSUpgradeable.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC1822Proxiable} from \"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\";\nimport {ERC1967Utils} from \"@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils.sol\";\nimport {Initializable} from \"./Initializable.sol\";\n\n/**\n * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an\n * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.\n *\n * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\n * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\n * `UUPSUpgradeable` with a custom implementation of upgrades.\n *\n * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.\n */\nabstract contract UUPSUpgradeable is Initializable, IERC1822Proxiable {\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n    address private immutable __self = address(this);\n\n    /**\n     * @dev The version of the upgrade interface of the contract. If this getter is missing, both `upgradeTo(address)`\n     * and `upgradeToAndCall(address,bytes)` are present, and `upgradeTo` must be used if no function should be called,\n     * while `upgradeToAndCall` will invoke the `receive` function if the second argument is the empty byte string.\n     * If the getter returns `\"5.0.0\"`, only `upgradeToAndCall(address,bytes)` is present, and the second argument must\n     * be the empty byte string if no function should be called, making it impossible to invoke the `receive` function\n     * during an upgrade.\n     */\n    string public constant UPGRADE_INTERFACE_VERSION = \"5.0.0\";\n\n    /**\n     * @dev The call is from an unauthorized context.\n     */\n    error UUPSUnauthorizedCallContext();\n\n    /**\n     * @dev The storage `slot` is unsupported as a UUID.\n     */\n    error UUPSUnsupportedProxiableUUID(bytes32 slot);\n\n    /**\n     * @dev Check that the execution is being performed through a delegatecall call and that the execution context is\n     * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case\n     * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a\n     * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to\n     * fail.\n     */\n    modifier onlyProxy() {\n        _checkProxy();\n        _;\n    }\n\n    /**\n     * @dev Check that the execution is not being performed through a delegate call. This allows a function to be\n     * callable on the implementing contract but not through proxies.\n     */\n    modifier notDelegated() {\n        _checkNotDelegated();\n        _;\n    }\n\n    function __UUPSUpgradeable_init() internal onlyInitializing {\n    }\n\n    function __UUPSUpgradeable_init_unchained() internal onlyInitializing {\n    }\n    /**\n     * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the\n     * implementation. It is used to validate the implementation's compatibility when performing an upgrade.\n     *\n     * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n     * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n     * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\n     */\n    function proxiableUUID() external view virtual notDelegated returns (bytes32) {\n        return ERC1967Utils.IMPLEMENTATION_SLOT;\n    }\n\n    /**\n     * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call\n     * encoded in `data`.\n     *\n     * Calls {_authorizeUpgrade}.\n     *\n     * Emits an {Upgraded} event.\n     *\n     * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\n     */\n    function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy {\n        _authorizeUpgrade(newImplementation);\n        _upgradeToAndCallUUPS(newImplementation, data);\n    }\n\n    /**\n     * @dev Reverts if the execution is not performed via delegatecall or the execution\n     * context is not of a proxy with an ERC1967-compliant implementation pointing to self.\n     * See {_onlyProxy}.\n     */\n    function _checkProxy() internal view virtual {\n        if (\n            address(this) == __self || // Must be called through delegatecall\n            ERC1967Utils.getImplementation() != __self // Must be called through an active proxy\n        ) {\n            revert UUPSUnauthorizedCallContext();\n        }\n    }\n\n    /**\n     * @dev Reverts if the execution is performed via delegatecall.\n     * See {notDelegated}.\n     */\n    function _checkNotDelegated() internal view virtual {\n        if (address(this) != __self) {\n            // Must not be called through delegatecall\n            revert UUPSUnauthorizedCallContext();\n        }\n    }\n\n    /**\n     * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by\n     * {upgradeToAndCall}.\n     *\n     * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.\n     *\n     * ```solidity\n     * function _authorizeUpgrade(address) internal onlyOwner {}\n     * ```\n     */\n    function _authorizeUpgrade(address newImplementation) internal virtual;\n\n    /**\n     * @dev Performs an implementation upgrade with a security check for UUPS proxies, and additional setup call.\n     *\n     * As a security check, {proxiableUUID} is invoked in the new implementation, and the return value\n     * is expected to be the implementation slot in ERC1967.\n     *\n     * Emits an {IERC1967-Upgraded} event.\n     */\n    function _upgradeToAndCallUUPS(address newImplementation, bytes memory data) private {\n        try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n            if (slot != ERC1967Utils.IMPLEMENTATION_SLOT) {\n                revert UUPSUnsupportedProxiableUUID(slot);\n            }\n            ERC1967Utils.upgradeToAndCall(newImplementation, data);\n        } catch {\n            // The implementation is not UUPS\n            revert ERC1967Utils.ERC1967InvalidImplementation(newImplementation);\n        }\n    }\n}\n"},{"file_path":"@securitize/digital_securities/contracts/token/IDSToken.sol","source_code":"pragma solidity ^0.8.20;\n\nimport \"@openzeppelin/contracts/interfaces/IERC20.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../utils/CommonUtils.sol\";\nimport \"../omnibus/IDSOmnibusWalletController.sol\";\n\n//SPDX-License-Identifier: GPL-3.0\nabstract contract IDSToken is IERC20, Initializable {\n    event Issue(address indexed to, uint256 value, uint256 valueLocked);\n    event Burn(address indexed burner, uint256 value, string reason);\n    event Seize(address indexed from, address indexed to, uint256 value, string reason);\n    event OmnibusDeposit(address indexed omnibusWallet, address to, uint256 value, uint8 assetTrackingMode);\n    event OmnibusWithdraw(address indexed omnibusWallet, address from, uint256 value, uint8 assetTrackingMode);\n    event OmnibusSeize(address indexed omnibusWallet, address from, uint256 value, string reason, uint8 assetTrackingMode);\n    event OmnibusBurn(address indexed omnibusWallet, address who, uint256 value, string reason, uint8 assetTrackingMode);\n    event OmnibusTransfer(address indexed omnibusWallet, address from, address to, uint256 value, uint8 assetTrackingMode);\n    event OmnibusTBEOperation(address indexed omnibusWallet, int256 totalDelta, int256 accreditedDelta,\n        int256 usAccreditedDelta, int256 usTotalDelta, int256 jpTotalDelta);\n    event OmnibusTBETransfer(address omnibusWallet, string externalId);\n\n    event WalletAdded(address wallet);\n    event WalletRemoved(address wallet);\n\n    function initialize(string calldata _name, string calldata _symbol, uint8 _decimals) public virtual;\n\n    /******************************\n       CONFIGURATION\n   *******************************/\n\n    /**\n     * @dev Sets the total issuance cap\n     * Note: The cap is compared to the total number of issued token, not the total number of tokens available,\n     * So if a token is burned, it is not removed from the \"total number of issued\".\n     * This call cannot be called again after it was called once.\n     * @param _cap address The address which is going to receive the newly issued tokens\n     */\n    function setCap(\n        uint256 _cap /*onlyMaster*/\n    ) public virtual;\n\n    /******************************\n       TOKEN ISSUANCE (MINTING)\n   *******************************/\n\n    /**\n     * @dev Issues unlocked tokens\n     * @param _to address The address which is going to receive the newly issued tokens\n     * @param _value uint256 the value of tokens to issue\n     * @return true if successful\n     */\n    function issueTokens(\n        address _to,\n        uint256 _value /*onlyIssuerOrAbove*/\n    ) public virtual returns (bool);\n\n    /**\n     * @dev Issuing tokens from the fund\n     * @param _to address The address which is going to receive the newly issued tokens\n     * @param _value uint256 the value of tokens to issue\n     * @param _valueLocked uint256 value of tokens, from those issued, to lock immediately.\n     * @param _reason reason for token locking\n     * @param _releaseTime timestamp to release the lock (or 0 for locks which can only released by an unlockTokens call)\n     * @return true if successful\n     */\n    function issueTokensCustom(\n        address _to,\n        uint256 _value,\n        uint256 _issuanceTime,\n        uint256 _valueLocked,\n        string memory _reason,\n        uint64 _releaseTime /*onlyIssuerOrAbove*/\n    ) public virtual returns (bool);\n\n    function issueTokensWithMultipleLocks(\n        address _to,\n        uint256 _value,\n        uint256 _issuanceTime,\n        uint256[] memory _valuesLocked,\n        string memory _reason,\n        uint64[] memory _releaseTimes /*onlyIssuerOrAbove*/\n    ) public virtual returns (bool);\n\n    function issueTokensWithNoCompliance(address _to, uint256 _value) public virtual /*onlyIssuerOrAbove*/;\n\n    //*********************\n    // TOKEN BURNING\n    //*********************\n\n    function burn(\n        address _who,\n        uint256 _value,\n        string calldata _reason /*onlyIssuerOrAbove*/\n    ) public virtual;\n\n    function omnibusBurn(\n        address _omnibusWallet,\n        address _who,\n        uint256 _value,\n        string calldata _reason /*onlyIssuerOrAbove*/\n    ) public virtual;\n\n    //*********************\n    // TOKEN SIEZING\n    //*********************\n\n    function seize(\n        address _from,\n        address _to,\n        uint256 _value,\n        string calldata _reason /*onlyIssuerOrAbove*/\n    ) public virtual;\n\n    function omnibusSeize(\n        address _omnibusWallet,\n        address _from,\n        address _to,\n        uint256 _value,\n        string calldata\n        /*onlyIssuerOrAbove*/\n    ) public virtual;\n\n    //*********************\n    // WALLET ENUMERATION\n    //*********************\n\n    function getWalletAt(uint256 _index) public view virtual returns (address);\n\n    function walletCount() public view virtual returns (uint256);\n\n    //**************************************\n    // MISCELLANEOUS FUNCTIONS\n    //**************************************\n    function isPaused() public view virtual returns (bool);\n\n    function balanceOfInvestor(string memory _id) public view virtual returns (uint256);\n\n    function updateOmnibusInvestorBalance(\n        address _omnibusWallet,\n        address _wallet,\n        uint256 _value,\n        CommonUtils.IncDec _increase /*onlyOmnibusWalletController*/\n    ) public virtual returns (bool);\n\n    function emitOmnibusTransferEvent(\n        address _omnibusWallet,\n        address _from,\n        address _to,\n        uint256 _value /*onlyOmnibusWalletController*/\n    ) public virtual;\n\n    function emitOmnibusTBEEvent(address omnibusWallet, int256 totalDelta, int256 accreditedDelta,\n        int256 usAccreditedDelta, int256 usTotalDelta, int256 jpTotalDelta /*onlyTBEOmnibus*/\n    ) public virtual;\n\n    function emitOmnibusTBETransferEvent(address omnibusWallet, string memory externalId) public virtual;\n\n    function updateInvestorBalance(address _wallet, uint256 _value, CommonUtils.IncDec _increase) internal virtual returns (bool);\n\n    function preTransferCheck(address _from, address _to, uint256 _value) public view virtual returns (uint256 code, string memory reason);\n}\n"},{"file_path":"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n *     function initialize() initializer public {\n *         __ERC20_init(\"MyToken\", \"MTK\");\n *     }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n *     function initializeV2() reinitializer(2) public {\n *         __ERC20Permit_init(\"MyToken\");\n *     }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n *     _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n    /**\n     * @dev Storage of the initializable contract.\n     *\n     * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions\n     * when using with upgradeable contracts.\n     *\n     * @custom:storage-location erc7201:openzeppelin.storage.Initializable\n     */\n    struct InitializableStorage {\n        /**\n         * @dev Indicates that the contract has been initialized.\n         */\n        uint64 _initialized;\n        /**\n         * @dev Indicates that the contract is in the process of being initialized.\n         */\n        bool _initializing;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.Initializable\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;\n\n    /**\n     * @dev The contract is already initialized.\n     */\n    error InvalidInitialization();\n\n    /**\n     * @dev The contract is not initializing.\n     */\n    error NotInitializing();\n\n    /**\n     * @dev Triggered when the contract has been initialized or reinitialized.\n     */\n    event Initialized(uint64 version);\n\n    /**\n     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n     * `onlyInitializing` functions can be used to initialize parent contracts.\n     *\n     * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any\n     * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in\n     * production.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier initializer() {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        // Cache values to avoid duplicated sloads\n        bool isTopLevelCall = !$._initializing;\n        uint64 initialized = $._initialized;\n\n        // Allowed calls:\n        // - initialSetup: the contract is not in the initializing state and no previous version was\n        //                 initialized\n        // - construction: the contract is initialized at version 1 (no reininitialization) and the\n        //                 current contract is just being deployed\n        bool initialSetup = initialized == 0 && isTopLevelCall;\n        bool construction = initialized == 1 && address(this).code.length == 0;\n\n        if (!initialSetup && !construction) {\n            revert InvalidInitialization();\n        }\n        $._initialized = 1;\n        if (isTopLevelCall) {\n            $._initializing = true;\n        }\n        _;\n        if (isTopLevelCall) {\n            $._initializing = false;\n            emit Initialized(1);\n        }\n    }\n\n    /**\n     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n     * used to initialize parent contracts.\n     *\n     * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n     * are added through upgrades and that require initialization.\n     *\n     * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n     * cannot be nested. If one is invoked in the context of another, execution will revert.\n     *\n     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n     * a contract, executing them in the right order is up to the developer or operator.\n     *\n     * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier reinitializer(uint64 version) {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        if ($._initializing || $._initialized >= version) {\n            revert InvalidInitialization();\n        }\n        $._initialized = version;\n        $._initializing = true;\n        _;\n        $._initializing = false;\n        emit Initialized(version);\n    }\n\n    /**\n     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n     * {initializer} and {reinitializer} modifiers, directly or indirectly.\n     */\n    modifier onlyInitializing() {\n        _checkInitializing();\n        _;\n    }\n\n    /**\n     * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.\n     */\n    function _checkInitializing() internal view virtual {\n        if (!_isInitializing()) {\n            revert NotInitializing();\n        }\n    }\n\n    /**\n     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n     * through proxies.\n     *\n     * Emits an {Initialized} event the first time it is successfully executed.\n     */\n    function _disableInitializers() internal virtual {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        if ($._initializing) {\n            revert InvalidInitialization();\n        }\n        if ($._initialized != type(uint64).max) {\n            $._initialized = type(uint64).max;\n            emit Initialized(type(uint64).max);\n        }\n    }\n\n    /**\n     * @dev Returns the highest version that has been initialized. See {reinitializer}.\n     */\n    function _getInitializedVersion() internal view returns (uint64) {\n        return _getInitializableStorage()._initialized;\n    }\n\n    /**\n     * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n     */\n    function _isInitializing() internal view returns (bool) {\n        return _getInitializableStorage()._initializing;\n    }\n\n    /**\n     * @dev Returns a pointer to the storage namespace.\n     */\n    // solhint-disable-next-line var-name-mixedcase\n    function _getInitializableStorage() private pure returns (InitializableStorage storage $) {\n        assembly {\n            $.slot := INITIALIZABLE_STORAGE\n        }\n    }\n}\n"},{"file_path":"@securitize/digital_securities/contracts/omnibus/IDSOmnibusTBEController.sol","source_code":"pragma solidity ^0.8.20;\n\nimport \"../service/ServiceConsumer.sol\";\nimport \"../data-stores/OmnibusTBEControllerDataStore.sol\";\n\n//SPDX-License-Identifier: GPL-3.0\nabstract contract IDSOmnibusTBEController {\n\n    function initialize(address _omnibusWallet, bool _isPartitionedToken) public virtual;\n\n    function bulkIssuance(\n        uint256 value,\n        uint256 issuanceTime,\n        uint256 totalInvestors,\n        uint256 accreditedInvestors,\n        uint256 usAccreditedInvestors,\n        uint256 usTotalInvestors,\n        uint256 jpTotalInvestors,\n        bytes32[] calldata euRetailCountries,\n        uint256[] calldata euRetailCountryCounts\n    ) public virtual;\n\n    function bulkBurn(\n        uint256 value,\n        uint256 totalInvestors,\n        uint256 accreditedInvestors,\n        uint256 usAccreditedInvestors,\n        uint256 usTotalInvestors,\n        uint256 jpTotalInvestors,\n        bytes32[] calldata euRetailCountries,\n        uint256[] calldata euRetailCountryCounts\n    ) public virtual;\n\n    function bulkTransfer(address[] calldata wallets, uint256[] calldata values) public virtual;\n\n    function adjustCounters(\n        int256 totalDelta,\n        int256 accreditedDelta,\n        int256 usAccreditedDelta,\n        int256 usTotalDelta,\n        int256 jpTotalDelta,\n        bytes32[] calldata euRetailCountries,\n        int256[] calldata euRetailCountryDeltas\n    ) public virtual;\n\n    function getOmnibusWallet() public view virtual returns (address);\n}\n"},{"file_path":"@securitize/digital_securities/contracts/service/ServiceConsumer.sol","source_code":"pragma solidity ^0.8.20;\n\nimport \"./IDSServiceConsumer.sol\";\nimport \"../data-stores/ServiceConsumerDataStore.sol\";\nimport \"../token/IDSToken.sol\";\nimport \"../compliance/IDSWalletManager.sol\";\nimport \"../compliance/IDSLockManager.sol\";\nimport \"../compliance/IDSLockManagerPartitioned.sol\";\nimport \"../compliance/IDSComplianceService.sol\";\nimport \"../compliance/IDSPartitionsManager.sol\";\nimport \"../compliance/IDSComplianceConfigurationService.sol\";\nimport \"../registry/IDSRegistryService.sol\";\nimport \"../omnibus/IDSOmnibusTBEController.sol\";\nimport \"../trust/IDSTrustService.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\n\n//SPDX-License-Identifier: GPL-3.0\nabstract contract ServiceConsumer is IDSServiceConsumer, ServiceConsumerDataStore, OwnableUpgradeable {\n\n    // Bring role constants to save gas both in deployment (less bytecode) and usage\n    uint8 public constant ROLE_NONE = 0;\n    uint8 public constant ROLE_MASTER = 1;\n    uint8 public constant ROLE_ISSUER = 2;\n    uint8 public constant ROLE_EXCHANGE = 4;\n    uint8 public constant ROLE_TRANSFER_AGENT = 8;\n\n    function __ServiceConsumer_init() public virtual onlyInitializing {\n        __Ownable_init(msg.sender);\n    }\n\n    modifier onlyMaster {\n        IDSTrustService trustManager = getTrustService();\n        require(owner() == msg.sender || trustManager.getRole(msg.sender) == ROLE_MASTER, \"Insufficient trust level\");\n        _;\n    }\n\n    /**\n   * @dev Allow invoking functions only by the users who have the MASTER role or the ISSUER role or the TRANSFER AGENT role.\n   */\n    modifier onlyIssuerOrTransferAgentOrAbove() {\n        IDSTrustService trustManager = getTrustService();\n        require(trustManager.getRole(msg.sender) == ROLE_TRANSFER_AGENT || trustManager.getRole(msg.sender) == ROLE_ISSUER || trustManager.getRole(msg.sender) == ROLE_MASTER, \"Insufficient trust level\");\n        _;\n    }\n\n    modifier onlyIssuerOrAbove {\n        IDSTrustService trustManager = getTrustService();\n        require(trustManager.getRole(msg.sender) == ROLE_ISSUER || trustManager.getRole(msg.sender) == ROLE_MASTER, \"Insufficient trust level\");\n        _;\n    }\n\n    modifier onlyTransferAgentOrAbove {\n        IDSTrustService trustManager = getTrustService();\n        require(trustManager.getRole(msg.sender) == ROLE_TRANSFER_AGENT || trustManager.getRole(msg.sender) == ROLE_MASTER, \"Insufficient trust level\");\n        _;\n    }\n\n    modifier onlyExchangeOrAbove {\n        IDSTrustService trustManager = getTrustService();\n        require(\n            trustManager.getRole(msg.sender) == ROLE_EXCHANGE\n            || trustManager.getRole(msg.sender) == ROLE_ISSUER\n            || trustManager.getRole(msg.sender) == ROLE_TRANSFER_AGENT\n            || trustManager.getRole(msg.sender) == ROLE_MASTER,\n            \"Insufficient trust level\"\n        );\n        _;\n    }\n\n    modifier onlyToken {\n        require(msg.sender == getDSService(DS_TOKEN), \"This function can only called by the associated token\");\n        _;\n    }\n\n    modifier onlyRegistry {\n        require(msg.sender == getDSService(REGISTRY_SERVICE), \"This function can only called by the registry service\");\n        _;\n    }\n\n    modifier onlyIssuerOrAboveOrToken {\n        if (msg.sender != getDSService(DS_TOKEN)) {\n            IDSTrustService trustManager = IDSTrustService(getDSService(TRUST_SERVICE));\n            require(trustManager.getRole(msg.sender) == ROLE_ISSUER || trustManager.getRole(msg.sender) == ROLE_MASTER, \"Insufficient trust level\");\n        }\n        _;\n    }\n\n    modifier onlyTransferAgentOrAboveOrToken {\n        if (msg.sender != getDSService(DS_TOKEN)) {\n            IDSTrustService trustManager = IDSTrustService(getDSService(TRUST_SERVICE));\n            require(trustManager.getRole(msg.sender) == ROLE_TRANSFER_AGENT || trustManager.getRole(msg.sender) == ROLE_MASTER, \"Insufficient trust level\");\n        }\n        _;\n    }\n\n    modifier onlyOmnibusWalletController(address omnibusWallet, IDSOmnibusWalletController omnibusWalletController) {\n        require(getRegistryService().getOmnibusWalletController(omnibusWallet) == omnibusWalletController, \"Wrong controller address\");\n        _;\n    }\n\n    modifier onlyTBEOmnibus {\n        require(msg.sender == address(getOmnibusTBEController()), \"Not authorized\");\n        _;\n    }\n\n    modifier onlyMasterOrTBEOmnibus {\n        IDSTrustService trustManager = getTrustService();\n        require(msg.sender == address(getOmnibusTBEController()) ||\n        owner() == msg.sender || trustManager.getRole(msg.sender) == ROLE_MASTER, \"Not authorized\");\n        _;\n    }\n\n    modifier onlyOwnerOrIssuerOrAbove {\n        if(owner() != msg.sender) {\n            IDSTrustService trustManager = getTrustService();\n            require(trustManager.getRole(msg.sender) == ROLE_ISSUER || trustManager.getRole(msg.sender) == ROLE_MASTER, \"Insufficient trust level\");\n        }\n        _;\n    }\n\n    function getDSService(uint256 _serviceId) public view override returns (address) {\n        return services[_serviceId];\n    }\n\n    function setDSService(uint256 _serviceId, address _address) public override onlyMaster returns (bool) {\n        services[_serviceId] = _address;\n        emit DSServiceSet(_serviceId, _address);\n        return true;\n    }\n\n    function getToken() internal view returns (IDSToken) {\n        return IDSToken(getDSService(DS_TOKEN));\n    }\n\n    function getTrustService() internal view returns (IDSTrustService) {\n        return IDSTrustService(getDSService(TRUST_SERVICE));\n    }\n\n    function getWalletManager() internal view returns (IDSWalletManager) {\n        return IDSWalletManager(getDSService(WALLET_MANAGER));\n    }\n\n    function getLockManager() internal view returns (IDSLockManager) {\n        return IDSLockManager(getDSService(LOCK_MANAGER));\n    }\n\n    function getLockManagerPartitioned() internal view returns (IDSLockManagerPartitioned) {\n        return IDSLockManagerPartitioned(getDSService(LOCK_MANAGER));\n    }\n\n    function getComplianceService() internal view returns (IDSComplianceService) {\n        return IDSComplianceService(getDSService(COMPLIANCE_SERVICE));\n    }\n\n    function getRegistryService() internal view returns (IDSRegistryService) {\n        return IDSRegistryService(getDSService(REGISTRY_SERVICE));\n    }\n\n    function getPartitionsManager() internal view returns (IDSPartitionsManager) {\n        return IDSPartitionsManager(getDSService(PARTITIONS_MANAGER));\n    }\n\n    function getComplianceConfigurationService() internal view returns (IDSComplianceConfigurationService) {\n        return IDSComplianceConfigurationService(getDSService(COMPLIANCE_CONFIGURATION_SERVICE));\n    }\n\n    function getOmnibusTBEController() internal view returns (IDSOmnibusTBEController) {\n        return IDSOmnibusTBEController(getDSService(OMNIBUS_TBE_CONTROLLER));\n    }\n}\n"},{"file_path":"@securitize/digital_securities/contracts/registry/IDSRegistryService.sol","source_code":"pragma solidity ^0.8.20;\n\nimport \"../utils/CommonUtils.sol\";\nimport \"../omnibus/IDSOmnibusWalletController.sol\";\n\n//SPDX-License-Identifier: GPL-3.0\nabstract contract IDSRegistryService {\n\n    function initialize() public virtual;\n\n    event DSRegistryServiceInvestorAdded(string investorId, address sender);\n    event DSRegistryServiceInvestorRemoved(string investorId, address sender);\n    event DSRegistryServiceInvestorCountryChanged(string investorId, string country, address sender);\n    event DSRegistryServiceInvestorAttributeChanged(string investorId, uint256 attributeId, uint256 value, uint256 expiry, string proofHash, address sender);\n    event DSRegistryServiceWalletAdded(address wallet, string investorId, address sender);\n    event DSRegistryServiceWalletRemoved(address wallet, string investorId, address sender);\n    event DSRegistryServiceOmnibusWalletAdded(address omnibusWallet, string investorId, IDSOmnibusWalletController omnibusWalletController);\n    event DSRegistryServiceOmnibusWalletRemoved(address omnibusWallet, string investorId);\n\n    uint8 public constant NONE = 0;\n    uint8 public constant KYC_APPROVED = 1;\n    uint8 public constant ACCREDITED = 2;\n    uint8 public constant QUALIFIED = 4;\n    uint8 public constant PROFESSIONAL = 8;\n\n    uint8 public constant PENDING = 0;\n    uint8 public constant APPROVED = 1;\n    uint8 public constant REJECTED = 2;\n\n    uint8 public constant EXCHANGE = 4;\n\n    modifier investorExists(string memory _id) {\n        require(isInvestor(_id), \"Unknown investor\");\n        _;\n    }\n\n    modifier newInvestor(string memory _id) {\n        require(!CommonUtils.isEmptyString(_id), \"Investor id must not be empty\");\n        require(!isInvestor(_id), \"Investor already exists\");\n        _;\n    }\n\n    modifier walletExists(address _address) {\n        require(isWallet(_address), \"Unknown wallet\");\n        _;\n    }\n\n    modifier newWallet(address _address) {\n        require(!isWallet(_address), \"Wallet already exists\");\n        _;\n    }\n\n    modifier newOmnibusWallet(address _omnibusWallet) {\n        require(!isOmnibusWallet(_omnibusWallet), \"Omnibus wallet already exists\");\n        _;\n    }\n\n    modifier omnibusWalletExists(address _omnibusWallet) {\n        require(isOmnibusWallet(_omnibusWallet), \"Unknown omnibus wallet\");\n        _;\n    }\n\n    modifier walletBelongsToInvestor(address _address, string memory _id) {\n        require(CommonUtils.isEqualString(getInvestor(_address), _id), \"Wallet does not belong to investor\");\n        _;\n    }\n\n    function registerInvestor(\n        string calldata _id,\n        string calldata _collision_hash /*onlyExchangeOrAbove newInvestor(_id)*/\n    ) public virtual returns (bool);\n\n    function updateInvestor(\n        string calldata _id,\n        string calldata _collisionHash,\n        string memory _country,\n        address[] memory _wallets,\n        uint8[] memory _attributeIds,\n        uint256[] memory _attributeValues,\n        uint256[] memory _attributeExpirations /*onlyIssuerOrAbove*/\n    ) public virtual returns (bool);\n\n    function removeInvestor(\n        string calldata _id /*onlyExchangeOrAbove investorExists(_id)*/\n    ) public virtual returns (bool);\n\n    function setCountry(\n        string calldata _id,\n        string memory _country /*onlyExchangeOrAbove investorExists(_id)*/\n    ) public virtual returns (bool);\n\n    function getCountry(string memory _id) public view virtual returns (string memory);\n\n    function getCollisionHash(string calldata _id) public view virtual returns (string memory);\n\n    function setAttribute(\n        string calldata _id,\n        uint8 _attributeId,\n        uint256 _value,\n        uint256 _expiry,\n        string memory _proofHash /*onlyExchangeOrAbove investorExists(_id)*/\n    ) public virtual returns (bool);\n\n    function getAttributeValue(string memory _id, uint8 _attributeId) public view virtual returns (uint256);\n\n    function getAttributeExpiry(string memory _id, uint8 _attributeId) public view virtual returns (uint256);\n\n    function getAttributeProofHash(string memory _id, uint8 _attributeId) public view virtual returns (string memory);\n\n    function addWallet(\n        address _address,\n        string memory _id /*onlyExchangeOrAbove newWallet(_address)*/\n    ) public virtual returns (bool);\n\n    function addWalletByInvestor(address _address) public virtual returns (bool);\n\n    function removeWallet(\n        address _address,\n        string memory _id /*onlyExchangeOrAbove walletExists walletBelongsToInvestor(_address, _id)*/\n    ) public virtual returns (bool);\n\n    function addOmnibusWallet(\n        string memory _id,\n        address _omnibusWallet,\n        IDSOmnibusWalletController _omnibusWalletController /*onlyIssuerOrAbove newOmnibusWallet*/\n    ) public virtual;\n\n    function removeOmnibusWallet(\n        string memory _id,\n        address _omnibusWallet /*onlyIssuerOrAbove omnibusWalletControllerExists*/\n    ) public virtual;\n\n    function getOmnibusWalletController(address _omnibusWallet) public view virtual returns (IDSOmnibusWalletController);\n\n    function isOmnibusWallet(address _omnibusWallet) public view virtual returns (bool);\n\n    function getInvestor(address _address) public view virtual returns (string memory);\n\n    function getInvestorDetails(address _address) public view virtual returns (string memory, string memory);\n\n    function getInvestorDetailsFull(string memory _id)\n        public\n        view\n        virtual\n        returns (string memory, uint256[] memory, uint256[] memory, string memory, string memory, string memory, string memory);\n\n    function isInvestor(string memory _id) public view virtual returns (bool);\n\n    function isWallet(address _address) public view virtual returns (bool);\n\n    function isAccreditedInvestor(string calldata _id) external view virtual returns (bool);\n\n    function isQualifiedInvestor(string calldata _id) external view virtual returns (bool);\n\n    function isAccreditedInvestor(address _wallet) external view virtual returns (bool);\n\n    function isQualifiedInvestor(address _wallet) external view virtual returns (bool);\n\n    function getInvestors(address _from, address _to) external view virtual returns (string memory, string memory);\n}\n"},{"file_path":"@securitize/digital_securities/contracts/data-stores/ServiceConsumerDataStore.sol","source_code":"pragma solidity ^0.8.20;\n\n//SPDX-License-Identifier: GPL-3.0\ncontract ServiceConsumerDataStore {\n\n    mapping(uint256 => address) internal services;\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[49] private __gap;\n}\n"},{"file_path":"@securitize/digital_securities/contracts/compliance/IDSLockManagerPartitioned.sol","source_code":"pragma solidity ^0.8.20;\n\nimport \"./IDSLockManager.sol\";\n\n//SPDX-License-Identifier: GPL-3.0\nabstract contract IDSLockManagerPartitioned {\n\n    event LockedPartition(address indexed who, uint256 value, uint256 indexed reason, string reasonString, uint256 releaseTime, bytes32 indexed partition);\n    event UnlockedPartition(address indexed who, uint256 value, uint256 indexed reason, string reasonString, uint256 releaseTime, bytes32 indexed partition);\n    event HolderLockedPartition(string investorId, uint256 value, uint256 indexed reason, string reasonString, uint256 releaseTime, bytes32 indexed partition);\n    event HolderUnlockedPartition(string investorId, uint256 value, uint256 indexed reason, string reasonString, uint256 releaseTime, bytes32 indexed partition);\n\n    function createLockForInvestor(\n        string memory _investorId,\n        uint256 _valueLocked,\n        uint256 _reasonCode,\n        string memory _reasonString,\n        uint256 _releaseTime,\n        bytes32 _partition\n    ) public virtual;\n\n    function addManualLockRecord(\n        address _to,\n        uint256 _valueLocked,\n        string memory _reason,\n        uint256 _releaseTime,\n        bytes32 _partition /*issuerOrAboveOrToken*/\n    ) public virtual;\n\n    function removeLockRecord(\n        address _to,\n        uint256 _lockIndex,\n        bytes32 _partition /*issuerOrAbove*/\n    ) public virtual returns (bool);\n\n    function removeLockRecordForInvestor(\n        string memory _investorId,\n        uint256 _lockIndex,\n        bytes32 _partition /*issuerOrAbove*/\n    ) public virtual returns (bool);\n\n    function lockCount(address _who, bytes32 _partition) public view virtual returns (uint256);\n\n    function lockInfo(\n        address _who,\n        uint256 _lockIndex,\n        bytes32 _partition\n    )\n        public\n        view\n        virtual\n        returns (\n            uint256 reasonCode,\n            string memory reasonString,\n            uint256 value,\n            uint256 autoReleaseTime\n        );\n\n    function lockCountForInvestor(string memory _investorId, bytes32 _partition) public view virtual returns (uint256);\n\n    function lockInfoForInvestor(\n        string memory _investorId,\n        uint256 _lockIndex,\n        bytes32 _partition\n    )\n        public\n        view\n        virtual\n        returns (\n            uint256 reasonCode,\n            string memory reasonString,\n            uint256 value,\n            uint256 autoReleaseTime\n        );\n\n    function getTransferableTokens(\n        address _who,\n        uint256 _time,\n        bytes32 _partition\n    ) public view virtual returns (uint256);\n\n    function getTransferableTokensForInvestor(\n        string memory _investorId,\n        uint256 _time,\n        bytes32 _partition\n    ) public view virtual returns (uint256);\n\n    /*************** Legacy functions ***************/\n    function createLockForHolder(\n        string memory _investorId,\n        uint256 _valueLocked,\n        uint256 _reasonCode,\n        string memory _reasonString,\n        uint256 _releaseTime,\n        bytes32 _partition\n    ) public virtual;\n\n    function removeLockRecordForHolder(\n        string memory _investorId,\n        uint256 _lockIndex,\n        bytes32 _partition\n    ) public virtual returns (bool);\n\n    function lockCountForHolder(string memory _holderId, bytes32 _partition) public view virtual returns (uint256);\n\n    function lockInfoForHolder(\n        string memory _holderId,\n        uint256 _lockIndex,\n        bytes32 _partition\n    )\n        public\n        view\n        virtual\n        returns (\n            uint256 reasonCode,\n            string memory reasonString,\n            uint256 value,\n            uint256 autoReleaseTime\n        );\n\n    function getTransferableTokensForHolder(\n        string memory _holderId,\n        uint256 _time,\n        bytes32 _partition\n    ) public view virtual returns (uint256);\n\n    /******************************/\n}\n"},{"file_path":"@securitize/digital_securities/contracts/data-stores/OmnibusTBEControllerDataStore.sol","source_code":"pragma solidity ^0.8.20;\n\nimport \"./ServiceConsumerDataStore.sol\";\n\n//SPDX-License-Identifier: GPL-3.0\ncontract OmnibusTBEControllerDataStore is ServiceConsumerDataStore {\n    address internal omnibusWallet;\n    bool internal isPartitionedToken;\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[49] private __gap;\n}\n"},{"file_path":"@securitize/digital_securities/contracts/utils/CommonUtils.sol","source_code":"pragma solidity ^0.8.20;\n\n//SPDX-License-Identifier: GPL-3.0\nlibrary CommonUtils {\n  enum IncDec { Increase, Decrease }\n\n  function encodeString(string memory _str) internal pure returns (bytes32) {\n    return keccak256(abi.encodePacked(_str));\n  }\n\n  function isEqualString(string memory _str1, string memory _str2) internal pure returns (bool) {\n    return encodeString(_str1) == encodeString(_str2);\n  }\n\n  function isEmptyString(string memory _str) internal pure returns (bool) {\n    return isEqualString(_str, \"\");\n  }\n}\n"}],"certified":false,"conflicting_implementations":null,"abi":[{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"implementation","type":"address"}],"name":"ERC1967InvalidImplementation","type":"error"},{"inputs":[],"name":"ERC1967NonPayable","type":"error"},{"inputs":[],"name":"EnforcedPause","type":"error"},{"inputs":[],"name":"ExpectedPause","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"UUPSUnauthorizedCallContext","type":"error"},{"inputs":[{"internalType":"bytes32","name":"slot","type":"bytes32"}],"name":"UUPSUnsupportedProxiableUUID","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"chainId","type":"uint16"},{"indexed":false,"internalType":"address","name":"bridgeAddress","type":"address"}],"name":"BridgeAddressAdd","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"chainId","type":"uint16"}],"name":"BridgeAddressRemove","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"sourceChainId","type":"uint16"},{"indexed":false,"internalType":"address","name":"dsToken","type":"address"},{"indexed":false,"internalType":"address","name":"investorWallet","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"DSTokenBridgeReceive","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"targetChainId","type":"uint16"},{"indexed":false,"internalType":"address","name":"dsToken","type":"address"},{"indexed":false,"internalType":"address","name":"investorWallet","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"DSTokenBridgeSend","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldGasLimit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newGasLimit","type":"uint256"}],"name":"GasLimitUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"version","type":"uint64"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"inputs":[],"name":"UPGRADE_INTERFACE_VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"bridgeAddresses","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"targetChain","type":"uint16"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"bridgeDSTokens","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"dsServiceConsumer","outputs":[{"internalType":"contract IDSServiceConsumer","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dsToken","outputs":[{"internalType":"contract IDSToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gasLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getImplementationAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getInitializedVersion","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_whChainId","type":"uint16"},{"internalType":"address","name":"_wormholeRelayer","type":"address"},{"internalType":"address","name":"_dsToken","type":"address"},{"internalType":"address","name":"_owner","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"targetChain","type":"uint16"}],"name":"quoteBridge","outputs":[{"internalType":"uint256","name":"cost","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"bytes[]","name":"","type":"bytes[]"},{"internalType":"bytes32","name":"sourceBridge","type":"bytes32"},{"internalType":"uint16","name":"sourceChain","type":"uint16"},{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"receiveWormholeMessages","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint16","name":"chainId","type":"uint16"}],"name":"removeBridgeAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"chainId","type":"uint16"},{"internalType":"address","name":"bridgeAddress","type":"address"}],"name":"setBridgeAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_gasLimit","type":"uint256"}],"name":"updateGasLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"whChainId","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wormholeRelayer","outputs":[{"internalType":"contract IWormholeRelayer","name":"","type":"address"}],"stateMutability":"view","type":"function"}],"is_changed_bytecode":false,"is_partially_verified":false,"constructor_args":null}