Overview
APE Balance
APE Value
$0.00More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 3 internal transactions
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
8833582 | 23 days ago | Contract Creation | 0 APE | |||
8833582 | 23 days ago | Contract Creation | 0 APE | |||
8833582 | 23 days ago | Contract Creation | 0 APE |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Source Code Verified (Exact Match)
Contract Name:
StrictAuthorizedTransferSecurityRegistry
Compiler Version
v0.8.24+commit.e11b9ed9
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.24; import { ListTypes, TransferSecurityLevels, IStrictAuthorizedTransferSecurityRegistry } from "./interfaces/IStrictAuthorizedTransferSecurityRegistry.sol"; import { ICreatorTokenTransferValidator } from "./interfaces/ICreatorTokenTransferValidator.sol"; import { IOwnable } from "./interfaces/IOwnable.sol"; import { IAccessControl } from "@openzeppelin/contracts/access/IAccessControl.sol"; import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; import { ERC165 } from "@openzeppelin/contracts/utils/introspection/ERC165.sol"; import { Tstorish } from "tstorish/Tstorish.sol"; import { IEOARegistry } from "./interfaces/IEOARegistry.sol"; import { StrictAuthorizedTransferSecurityRegistryExtraViewFns } from "./StrictAuthorizedTransferSecurityRegistryExtraViewFns.sol"; /// @title StrictAuthorizedTransferSecurityRegistry /// @dev Implementation of a simplified version of the Transfer Security Registry that only /// supports authorizers and whitelisted operators, and allows collections to disable /// direct transfers (where caller == from) and contract recipients (requiring EOA /// registration by providing a signature). Note that a number of view functions on /// collections that add this validator will not work. contract StrictAuthorizedTransferSecurityRegistry is Tstorish, IStrictAuthorizedTransferSecurityRegistry, ERC165 { using EnumerableSet for EnumerableSet.AddressSet; /** * @dev This struct is used internally to represent an enumerable list of accounts. */ struct AccountList { EnumerableSet.AddressSet enumerableAccounts; mapping (address => bool) nonEnumerableAccounts; } /** * @dev This struct is used internally for the storage of authorizer + operator lists. */ struct List { address owner; AccountList authorizers; AccountList operators; AccountList blacklist; } struct CollectionConfiguration { uint120 listId; bool policyBypassed; bool blacklistBased; bool directTransfersDisabled; bool contractRecipientsDisabled; bool signatureRegistrationRequired; } /// @dev The default admin role value for contracts that implement access control. bytes32 private constant DEFAULT_ACCESS_CONTROL_ADMIN_ROLE = 0x00; /// @notice Keeps track of the most recently created list id. uint120 public lastListId; /// @dev Mapping of list ids to list settings mapping (uint120 => List) private lists; /// @dev Mapping of collection addresses to list ids & security policies. mapping (address => CollectionConfiguration) private collectionConfiguration; // TSTORE slot: scope ++ 8 empty bytes ++ collection bytes4 private constant _AUTHORIZED_OPERATOR_SCOPE = 0x596a397a; // TSTORE slot: keccak256(scope ++ identifier ++ collection) bytes4 private constant _AUTHORIZED_IDENTIFIER_SCOPE = 0x7e746c61; // TSTORE slot: keccak256(scope ++ identifier ++ collection) bytes4 private constant _AUTHORIZED_AMOUNT_SCOPE = 0x71836d45; address private immutable _EXTRA_VIEW_FUNCTIONS; IEOARegistry private immutable _EOA_REGISTRY; /** * @dev This modifier restricts a function call to the owner of the list `id`. * @dev Throws when the caller is not the list owner. */ modifier onlyListOwner(uint120 id) { _requireCallerOwnsList(id); _; } /** * @dev This modifier reverts a transaction if the supplied array has a zero length. * @dev Throws when the array parameter has a zero length. */ modifier notZero(uint256 value) { if (value == 0) { revert StrictAuthorizedTransferSecurityRegistry__ArrayLengthCannotBeZero(); } _; } constructor(address defaultOwner, address eoaRegistry) { uint120 id = 0; lists[id].owner = defaultOwner; emit CreatedList(id, "DEFAULT LIST"); emit ReassignedListOwnership(id, defaultOwner); // Deploy a contract containing legacy view functions. _EXTRA_VIEW_FUNCTIONS = address(new StrictAuthorizedTransferSecurityRegistryExtraViewFns()); _EOA_REGISTRY = IEOARegistry(eoaRegistry); } // Delegatecall to contract with legacy view functions in the fallback. fallback() external { address target = _EXTRA_VIEW_FUNCTIONS; assembly { calldatacopy(0, 0, calldatasize()) let status := delegatecall(gas(), target, 0, calldatasize(), 0, 0) returndatacopy(0, 0, returndatasize()) switch status case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } /// Manage lists of authorizers & operators that can be applied to collections function createList(string calldata name) external returns (uint120) { uint120 id = ++lastListId; lists[id].owner = msg.sender; emit CreatedList(id, name); emit ReassignedListOwnership(id, msg.sender); return id; } function createListCopy(string calldata name, uint120 sourceListId) external override returns (uint120) { uint120 id = ++lastListId; unchecked { if (sourceListId > id - 1) { revert StrictAuthorizedTransferSecurityRegistry__ListDoesNotExist(); } } List storage sourceList = lists[sourceListId]; List storage targetList = lists[id]; targetList.owner = msg.sender; emit CreatedList(id, name); emit ReassignedListOwnership(id, msg.sender); _copyAddressSet(ListTypes.AuthorizerList, id, sourceList.authorizers, targetList.authorizers); _copyAddressSet(ListTypes.OperatorList, id, sourceList.operators, targetList.operators); _copyAddressSet(ListTypes.OperatorRequiringAuthorizationList, id, sourceList.blacklist, targetList.blacklist); return id; } function reassignOwnershipOfList(uint120 id, address newOwner) external onlyListOwner(id) { if (newOwner == address(0)) { revert StrictAuthorizedTransferSecurityRegistry__ListOwnershipCannotBeTransferredToZeroAddress(); } lists[id].owner = newOwner; emit ReassignedListOwnership(id, newOwner); } function renounceOwnershipOfList(uint120 id) external onlyListOwner(id) { lists[id].owner = address(0); emit ReassignedListOwnership(id, address(0)); } function applyListToCollection(address collection, uint120 id) external { _requireCallerIsNFTOrContractOwnerOrAdmin(collection); if (id > lastListId) { revert StrictAuthorizedTransferSecurityRegistry__ListDoesNotExist(); } collectionConfiguration[collection].listId = id; emit AppliedListToCollection(collection, id); } function listOwners(uint120 id) external view returns (address) { return lists[id].owner; } /// Manage and query for authorizers on lists function addAccountToAuthorizers(uint120 id, address account) external onlyListOwner(id) { address[] memory accounts = new address[](1); accounts[0] = account; _addAccounts(id, accounts, lists[id].authorizers, ListTypes.AuthorizerList); } function addAccountsToAuthorizers(uint120 id, address[] calldata accounts) external onlyListOwner(id) notZero(accounts.length) { _addAccounts(id, accounts, lists[id].authorizers, ListTypes.AuthorizerList); } function addAuthorizers(uint120 id, address[] calldata accounts) external onlyListOwner(id) notZero(accounts.length) { _addAccounts(id, accounts, lists[id].authorizers, ListTypes.AuthorizerList); } function removeAccountFromAuthorizers(uint120 id, address account) external onlyListOwner(id) { address[] memory accounts = new address[](1); accounts[0] = account; _removeAccounts(id, accounts, lists[id].authorizers, ListTypes.AuthorizerList); } function removeAccountsFromAuthorizers(uint120 id, address[] calldata accounts) external onlyListOwner(id) notZero(accounts.length) { _removeAccounts(id, accounts, lists[id].authorizers, ListTypes.AuthorizerList); } function getAuthorizerAccounts(uint120 id) external view returns (address[] memory) { return lists[id].authorizers.enumerableAccounts.values(); } function isAccountAuthorizer(uint120 id, address account) external view returns (bool) { return lists[id].authorizers.nonEnumerableAccounts[account]; } function getAuthorizerAccountsByCollection(address collection) external view returns (address[] memory) { return lists[collectionConfiguration[collection].listId].authorizers.enumerableAccounts.values(); } function isAccountAuthorizerOfCollection(address collection, address account) external view returns (bool) { return lists[collectionConfiguration[collection].listId].authorizers.nonEnumerableAccounts[account]; } function _ensureCallerIsCollectionAuthorizer(address collection) internal view { if (!lists[collectionConfiguration[collection].listId].authorizers.nonEnumerableAccounts[msg.sender]) { revert StrictAuthorizedTransferSecurityRegistry__CallerIsNotValidAuthorizer(); } } /// Manage and query for operators on lists function addAccountToWhitelist(uint120 id, address account) external onlyListOwner(id) { address[] memory accounts = new address[](1); accounts[0] = account; _addAccounts(id, accounts, lists[id].operators, ListTypes.OperatorList); } function addAccountsToWhitelist(uint120 id, address[] calldata accounts) external onlyListOwner(id) notZero(accounts.length) { _addAccounts(id, accounts, lists[id].operators, ListTypes.OperatorList); } function addOperators(uint120 id, address[] calldata accounts) external onlyListOwner(id) notZero(accounts.length) { _addAccounts(id, accounts, lists[id].operators, ListTypes.OperatorList); } function removeAccountFromWhitelist(uint120 id, address account) external onlyListOwner(id) { address[] memory accounts = new address[](1); accounts[0] = account; _removeAccounts(id, accounts, lists[id].operators, ListTypes.OperatorList); } function removeAccountsFromWhitelist(uint120 id, address[] calldata accounts) external onlyListOwner(id) notZero(accounts.length) { _removeAccounts(id, accounts, lists[id].operators, ListTypes.OperatorList); } function getWhitelistedAccounts(uint120 id) external view returns (address[] memory) { return lists[id].operators.enumerableAccounts.values(); } function isAccountWhitelisted(uint120 id, address account) external view returns (bool) { return lists[id].operators.nonEnumerableAccounts[account]; } function getWhitelistedAccountsByCollection(address collection) external view returns (address[] memory) { return lists[collectionConfiguration[collection].listId].operators.enumerableAccounts.values(); } function isAccountWhitelistedByCollection(address collection, address account) external view returns (bool) { return lists[collectionConfiguration[collection].listId].operators.nonEnumerableAccounts[account]; } /// Manage and query for blacklists on lists function addAccountToBlacklist(uint120 id, address account) external onlyListOwner(id) { address[] memory accounts = new address[](1); accounts[0] = account; _addAccounts(id, accounts, lists[id].blacklist, ListTypes.OperatorRequiringAuthorizationList); } function addAccountsToBlacklist(uint120 id, address[] calldata accounts) external onlyListOwner(id) notZero(accounts.length) { _addAccounts(id, accounts, lists[id].blacklist, ListTypes.OperatorRequiringAuthorizationList); } function removeAccountFromBlacklist(uint120 id, address account) external onlyListOwner(id) { address[] memory accounts = new address[](1); accounts[0] = account; _removeAccounts(id, accounts, lists[id].blacklist, ListTypes.OperatorRequiringAuthorizationList); } function removeAccountsFromBlacklist(uint120 id, address[] calldata accounts) external onlyListOwner(id) notZero(accounts.length) { _removeAccounts(id, accounts, lists[id].blacklist, ListTypes.OperatorRequiringAuthorizationList); } function getBlacklistedAccounts(uint120 id) external view returns (address[] memory) { return lists[id].blacklist.enumerableAccounts.values(); } function isAccountBlacklisted(uint120 id, address account) external view returns (bool) { return lists[id].blacklist.nonEnumerableAccounts[account]; } function getBlacklistedAccountsByCollection(address collection) external view returns (address[] memory) { return lists[collectionConfiguration[collection].listId].blacklist.enumerableAccounts.values(); } function isAccountBlacklistedByCollection(address collection, address account) external view returns (bool) { return lists[collectionConfiguration[collection].listId].blacklist.nonEnumerableAccounts[account]; } /// Ensure that a specific operator has been authorized to transfer tokens function validateTransfer(address caller, address from, address to) external view { _validateTransfer(caller, from, to); } /// Ensure that a transfer has been authorized for a specific tokenId function validateTransfer(address caller, address from, address to, uint256 tokenId) external view { _validateTransferByIdentifer(caller, from, to, tokenId); } /// Ensure that a transfer has been authorized for a specific amount of a specific tokenId, and /// reduce the transferable amount remaining function validateTransfer(address caller, address from, address to, uint256 tokenId, uint256 amount) external { _validateTransferByAmount(caller, from, to, tokenId, amount); } /// Legacy alias for validateTransfer (address caller, address from, address to) function applyCollectionTransferPolicy(address caller, address from, address to) external view { _validateTransfer(caller, from, to); } /// Temporarily assign a specific allowed operator for a given collection function beforeAuthorizedTransfer(address operator, address token) external { _ensureCallerIsCollectionAuthorizer(token); _setTstorish( _getAuthorizedOperatorSlot(token), uint256(uint160(operator)) ); } /// Clear assignment of a specific allowed operator for a given collection function afterAuthorizedTransfer(address token) external { _ensureCallerIsCollectionAuthorizer(token); _clearTstorish(_getAuthorizedOperatorSlot(token)); } /// Temporarily allow a specific tokenId from a given collection to be transferred function beforeAuthorizedTransfer(address token, uint256 tokenId) external { _ensureCallerIsCollectionAuthorizer(token); _setTstorish( _getAuthorizedIdentifierSlot(token, tokenId), 1 ); } /// Clear assignment of an specific tokenId's transfer allowance function afterAuthorizedTransfer(address token, uint256 tokenId) external { _ensureCallerIsCollectionAuthorizer(token); _clearTstorish(_getAuthorizedIdentifierSlot(token, tokenId)); } /// Temporarily allow a specific amount of a specific tokenId from a given collection to be transferred function beforeAuthorizedTransferWithAmount(address token, uint256 tokenId, uint256 amount) external { _ensureCallerIsCollectionAuthorizer(token); uint256 slot = _getAuthorizedAmountSlot(token, tokenId); uint256 currentAmount = _getTstorish(slot); uint256 newAmount = currentAmount + amount; _setTstorish(slot, newAmount); } /// Clear assignment of a tokenId's transfer allowance for a specific amount function afterAuthorizedTransferWithAmount(address token, uint256 tokenId) external { _ensureCallerIsCollectionAuthorizer(token); _clearTstorish(_getAuthorizedAmountSlot(token, tokenId)); } function setTransferSecurityLevelOfCollection( address collection, uint8 level, bool enableAuthorizationMode, bool authorizersCanSetWildcardOperators, bool enableAccountFreezingMode ) external { if (!enableAuthorizationMode || !authorizersCanSetWildcardOperators || enableAccountFreezingMode) { revert StrictAuthorizedTransferSecurityRegistry__UnsupportedSecurityLevelDetail(); } _setTransferSecurityLevelOfCollection(collection, TransferSecurityLevels(level)); } function setTransferSecurityLevelOfCollection( address collection, TransferSecurityLevels level ) external { _setTransferSecurityLevelOfCollection(collection, level); } function isVerifiedEOA(address account) external view returns (bool) { return _EOA_REGISTRY.isVerifiedEOA(account); } /// @notice ERC-165 Interface Support function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165) returns (bool) { return interfaceId == type(ICreatorTokenTransferValidator).interfaceId || interfaceId == type(IStrictAuthorizedTransferSecurityRegistry).interfaceId || super.supportsInterface(interfaceId); } function _setTransferSecurityLevelOfCollection( address collection, TransferSecurityLevels level ) internal { _requireCallerIsNFTOrContractOwnerOrAdmin(collection); if (level == TransferSecurityLevels.Recommended) { level = TransferSecurityLevels.Three; } CollectionConfiguration storage config = collectionConfiguration[collection]; if (level == TransferSecurityLevels.One) { config.policyBypassed = true; config.blacklistBased = false; config.directTransfersDisabled = false; config.contractRecipientsDisabled = false; config.signatureRegistrationRequired = false; } else if (level == TransferSecurityLevels.Two) { config.policyBypassed = false; config.blacklistBased = true; config.directTransfersDisabled = false; config.contractRecipientsDisabled = false; config.signatureRegistrationRequired = false; } else if (level == TransferSecurityLevels.Three) { config.policyBypassed = false; config.blacklistBased = false; config.directTransfersDisabled = false; config.contractRecipientsDisabled = false; config.signatureRegistrationRequired = false; } else if (level == TransferSecurityLevels.Four) { config.policyBypassed = false; config.blacklistBased = false; config.directTransfersDisabled = true; config.contractRecipientsDisabled = false; config.signatureRegistrationRequired = false; } else if (level == TransferSecurityLevels.Five) { config.policyBypassed = false; config.blacklistBased = false; config.directTransfersDisabled = false; config.contractRecipientsDisabled = true; config.signatureRegistrationRequired = false; } else if (level == TransferSecurityLevels.Six) { config.policyBypassed = false; config.blacklistBased = false; config.directTransfersDisabled = false; config.contractRecipientsDisabled = false; config.signatureRegistrationRequired = true; } else if (level == TransferSecurityLevels.Seven) { config.policyBypassed = false; config.blacklistBased = false; config.directTransfersDisabled = true; config.contractRecipientsDisabled = true; config.signatureRegistrationRequired = false; } else if (level == TransferSecurityLevels.Eight) { config.policyBypassed = false; config.blacklistBased = false; config.directTransfersDisabled = true; config.contractRecipientsDisabled = false; config.signatureRegistrationRequired = true; } else { revert StrictAuthorizedTransferSecurityRegistry__UnsupportedSecurityLevel(); } emit SetTransferSecurityLevel(collection, level); } /** * @notice Copies all addresses in `ptrFromList` to `ptrToList`. * * @dev This function will copy all addresses from one list to another list. * @dev Note: If used to copy adddresses to an existing list the current list contents will not be * @dev deleted before copying. New addresses will be appeneded to the end of the list and the * @dev non-enumerable mapping key value will be set to true. * * @dev <h4>Postconditions:</h4> * 1. Addresses in from list that are not already present in to list are added to the to list. * 2. Emits an `AddedAccountToList` event for each address copied to the list. * * @param listType The type of list addresses are being copied from and to. * @param destinationListId The id of the list being copied to. * @param ptrFromList The storage pointer for the list being copied from. * @param ptrToList The storage pointer for the list being copied to. */ function _copyAddressSet( ListTypes listType, uint120 destinationListId, AccountList storage ptrFromList, AccountList storage ptrToList ) private { EnumerableSet.AddressSet storage ptrFromSet = ptrFromList.enumerableAccounts; EnumerableSet.AddressSet storage ptrToSet = ptrToList.enumerableAccounts; mapping (address => bool) storage ptrToNonEnumerableSet = ptrToList.nonEnumerableAccounts; uint256 sourceLength = ptrFromSet.length(); address account; for (uint256 i = 0; i < sourceLength;) { account = ptrFromSet.at(i); if (ptrToSet.add(account)) { emit AddedAccountToList(listType, destinationListId, account); ptrToNonEnumerableSet[account] = true; } unchecked { ++i; } } } /** * @notice Requires the caller to be the owner of list `id`. * * @dev Throws when the caller is not the owner of the list. */ function _requireCallerOwnsList(uint120 id) private view { if (msg.sender != lists[id].owner) { revert StrictAuthorizedTransferSecurityRegistry__CallerDoesNotOwnList(); } } /** * @notice Reverts the transaction if the caller is not the owner or assigned the default * @notice admin role of the contract at `tokenAddress`. * * @dev Throws when the caller is neither owner nor assigned the default admin role. * * @param tokenAddress The contract address of the token to check permissions for. */ function _requireCallerIsNFTOrContractOwnerOrAdmin(address tokenAddress) internal view { if (msg.sender == tokenAddress) { return; } if (msg.sender == _safeOwner(tokenAddress)) { return; } if (!_safeHasRole(tokenAddress)) { revert StrictAuthorizedTransferSecurityRegistry__CallerMustHaveElevatedPermissionsForSpecifiedNFT(); } } /** * @dev A gas efficient, and fallback-safe way to call the owner function on a token contract. * This will get the owner if it exists - and when the function is unimplemented, the * presence of a fallback function will not result in halted execution. */ function _safeOwner( address tokenAddress ) internal view returns(address owner) { assembly { mstore(0x00, 0x8da5cb5b) let status := staticcall(gas(), tokenAddress, 0x1c, 0x04, 0x00, 0x20) if and(iszero(lt(returndatasize(), 0x20)), status) { owner := mload(0x00) } } } /** * @dev A gas efficient, and fallback-safe way to call the hasRole function on a token contract. * This will check if the account `hasRole` if `hasRole` exists - and when the function is unimplemented, the * presence of a fallback function will not result in halted execution. */ function _safeHasRole( address tokenAddress ) internal view returns(bool hasRole) { assembly { let ptr := mload(0x40) mstore(0x40, add(ptr, 0x60)) mstore(ptr, 0x91d14854) mstore(add(0x20, ptr), DEFAULT_ACCESS_CONTROL_ADMIN_ROLE) mstore(add(0x40, ptr), caller()) let status := staticcall(gas(), tokenAddress, add(ptr, 0x1c), 0x44, 0x00, 0x20) if and(iszero(lt(returndatasize(), 0x20)), status) { hasRole := mload(0x00) } } } /** * @dev Internal function used to efficiently retrieve the code length of `account`. * * @param account The address to get the deployed code length for. * * @return length The length of deployed code at the address. */ function _getCodeLengthAsm(address account) internal view returns (uint256 length) { assembly { length := extcodesize(account) } } function _addAccounts( uint120 id, address[] memory accounts, AccountList storage accountList, ListTypes listType ) internal { address account; for (uint256 i = 0; i < accounts.length;) { account = accounts[i]; if (account == address(0)) { revert StrictAuthorizedTransferSecurityRegistry__ZeroAddressNotAllowed(); } if (accountList.enumerableAccounts.add(account)) { emit AddedAccountToList(listType, id, account); accountList.nonEnumerableAccounts[account] = true; } unchecked { ++i; } } } function _removeAccounts( uint120 id, address[] memory accounts, AccountList storage accountList, ListTypes listType ) internal { address account; for (uint256 i = 0; i < accounts.length;) { account = accounts[i]; if (accountList.enumerableAccounts.remove(account)) { emit RemovedAccountFromList(listType, id, account); delete accountList.nonEnumerableAccounts[account]; } unchecked { ++i; } } } function _validateTransfer(address operator, address from, address to) internal view { CollectionConfiguration memory config = collectionConfiguration[msg.sender]; if (config.policyBypassed) { return; } if (config.contractRecipientsDisabled) { if (to.code.length != 0) { revert StrictAuthorizedTransferSecurityRegistry__ReceiverMustNotHaveDeployedCode(); } } if (config.signatureRegistrationRequired) { if (!_EOA_REGISTRY.isVerifiedEOA(to)) { revert StrictAuthorizedTransferSecurityRegistry__ReceiverProofOfEOASignatureUnverified(); } } if (operator == from) { if (config.directTransfersDisabled) { revert StrictAuthorizedTransferSecurityRegistry__CallerMustBeWhitelistedOperator(); } return; } uint256 slot = _getAuthorizedOperatorSlot(msg.sender); if (operator == address(uint160(_getTstorish(slot)))) { return; } if (config.blacklistBased) { if (lists[config.listId].blacklist.nonEnumerableAccounts[operator]) { revert StrictAuthorizedTransferSecurityRegistry__UnauthorizedTransfer(); } } else { if (!lists[config.listId].operators.nonEnumerableAccounts[operator]) { revert StrictAuthorizedTransferSecurityRegistry__UnauthorizedTransfer(); } } } function _validateTransferByIdentifer(address operator, address from, address to, uint256 identifier) internal view { CollectionConfiguration memory config = collectionConfiguration[msg.sender]; if (config.policyBypassed) { return; } if (config.contractRecipientsDisabled) { if (to.code.length != 0) { revert StrictAuthorizedTransferSecurityRegistry__ReceiverMustNotHaveDeployedCode(); } } if (config.signatureRegistrationRequired) { if (!_EOA_REGISTRY.isVerifiedEOA(to)) { revert StrictAuthorizedTransferSecurityRegistry__ReceiverProofOfEOASignatureUnverified(); } } if (operator == from) { if (config.directTransfersDisabled) { revert StrictAuthorizedTransferSecurityRegistry__CallerMustBeWhitelistedOperator(); } return; } uint256 slot = _getAuthorizedIdentifierSlot(msg.sender, identifier); uint256 authorizedIdentifier = _getTstorish(slot); if (authorizedIdentifier != 0) { return; } if (config.blacklistBased) { if (lists[config.listId].blacklist.nonEnumerableAccounts[operator]) { revert StrictAuthorizedTransferSecurityRegistry__UnauthorizedTransfer(); } } else { if (!lists[config.listId].operators.nonEnumerableAccounts[operator]) { revert StrictAuthorizedTransferSecurityRegistry__UnauthorizedTransfer(); } } } function _validateTransferByAmount(address operator, address from, address to, uint256 identifier, uint256 amount) internal { CollectionConfiguration memory config = collectionConfiguration[msg.sender]; if (config.policyBypassed) { return; } if (config.contractRecipientsDisabled) { if (to.code.length != 0) { revert StrictAuthorizedTransferSecurityRegistry__ReceiverMustNotHaveDeployedCode(); } } if (config.signatureRegistrationRequired) { if (!_EOA_REGISTRY.isVerifiedEOA(to)) { revert StrictAuthorizedTransferSecurityRegistry__ReceiverProofOfEOASignatureUnverified(); } } if (operator == from) { if (config.directTransfersDisabled) { revert StrictAuthorizedTransferSecurityRegistry__CallerMustBeWhitelistedOperator(); } return; } uint256 slot = _getAuthorizedAmountSlot(msg.sender, identifier); uint256 authorizedAmount = _getTstorish(slot); if (authorizedAmount >= amount) { unchecked { _setTstorish(slot, authorizedAmount - amount); } return; } if (config.blacklistBased) { if (lists[config.listId].blacklist.nonEnumerableAccounts[operator]) { revert StrictAuthorizedTransferSecurityRegistry__UnauthorizedTransfer(); } } else { if (!lists[config.listId].operators.nonEnumerableAccounts[operator]) { revert StrictAuthorizedTransferSecurityRegistry__UnauthorizedTransfer(); } } } function _getAuthorizedOperatorSlot( address collection ) internal pure returns (uint256 slot) { bytes4 authorizedOperatorScope = _AUTHORIZED_OPERATOR_SCOPE; assembly { slot := or( authorizedOperatorScope, and(collection, 0xffffffffffffffffffffffffffffffffffffffff) ) } } function _getAuthorizedIdentifierSlot( address collection, uint256 identifier ) internal pure returns (uint256 slot) { bytes4 authorizedIdentifierScope = _AUTHORIZED_IDENTIFIER_SCOPE; assembly { mstore(0x0, authorizedIdentifierScope) mstore(0x18, collection) mstore(0x04, identifier) slot := keccak256(0x0, 0x38) } } function _getAuthorizedAmountSlot( address collection, uint256 identifier ) internal pure returns (uint256 slot) { bytes4 authorizedAmountScope = _AUTHORIZED_AMOUNT_SCOPE; assembly { mstore(0x0, authorizedAmountScope) mstore(0x18, collection) mstore(0x04, identifier) slot := keccak256(0x0, 0x38) } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; enum ListTypes { AuthorizerList, OperatorList, OperatorRequiringAuthorizationList } enum TransferSecurityLevels { Recommended, One, Two, Three, Four, Five, Six, Seven, Eight } /// @title IStrictAuthorizedTransferSecurityRegistry /// @dev Interface for the Authorized Transfer Security Registry, a simplified version of the Transfer /// Security Registry that only supports authorizers and whitelisted operators, and assumes a /// security level of OperatorWhitelistEnableOTC + authorizers for all collections that use it. /// Note that a number of view functions on collections that add this validator will not work. interface IStrictAuthorizedTransferSecurityRegistry { event CreatedList(uint256 indexed id, string name); event AppliedListToCollection(address indexed collection, uint120 indexed id); event ReassignedListOwnership(uint256 indexed id, address indexed newOwner); event AddedAccountToList(ListTypes indexed kind, uint256 indexed id, address indexed account); event RemovedAccountFromList(ListTypes indexed kind, uint256 indexed id, address indexed account); event SetTransferSecurityLevel(address collection, TransferSecurityLevels level); error StrictAuthorizedTransferSecurityRegistry__ListDoesNotExist(); error StrictAuthorizedTransferSecurityRegistry__CallerDoesNotOwnList(); error StrictAuthorizedTransferSecurityRegistry__ArrayLengthCannotBeZero(); error StrictAuthorizedTransferSecurityRegistry__CallerMustHaveElevatedPermissionsForSpecifiedNFT(); error StrictAuthorizedTransferSecurityRegistry__ListOwnershipCannotBeTransferredToZeroAddress(); error StrictAuthorizedTransferSecurityRegistry__ZeroAddressNotAllowed(); error StrictAuthorizedTransferSecurityRegistry__UnauthorizedTransfer(); error StrictAuthorizedTransferSecurityRegistry__CallerIsNotValidAuthorizer(); error StrictAuthorizedTransferSecurityRegistry__UnsupportedSecurityLevel(); error StrictAuthorizedTransferSecurityRegistry__UnsupportedSecurityLevelDetail(); error StrictAuthorizedTransferSecurityRegistry__CallerMustBeWhitelistedOperator(); error StrictAuthorizedTransferSecurityRegistry__ReceiverMustNotHaveDeployedCode(); error StrictAuthorizedTransferSecurityRegistry__ReceiverProofOfEOASignatureUnverified(); /// Manage lists of authorizers & operators that can be applied to collections function createList(string calldata name) external returns (uint120); function createListCopy(string calldata name, uint120 sourceListId) external returns (uint120); function reassignOwnershipOfList(uint120 id, address newOwner) external; function renounceOwnershipOfList(uint120 id) external; function applyListToCollection(address collection, uint120 id) external; function listOwners(uint120 id) external view returns (address); /// Manage and query for authorizers on lists function addAccountToAuthorizers(uint120 id, address account) external; function addAccountsToAuthorizers(uint120 id, address[] calldata accounts) external; function addAuthorizers(uint120 id, address[] calldata accounts) external; function removeAccountFromAuthorizers(uint120 id, address account) external; function removeAccountsFromAuthorizers(uint120 id, address[] calldata accounts) external; function getAuthorizerAccounts(uint120 id) external view returns (address[] memory); function isAccountAuthorizer(uint120 id, address account) external view returns (bool); function getAuthorizerAccountsByCollection(address collection) external view returns (address[] memory); function isAccountAuthorizerOfCollection(address collection, address account) external view returns (bool); /// Manage and query for operators on lists function addAccountToWhitelist(uint120 id, address account) external; function addAccountsToWhitelist(uint120 id, address[] calldata accounts) external; function addOperators(uint120 id, address[] calldata accounts) external; function removeAccountFromWhitelist(uint120 id, address account) external; function removeAccountsFromWhitelist(uint120 id, address[] calldata accounts) external; function getWhitelistedAccounts(uint120 id) external view returns (address[] memory); function isAccountWhitelisted(uint120 id, address account) external view returns (bool); function getWhitelistedAccountsByCollection(address collection) external view returns (address[] memory); function isAccountWhitelistedByCollection(address collection, address account) external view returns (bool); /// Manage and query for blacklists on lists function addAccountToBlacklist(uint120 id, address account) external; function addAccountsToBlacklist(uint120 id, address[] calldata accounts) external; function removeAccountFromBlacklist(uint120 id, address account) external; function removeAccountsFromBlacklist(uint120 id, address[] calldata accounts) external; function getBlacklistedAccounts(uint120 id) external view returns (address[] memory); function isAccountBlacklisted(uint120 id, address account) external view returns (bool); function getBlacklistedAccountsByCollection(address collection) external view returns (address[] memory); function isAccountBlacklistedByCollection(address collection, address account) external view returns (bool); function setTransferSecurityLevelOfCollection( address collection, uint8 level, bool enableAuthorizationMode, bool authorizersCanSetWildcardOperators, bool enableAccountFreezingMode ) external; function setTransferSecurityLevelOfCollection( address collection, TransferSecurityLevels level ) external; function isVerifiedEOA(address account) external view returns (bool); /// Ensure that a specific operator has been authorized to transfer tokens function validateTransfer(address caller, address from, address to) external view; /// Ensure that a transfer has been authorized for a specific tokenId function validateTransfer(address caller, address from, address to, uint256 tokenId) external view; /// Ensure that a transfer has been authorized for a specific amount of a specific tokenId, and /// reduce the transferable amount remaining function validateTransfer(address caller, address from, address to, uint256 tokenId, uint256 amount) external; /// Legacy alias for validateTransfer (address caller, address from, address to) function applyCollectionTransferPolicy(address caller, address from, address to) external view; /// Temporarily assign a specific allowed operator for a given collection function beforeAuthorizedTransfer(address operator, address token) external; /// Clear assignment of a specific allowed operator for a given collection function afterAuthorizedTransfer(address token) external; /// Temporarily allow a specific tokenId from a given collection to be transferred function beforeAuthorizedTransfer(address token, uint256 tokenId) external; /// Clear assignment of an specific tokenId's transfer allowance function afterAuthorizedTransfer(address token, uint256 tokenId) external; /// Temporarily allow a specific amount of a specific tokenId from a given collection to be transferred function beforeAuthorizedTransferWithAmount(address token, uint256 tokenId, uint256 amount) external; /// Clear assignment of a tokenId's transfer allowance for a specific amount function afterAuthorizedTransferWithAmount(address token, uint256 tokenId) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "./IEOARegistry.sol"; import "./ITransferSecurityRegistry.sol"; import "./ITransferValidator.sol"; interface ICreatorTokenTransferValidator is ITransferSecurityRegistry, ITransferValidator, IEOARegistry {}
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; interface IOwnable { function owner() external view returns (address); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableSet.sol) // This file was procedurally generated from scripts/generate/templates/EnumerableSet.js. pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. * * [WARNING] * ==== * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure * unusable. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. * * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an * array of EnumerableSet. * ==== */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastValue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastValue; // Update the index for the moved value set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { bytes32[] memory store = _values(set._inner); bytes32[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values in the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.24; contract Tstorish { // Declare a storage variable indicating if TSTORE support has been // activated post-deployment. bool private _tstoreSupport; /* * ------------------------------------------------------------------------+ * Opcode | Mnemonic | Stack | Memory | * ------------------------------------------------------------------------| * 60 0x02 | PUSH1 0x02 | 0x02 | | * 60 0x1e | PUSH1 0x1e | 0x1e 0x02 | | * 61 0x3d5c | PUSH2 0x3d5c | 0x3d5c 0x1e 0x02 | | * 3d | RETURNDATASIZE | 0 0x3d5c 0x1e 0x02 | | * | * :: store deployed bytecode in memory: (3d) RETURNDATASIZE (5c) TLOAD :: | * 52 | MSTORE | 0x1e 0x02 | [0..0x20): 0x3d5c | * f3 | RETURN | | [0..0x20): 0x3d5c | * ------------------------------------------------------------------------+ */ uint256 constant _TLOAD_TEST_PAYLOAD = 0x6002_601e_613d5c_3d_52_f3; uint256 constant _TLOAD_TEST_PAYLOAD_LENGTH = 0x0a; uint256 constant _TLOAD_TEST_PAYLOAD_OFFSET = 0x16; // Declare an immutable variable to store the tstore test contract address. address private immutable _tloadTestContract; // Declare an immutable variable to store the initial TSTORE support status. bool private immutable _tstoreInitialSupport; // Declare an immutable function type variable for the _setTstorish function // based on chain support for tstore at time of deployment. function(uint256,uint256) internal immutable _setTstorish; // Declare an immutable function type variable for the _getTstorish function // based on chain support for tstore at time of deployment. function(uint256) view returns (uint256) internal immutable _getTstorish; // Declare an immutable function type variable for the _clearTstorish function // based on chain support for tstore at time of deployment. function(uint256) internal immutable _clearTstorish; // Declare a few custom revert error types. error TStoreAlreadyActivated(); error TStoreNotSupported(); error TloadTestContractDeploymentFailed(); error OnlyDirectCalls(); /** * @dev Determine TSTORE availability during deployment. This involves * attempting to deploy a contract that utilizes TLOAD as part of the * contract construction bytecode, and configuring initial support for * using TSTORE in place of SSTORE based on the result. */ constructor() { // Deploy the contract testing TLOAD support and store the address. address tloadTestContract = _prepareTloadTest(); // Ensure the deployment was successful. if (tloadTestContract == address(0)) { revert TloadTestContractDeploymentFailed(); } // Determine if TSTORE is supported. bool tstoreInitialSupport = _testTload(tloadTestContract); if (tstoreInitialSupport) { // If TSTORE is supported, set functions to their versions that use // tstore/tload directly without support checks. _setTstorish = _setTstore; _getTstorish = _getTstore; _clearTstorish = _clearTstore; } else { // If TSTORE is not supported, set functions to their versions that // fallback to sstore/sload until _tstoreSupport is true. _setTstorish = _setTstorishWithSstoreFallback; _getTstorish = _getTstorishWithSloadFallback; _clearTstorish = _clearTstorishWithSstoreFallback; } _tstoreInitialSupport = tstoreInitialSupport; // Set the address of the deployed TLOAD test contract as an immutable. _tloadTestContract = tloadTestContract; } /** * @dev External function to activate TSTORE usage. Does not need to be * called if TSTORE is supported from deployment, and only needs to be * called once. Reverts if TSTORE has already been activated or if the * opcode is not available. Note that this must be called directly from * an externally-owned account to avoid potential reentrancy issues. */ function __activateTstore() external { // Ensure this function is triggered from an externally-owned account. if (msg.sender != tx.origin) { revert OnlyDirectCalls(); } // Determine if TSTORE can potentially be activated. if (_tstoreInitialSupport || _tstoreSupport) { revert TStoreAlreadyActivated(); } // Determine if TSTORE can be activated and revert if not. if (!_testTload(_tloadTestContract)) { revert TStoreNotSupported(); } // Mark TSTORE as activated. _tstoreSupport = true; } /** * @dev Private function to set a TSTORISH value. Assigned to _setTstorish * internal function variable at construction if chain has tstore support. * * @param storageSlot The slot to write the TSTORISH value to. * @param value The value to write to the given storage slot. */ function _setTstore(uint256 storageSlot, uint256 value) private { assembly { tstore(storageSlot, value) } } /** * @dev Private function to set a TSTORISH value with sstore fallback. * Assigned to _setTstorish internal function variable at construction * if chain does not have tstore support. * * @param storageSlot The slot to write the TSTORISH value to. * @param value The value to write to the given storage slot. */ function _setTstorishWithSstoreFallback(uint256 storageSlot, uint256 value) private { if (_tstoreSupport) { assembly { tstore(storageSlot, value) } } else { assembly { sstore(storageSlot, value) } } } /** * @dev Private function to read a TSTORISH value. Assigned to _getTstorish * internal function variable at construction if chain has tstore support. * * @param storageSlot The slot to read the TSTORISH value from. * * @return value The TSTORISH value at the given storage slot. */ function _getTstore( uint256 storageSlot ) private view returns (uint256 value) { assembly { value := tload(storageSlot) } } /** * @dev Private function to read a TSTORISH value with sload fallback. * Assigned to _getTstorish internal function variable at construction * if chain does not have tstore support. * * @param storageSlot The slot to read the TSTORISH value from. * * @return value The TSTORISH value at the given storage slot. */ function _getTstorishWithSloadFallback( uint256 storageSlot ) private view returns (uint256 value) { if (_tstoreSupport) { assembly { value := tload(storageSlot) } } else { assembly { value := sload(storageSlot) } } } /** * @dev Private function to clear a TSTORISH value. Assigned to _clearTstorish internal * function variable at construction if chain has tstore support. * * @param storageSlot The slot to clear the TSTORISH value for. */ function _clearTstore(uint256 storageSlot) private { assembly { tstore(storageSlot, 0) } } /** * @dev Private function to clear a TSTORISH value with sstore fallback. * Assigned to _clearTstorish internal function variable at construction * if chain does not have tstore support. * * @param storageSlot The slot to clear the TSTORISH value for. */ function _clearTstorishWithSstoreFallback(uint256 storageSlot) private { if (_tstoreSupport) { assembly { tstore(storageSlot, 0) } } else { assembly { sstore(storageSlot, 0) } } } /** * @dev Private function to deploy a test contract that utilizes TLOAD as * part of its fallback logic. */ function _prepareTloadTest() private returns (address contractAddress) { // Utilize assembly to deploy a contract testing TLOAD support. assembly { // Write the contract deployment code payload to scratch space. mstore(0, _TLOAD_TEST_PAYLOAD) // Deploy the contract. contractAddress := create( 0, _TLOAD_TEST_PAYLOAD_OFFSET, _TLOAD_TEST_PAYLOAD_LENGTH ) } } /** * @dev Private view function to determine if TSTORE/TLOAD are supported by * the current EVM implementation by attempting to call the test * contract, which utilizes TLOAD as part of its fallback logic. */ function _testTload( address tloadTestContract ) private view returns (bool ok) { // Call the test contract, which will perform a TLOAD test. If the call // does not revert, then TLOAD/TSTORE is supported. Do not forward all // available gas, as all forwarded gas will be consumed on revert. (ok, ) = tloadTestContract.staticcall{ gas: gasleft() / 10 }(""); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; interface IEOARegistry is IERC165 { function isVerifiedEOA(address account) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.24; import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; import { Tstorish } from "tstorish/Tstorish.sol"; import { TransferSecurityLevels } from "./interfaces/IStrictAuthorizedTransferSecurityRegistry.sol"; /// @title StrictAuthorizedTransferSecurityRegistryExtraViewFns /// @dev Additional view functions, called by StrictAuthorizedTransferSecurityRegistry /// via delegatecall in the fallback. contract StrictAuthorizedTransferSecurityRegistryExtraViewFns is Tstorish { using EnumerableSet for EnumerableSet.AddressSet; error StrictAuthorizedTransferSecurityRegistry__NotImplemented(); struct CollectionSecurityPolicy { TransferSecurityLevels transferSecurityLevel; uint120 operatorWhitelistId; uint120 permittedContractReceiversId; } struct AccountList { EnumerableSet.AddressSet enumerableAccounts; mapping (address => bool) nonEnumerableAccounts; } struct List { address owner; AccountList authorizers; AccountList operators; } struct CollectionConfiguration { uint120 listId; bool policyBypassed; bool blacklistBased; bool directTransfersDisabled; bool contractRecipientsDisabled; bool signatureRegistrationRequired; } uint120 private UNUSED_lastListId; mapping (uint120 => List) private lists; /// @dev Mapping of collection addresses to list ids & security policies. mapping (address => CollectionConfiguration) private collectionConfiguration; // view functions from other transfer security registries, included for completeness function getBlacklistedAccounts(uint120) external pure returns (address[] memory) {} function getWhitelistedAccounts(uint120 id) external view returns (address[] memory) { return lists[id].operators.enumerableAccounts.values(); } function getBlacklistedCodeHashes(uint120) external pure returns (bytes32[] memory) {} function getWhitelistedCodeHashes(uint120) external pure returns (bytes32[] memory) {} function isAccountBlacklisted(uint120, address) external pure returns (bool) { return false; } function isAccountWhitelisted(uint120 id, address account) external view returns (bool) { return lists[id].operators.nonEnumerableAccounts[account]; } function isCodeHashBlacklisted(uint120, bytes32) external pure returns (bool) { return false; } function isCodeHashWhitelisted(uint120, bytes32) external pure returns (bool) { return false; } function getBlacklistedAccountsByCollection(address) external pure returns (address[] memory) {} function getWhitelistedAccountsByCollection(address collection) external view returns (address[] memory) { return lists[collectionConfiguration[collection].listId].operators.enumerableAccounts.values(); } function getBlacklistedCodeHashesByCollection(address) external pure returns (bytes32[] memory) {} function getWhitelistedCodeHashesByCollection(address) external pure returns (bytes32[] memory) {} function isAccountBlacklistedByCollection(address, address) external pure returns (bool) { return false; } function isAccountWhitelistedByCollection( address collection, address account ) external view returns (bool) { return lists[collectionConfiguration[collection].listId].operators.nonEnumerableAccounts[account]; } function isCodeHashBlacklistedByCollection(address, bytes32) external pure returns (bool) { return false; } function isCodeHashWhitelistedByCollection(address, bytes32) external pure returns (bool) { return false; } function getCollectionSecurityPolicy( address collection ) external view returns (CollectionSecurityPolicy memory) { CollectionConfiguration memory config = collectionConfiguration[collection]; return CollectionSecurityPolicy({ transferSecurityLevel: _getSecurityLevel(config), operatorWhitelistId: config.listId, permittedContractReceiversId: 0 }); } function getWhitelistedOperators(uint120 id) external view returns (address[] memory) { return lists[id].operators.enumerableAccounts.values(); } function getPermittedContractReceivers(uint120) external pure returns (address[] memory) {} function isOperatorWhitelisted(uint120 id, address operator) external view returns (bool) { return lists[id].operators.nonEnumerableAccounts[operator]; } function isContractReceiverPermitted(uint120, address) external pure returns (bool) { return true; } function _getSecurityLevel( CollectionConfiguration memory config ) internal pure returns (TransferSecurityLevels level) { bool policyBypassed = config.policyBypassed; bool blacklistBased = config.blacklistBased; bool directTransfersDisabled = config.directTransfersDisabled; bool contractRecipientsDisabled = config.contractRecipientsDisabled; bool signatureRegistrationRequired = config.signatureRegistrationRequired; if (policyBypassed) { return TransferSecurityLevels.One; } if (blacklistBased) { return TransferSecurityLevels.Two; } if (directTransfersDisabled) { if (signatureRegistrationRequired) { return TransferSecurityLevels.Eight; } else if (contractRecipientsDisabled) { return TransferSecurityLevels.Seven; } return TransferSecurityLevels.Four; } if (signatureRegistrationRequired) { return TransferSecurityLevels.Six; } else if (contractRecipientsDisabled) { return TransferSecurityLevels.Five; } return TransferSecurityLevels.Three; } fallback() external { revert StrictAuthorizedTransferSecurityRegistry__NotImplemented(); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "../utils/TransferPolicy.sol"; interface ITransferSecurityRegistry { event AddedToAllowlist(AllowlistTypes indexed kind, uint256 indexed id, address indexed account); event CreatedAllowlist(AllowlistTypes indexed kind, uint256 indexed id, string indexed name); event ReassignedAllowlistOwnership(AllowlistTypes indexed kind, uint256 indexed id, address indexed newOwner); event RemovedFromAllowlist(AllowlistTypes indexed kind, uint256 indexed id, address indexed account); event SetAllowlist(AllowlistTypes indexed kind, address indexed collection, uint120 indexed id); event SetTransferSecurityLevel(address indexed collection, TransferSecurityLevels level); function createOperatorWhitelist(string calldata name) external returns (uint120); function createPermittedContractReceiverAllowlist(string calldata name) external returns (uint120); function reassignOwnershipOfOperatorWhitelist(uint120 id, address newOwner) external; function reassignOwnershipOfPermittedContractReceiverAllowlist(uint120 id, address newOwner) external; function renounceOwnershipOfOperatorWhitelist(uint120 id) external; function renounceOwnershipOfPermittedContractReceiverAllowlist(uint120 id) external; function setTransferSecurityLevelOfCollection(address collection, TransferSecurityLevels level) external; function setOperatorWhitelistOfCollection(address collection, uint120 id) external; function setPermittedContractReceiverAllowlistOfCollection(address collection, uint120 id) external; function addOperatorToWhitelist(uint120 id, address operator) external; function addPermittedContractReceiverToAllowlist(uint120 id, address receiver) external; function removeOperatorFromWhitelist(uint120 id, address operator) external; function removePermittedContractReceiverFromAllowlist(uint120 id, address receiver) external; function getCollectionSecurityPolicy(address collection) external view returns (CollectionSecurityPolicy memory); function getWhitelistedOperators(uint120 id) external view returns (address[] memory); function getPermittedContractReceivers(uint120 id) external view returns (address[] memory); function isOperatorWhitelisted(uint120 id, address operator) external view returns (bool); function isContractReceiverPermitted(uint120 id, address receiver) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "../utils/TransferPolicy.sol"; interface ITransferValidator { function applyCollectionTransferPolicy(address caller, address from, address to) external view; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /** * @dev Used in events to indicate the list type that an account or * @dev codehash is being added to or removed from. * * @dev Used in Creator Token Standards V2. */ enum ListTypes { // 0: List type that will block a matching address/codehash that is on the list. Blacklist, // 1: List type that will block any matching address/codehash that is not on the list. Whitelist } /** * @dev Used in events to indicate the list type that event relates to. * * @dev Used in Creator Token Standards V1. */ enum AllowlistTypes { // 0: List type that defines the allowed operator addresses. Operators, // 1: List type that defines the allowed contract receivers. PermittedContractReceivers } /** @dev Defines the constraints that will be applied for receipt of tokens. */ enum ReceiverConstraints { // 0: Any address may receive tokens. None, // 1: Address must not have deployed bytecode. NoCode, // 2: Address must verify a signature with the EOA Registry to prove it is an EOA. EOA } /** * @dev Defines the constraints that will be applied to the transfer caller. */ enum CallerConstraints { // 0: Any address may transfer tokens. None, // 1: Addresses and codehashes not on the blacklist may transfer tokens. OperatorBlacklistEnableOTC, // 2: Addresses and codehashes on the whitelist and the owner of the token may transfer tokens. OperatorWhitelistEnableOTC, // 3: Addresses and codehashes on the whitelist may transfer tokens. OperatorWhitelistDisableOTC } /** * @dev Defines constraints for staking tokens in token wrapper contracts. */ enum StakerConstraints { // 0: No constraints applied to staker. None, // 1: Transaction originator must be the address that will receive the wrapped tokens. CallerIsTxOrigin, // 2: Address that will receive the wrapped tokens must be a verified EOA. EOA } /** * @dev Used in both Creator Token Standards V1 and V2. * @dev Levels may have different transfer restrictions in V1 and V2. Refer to the * @dev Creator Token Transfer Validator implementation for the version being utilized * @dev to determine the effect of the selected level. */ enum TransferSecurityLevels { Recommended, One, Two, Three, Four, Five, Six, Seven, Eight } /** * @dev Defines the caller and receiver constraints for a transfer security level. * @dev Used in Creator Token Standards V1. * * @dev **callerConstraints**: The restrictions applied to the transfer caller. * @dev **receiverConstraints**: The restrictions applied to the transfer recipient. */ struct TransferSecurityPolicy { CallerConstraints callerConstraints; ReceiverConstraints receiverConstraints; } /** * @dev Defines the security policy for a token collection in Creator Token Standards V1. * * @dev **transferSecurityLevel**: The transfer security level set for the collection. * @dev **operatorWhitelistId**: The list id for the operator whitelist. * @dev **permittedContractReceiversId: The list id for the contracts that are allowed to receive tokens. */ struct CollectionSecurityPolicy { TransferSecurityLevels transferSecurityLevel; uint120 operatorWhitelistId; uint120 permittedContractReceiversId; } /** * @dev Defines the security policy for a token collection in Creator Token Standards V2. * * @dev **transferSecurityLevel**: The transfer security level set for the collection. * @dev **listId**: The list id that contains the blacklist and whitelist to apply to the collection. */ struct CollectionSecurityPolicyV2 { TransferSecurityLevels transferSecurityLevel; uint120 listId; } /** * @dev Used internally in the Creator Token Base V2 contract to pack transfer validator configuration. * * @dev **isInitialized**: If not initialized by the collection owner or admin the default validator will be used. * @dev **version**: The transfer validator version. * @dev **transferValidator**: The address of the transfer validator to use for applying collection security settings. */ struct TransferValidatorReference { bool isInitialized; uint16 version; address transferValidator; }
{ "remappings": [ "seaport-core/=lib/seaport-core/", "seaport-types/=lib/seaport-types/", "seaport-sol/=lib/seaport-sol/src/", "seaport-deploy/=lib/seaport-deploy/src/", "solady/=lib/solady/", "@openzeppelin/=lib/openzeppelin-contracts/", "@limitbreak/creator-token-standards/=lib/creator-token-standards/src/", "@rari-capital/solmate/=lib/seaport-sol/lib/seaport/lib/solmate/", "ERC721A/=lib/creator-token-standards/lib/ERC721A/contracts/", "creator-token-standards/=lib/creator-token-standards/", "ds-test/=lib/forge-std/lib/ds-test/src/", "erc4626-tests/=lib/seaport-sol/lib/seaport/lib/openzeppelin-contracts/lib/erc4626-tests/", "erc721a/=lib/creator-token-standards/lib/ERC721A/", "forge-std/=lib/forge-std/src/", "murky/=lib/creator-token-standards/lib/murky/", "openzeppelin-contracts/=lib/openzeppelin-contracts/", "seaport/=lib/seaport-sol/lib/seaport/contracts/", "solarray/=lib/seaport-sol/lib/solarray/src/", "solmate/=lib/seaport-sol/lib/seaport/lib/solmate/src/", "tstorish/=lib/tstorish/src/" ], "optimizer": { "enabled": true, "runs": 9999999 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "evmVersion": "cancun", "viaIR": false, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"defaultOwner","type":"address"},{"internalType":"address","name":"eoaRegistry","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"OnlyDirectCalls","type":"error"},{"inputs":[],"name":"StrictAuthorizedTransferSecurityRegistry__ArrayLengthCannotBeZero","type":"error"},{"inputs":[],"name":"StrictAuthorizedTransferSecurityRegistry__CallerDoesNotOwnList","type":"error"},{"inputs":[],"name":"StrictAuthorizedTransferSecurityRegistry__CallerIsNotValidAuthorizer","type":"error"},{"inputs":[],"name":"StrictAuthorizedTransferSecurityRegistry__CallerMustBeWhitelistedOperator","type":"error"},{"inputs":[],"name":"StrictAuthorizedTransferSecurityRegistry__CallerMustHaveElevatedPermissionsForSpecifiedNFT","type":"error"},{"inputs":[],"name":"StrictAuthorizedTransferSecurityRegistry__ListDoesNotExist","type":"error"},{"inputs":[],"name":"StrictAuthorizedTransferSecurityRegistry__ListOwnershipCannotBeTransferredToZeroAddress","type":"error"},{"inputs":[],"name":"StrictAuthorizedTransferSecurityRegistry__ReceiverMustNotHaveDeployedCode","type":"error"},{"inputs":[],"name":"StrictAuthorizedTransferSecurityRegistry__ReceiverProofOfEOASignatureUnverified","type":"error"},{"inputs":[],"name":"StrictAuthorizedTransferSecurityRegistry__UnauthorizedTransfer","type":"error"},{"inputs":[],"name":"StrictAuthorizedTransferSecurityRegistry__UnsupportedSecurityLevel","type":"error"},{"inputs":[],"name":"StrictAuthorizedTransferSecurityRegistry__UnsupportedSecurityLevelDetail","type":"error"},{"inputs":[],"name":"StrictAuthorizedTransferSecurityRegistry__ZeroAddressNotAllowed","type":"error"},{"inputs":[],"name":"TStoreAlreadyActivated","type":"error"},{"inputs":[],"name":"TStoreNotSupported","type":"error"},{"inputs":[],"name":"TloadTestContractDeploymentFailed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"enum ListTypes","name":"kind","type":"uint8"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"AddedAccountToList","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"collection","type":"address"},{"indexed":true,"internalType":"uint120","name":"id","type":"uint120"}],"name":"AppliedListToCollection","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"string","name":"name","type":"string"}],"name":"CreatedList","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"ReassignedListOwnership","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"enum ListTypes","name":"kind","type":"uint8"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"RemovedAccountFromList","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"collection","type":"address"},{"indexed":false,"internalType":"enum TransferSecurityLevels","name":"level","type":"uint8"}],"name":"SetTransferSecurityLevel","type":"event"},{"stateMutability":"nonpayable","type":"fallback"},{"inputs":[],"name":"__activateTstore","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint120","name":"id","type":"uint120"},{"internalType":"address","name":"account","type":"address"}],"name":"addAccountToAuthorizers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint120","name":"id","type":"uint120"},{"internalType":"address","name":"account","type":"address"}],"name":"addAccountToBlacklist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint120","name":"id","type":"uint120"},{"internalType":"address","name":"account","type":"address"}],"name":"addAccountToWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint120","name":"id","type":"uint120"},{"internalType":"address[]","name":"accounts","type":"address[]"}],"name":"addAccountsToAuthorizers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint120","name":"id","type":"uint120"},{"internalType":"address[]","name":"accounts","type":"address[]"}],"name":"addAccountsToBlacklist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint120","name":"id","type":"uint120"},{"internalType":"address[]","name":"accounts","type":"address[]"}],"name":"addAccountsToWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint120","name":"id","type":"uint120"},{"internalType":"address[]","name":"accounts","type":"address[]"}],"name":"addAuthorizers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint120","name":"id","type":"uint120"},{"internalType":"address[]","name":"accounts","type":"address[]"}],"name":"addOperators","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"afterAuthorizedTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"afterAuthorizedTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"afterAuthorizedTransferWithAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"caller","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"}],"name":"applyCollectionTransferPolicy","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint120","name":"id","type":"uint120"}],"name":"applyListToCollection","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"beforeAuthorizedTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"token","type":"address"}],"name":"beforeAuthorizedTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"beforeAuthorizedTransferWithAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"}],"name":"createList","outputs":[{"internalType":"uint120","name":"","type":"uint120"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"uint120","name":"sourceListId","type":"uint120"}],"name":"createListCopy","outputs":[{"internalType":"uint120","name":"","type":"uint120"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint120","name":"id","type":"uint120"}],"name":"getAuthorizerAccounts","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"}],"name":"getAuthorizerAccountsByCollection","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint120","name":"id","type":"uint120"}],"name":"getBlacklistedAccounts","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"}],"name":"getBlacklistedAccountsByCollection","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint120","name":"id","type":"uint120"}],"name":"getWhitelistedAccounts","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"}],"name":"getWhitelistedAccountsByCollection","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint120","name":"id","type":"uint120"},{"internalType":"address","name":"account","type":"address"}],"name":"isAccountAuthorizer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"isAccountAuthorizerOfCollection","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint120","name":"id","type":"uint120"},{"internalType":"address","name":"account","type":"address"}],"name":"isAccountBlacklisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"isAccountBlacklistedByCollection","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint120","name":"id","type":"uint120"},{"internalType":"address","name":"account","type":"address"}],"name":"isAccountWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"isAccountWhitelistedByCollection","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isVerifiedEOA","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastListId","outputs":[{"internalType":"uint120","name":"","type":"uint120"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint120","name":"id","type":"uint120"}],"name":"listOwners","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint120","name":"id","type":"uint120"},{"internalType":"address","name":"newOwner","type":"address"}],"name":"reassignOwnershipOfList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint120","name":"id","type":"uint120"},{"internalType":"address","name":"account","type":"address"}],"name":"removeAccountFromAuthorizers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint120","name":"id","type":"uint120"},{"internalType":"address","name":"account","type":"address"}],"name":"removeAccountFromBlacklist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint120","name":"id","type":"uint120"},{"internalType":"address","name":"account","type":"address"}],"name":"removeAccountFromWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint120","name":"id","type":"uint120"},{"internalType":"address[]","name":"accounts","type":"address[]"}],"name":"removeAccountsFromAuthorizers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint120","name":"id","type":"uint120"},{"internalType":"address[]","name":"accounts","type":"address[]"}],"name":"removeAccountsFromBlacklist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint120","name":"id","type":"uint120"},{"internalType":"address[]","name":"accounts","type":"address[]"}],"name":"removeAccountsFromWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint120","name":"id","type":"uint120"}],"name":"renounceOwnershipOfList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint8","name":"level","type":"uint8"},{"internalType":"bool","name":"enableAuthorizationMode","type":"bool"},{"internalType":"bool","name":"authorizersCanSetWildcardOperators","type":"bool"},{"internalType":"bool","name":"enableAccountFreezingMode","type":"bool"}],"name":"setTransferSecurityLevelOfCollection","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"enum TransferSecurityLevels","name":"level","type":"uint8"}],"name":"setTransferSecurityLevelOfCollection","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"caller","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"validateTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"caller","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"}],"name":"validateTransfer","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"caller","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"validateTransfer","outputs":[],"stateMutability":"view","type":"function"}]
Contract Creation Code
61016060405234801562000011575f80fd5b5060405162004d8138038062004d8183398101604081905262000034916200032c565b5f6200003f62000235565b90506001600160a01b0381166200006957604051632aea588760e01b815260040160405180910390fd5b5f62000075826200024e565b90508015620000c157620002b0602090811b62001d8d176001600160401b0390811660c052620002b7821b62001d9417811660e052620002bb90911b62001d98171661010052620000ff565b620002c1602090811b62001d9e176001600160401b0390811660c052620002d7821b62001db317811660e052620002f190911b62001dcc1716610100525b151560a0526001600160a01b039081166080525f80805260016020527fa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb4980549285166001600160a01b03199093169290921790915560405181907f5cc365f89543268cb9f25c255f7f610e9147e733c589bc2732279575f125be1490620001a6906020808252600c908201526b1111519055531508131254d560a21b604082015260600190565b60405180910390a26040516001600160a01b038416906001600160781b038316907f9b0894203394c3cbb23140db7a23b224d3e18e0366e9f65bd9c8402650e27367905f90a3604051620001fa9062000307565b604051809103905ff08015801562000214573d5f803e3d5ffd5b506001600160a01b0390811661012052919091166101405250620003829050565b5f696002601e613d5c3d52f35f52600a60165ff0905090565b5f816001600160a01b0316600a5a62000268919062000362565b6040515f8181818686fa925050503d805f8114620002a2576040519150601f19603f3d011682016040523d82523d5f602084013e620002a7565b606091505b50909392505050565b80825d5050565b5c90565b5f815d50565b5f5460ff1615620002d35780825d5050565b9055565b5f805460ff1615620002e857505c90565b5080545b919050565b5f5460ff161562000302575f815d50565b5f9055565b610d07806200407a83390190565b80516001600160a01b0381168114620002ec575f80fd5b5f80604083850312156200033e575f80fd5b620003498362000315565b9150620003596020840162000315565b90509250929050565b5f826200037d57634e487b7160e01b5f52601260045260245ffd5b500490565b60805160a05160c05160e051610100516101205161014051613c67620004135f395f8181611424015281816122b2015281816126fd0152612f7a01525f61032001525f610adb01525f8181610c57015281816124040152818161283901526130cc01525f8181610c8f01528181610e0f01528181610f7c015261243801525f61116701525f6111ce0152613c675ff3fe608060405234801561000f575f80fd5b506004361061031e575f3560e01c806388c1d66d116101a5578063b8dcc68f116100ec578063ddae38f211610095578063e991dc301161006f578063e991dc30146108ec578063ede0fe31146108ff578063fd51f20f146109125761031e565b8063ddae38f214610615578063de02cbb1146108c6578063df5fd29a146108d95761031e565b8063caee23ea116100c6578063caee23ea1461088d578063da0194c0146108a0578063dda964e3146108b35761031e565b8063b8dcc68f14610854578063bf7bfd7e14610867578063c3d58f4d1461087a5761031e565b8063a1cc5cc11161014e578063b6e39ba111610128578063b6e39ba1146107d3578063b70510f5146107e6578063b89c4b0d146108415761031e565b8063a1cc5cc114610755578063a5ce71f514610755578063ae602f44146107685761031e565b80638b6ee8651161017f5780638b6ee865146106c85780638e28800f146106db578063982d03c0146107425761031e565b806388c1d66d1461068f57806389631626146106a257806389a9c855146106b55761031e565b8063317e3e8d116102695780636971082811610212578063755b6fd7116101ec578063755b6fd7146106155780637bac97de146106285780637c1e14b4146104e85761031e565b806369710828146105e75780636bfab91d146105fa5780637423eb3c1461060d5761031e565b80633e5c139d116102435780633e5c139d146105ae57806343999db8146105c157806350793315146105d45761031e565b8063317e3e8d146105215780633a0e3160146105345780633cda743a146105475761031e565b806316a17ce0116102cb578063285fb8c8116102a5578063285fb8c8146104e857806328cc1131146104fb5780632eb0b98a1461050e5761031e565b806316a17ce01461043b5780631854b2411461049657806323c99262146104a95761031e565b80630ad38899116102fc5780630ad38899146103f55780630b6153091461040857806310b5c6a01461041b5761031e565b8063015499301461035f57806301ffc9a714610372578063057497cb1461039a575b7f0000000000000000000000000000000000000000000000000000000000000000365f80375f80365f845af43d5f803e808015610359573d5ff35b3d5ffd5b005b61035d61036d36600461359c565b610925565b61038561038036600461361b565b6109d0565b60405190151581526020015b60405180910390f35b6103856103a836600461367d565b6effffffffffffffffffffffffffffff82165f90815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845260060190915290205460ff1692915050565b61035d6104033660046136ae565b610a93565b61035d61041636600461367d565b610b05565b61042e6104293660046136c7565b610bc4565b60405161039191906136e0565b61038561044936600461367d565b6effffffffffffffffffffffffffffff82165f90815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845260090190915290205460ff1692915050565b61035d6104a4366004613739565b610bf2565b5f546104c89061010090046effffffffffffffffffffffffffffff1681565b6040516effffffffffffffffffffffffffffff9091168152602001610391565b61035d6104f636600461378a565b610bff565b61035d6105093660046137ca565b610c0f565b61035d61051c36600461359c565b610cbe565b61035d61052f366004613807565b610d63565b61035d610542366004613877565b610dcb565b61038561055536600461389f565b73ffffffffffffffffffffffffffffffffffffffff9182165f908152600260209081526040808320546effffffffffffffffffffffffffffff168352600182528083209390941682526003909201909152205460ff1690565b61042e6105bc3660046136ae565b610e3a565b61035d6105cf36600461367d565b610e8b565b61035d6105e236600461389f565b610f1e565b61035d6105f536600461359c565b610fa3565b61035d61060836600461367d565b611047565b61035d61112c565b61035d61062336600461359c565b611254565b61038561063636600461389f565b73ffffffffffffffffffffffffffffffffffffffff9182165f908152600260209081526040808320546effffffffffffffffffffffffffffff168352600182528083209390941682526009909201909152205460ff1690565b61035d61069d36600461367d565b6112f6565b61042e6106b03660046136c7565b6113af565b6103856106c33660046136ae565b6113dd565b61035d6106d63660046136c7565b61148f565b6103856106e936600461389f565b73ffffffffffffffffffffffffffffffffffffffff9182165f908152600260209081526040808320546effffffffffffffffffffffffffffff168352600182528083209390941682526006909201909152205460ff1690565b61042e6107503660046136ae565b61150c565b61035d61076336600461359c565b61155d565b6107ae6107763660046136c7565b6effffffffffffffffffffffffffffff165f9081526001602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610391565b61035d6107e1366004613877565b611602565b6103856107f436600461367d565b6effffffffffffffffffffffffffffff82165f90815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845260030190915290205460ff1692915050565b61035d61084f366004613877565b611647565b6104c86108623660046138fe565b61168c565b61035d61087536600461393d565b611796565b61035d61088836600461367d565b611881565b61035d61089b366004613965565b611914565b61035d6108ae3660046139ad565b611920565b61042e6108c13660046136c7565b61192a565b6104c86108d43660046139e5565b611959565b61035d6108e736600461359c565b611b26565b61042e6108fa3660046136ae565b611bc8565b61035d61090d36600461367d565b611c19565b61035d61092036600461367d565b611cd3565b8261092f81611de1565b815f81900361096a576040517f693f369c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109c9858585808060200260200160405190810160405280939291908181526020018383602002808284375f9201829052506effffffffffffffffffffffffffffff8c168152600160205260409020600701925060029150611e4f9050565b5050505050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082161580610a4157507fffffffff0000000000000000000000000000000000000000000000000000000082167f751a614900000000000000000000000000000000000000000000000000000000145b80610a8d57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b610a9c81611fa6565b610b027f596a397a0000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff8316175b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff16565b50565b81610b0f81611de1565b6040805160018082528183019092525f916020808301908036833701905050905082815f81518110610b4357610b43613a2c565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050610bbe848260015f886effffffffffffffffffffffffffffff166effffffffffffffffffffffffffffff1681526020019081526020015f206001015f61202d565b50505050565b6effffffffffffffffffffffffffffff81165f908152600160205260409020606090610a8d9060070161211f565b6109c98585858585612132565b610c0a83838361257d565b505050565b610c1883611fa6565b7f71836d45000000000000000000000000000000000000000000000000000000005f908152601884905260048390526038812090610c798263ffffffff7f000000000000000000000000000000000000000000000000000000000000000016565b90505f610c868483613a86565b9050610cb683827f000000000000000000000000000000000000000000000000000000000000000063ffffffff16565b505050505050565b82610cc881611de1565b815f819003610d03576040517f693f369c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109c9858585808060200260200160405190810160405280939291908181526020018383602002808284375f9201829052506effffffffffffffffffffffffffffff8c1681526001602081905260409091206004019350915061202d9050565b821580610d6e575081155b80610d765750805b15610dad576040517f7ced84b900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109c9858560ff166008811115610dc657610dc6613a99565b6129a0565b610dd482611fa6565b7f7e746c61000000000000000000000000000000000000000000000000000000005f9081526018839052600482905260389020610e369060017f000000000000000000000000000000000000000000000000000000000000000063ffffffff16565b5050565b73ffffffffffffffffffffffffffffffffffffffff81165f908152600260209081526040808320546effffffffffffffffffffffffffffff168352600191829052909120606091610a8d910161211f565b81610e9581611de1565b6040805160018082528183019092525f916020808301908036833701905050905082815f81518110610ec957610ec9613a2c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091018201526effffffffffffffffffffffffffffff85165f908152600190915260409020610bbe90859083906007016002611e4f565b610f2781611fa6565b610e367f596a397a0000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff8316178373ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000063ffffffff16565b82610fad81611de1565b815f819003610fe8576040517f693f369c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109c9858585808060200260200160405190810160405280939291908181526020018383602002808284375f9201829052506effffffffffffffffffffffffffffff8c16815260016020526040902060070192506002915061202d9050565b8161105181611de1565b73ffffffffffffffffffffffffffffffffffffffff821661109e576040517f2ba5f16500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6effffffffffffffffffffffffffffff83165f8181526001602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff871690811790915590519092917f9b0894203394c3cbb23140db7a23b224d3e18e0366e9f65bd9c8402650e2736791a3505050565b333214611165576040517f2599431400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000008061119257505f5460ff165b156111c9576040517ff45b98b000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6111f27f0000000000000000000000000000000000000000000000000000000000000000612d08565b611228576040517f70a4078f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b8261125e81611de1565b815f819003611299576040517f693f369c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109c9858585808060200260200160405190810160405280939291908181526020018383602002808284375f9201829052506effffffffffffffffffffffffffffff8c16815260016020819052604082200193509150611e4f9050565b8161130081611de1565b6040805160018082528183019092525f916020808301908036833701905050905082815f8151811061133457611334613a2c565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050610bbe848260015f886effffffffffffffffffffffffffffff166effffffffffffffffffffffffffffff1681526020019081526020015f206001015f611e4f565b6effffffffffffffffffffffffffffff81165f908152600160205260409020606090610a8d9060040161211f565b6040517f89a9c85500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82811660048301525f917f0000000000000000000000000000000000000000000000000000000000000000909116906389a9c85590602401602060405180830381865afa15801561146b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a8d9190613ac6565b8061149981611de1565b6effffffffffffffffffffffffffffff82165f8181526001602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055519091907f9b0894203394c3cbb23140db7a23b224d3e18e0366e9f65bd9c8402650e27367908390a35050565b73ffffffffffffffffffffffffffffffffffffffff81165f908152600260209081526040808320546effffffffffffffffffffffffffffff16835260019091529020606090610a8d9060070161211f565b8261156781611de1565b815f8190036115a2576040517f693f369c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109c9858585808060200260200160405190810160405280939291908181526020018383602002808284375f9201829052506effffffffffffffffffffffffffffff8c16815260016020819052604090912060040193509150611e4f9050565b61160b82611fa6565b7f71836d45000000000000000000000000000000000000000000000000000000005f9081526018839052600482905260389020610e3690610ad9565b61165082611fa6565b7f7e746c61000000000000000000000000000000000000000000000000000000005f9081526018839052600482905260389020610e3690610ad9565b5f805f600181819054906101000a90046effffffffffffffffffffffffffffff166116b690613ae1565b82546effffffffffffffffffffffffffffff8083166101009490940a848102910219909116179092555f818152600160205260409081902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000163317905551919250907f5cc365f89543268cb9f25c255f7f610e9147e733c589bc2732279575f125be149061174a9087908790613b0e565b60405180910390a260405133906effffffffffffffffffffffffffffff8316907f9b0894203394c3cbb23140db7a23b224d3e18e0366e9f65bd9c8402650e27367905f90a39392505050565b61179f82612d73565b5f546effffffffffffffffffffffffffffff610100909104811690821611156117f4576040517f3fbf501e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82165f8181526002602052604080822080547fffffffffffffffffffffffffffffffffff000000000000000000000000000000166effffffffffffffffffffffffffffff861690811790915590519092917fa66ff5557b7dc1562bb5e83306e15b513a25aa7537369bce38fc29c20847a79191a35050565b8161188b81611de1565b6040805160018082528183019092525f916020808301908036833701905050905082815f815181106118bf576118bf613a2c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091018201526effffffffffffffffffffffffffffff85165f908152600190915260409020610bbe9085908390600701600261202d565b610bbe84848484612dfa565b610e3682826129a0565b6effffffffffffffffffffffffffffff81165f908152600160208190526040909120606091610a8d910161211f565b5f805f600181819054906101000a90046effffffffffffffffffffffffffffff1661198390613ae1565b91906101000a8154816effffffffffffffffffffffffffffff02191690836effffffffffffffffffffffffffffff16021790559050600181036effffffffffffffffffffffffffffff16836effffffffffffffffffffffffffffff161115611a17576040517f3fbf501e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6effffffffffffffffffffffffffffff8084165f908152600160205260408082209284168083529181902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000163317815590519091907f5cc365f89543268cb9f25c255f7f610e9147e733c589bc2732279575f125be1490611a9e908a908a90613b0e565b60405180910390a260405133906effffffffffffffffffffffffffffff8516907f9b0894203394c3cbb23140db7a23b224d3e18e0366e9f65bd9c8402650e27367905f90a3611af55f848460010184600101613213565b611b086001848460040184600401613213565b611b1b6002848460070184600701613213565b509095945050505050565b82611b3081611de1565b815f819003611b6b576040517f693f369c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109c9858585808060200260200160405190810160405280939291908181526020018383602002808284375f9201829052506effffffffffffffffffffffffffffff8c1681526001602081905260408220019350915061202d9050565b73ffffffffffffffffffffffffffffffffffffffff81165f908152600260209081526040808320546effffffffffffffffffffffffffffff16835260019091529020606090610a8d9060040161211f565b81611c2381611de1565b6040805160018082528183019092525f916020808301908036833701905050905082815f81518110611c5757611c57613a2c565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050610bbe848260015f886effffffffffffffffffffffffffffff166effffffffffffffffffffffffffffff1681526020019081526020015f206004016001611e4f565b81611cdd81611de1565b6040805160018082528183019092525f916020808301908036833701905050905082815f81518110611d1157611d11613a2c565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050610bbe848260015f886effffffffffffffffffffffffffffff166effffffffffffffffffffffffffffff1681526020019081526020015f20600401600161202d565b80825d5050565b5c90565b5f815d50565b5f5460ff1615611daf5780825d5050565b9055565b5f805460ff1615611dc357505c90565b5080545b919050565b5f5460ff1615611ddc575f815d50565b5f9055565b6effffffffffffffffffffffffffffff81165f9081526001602052604090205473ffffffffffffffffffffffffffffffffffffffff163314610b02576040517fd5f2492900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f805b8451811015610cb657848181518110611e6d57611e6d613a2c565b602002602001015191505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611edc576040517f8f6e844e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611ee68483613310565b15611f9e578173ffffffffffffffffffffffffffffffffffffffff16866effffffffffffffffffffffffffffff16846002811115611f2657611f26613a99565b6040517fda8f3bd170446760f0f965a9b52bf271cb9679b5e0a70059eff2d49425229d17905f90a473ffffffffffffffffffffffffffffffffffffffff82165f908152600285016020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555b600101611e52565b73ffffffffffffffffffffffffffffffffffffffff81165f908152600260209081526040808320546effffffffffffffffffffffffffffff1683526001825280832033845260030190915290205460ff16610b02576040517feab2f2de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f805b8451811015610cb65784818151811061204b5761204b613a2c565b602090810291909101015191506120628483613331565b15612117578173ffffffffffffffffffffffffffffffffffffffff16866effffffffffffffffffffffffffffff168460028111156120a2576120a2613a99565b6040517f503012490a650739416858609e898957b874d17415a062945179c57357978840905f90a473ffffffffffffffffffffffffffffffffffffffff82165f908152600285016020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555b600101612030565b60605f61212b83613352565b9392505050565b335f90815260026020908152604091829020825160c08101845290546effffffffffffffffffffffffffffff8116825260ff6f01000000000000000000000000000000820481161580159484019490945270010000000000000000000000000000000082048116151594830194909452710100000000000000000000000000000000008104841615156060830152720100000000000000000000000000000000000081048416151560808301527301000000000000000000000000000000000000009004909216151560a083015261220a57506109c9565b8060800151156122635773ffffffffffffffffffffffffffffffffffffffff84163b15612263576040517f52245b9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060a0015115612351576040517f89a9c85500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301527f000000000000000000000000000000000000000000000000000000000000000016906389a9c85590602401602060405180830381865afa1580156122f7573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061231b9190613ac6565b612351576040517fa451bf2a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16036123c6578060600151156123c0576040517ff87c961400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506109c9565b7f71836d45000000000000000000000000000000000000000000000000000000005f90815233601852600484905260388120906124268263ffffffff7f000000000000000000000000000000000000000000000000000000000000000016565b90508381106124675761245f828583037f000000000000000000000000000000000000000000000000000000000000000063ffffffff16565b5050506109c9565b8260400151156124f55782516effffffffffffffffffffffffffffff165f90815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8c16845260090190915290205460ff16156124f0576040517f1de5204e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612573565b82516effffffffffffffffffffffffffffff165f90815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8c16845260060190915290205460ff16612573576040517f1de5204e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050565b335f90815260026020908152604091829020825160c08101845290546effffffffffffffffffffffffffffff8116825260ff6f01000000000000000000000000000000820481161580159484019490945270010000000000000000000000000000000082048116151594830194909452710100000000000000000000000000000000008104841615156060830152720100000000000000000000000000000000000081048416151560808301527301000000000000000000000000000000000000009004909216151560a08301526126555750505050565b8060800151156126ae5773ffffffffffffffffffffffffffffffffffffffff82163b156126ae576040517f52245b9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060a001511561279c576040517f89a9c85500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301527f000000000000000000000000000000000000000000000000000000000000000016906389a9c85590602401602060405180830381865afa158015612742573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127669190613ac6565b61279c576040517fa451bf2a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff160361280b57806060015115610bbe576040517ff87c961400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b337f596a397a000000000000000000000000000000000000000000000000000000001761285b8163ffffffff7f000000000000000000000000000000000000000000000000000000000000000016565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603612894575050505050565b8160400151156129225781516effffffffffffffffffffffffffffff165f90815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8916845260090190915290205460ff161561291d576040517f1de5204e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109c9565b81516effffffffffffffffffffffffffffff165f90815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8916845260060190915290205460ff166109c9576040517f1de5204e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6129a982612d73565b5f8160088111156129bc576129bc613a99565b036129c5575060035b73ffffffffffffffffffffffffffffffffffffffff82165f90815260026020526040902060018260088111156129fd576129fd613a99565b03612a3f5780547fffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffffff166f01000000000000000000000000000000178155612cca565b6002826008811115612a5357612a53613a99565b03612a965780547fffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffffff16700100000000000000000000000000000000178155612cca565b6003826008811115612aaa57612aaa613a99565b03612ada5780547fffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffffff168155612cca565b6004826008811115612aee57612aee613a99565b03612b325780547fffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffffff1671010000000000000000000000000000000000178155612cca565b6005826008811115612b4657612b46613a99565b03612b8b5780547fffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffffff167201000000000000000000000000000000000000178155612cca565b6006826008811115612b9f57612b9f613a99565b03612be55780547fffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffffff16730100000000000000000000000000000000000000178155612cca565b6007826008811115612bf957612bf9613a99565b03612c3e5780547fffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffffff167201010000000000000000000000000000000000178155612cca565b6008826008811115612c5257612c52613a99565b03612c985780547fffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffffff16730100010000000000000000000000000000000000178155612cca565b6040517f5ec600e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fb39d8f1e6f05413a407e46fc950eb92e9f5b3d65a47c3f0bdc7a2741a6ec0f7d8383604051612cfb929190613b5a565b60405180910390a1505050565b5f8173ffffffffffffffffffffffffffffffffffffffff16600a5a612d2d9190613bb9565b6040515f8181818686fa925050503d805f8114612d65576040519150601f19603f3d011682016040523d82523d5f602084013e612d6a565b606091505b50909392505050565b73ffffffffffffffffffffffffffffffffffffffff81163303612d935750565b612d9c816133ab565b73ffffffffffffffffffffffffffffffffffffffff163303612dbb5750565b612dc4816133d4565b610b02576040517f05b3336400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b335f90815260026020908152604091829020825160c08101845290546effffffffffffffffffffffffffffff8116825260ff6f01000000000000000000000000000000820481161580159484019490945270010000000000000000000000000000000082048116151594830194909452710100000000000000000000000000000000008104841615156060830152720100000000000000000000000000000000000081048416151560808301527301000000000000000000000000000000000000009004909216151560a0830152612ed25750610bbe565b806080015115612f2b5773ffffffffffffffffffffffffffffffffffffffff83163b15612f2b576040517f52245b9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060a0015115613019576040517f89a9c85500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301527f000000000000000000000000000000000000000000000000000000000000000016906389a9c85590602401602060405180830381865afa158015612fbf573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612fe39190613ac6565b613019576040517fa451bf2a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff160361308e57806060015115613088576040517ff87c961400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610bbe565b7f7e746c61000000000000000000000000000000000000000000000000000000005f90815233601852600483905260388120906130ee8263ffffffff7f000000000000000000000000000000000000000000000000000000000000000016565b905080156130fe57505050610bbe565b82604001511561318c5782516effffffffffffffffffffffffffffff165f90815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8b16845260090190915290205460ff1615613187576040517f1de5204e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61320a565b82516effffffffffffffffffffffffffffff165f90815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8b16845260060190915290205460ff1661320a576040517f1de5204e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050505050565b8181600281015f61322384613415565b90505f805b828110156133045761323a868261341e565b91506132468583613310565b156132fc578173ffffffffffffffffffffffffffffffffffffffff16896effffffffffffffffffffffffffffff168b600281111561328657613286613a99565b6040517fda8f3bd170446760f0f965a9b52bf271cb9679b5e0a70059eff2d49425229d17905f90a473ffffffffffffffffffffffffffffffffffffffff82165f90815260208590526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555b600101613228565b50505050505050505050565b5f61212b8373ffffffffffffffffffffffffffffffffffffffff8416613429565b5f61212b8373ffffffffffffffffffffffffffffffffffffffff8416613475565b6060815f0180548060200260200160405190810160405280929190818152602001828054801561339f57602002820191905f5260205f20905b81548152602001906001019080831161338b575b50505050509050919050565b5f638da5cb5b5f5260205f6004601c855afa8060203d101516156133ce575f5191505b50919050565b5f604051606081016040526391d1485481525f816020015233816040015260205f6044601c8401865afa90508060203d101516156133ce5750505f51919050565b5f610a8d825490565b5f61212b8383613558565b5f81815260018301602052604081205461346e57508154600181810184555f848152602080822090930184905584548482528286019093526040902091909155610a8d565b505f610a8d565b5f818152600183016020526040812054801561354f575f613497600183613bf1565b85549091505f906134aa90600190613bf1565b9050818114613509575f865f0182815481106134c8576134c8613a2c565b905f5260205f200154905080875f0184815481106134e8576134e8613a2c565b5f918252602080832090910192909255918252600188019052604090208390555b855486908061351a5761351a613c04565b600190038181905f5260205f20015f90559055856001015f8681526020019081526020015f205f905560019350505050610a8d565b5f915050610a8d565b5f825f01828154811061356d5761356d613a2c565b905f5260205f200154905092915050565b80356effffffffffffffffffffffffffffff81168114611dc7575f80fd5b5f805f604084860312156135ae575f80fd5b6135b78461357e565b9250602084013567ffffffffffffffff808211156135d3575f80fd5b818601915086601f8301126135e6575f80fd5b8135818111156135f4575f80fd5b8760208260051b8501011115613608575f80fd5b6020830194508093505050509250925092565b5f6020828403121561362b575f80fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461212b575f80fd5b803573ffffffffffffffffffffffffffffffffffffffff81168114611dc7575f80fd5b5f806040838503121561368e575f80fd5b6136978361357e565b91506136a56020840161365a565b90509250929050565b5f602082840312156136be575f80fd5b61212b8261365a565b5f602082840312156136d7575f80fd5b61212b8261357e565b602080825282518282018190525f9190848201906040850190845b8181101561372d57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016136fb565b50909695505050505050565b5f805f805f60a0868803121561374d575f80fd5b6137568661365a565b94506137646020870161365a565b93506137726040870161365a565b94979396509394606081013594506080013592915050565b5f805f6060848603121561379c575f80fd5b6137a58461365a565b92506137b36020850161365a565b91506137c16040850161365a565b90509250925092565b5f805f606084860312156137dc575f80fd5b6137e58461365a565b95602085013595506040909401359392505050565b8015158114610b02575f80fd5b5f805f805f60a0868803121561381b575f80fd5b6138248661365a565b9450602086013560ff81168114613839575f80fd5b93506040860135613849816137fa565b92506060860135613859816137fa565b91506080860135613869816137fa565b809150509295509295909350565b5f8060408385031215613888575f80fd5b6138918361365a565b946020939093013593505050565b5f80604083850312156138b0575f80fd5b6136978361365a565b5f8083601f8401126138c9575f80fd5b50813567ffffffffffffffff8111156138e0575f80fd5b6020830191508360208285010111156138f7575f80fd5b9250929050565b5f806020838503121561390f575f80fd5b823567ffffffffffffffff811115613925575f80fd5b613931858286016138b9565b90969095509350505050565b5f806040838503121561394e575f80fd5b6139578361365a565b91506136a56020840161357e565b5f805f8060808587031215613978575f80fd5b6139818561365a565b935061398f6020860161365a565b925061399d6040860161365a565b9396929550929360600135925050565b5f80604083850312156139be575f80fd5b6139c78361365a565b91506020830135600981106139da575f80fd5b809150509250929050565b5f805f604084860312156139f7575f80fd5b833567ffffffffffffffff811115613a0d575f80fd5b613a19868287016138b9565b90945092506137c190506020850161357e565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b80820180821115610a8d57610a8d613a59565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b5f60208284031215613ad6575f80fd5b815161212b816137fa565b5f6effffffffffffffffffffffffffffff808316818103613b0457613b04613a59565b6001019392505050565b60208152816020820152818360408301375f818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b73ffffffffffffffffffffffffffffffffffffffff831681526040810160098310613bac577f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b8260208301529392505050565b5f82613bec577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b500490565b81810381811115610a8d57610a8d613a59565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603160045260245ffdfea2646970667358221220160996c94b1d698a40469e3f97911dd81a027efec7d78941305ede91222dd7d864736f6c6343000818003361012060405234801562000011575f80fd5b505f6200001d620000f4565b90506001600160a01b0381166200004757604051632aea588760e01b815260040160405180910390fd5b5f62000053826200010d565b905080156200009f576200016f602090811b62000678176001600160401b0390811660c05262000176821b6200067f17811660e0526200017a90911b62000683171661010052620000dd565b62000180602090811b62000689176001600160401b0390811660c05262000196821b6200069e17811660e052620001ac90911b620006b71716610100525b151560a0526001600160a01b0316608052620001e2565b5f696002601e613d5c3d52f35f52600a60165ff0905090565b5f816001600160a01b0316600a5a620001279190620001c2565b6040515f8181818686fa925050503d805f811462000161576040519150601f19603f3d011682016040523d82523d5f602084013e62000166565b606091505b50909392505050565b80825d5050565b5c90565b5f815d50565b5f5460ff1615620001925780825d5050565b9055565b5f805460ff1615620001a757505c90565b505490565b5f5460ff1615620001bd575f815d50565b5f9055565b5f82620001dd57634e487b7160e01b5f52601260045260245ffd5b500490565b60805160a05160c05160e05161010051610af0620002175f395f50505f50505f50505f6103f501525f61045c0152610af05ff3fe608060405234801561000f575f80fd5b5060043610610180575f3560e01c80637bac97de116100d6578063982d03c01161008a578063d415f62f11610064578063d415f62f146102a2578063d72dde5e146101b2578063e991dc301461037357610180565b8063982d03c014610345578063b67d8f9914610273578063b95545521461035357610180565b80638e28800f116100bb5780638e28800f146102c85780639340a7cc146102585780639445f5301461032f57610180565b80637bac97de146102ba578063896316261461028157610180565b80632c7fe70a116101385780635e17263d116101125780635e17263d146102a25780637161ac8d146102945780637423eb3c146102b057610180565b80632c7fe70a146102735780633fe5df99146102815780634c9d0b451461029457610180565b806316a17ce01161016957806316a17ce01461024357806316f18d741461025857806317e94a6c1461022257610180565b8063057497cb146101b257806310b5c6a014610222575b6040517f89452af100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61020d6101c0366004610895565b6effffffffffffffffffffffffffffff82165f90815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845260060190915290205460ff1692915050565b60405190151581526020015b60405180910390f35b6102366102303660046108c6565b50606090565b60405161021991906108df565b61020d610251366004610895565b5f92915050565b610266610230366004610938565b6040516102199190610951565b61020d610251366004610988565b61023661028f3660046108c6565b610386565b6102666102303660046108c6565b61020d6102513660046109b0565b6102b86103ba565b005b61020d6102513660046109ca565b61020d6102d63660046109ca565b73ffffffffffffffffffffffffffffffffffffffff9182165f908152600260209081526040808320546effffffffffffffffffffffffffffff168352600182528083209390941682526006909201909152205460ff1690565b61020d61033d366004610895565b600192915050565b610236610230366004610938565b610366610361366004610938565b6104e2565b6040516102199190610a11565b610236610381366004610938565b610627565b6effffffffffffffffffffffffffffff81165f9081526001602052604090206060906103b4906004016106cc565b92915050565b3332146103f3576040517f2599431400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000008061042057505f5460ff165b15610457576040517ff45b98b000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104807f00000000000000000000000000000000000000000000000000000000000000006106df565b6104b6576040517f70a4078f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b60408051606080820183525f808352602080840182905283850182905273ffffffffffffffffffffffffffffffffffffffff861682526002815290849020845160c08101865290546effffffffffffffffffffffffffffff8116825260ff6f0100000000000000000000000000000082048116151593830193909352700100000000000000000000000000000000810483161515828701527101000000000000000000000000000000000081048316151582850152720100000000000000000000000000000000000081048316151560808301527301000000000000000000000000000000000000009004909116151560a08201528351918201909352909190806105ec8361074a565b60088111156105fd576105fd6109e4565b815291516effffffffffffffffffffffffffffff1660208301525f60409092019190915292915050565b73ffffffffffffffffffffffffffffffffffffffff81165f908152600260209081526040808320546effffffffffffffffffffffffffffff168352600190915290206060906103b4906004016106cc565b80825d5050565b5c90565b5f815d50565b5f5460ff161561069a5780825d5050565b9055565b5f805460ff16156106ae57505c90565b5080545b919050565b5f5460ff16156106c7575f815d50565b5f9055565b60605f6106d8836107fb565b9392505050565b5f8173ffffffffffffffffffffffffffffffffffffffff16600a5a6107049190610a82565b6040515f8181818686fa925050503d805f811461073c576040519150601f19603f3d011682016040523d82523d5f602084013e610741565b606091505b50909392505050565b602081015160408201516060830151608084015160a08501515f9493929190841561077c575060019695505050505050565b831561078f575060029695505050505050565b82156107c85780156107a8575060089695505050505050565b81156107bb575060079695505050505050565b5060049695505050505050565b80156107db575060069695505050505050565b81156107ee575060059695505050505050565b5060039695505050505050565b6060815f0180548060200260200160405190810160405280929190818152602001828054801561084857602002820191905f5260205f20905b815481526020019060010190808311610834575b50505050509050919050565b80356effffffffffffffffffffffffffffff811681146106b2575f80fd5b803573ffffffffffffffffffffffffffffffffffffffff811681146106b2575f80fd5b5f80604083850312156108a6575f80fd5b6108af83610854565b91506108bd60208401610872565b90509250929050565b5f602082840312156108d6575f80fd5b6106d882610854565b602080825282518282018190525f9190848201906040850190845b8181101561092c57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016108fa565b50909695505050505050565b5f60208284031215610948575f80fd5b6106d882610872565b602080825282518282018190525f9190848201906040850190845b8181101561092c5783518352928401929184019160010161096c565b5f8060408385031215610999575f80fd5b6109a283610872565b946020939093013593505050565b5f80604083850312156109c1575f80fd5b6109a283610854565b5f80604083850312156109db575f80fd5b6108af83610872565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b8151606082019060098110610a4d577f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b8083525060208301516effffffffffffffffffffffffffffff8082166020850152806040860151166040850152505092915050565b5f82610ab5577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b50049056fea2646970667358221220c104b63905a188c6b1e795f6018b36d9c876d6bd4f6ea96593fb37a009e87c1c64736f6c634300081800330000000000000000000000000000000000a1793068b5b7e278de7c641e9e75c8000000000000000000000000721c00182a990771244d7a71b9fa2ea789a3b433
Deployed Bytecode
0x608060405234801561000f575f80fd5b506004361061031e575f3560e01c806388c1d66d116101a5578063b8dcc68f116100ec578063ddae38f211610095578063e991dc301161006f578063e991dc30146108ec578063ede0fe31146108ff578063fd51f20f146109125761031e565b8063ddae38f214610615578063de02cbb1146108c6578063df5fd29a146108d95761031e565b8063caee23ea116100c6578063caee23ea1461088d578063da0194c0146108a0578063dda964e3146108b35761031e565b8063b8dcc68f14610854578063bf7bfd7e14610867578063c3d58f4d1461087a5761031e565b8063a1cc5cc11161014e578063b6e39ba111610128578063b6e39ba1146107d3578063b70510f5146107e6578063b89c4b0d146108415761031e565b8063a1cc5cc114610755578063a5ce71f514610755578063ae602f44146107685761031e565b80638b6ee8651161017f5780638b6ee865146106c85780638e28800f146106db578063982d03c0146107425761031e565b806388c1d66d1461068f57806389631626146106a257806389a9c855146106b55761031e565b8063317e3e8d116102695780636971082811610212578063755b6fd7116101ec578063755b6fd7146106155780637bac97de146106285780637c1e14b4146104e85761031e565b806369710828146105e75780636bfab91d146105fa5780637423eb3c1461060d5761031e565b80633e5c139d116102435780633e5c139d146105ae57806343999db8146105c157806350793315146105d45761031e565b8063317e3e8d146105215780633a0e3160146105345780633cda743a146105475761031e565b806316a17ce0116102cb578063285fb8c8116102a5578063285fb8c8146104e857806328cc1131146104fb5780632eb0b98a1461050e5761031e565b806316a17ce01461043b5780631854b2411461049657806323c99262146104a95761031e565b80630ad38899116102fc5780630ad38899146103f55780630b6153091461040857806310b5c6a01461041b5761031e565b8063015499301461035f57806301ffc9a714610372578063057497cb1461039a575b7f0000000000000000000000001fca38fd099c7701b4f28fbc3f0ba57ed4067137365f80375f80365f845af43d5f803e808015610359573d5ff35b3d5ffd5b005b61035d61036d36600461359c565b610925565b61038561038036600461361b565b6109d0565b60405190151581526020015b60405180910390f35b6103856103a836600461367d565b6effffffffffffffffffffffffffffff82165f90815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845260060190915290205460ff1692915050565b61035d6104033660046136ae565b610a93565b61035d61041636600461367d565b610b05565b61042e6104293660046136c7565b610bc4565b60405161039191906136e0565b61038561044936600461367d565b6effffffffffffffffffffffffffffff82165f90815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845260090190915290205460ff1692915050565b61035d6104a4366004613739565b610bf2565b5f546104c89061010090046effffffffffffffffffffffffffffff1681565b6040516effffffffffffffffffffffffffffff9091168152602001610391565b61035d6104f636600461378a565b610bff565b61035d6105093660046137ca565b610c0f565b61035d61051c36600461359c565b610cbe565b61035d61052f366004613807565b610d63565b61035d610542366004613877565b610dcb565b61038561055536600461389f565b73ffffffffffffffffffffffffffffffffffffffff9182165f908152600260209081526040808320546effffffffffffffffffffffffffffff168352600182528083209390941682526003909201909152205460ff1690565b61042e6105bc3660046136ae565b610e3a565b61035d6105cf36600461367d565b610e8b565b61035d6105e236600461389f565b610f1e565b61035d6105f536600461359c565b610fa3565b61035d61060836600461367d565b611047565b61035d61112c565b61035d61062336600461359c565b611254565b61038561063636600461389f565b73ffffffffffffffffffffffffffffffffffffffff9182165f908152600260209081526040808320546effffffffffffffffffffffffffffff168352600182528083209390941682526009909201909152205460ff1690565b61035d61069d36600461367d565b6112f6565b61042e6106b03660046136c7565b6113af565b6103856106c33660046136ae565b6113dd565b61035d6106d63660046136c7565b61148f565b6103856106e936600461389f565b73ffffffffffffffffffffffffffffffffffffffff9182165f908152600260209081526040808320546effffffffffffffffffffffffffffff168352600182528083209390941682526006909201909152205460ff1690565b61042e6107503660046136ae565b61150c565b61035d61076336600461359c565b61155d565b6107ae6107763660046136c7565b6effffffffffffffffffffffffffffff165f9081526001602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610391565b61035d6107e1366004613877565b611602565b6103856107f436600461367d565b6effffffffffffffffffffffffffffff82165f90815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845260030190915290205460ff1692915050565b61035d61084f366004613877565b611647565b6104c86108623660046138fe565b61168c565b61035d61087536600461393d565b611796565b61035d61088836600461367d565b611881565b61035d61089b366004613965565b611914565b61035d6108ae3660046139ad565b611920565b61042e6108c13660046136c7565b61192a565b6104c86108d43660046139e5565b611959565b61035d6108e736600461359c565b611b26565b61042e6108fa3660046136ae565b611bc8565b61035d61090d36600461367d565b611c19565b61035d61092036600461367d565b611cd3565b8261092f81611de1565b815f81900361096a576040517f693f369c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109c9858585808060200260200160405190810160405280939291908181526020018383602002808284375f9201829052506effffffffffffffffffffffffffffff8c168152600160205260409020600701925060029150611e4f9050565b5050505050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082161580610a4157507fffffffff0000000000000000000000000000000000000000000000000000000082167f751a614900000000000000000000000000000000000000000000000000000000145b80610a8d57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b610a9c81611fa6565b610b027f596a397a0000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff8316175b7f000000000000000000000000000000000000000000000000000002bb00001d9863ffffffff16565b50565b81610b0f81611de1565b6040805160018082528183019092525f916020808301908036833701905050905082815f81518110610b4357610b43613a2c565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050610bbe848260015f886effffffffffffffffffffffffffffff166effffffffffffffffffffffffffffff1681526020019081526020015f206001015f61202d565b50505050565b6effffffffffffffffffffffffffffff81165f908152600160205260409020606090610a8d9060070161211f565b6109c98585858585612132565b610c0a83838361257d565b505050565b610c1883611fa6565b7f71836d45000000000000000000000000000000000000000000000000000000005f908152601884905260048390526038812090610c798263ffffffff7f000000000000000000000000000000000000000000000000000002b700001d9416565b90505f610c868483613a86565b9050610cb683827f000000000000000000000000000000000000000000000000000002b000001d8d63ffffffff16565b505050505050565b82610cc881611de1565b815f819003610d03576040517f693f369c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109c9858585808060200260200160405190810160405280939291908181526020018383602002808284375f9201829052506effffffffffffffffffffffffffffff8c1681526001602081905260409091206004019350915061202d9050565b821580610d6e575081155b80610d765750805b15610dad576040517f7ced84b900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109c9858560ff166008811115610dc657610dc6613a99565b6129a0565b610dd482611fa6565b7f7e746c61000000000000000000000000000000000000000000000000000000005f9081526018839052600482905260389020610e369060017f000000000000000000000000000000000000000000000000000002b000001d8d63ffffffff16565b5050565b73ffffffffffffffffffffffffffffffffffffffff81165f908152600260209081526040808320546effffffffffffffffffffffffffffff168352600191829052909120606091610a8d910161211f565b81610e9581611de1565b6040805160018082528183019092525f916020808301908036833701905050905082815f81518110610ec957610ec9613a2c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091018201526effffffffffffffffffffffffffffff85165f908152600190915260409020610bbe90859083906007016002611e4f565b610f2781611fa6565b610e367f596a397a0000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff8316178373ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000002b000001d8d63ffffffff16565b82610fad81611de1565b815f819003610fe8576040517f693f369c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109c9858585808060200260200160405190810160405280939291908181526020018383602002808284375f9201829052506effffffffffffffffffffffffffffff8c16815260016020526040902060070192506002915061202d9050565b8161105181611de1565b73ffffffffffffffffffffffffffffffffffffffff821661109e576040517f2ba5f16500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6effffffffffffffffffffffffffffff83165f8181526001602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff871690811790915590519092917f9b0894203394c3cbb23140db7a23b224d3e18e0366e9f65bd9c8402650e2736791a3505050565b333214611165576040517f2599431400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000018061119257505f5460ff165b156111c9576040517ff45b98b000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6111f27f000000000000000000000000bb0bffd7f8ef12ecaa0435aef8a7bd522798251c612d08565b611228576040517f70a4078f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b8261125e81611de1565b815f819003611299576040517f693f369c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109c9858585808060200260200160405190810160405280939291908181526020018383602002808284375f9201829052506effffffffffffffffffffffffffffff8c16815260016020819052604082200193509150611e4f9050565b8161130081611de1565b6040805160018082528183019092525f916020808301908036833701905050905082815f8151811061133457611334613a2c565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050610bbe848260015f886effffffffffffffffffffffffffffff166effffffffffffffffffffffffffffff1681526020019081526020015f206001015f611e4f565b6effffffffffffffffffffffffffffff81165f908152600160205260409020606090610a8d9060040161211f565b6040517f89a9c85500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82811660048301525f917f000000000000000000000000721c00182a990771244d7a71b9fa2ea789a3b433909116906389a9c85590602401602060405180830381865afa15801561146b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a8d9190613ac6565b8061149981611de1565b6effffffffffffffffffffffffffffff82165f8181526001602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055519091907f9b0894203394c3cbb23140db7a23b224d3e18e0366e9f65bd9c8402650e27367908390a35050565b73ffffffffffffffffffffffffffffffffffffffff81165f908152600260209081526040808320546effffffffffffffffffffffffffffff16835260019091529020606090610a8d9060070161211f565b8261156781611de1565b815f8190036115a2576040517f693f369c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109c9858585808060200260200160405190810160405280939291908181526020018383602002808284375f9201829052506effffffffffffffffffffffffffffff8c16815260016020819052604090912060040193509150611e4f9050565b61160b82611fa6565b7f71836d45000000000000000000000000000000000000000000000000000000005f9081526018839052600482905260389020610e3690610ad9565b61165082611fa6565b7f7e746c61000000000000000000000000000000000000000000000000000000005f9081526018839052600482905260389020610e3690610ad9565b5f805f600181819054906101000a90046effffffffffffffffffffffffffffff166116b690613ae1565b82546effffffffffffffffffffffffffffff8083166101009490940a848102910219909116179092555f818152600160205260409081902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000163317905551919250907f5cc365f89543268cb9f25c255f7f610e9147e733c589bc2732279575f125be149061174a9087908790613b0e565b60405180910390a260405133906effffffffffffffffffffffffffffff8316907f9b0894203394c3cbb23140db7a23b224d3e18e0366e9f65bd9c8402650e27367905f90a39392505050565b61179f82612d73565b5f546effffffffffffffffffffffffffffff610100909104811690821611156117f4576040517f3fbf501e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82165f8181526002602052604080822080547fffffffffffffffffffffffffffffffffff000000000000000000000000000000166effffffffffffffffffffffffffffff861690811790915590519092917fa66ff5557b7dc1562bb5e83306e15b513a25aa7537369bce38fc29c20847a79191a35050565b8161188b81611de1565b6040805160018082528183019092525f916020808301908036833701905050905082815f815181106118bf576118bf613a2c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091018201526effffffffffffffffffffffffffffff85165f908152600190915260409020610bbe9085908390600701600261202d565b610bbe84848484612dfa565b610e3682826129a0565b6effffffffffffffffffffffffffffff81165f908152600160208190526040909120606091610a8d910161211f565b5f805f600181819054906101000a90046effffffffffffffffffffffffffffff1661198390613ae1565b91906101000a8154816effffffffffffffffffffffffffffff02191690836effffffffffffffffffffffffffffff16021790559050600181036effffffffffffffffffffffffffffff16836effffffffffffffffffffffffffffff161115611a17576040517f3fbf501e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6effffffffffffffffffffffffffffff8084165f908152600160205260408082209284168083529181902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000163317815590519091907f5cc365f89543268cb9f25c255f7f610e9147e733c589bc2732279575f125be1490611a9e908a908a90613b0e565b60405180910390a260405133906effffffffffffffffffffffffffffff8516907f9b0894203394c3cbb23140db7a23b224d3e18e0366e9f65bd9c8402650e27367905f90a3611af55f848460010184600101613213565b611b086001848460040184600401613213565b611b1b6002848460070184600701613213565b509095945050505050565b82611b3081611de1565b815f819003611b6b576040517f693f369c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109c9858585808060200260200160405190810160405280939291908181526020018383602002808284375f9201829052506effffffffffffffffffffffffffffff8c1681526001602081905260408220019350915061202d9050565b73ffffffffffffffffffffffffffffffffffffffff81165f908152600260209081526040808320546effffffffffffffffffffffffffffff16835260019091529020606090610a8d9060040161211f565b81611c2381611de1565b6040805160018082528183019092525f916020808301908036833701905050905082815f81518110611c5757611c57613a2c565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050610bbe848260015f886effffffffffffffffffffffffffffff166effffffffffffffffffffffffffffff1681526020019081526020015f206004016001611e4f565b81611cdd81611de1565b6040805160018082528183019092525f916020808301908036833701905050905082815f81518110611d1157611d11613a2c565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050610bbe848260015f886effffffffffffffffffffffffffffff166effffffffffffffffffffffffffffff1681526020019081526020015f20600401600161202d565b80825d5050565b5c90565b5f815d50565b5f5460ff1615611daf5780825d5050565b9055565b5f805460ff1615611dc357505c90565b5080545b919050565b5f5460ff1615611ddc575f815d50565b5f9055565b6effffffffffffffffffffffffffffff81165f9081526001602052604090205473ffffffffffffffffffffffffffffffffffffffff163314610b02576040517fd5f2492900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f805b8451811015610cb657848181518110611e6d57611e6d613a2c565b602002602001015191505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611edc576040517f8f6e844e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611ee68483613310565b15611f9e578173ffffffffffffffffffffffffffffffffffffffff16866effffffffffffffffffffffffffffff16846002811115611f2657611f26613a99565b6040517fda8f3bd170446760f0f965a9b52bf271cb9679b5e0a70059eff2d49425229d17905f90a473ffffffffffffffffffffffffffffffffffffffff82165f908152600285016020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555b600101611e52565b73ffffffffffffffffffffffffffffffffffffffff81165f908152600260209081526040808320546effffffffffffffffffffffffffffff1683526001825280832033845260030190915290205460ff16610b02576040517feab2f2de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f805b8451811015610cb65784818151811061204b5761204b613a2c565b602090810291909101015191506120628483613331565b15612117578173ffffffffffffffffffffffffffffffffffffffff16866effffffffffffffffffffffffffffff168460028111156120a2576120a2613a99565b6040517f503012490a650739416858609e898957b874d17415a062945179c57357978840905f90a473ffffffffffffffffffffffffffffffffffffffff82165f908152600285016020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555b600101612030565b60605f61212b83613352565b9392505050565b335f90815260026020908152604091829020825160c08101845290546effffffffffffffffffffffffffffff8116825260ff6f01000000000000000000000000000000820481161580159484019490945270010000000000000000000000000000000082048116151594830194909452710100000000000000000000000000000000008104841615156060830152720100000000000000000000000000000000000081048416151560808301527301000000000000000000000000000000000000009004909216151560a083015261220a57506109c9565b8060800151156122635773ffffffffffffffffffffffffffffffffffffffff84163b15612263576040517f52245b9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060a0015115612351576040517f89a9c85500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301527f000000000000000000000000721c00182a990771244d7a71b9fa2ea789a3b43316906389a9c85590602401602060405180830381865afa1580156122f7573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061231b9190613ac6565b612351576040517fa451bf2a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16036123c6578060600151156123c0576040517ff87c961400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506109c9565b7f71836d45000000000000000000000000000000000000000000000000000000005f90815233601852600484905260388120906124268263ffffffff7f000000000000000000000000000000000000000000000000000002b700001d9416565b90508381106124675761245f828583037f000000000000000000000000000000000000000000000000000002b000001d8d63ffffffff16565b5050506109c9565b8260400151156124f55782516effffffffffffffffffffffffffffff165f90815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8c16845260090190915290205460ff16156124f0576040517f1de5204e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612573565b82516effffffffffffffffffffffffffffff165f90815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8c16845260060190915290205460ff16612573576040517f1de5204e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050565b335f90815260026020908152604091829020825160c08101845290546effffffffffffffffffffffffffffff8116825260ff6f01000000000000000000000000000000820481161580159484019490945270010000000000000000000000000000000082048116151594830194909452710100000000000000000000000000000000008104841615156060830152720100000000000000000000000000000000000081048416151560808301527301000000000000000000000000000000000000009004909216151560a08301526126555750505050565b8060800151156126ae5773ffffffffffffffffffffffffffffffffffffffff82163b156126ae576040517f52245b9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060a001511561279c576040517f89a9c85500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301527f000000000000000000000000721c00182a990771244d7a71b9fa2ea789a3b43316906389a9c85590602401602060405180830381865afa158015612742573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127669190613ac6565b61279c576040517fa451bf2a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff160361280b57806060015115610bbe576040517ff87c961400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b337f596a397a000000000000000000000000000000000000000000000000000000001761285b8163ffffffff7f000000000000000000000000000000000000000000000000000002b700001d9416565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603612894575050505050565b8160400151156129225781516effffffffffffffffffffffffffffff165f90815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8916845260090190915290205460ff161561291d576040517f1de5204e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109c9565b81516effffffffffffffffffffffffffffff165f90815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8916845260060190915290205460ff166109c9576040517f1de5204e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6129a982612d73565b5f8160088111156129bc576129bc613a99565b036129c5575060035b73ffffffffffffffffffffffffffffffffffffffff82165f90815260026020526040902060018260088111156129fd576129fd613a99565b03612a3f5780547fffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffffff166f01000000000000000000000000000000178155612cca565b6002826008811115612a5357612a53613a99565b03612a965780547fffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffffff16700100000000000000000000000000000000178155612cca565b6003826008811115612aaa57612aaa613a99565b03612ada5780547fffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffffff168155612cca565b6004826008811115612aee57612aee613a99565b03612b325780547fffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffffff1671010000000000000000000000000000000000178155612cca565b6005826008811115612b4657612b46613a99565b03612b8b5780547fffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffffff167201000000000000000000000000000000000000178155612cca565b6006826008811115612b9f57612b9f613a99565b03612be55780547fffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffffff16730100000000000000000000000000000000000000178155612cca565b6007826008811115612bf957612bf9613a99565b03612c3e5780547fffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffffff167201010000000000000000000000000000000000178155612cca565b6008826008811115612c5257612c52613a99565b03612c985780547fffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffffff16730100010000000000000000000000000000000000178155612cca565b6040517f5ec600e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fb39d8f1e6f05413a407e46fc950eb92e9f5b3d65a47c3f0bdc7a2741a6ec0f7d8383604051612cfb929190613b5a565b60405180910390a1505050565b5f8173ffffffffffffffffffffffffffffffffffffffff16600a5a612d2d9190613bb9565b6040515f8181818686fa925050503d805f8114612d65576040519150601f19603f3d011682016040523d82523d5f602084013e612d6a565b606091505b50909392505050565b73ffffffffffffffffffffffffffffffffffffffff81163303612d935750565b612d9c816133ab565b73ffffffffffffffffffffffffffffffffffffffff163303612dbb5750565b612dc4816133d4565b610b02576040517f05b3336400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b335f90815260026020908152604091829020825160c08101845290546effffffffffffffffffffffffffffff8116825260ff6f01000000000000000000000000000000820481161580159484019490945270010000000000000000000000000000000082048116151594830194909452710100000000000000000000000000000000008104841615156060830152720100000000000000000000000000000000000081048416151560808301527301000000000000000000000000000000000000009004909216151560a0830152612ed25750610bbe565b806080015115612f2b5773ffffffffffffffffffffffffffffffffffffffff83163b15612f2b576040517f52245b9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060a0015115613019576040517f89a9c85500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301527f000000000000000000000000721c00182a990771244d7a71b9fa2ea789a3b43316906389a9c85590602401602060405180830381865afa158015612fbf573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612fe39190613ac6565b613019576040517fa451bf2a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff160361308e57806060015115613088576040517ff87c961400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610bbe565b7f7e746c61000000000000000000000000000000000000000000000000000000005f90815233601852600483905260388120906130ee8263ffffffff7f000000000000000000000000000000000000000000000000000002b700001d9416565b905080156130fe57505050610bbe565b82604001511561318c5782516effffffffffffffffffffffffffffff165f90815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8b16845260090190915290205460ff1615613187576040517f1de5204e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61320a565b82516effffffffffffffffffffffffffffff165f90815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8b16845260060190915290205460ff1661320a576040517f1de5204e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050505050565b8181600281015f61322384613415565b90505f805b828110156133045761323a868261341e565b91506132468583613310565b156132fc578173ffffffffffffffffffffffffffffffffffffffff16896effffffffffffffffffffffffffffff168b600281111561328657613286613a99565b6040517fda8f3bd170446760f0f965a9b52bf271cb9679b5e0a70059eff2d49425229d17905f90a473ffffffffffffffffffffffffffffffffffffffff82165f90815260208590526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555b600101613228565b50505050505050505050565b5f61212b8373ffffffffffffffffffffffffffffffffffffffff8416613429565b5f61212b8373ffffffffffffffffffffffffffffffffffffffff8416613475565b6060815f0180548060200260200160405190810160405280929190818152602001828054801561339f57602002820191905f5260205f20905b81548152602001906001019080831161338b575b50505050509050919050565b5f638da5cb5b5f5260205f6004601c855afa8060203d101516156133ce575f5191505b50919050565b5f604051606081016040526391d1485481525f816020015233816040015260205f6044601c8401865afa90508060203d101516156133ce5750505f51919050565b5f610a8d825490565b5f61212b8383613558565b5f81815260018301602052604081205461346e57508154600181810184555f848152602080822090930184905584548482528286019093526040902091909155610a8d565b505f610a8d565b5f818152600183016020526040812054801561354f575f613497600183613bf1565b85549091505f906134aa90600190613bf1565b9050818114613509575f865f0182815481106134c8576134c8613a2c565b905f5260205f200154905080875f0184815481106134e8576134e8613a2c565b5f918252602080832090910192909255918252600188019052604090208390555b855486908061351a5761351a613c04565b600190038181905f5260205f20015f90559055856001015f8681526020019081526020015f205f905560019350505050610a8d565b5f915050610a8d565b5f825f01828154811061356d5761356d613a2c565b905f5260205f200154905092915050565b80356effffffffffffffffffffffffffffff81168114611dc7575f80fd5b5f805f604084860312156135ae575f80fd5b6135b78461357e565b9250602084013567ffffffffffffffff808211156135d3575f80fd5b818601915086601f8301126135e6575f80fd5b8135818111156135f4575f80fd5b8760208260051b8501011115613608575f80fd5b6020830194508093505050509250925092565b5f6020828403121561362b575f80fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461212b575f80fd5b803573ffffffffffffffffffffffffffffffffffffffff81168114611dc7575f80fd5b5f806040838503121561368e575f80fd5b6136978361357e565b91506136a56020840161365a565b90509250929050565b5f602082840312156136be575f80fd5b61212b8261365a565b5f602082840312156136d7575f80fd5b61212b8261357e565b602080825282518282018190525f9190848201906040850190845b8181101561372d57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016136fb565b50909695505050505050565b5f805f805f60a0868803121561374d575f80fd5b6137568661365a565b94506137646020870161365a565b93506137726040870161365a565b94979396509394606081013594506080013592915050565b5f805f6060848603121561379c575f80fd5b6137a58461365a565b92506137b36020850161365a565b91506137c16040850161365a565b90509250925092565b5f805f606084860312156137dc575f80fd5b6137e58461365a565b95602085013595506040909401359392505050565b8015158114610b02575f80fd5b5f805f805f60a0868803121561381b575f80fd5b6138248661365a565b9450602086013560ff81168114613839575f80fd5b93506040860135613849816137fa565b92506060860135613859816137fa565b91506080860135613869816137fa565b809150509295509295909350565b5f8060408385031215613888575f80fd5b6138918361365a565b946020939093013593505050565b5f80604083850312156138b0575f80fd5b6136978361365a565b5f8083601f8401126138c9575f80fd5b50813567ffffffffffffffff8111156138e0575f80fd5b6020830191508360208285010111156138f7575f80fd5b9250929050565b5f806020838503121561390f575f80fd5b823567ffffffffffffffff811115613925575f80fd5b613931858286016138b9565b90969095509350505050565b5f806040838503121561394e575f80fd5b6139578361365a565b91506136a56020840161357e565b5f805f8060808587031215613978575f80fd5b6139818561365a565b935061398f6020860161365a565b925061399d6040860161365a565b9396929550929360600135925050565b5f80604083850312156139be575f80fd5b6139c78361365a565b91506020830135600981106139da575f80fd5b809150509250929050565b5f805f604084860312156139f7575f80fd5b833567ffffffffffffffff811115613a0d575f80fd5b613a19868287016138b9565b90945092506137c190506020850161357e565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b80820180821115610a8d57610a8d613a59565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b5f60208284031215613ad6575f80fd5b815161212b816137fa565b5f6effffffffffffffffffffffffffffff808316818103613b0457613b04613a59565b6001019392505050565b60208152816020820152818360408301375f818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b73ffffffffffffffffffffffffffffffffffffffff831681526040810160098310613bac577f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b8260208301529392505050565b5f82613bec577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b500490565b81810381811115610a8d57610a8d613a59565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603160045260245ffdfea2646970667358221220160996c94b1d698a40469e3f97911dd81a027efec7d78941305ede91222dd7d864736f6c63430008180033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000000000000a1793068B5b7e278dE7c641E9E75C8000000000000000000000000721C00182a990771244d7A71B9FA2ea789A3b433
-----Decoded View---------------
Arg [0] : defaultOwner (address): 0x0000000000a1793068B5b7e278dE7c641E9E75C8
Arg [1] : eoaRegistry (address): 0x721C00182a990771244d7A71B9FA2ea789A3b433
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000a1793068B5b7e278dE7c641E9E75C8
Arg [1] : 000000000000000000000000721C00182a990771244d7A71B9FA2ea789A3b433
Deployed Bytecode Sourcemap
1360:31853:5:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4475:21;4548:14;4458;;4529:34;4640:1;4637;4621:14;4618:1;4610:6;4603:5;4590:52;4676:16;4673:1;4670;4655:38;4713:6;4732:66;;;;4847:16;4844:1;4837:27;4732:66;4767:16;4764:1;4757:27;4706:172;;11897:235;;;;;;:::i;:::-;;:::i;17445:340::-;;;;;;:::i;:::-;;:::i;:::-;;;1401:14:14;;1394:22;1376:41;;1364:2;1349:18;17445:340:5;;;;;;;;10943:162;;;;;;:::i;:::-;11048:9;;;11025:4;11048:9;;;:5;:9;;;;;;;;:50;;;;;:41;;:50;;;;;;;;10943:162;;;;;14931:176;;;;;;:::i;:::-;;:::i;7928:274::-;;;;;;:::i;:::-;;:::i;12684:156::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;12846:162::-;;;;;;:::i;:::-;12951:9;;;12928:4;12951:9;;;:5;:9;;;;;;;;:50;;;;;:41;;:50;;;;;;;;12846:162;;;;;14082:187;;;;;;:::i;:::-;;:::i;2508:25::-;;;;;;;;;;;;;;;3615:32:14;3603:45;;;3585:64;;3573:2;3558:18;2508:25:5;3439:216:14;14360:147:5;;;;;;:::i;:::-;;:::i;15833:372::-;;;;;;:::i;:::-;;:::i;10550:221::-;;;;;;:::i;:::-;;:::i;16508:548::-;;;;;;:::i;:::-;;:::i;15200:240::-;;;;;;:::i;:::-;;:::i;9000:223::-;;;;;;:::i;:::-;9130:35;;;;9101:4;9130:35;;;:23;:35;;;;;;;;:42;;;9124:49;;:5;:49;;;;;:92;;;;;;:83;;;;:92;;;;;;;;9000:223;8777:217;;;;;;:::i;:::-;;:::i;11609:282::-;;;;;;:::i;:::-;;:::i;14591:255::-;;;;;;:::i;:::-;;:::i;12434:243::-;;;;;;:::i;:::-;;:::i;6144:345::-;;;;;;:::i;:::-;;:::i;4491:617:4:-;;;:::i;7713:209:5:-;;;;;;:::i;:::-;;:::i;13235:222::-;;;;;;:::i;:::-;13366:35;;;;13337:4;13366:35;;;:23;:35;;;;;;;;:42;;;13360:49;;:5;:49;;;;;:90;;;;;;:81;;;;:90;;;;;;;;13235:222;7216:266;;;;;;:::i;:::-;;:::i;10781:156::-;;;;;;:::i;:::-;;:::i;17268:129::-;;;;;;:::i;:::-;;:::i;6495:172::-;;;;;;:::i;:::-;;:::i;11332:222::-;;;;;;:::i;:::-;11463:35;;;;11434:4;11463:35;;;:23;:35;;;;;;;;:42;;;11457:49;;:5;:49;;;;;:90;;;;;;:81;;;;:90;;;;;;;;11332:222;13013:216;;;;;;:::i;:::-;;:::i;9848:213::-;;;;;;:::i;:::-;;:::i;7057:103::-;;;;;;:::i;:::-;7138:9;;7112:7;7138:9;;;:5;:9;;;;;:15;;;;7057:103;;;;5904:42:14;5892:55;;;5874:74;;5862:2;5847:18;7057:103:5;5728:226:14;16292:210:5;;;;;;:::i;:::-;;:::i;8608:163::-;;;;;;:::i;:::-;8712:9;;;8689:4;8712:9;;;:5;:9;;;;;;;;:52;;;;;:43;;:52;;;;;;;;8608:163;;;;;15515:204;;;;;;:::i;:::-;;:::i;4983:261::-;;;;;;:::i;:::-;;:::i;6673:378::-;;;;;;:::i;:::-;;:::i;12138:290::-;;;;;;:::i;:::-;;:::i;13756:171::-;;;;;;:::i;:::-;;:::i;17062:200::-;;;;;;:::i;:::-;;:::i;8445:157::-;;;;;;:::i;:::-;;:::i;5250:888::-;;;;;;:::i;:::-;;:::i;8212:227::-;;;;;;:::i;:::-;;:::i;11110:216::-;;;;;;:::i;:::-;;:::i;9582:260::-;;;;;;:::i;:::-;;:::i;10276:268::-;;;;;;:::i;:::-;;:::i;11897:235::-;11993:2;3501:26;3524:2;3501:22;:26::i;:::-;12005:8;3774:1:::1;3765:10:::0;;;3761:115:::1;;3798:67;;;;;;;;;;;;;;3761:115;12032:93:::2;12045:2;12049:8;;12032:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;::::0;;;-1:-1:-1;12059:9:5::2;::::0;::::2;::::0;;:5:::2;:9;::::0;;;;:19:::2;;::::0;-1:-1:-1;12080:44:5::2;::::0;-1:-1:-1;12032:12:5::2;::::0;-1:-1:-1;12032:93:5:i:2;:::-;3537:1:::1;11897:235:::0;;;;:::o;17445:340::-;17538:4;17573:63;;;;;:153;;-1:-1:-1;17652:74:5;;;17667:59;17652:74;17573:153;:205;;;-1:-1:-1;952:25:1;937:40;;;;17742:36:5;17554:224;17445:340;-1:-1:-1;;17445:340:5:o;14931:176::-;14998:42;15034:5;14998:35;:42::i;:::-;15051:49;32174:26;32318:42;32302:59;;32241:134;15066:33;15051:14;:49;;:::i;:::-;14931:176;:::o;7928:274::-;8018:2;3501:26;3524:2;3501:22;:26::i;:::-;8060:16:::1;::::0;;8074:1:::1;8060:16:::0;;;;;::::1;::::0;;;8032:25:::1;::::0;8060:16:::1;::::0;;::::1;::::0;;::::1;::::0;::::1;;::::0;-1:-1:-1;8060:16:5::1;8032:44;;8100:7;8086:8;8095:1;8086:11;;;;;;;;:::i;:::-;;;;;;:21;;;;;;;;;::::0;::::1;8117:78;8133:2;8137:8;8147:5;:9;8153:2;8147:9;;;;;;;;;;;;;;;:21;;8170:24;8117:15;:78::i;:::-;8022:180;7928:274:::0;;;:::o;12684:156::-;12786:9;;;;;;;:5;:9;;;;;12751:16;;12786:47;;:19;;:45;:47::i;14082:187::-;14202:60;14228:6;14236:4;14242:2;14246:7;14255:6;14202:25;:60::i;14360:147::-;14465:35;14483:6;14491:4;14497:2;14465:17;:35::i;:::-;14360:147;;;:::o;15833:372::-;15944:42;15980:5;15944:35;:42::i;:::-;32989:24;15997:12;33046:34;;;33100:4;33093:24;;;33137:4;33130:24;;;33190:4;33175:20;;;16087:18;33175:20;16087:18;:12;:18;:::i;:::-;16063:42;-1:-1:-1;16116:17:5;16136:22;16152:6;16063:42;16136:22;:::i;:::-;16116:42;;16169:29;16182:4;16188:9;16169:12;:29;;:::i;:::-;15934:271;;;15833:372;;;:::o;10550:221::-;10651:2;3501:26;3524:2;3501:22;:26::i;:::-;10663:8;3774:1:::1;3765:10:::0;;;3761:115:::1;;3798:67;;;;;;;;;;;;;;3761:115;10690:74:::2;10706:2;10710:8;;10690:74;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;::::0;;;-1:-1:-1;10720:9:5::2;::::0;::::2;::::0;;:5:::2;:9;::::0;;;;;;;:19:::2;;::::0;-1:-1:-1;10720:5:5;-1:-1:-1;10690:15:5::2;::::0;-1:-1:-1;10690:74:5:i:2;16508:548::-:0;16760:23;16759:24;:63;;;;16788:34;16787:35;16759:63;:92;;;;16826:25;16759:92;16755:204;;;16874:74;;;;;;;;;;;;;;16755:204;16969:80;17007:10;17042:5;17019:29;;;;;;;;;;:::i;:::-;16969:37;:80::i;15200:240::-;15285:42;15321:5;15285:35;:42::i;:::-;32579:28;32520:12;32640:38;;;32698:4;32691:24;;;32735:4;32728:24;;;32788:4;32773:20;;15338:95;;15422:1;15338:12;:95;;:::i;:::-;15200:240;;:::o;8777:217::-;8904:35;;;8898:49;8904:35;;;:23;:35;;;;;;;;:42;;;8898:49;;:5;:49;;;;;;;8863:16;;8898:89;;:61;:87;:89::i;11609:282::-;11692:2;3501:26;3524:2;3501:22;:26::i;:::-;11734:16:::1;::::0;;11748:1:::1;11734:16:::0;;;;;::::1;::::0;;;11706:25:::1;::::0;11734:16:::1;::::0;;::::1;::::0;;::::1;::::0;::::1;;::::0;-1:-1:-1;11734:16:5::1;11706:44;;11774:7;11760:8;11769:1;11760:11;;;;;;;;:::i;:::-;:21;::::0;;::::1;:11;::::0;;::::1;::::0;;;;;;:21;11818:9:::1;::::0;::::1;;::::0;;;:5:::1;:9:::0;;;;;;11791:93:::1;::::0;11804:2;;11808:8;;11818:19:::1;;11839:44;11791:12;:93::i;14591:255::-:0;14677:42;14713:5;14677:35;:42::i;:::-;14730:109;32174:26;32318:42;32302:59;;32241:134;14819:8;14803:26;;14730:12;:109;;:::i;12434:243::-;12535:2;3501:26;3524:2;3501:22;:26::i;:::-;12547:8;3774:1:::1;3765:10:::0;;;3761:115:::1;;3798:67;;;;;;;;;;;;;;3761:115;12574:96:::2;12590:2;12594:8;;12574:96;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;::::0;;;-1:-1:-1;12604:9:5::2;::::0;::::2;::::0;;:5:::2;:9;::::0;;;;:19:::2;;::::0;-1:-1:-1;12625:44:5::2;::::0;-1:-1:-1;12574:15:5::2;::::0;-1:-1:-1;12574:96:5:i:2;6144:345::-:0;6230:2;3501:26;3524:2;3501:22;:26::i;:::-;6248:22:::1;::::0;::::1;6244:149;;6293:89;;;;;;;;;;;;;;6244:149;6403:9;::::0;::::1;;::::0;;;:5:::1;:9;::::0;;;;;:26;;;::::1;;::::0;::::1;::::0;;::::1;::::0;;;6445:37;;6403:26;;:9;6445:37:::1;::::0;::::1;6144:345:::0;;;:::o;4491:617:4:-;4621:10;4635:9;4621:23;4617:78;;4667:17;;;;;;;;;;;;;;4617:78;4770:21;:39;;;-1:-1:-1;4795:14:4;;;;4770:39;4766:101;;;4832:24;;;;;;;;;;;;;;4766:101;4949:30;4960:18;4949:10;:30::i;:::-;4944:89;;5002:20;;;;;;;;;;;;;;4944:89;5080:14;:21;;;;5097:4;5080:21;;;4491:617::o;7713:209:5:-;7801:2;3501:26;3524:2;3501:22;:26::i;:::-;7813:8;3774:1:::1;3765:10:::0;;;3761:115:::1;;3798:67;;;;;;;;;;;;;;3761:115;7840:75:::2;7853:2;7857:8;;7840:75;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;::::0;;;-1:-1:-1;7867:9:5::2;::::0;::::2;::::0;;:5:::2;:9;::::0;;;;;;:21:::2;::::0;-1:-1:-1;7840:75:5;-1:-1:-1;7840:12:5::2;::::0;-1:-1:-1;7840:75:5:i:2;7216:266::-:0;7301:2;3501:26;3524:2;3501:22;:26::i;:::-;7343:16:::1;::::0;;7357:1:::1;7343:16:::0;;;;;::::1;::::0;;;7315:25:::1;::::0;7343:16:::1;::::0;;::::1;::::0;;::::1;::::0;::::1;;::::0;-1:-1:-1;7343:16:5::1;7315:44;;7383:7;7369:8;7378:1;7369:11;;;;;;;;:::i;:::-;;;;;;:21;;;;;;;;;::::0;::::1;7400:75;7413:2;7417:8;7427:5;:9;7433:2;7427:9;;;;;;;;;;;;;;;:21;;7450:24;7400:12;:75::i;10781:156::-:0;10883:9;;;;;;;:5;:9;;;;;10848:16;;10883:47;;:19;;:45;:47::i;17268:129::-;17354:36;;;;;:27;5892:55:14;;;17354:36:5;;;5874:74:14;17331:4:5;;17354:13;:27;;;;;;5847:18:14;;17354:36:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;6495:172::-;6563:2;3501:26;3524:2;3501:22;:26::i;:::-;6577:9:::1;::::0;::::1;6603:1;6577:9:::0;;;:5:::1;:9;::::0;;;;;:28;;;::::1;::::0;;6621:39;6603:1;;6577:9;6621:39:::1;::::0;6603:1;;6621:39:::1;6495:172:::0;;:::o;13013:216::-;13141:35;;;13135:49;13141:35;;;:23;:35;;;;;;;;:42;;;13135:49;;:5;:49;;;;;13100:16;;13135:87;;:59;;:85;:87::i;9848:213::-;9944:2;3501:26;3524:2;3501:22;:26::i;:::-;9956:8;3774:1:::1;3765:10:::0;;;3761:115:::1;;3798:67;;;;;;;;;;;;;;3761:115;9983:71:::2;9996:2;10000:8;;9983:71;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;::::0;;;-1:-1:-1;10010:9:5::2;::::0;::::2;::::0;;:5:::2;:9;::::0;;;;;;;:19:::2;;::::0;-1:-1:-1;10010:5:5;-1:-1:-1;9983:12:5::2;::::0;-1:-1:-1;9983:71:5:i:2;16292:210::-:0;16386:42;16422:5;16386:35;:42::i;:::-;32989:24;32934:12;33046:34;;;33100:4;33093:24;;;33137:4;33130:24;;;33190:4;33175:20;;16439:56;;16454:40;32815:396;15515:204;15599:42;15635:5;15599:35;:42::i;:::-;32579:28;32520:12;32640:38;;;32698:4;32691:24;;;32735:4;32728:24;;;32788:4;32773:20;;15652:60;;15667:44;32397:412;4983:261;5043:7;5062:10;5077;;5075:12;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5098:9:5;;;-1:-1:-1;5098:9:5;;;;;;;:28;;;;5116:10;5098:28;;;5142:21;5075:12;;-1:-1:-1;5075:12:5;5142:21;;;;5158:4;;;;5142:21;:::i;:::-;;;;;;;;5178:39;;5206:10;;5178:39;;;;;;;;;5235:2;4983:261;-1:-1:-1;;;4983:261:5:o;6673:378::-;6755:53;6797:10;6755:41;:53::i;:::-;6828:10;;;;;;;;;6823:15;;;;6819:113;;;6861:60;;;;;;;;;;;;;;6819:113;6942:35;;;;;;;:23;:35;;;;;;:47;;;;;;;;;;;;;7005:39;;6942:47;;:35;7005:39;;;6673:378;;:::o;12138:290::-;12226:2;3501:26;3524:2;3501:22;:26::i;:::-;12268:16:::1;::::0;;12282:1:::1;12268:16:::0;;;;;::::1;::::0;;;12240:25:::1;::::0;12268:16:::1;::::0;;::::1;::::0;;::::1;::::0;::::1;;::::0;-1:-1:-1;12268:16:5::1;12240:44;;12308:7;12294:8;12303:1;12294:11;;;;;;;;:::i;:::-;:21;::::0;;::::1;:11;::::0;;::::1;::::0;;;;;;:21;12355:9:::1;::::0;::::1;;::::0;;;:5:::1;:9:::0;;;;;;12325:96:::1;::::0;12341:2;;12345:8;;12355:19:::1;;12376:44;12325:15;:96::i;13756:171::-:0;13865:55;13894:6;13902:4;13908:2;13912:7;13865:28;:55::i;17062:200::-;17199:56;17237:10;17249:5;17199:37;:56::i;8445:157::-;8546:9;;;;;;;:5;:9;;;;;;;;8511:16;;8546:49;;:21;:47;:49::i;5250:888::-;5345:7;5364:10;5379;;5377:12;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;5364:25;;5448:1;5443:2;:6;5428:21;;:12;:21;;;5424:127;;;5476:60;;;;;;;;;;;;;;5424:127;5596:19;;;;5570:23;5596:19;;;:5;:19;;;;;;5651:9;;;;;;;;;;5671:29;;;;5690:10;5671:29;;;5716:21;;5651:9;;;5716:21;;;;5732:4;;;;5716:21;:::i;:::-;;;;;;;;5752:39;;5780:10;;5752:39;;;;;;;;;5802:93;5818:24;5844:2;5848:10;:22;;5872:10;:22;;5802:15;:93::i;:::-;5905:87;5921:22;5945:2;5949:10;:20;;5971:10;:20;;5905:15;:87::i;:::-;6002:109;6018:44;6064:2;6068:10;:20;;6090:10;:20;;6002:15;:109::i;:::-;-1:-1:-1;6129:2:5;;5250:888;-1:-1:-1;;;;;5250:888:5:o;8212:227::-;8315:2;3501:26;3524:2;3501:22;:26::i;:::-;8327:8;3774:1:::1;3765:10:::0;;;3761:115:::1;;3798:67;;;;;;;;;;;;;;3761:115;8354:78:::2;8370:2;8374:8;;8354:78;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;::::0;;;-1:-1:-1;8384:9:5::2;::::0;::::2;::::0;;:5:::2;:9;::::0;;;;;;:21:::2;::::0;-1:-1:-1;8354:78:5;-1:-1:-1;8354:15:5::2;::::0;-1:-1:-1;8354:78:5:i:2;11110:216::-:0;11238:35;;;11232:49;11238:35;;;:23;:35;;;;;;;;:42;;;11232:49;;:5;:49;;;;;11197:16;;11232:87;;:59;;:85;:87::i;9582:260::-;9665:2;3501:26;3524:2;3501:22;:26::i;:::-;9707:16:::1;::::0;;9721:1:::1;9707:16:::0;;;;;::::1;::::0;;;9679:25:::1;::::0;9707:16:::1;::::0;;::::1;::::0;;::::1;::::0;::::1;;::::0;-1:-1:-1;9707:16:5::1;9679:44;;9747:7;9733:8;9742:1;9733:11;;;;;;;;:::i;:::-;;;;;;:21;;;;;;;;;::::0;::::1;9764:71;9777:2;9781:8;9791:5;:9;9797:2;9791:9;;;;;;;;;;;;;;;:19;;9812:22;9764:12;:71::i;10276:268::-:0;10364:2;3501:26;3524:2;3501:22;:26::i;:::-;10406:16:::1;::::0;;10420:1:::1;10406:16:::0;;;;;::::1;::::0;;;10378:25:::1;::::0;10406:16:::1;::::0;;::::1;::::0;;::::1;::::0;::::1;;::::0;-1:-1:-1;10406:16:5::1;10378:44;;10446:7;10432:8;10441:1;10432:11;;;;;;;;:::i;:::-;;;;;;:21;;;;;;;;;::::0;::::1;10463:74;10479:2;10483:8;10493:5;:9;10499:2;10493:9;;;;;;;;;;;;;;;:19;;10514:22;10463:15;:74::i;5440:139:4:-:0;5557:5;5544:11;5537:26;5440:139;;:::o;6597:168::-;6731:18;;6597:168::o;7745:122::-;7849:1;7836:11;7829:22;7745:122;:::o;5954:308::-;6052:14;;;;6048:208;;;6129:5;6116:11;6109:26;15200:240:5;;:::o;6048:208:4:-;6206:26;;5954:308::o;7143:337::-;7239:13;7268:14;;;;7264:210;;;-1:-1:-1;7334:18:4;;7143:337::o;7264:210::-;-1:-1:-1;7432:18:4;;7264:210;7143:337;;;:::o;8175:287::-;8260:14;;;;8256:200;;;8337:1;8324:11;8317:22;14931:176:5;:::o;8256:200:4:-;8430:1;8410:22;;8175:287::o;22921:204:5:-;23006:9;;;;;;;:5;:9;;;;;:15;;;22992:10;:29;22988:131;;23044:64;;;;;;;;;;;;;;25882:705;26053:15;;26078:503;26102:8;:15;26098:1;:19;26078:503;;;26144:8;26153:1;26144:11;;;;;;;;:::i;:::-;;;;;;;26134:21;;26193:1;26174:21;;:7;:21;;;26170:132;;26222:65;;;;;;;;;;;;;;26170:132;26320:43;:11;26355:7;26320:34;:43::i;:::-;26316:195;;;26421:7;26388:41;;26417:2;26388:41;;26407:8;26388:41;;;;;;;;:::i;:::-;;;;;;;;26447:42;;;;;;;:33;;;:42;;;;;:49;;;;26492:4;26447:49;;;26316:195;26553:3;;26078:503;;9229:299;9329:35;;;9323:49;9329:35;;;:23;:35;;;;;;;;:42;;;9323:49;;:5;:49;;;;;9407:10;9323:95;;:83;;:95;;;;;;;;9318:204;;9441:70;;;;;;;;;;;;;;26593:569;26767:15;;26792:364;26816:8;:15;26812:1;:19;26792:364;;;26858:8;26867:1;26858:11;;;;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;26888:46:5;:11;26858;26888:37;:46::i;:::-;26884:202;;;26996:7;26959:45;;26992:2;26959:45;;26982:8;26959:45;;;;;;;;:::i;:::-;;;;;;;;27029:42;;;;;;;:33;;;:42;;;;;27022:49;;;;;;26884:202;27128:3;;26792:364;;10251:300:3;10314:16;10342:22;10367:19;10375:3;10367:7;:19::i;:::-;10342:44;10251:300;-1:-1:-1;;;10251:300:3:o;30310:1708:5:-;30508:10;30444:37;30484:35;;;:23;:35;;;;;;;;;30444:75;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30530:58;;30571:7;;;30530:58;30602:6;:33;;;30598:203;;;30655:14;;;;:19;30651:140;;30701:75;;;;;;;;;;;;;;30651:140;30823:6;:36;;;30819:225;;;30880:31;;;;;:27;5892:55:14;;;30880:31:5;;;5874:74:14;30880:13:5;:27;;;;5847:18:14;;30880:31:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;30875:159;;30938:81;;;;;;;;;;;;;;30875:159;31070:4;31058:16;;:8;:16;;;31054:218;;31094:6;:30;;;31090:151;;;31151:75;;;;;;;;;;;;;;31090:151;31255:7;;;31054:218;32989:24;31282:12;33046:34;;;31322:10;33100:4;33093:24;33137:4;33130:24;;;33190:4;33175:20;;;31383:18;33175:20;31383:18;:12;:18;:::i;:::-;31356:45;;31435:6;31415:16;:26;31411:165;;31485:45;31498:4;31523:6;31504:16;:25;31485:12;:45;;:::i;:::-;31559:7;;;;;31411:165;31590:6;:21;;;31586:426;;;31637:13;;31631:20;;;;;;:5;:20;;;;;;;;:62;;;;;:52;;:62;;;;;;;;31627:172;;;31720:64;;;;;;;;;;;;;;31627:172;31586:426;;;31840:13;;31834:20;;;;;;:5;:20;;;;;;;;:62;;;;;:52;;:62;;;;;;;;31829:173;;31923:64;;;;;;;;;;;;;;31829:173;30434:1584;;;30310:1708;;;;;:::o;27168:1524::-;27327:10;27263:37;27303:35;;;:23;:35;;;;;;;;;27263:75;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27349:58;;27390:7;27168:1524;;;:::o;27349:58::-;27421:6;:33;;;27417:203;;;27474:14;;;;:19;27470:140;;27520:75;;;;;;;;;;;;;;27470:140;27642:6;:36;;;27638:225;;;27699:31;;;;;:27;5892:55:14;;;27699:31:5;;;5874:74:14;27699:13:5;:27;;;;5847:18:14;;27699:31:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;27694:159;;27757:81;;;;;;;;;;;;;;27694:159;27889:4;27877:16;;:8;:16;;;27873:218;;27913:6;:30;;;27909:151;;;27970:75;;;;;;;;;;;;;;27873:218;28143:10;32174:26;32241:134;28197:18;32241:134;28197:18;:12;:18;:::i;:::-;28169:48;;:8;:48;;;28165:85;;28233:7;;27168:1524;;;:::o;28165:85::-;28264:6;:21;;;28260:426;;;28311:13;;28305:20;;;;;;:5;:20;;;;;;;;:62;;;;;:52;;:62;;;;;;;;28301:172;;;28394:64;;;;;;;;;;;;;;28301:172;28260:426;;;28514:13;;28508:20;;;;;;:5;:20;;;;;;;;:62;;;;;:52;;:62;;;;;;;;28503:173;;28597:64;;;;;;;;;;;;;;17791:3053;17929:53;17971:10;17929:41;:53::i;:::-;18006:34;17997:5;:43;;;;;;;;:::i;:::-;;17993:110;;-1:-1:-1;18064:28:5;17993:110;18154:35;;;18113:38;18154:35;;;:23;:35;;;;;18221:26;18212:5;:35;;;;;;;;:::i;:::-;;18208:2571;;18263:28;;18455:44;;18263:28;18455:44;;;18208:2571;;;18529:26;18520:5;:35;;;;;;;;:::i;:::-;;18516:2263;;18571:29;;18763:44;;18614:28;18763:44;;;18516:2263;;;18837:28;18828:5;:37;;;;;;;;:::i;:::-;;18824:1955;;18881:29;;19074:44;;;;18824:1955;;;19148:27;19139:5;:36;;;;;;;;:::i;:::-;;19135:1644;;19191:29;;19383:44;;19277:37;19383:44;;;19135:1644;;;19457:27;19448:5;:36;;;;;;;;:::i;:::-;;19444:1335;;19500:29;;19692:44;;19638:40;19692:44;;;19444:1335;;;19766:26;19757:5;:35;;;;;;;;:::i;:::-;;19753:1026;;19808:29;;20001:43;;;;;;19753:1026;;;20074:28;20065:5;:37;;;;;;;;:::i;:::-;;20061:718;;20118:29;;20309:44;;20255:40;20309:44;;;20061:718;;;20383:28;20374:5;:37;;;;;;;;:::i;:::-;;20370:409;;20427:29;;20619:43;;;;;;20370:409;;;20700:68;;;;;;;;;;;;;;20370:409;20794:43;20819:10;20831:5;20794:43;;;;;;;:::i;:::-;;;;;;;;17919:2925;17791:3053;;:::o;9346:407:4:-;9429:7;9691:17;:28;;9738:2;9726:9;:14;;;;:::i;:::-;9691:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;9682:64:4;;9346:407;-1:-1:-1;;;9346:407:4:o;23496:418:5:-;23597:26;;;:10;:26;23593:63;;23496:418;:::o;23593:63::-;23684:24;23695:12;23684:10;:24::i;:::-;23670:38;;:10;:38;23666:75;;23496:418;:::o;23666:75::-;23756:26;23769:12;23756;:26::i;:::-;23751:157;;23805:92;;;;;;;;;;;;;;28698:1606;28888:10;28824:37;28864:35;;;:23;:35;;;;;;;;;28824:75;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28910:58;;28951:7;;;28910:58;28982:6;:33;;;28978:203;;;29035:14;;;;:19;29031:140;;29081:75;;;;;;;;;;;;;;29031:140;29203:6;:36;;;29199:225;;;29260:31;;;;;:27;5892:55:14;;;29260:31:5;;;5874:74:14;29260:13:5;:27;;;;5847:18:14;;29260:31:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;29255:159;;29318:81;;;;;;;;;;;;;;29255:159;29450:4;29438:16;;:8;:16;;;29434:218;;29474:6;:30;;;29470:151;;;29531:75;;;;;;;;;;;;;;29470:151;29635:7;;;29434:218;32579:28;29662:12;32640:38;;;29706:10;32698:4;32691:24;32735:4;32728:24;;;32788:4;32773:20;;;29771:18;32773:20;29771:18;:12;:18;:::i;:::-;29740:49;-1:-1:-1;29804:25:5;;29800:62;;29845:7;;;;;29800:62;29876:6;:21;;;29872:426;;;29923:13;;29917:20;;;;;;:5;:20;;;;;;;;:62;;;;;:52;;:62;;;;;;;;29913:172;;;30006:64;;;;;;;;;;;;;;29913:172;29872:426;;;30126:13;;30120:20;;;;;;:5;:20;;;;;;;;:62;;;;;:52;;:62;;;;;;;;30115:173;;30209:64;;;;;;;;;;;;;;30115:173;28814:1490;;;28698:1606;;;;:::o;21876:882::-;22114:11;22198:9;22294:31;;;22068:43;22358:19;22114:11;22358:17;:19::i;:::-;22335:42;-1:-1:-1;22387:15:5;;22412:340;22436:12;22432:1;:16;22412:340;;;22475:16;:10;22489:1;22475:13;:16::i;:::-;22465:26;-1:-1:-1;22510:21:5;:8;22465:26;22510:12;:21::i;:::-;22506:176;;;22604:7;22556:56;;22585:17;22556:56;;22575:8;22556:56;;;;;;;;:::i;:::-;;;;;;;;22630:30;;;;;;;;;;;;;;:37;;;;22663:4;22630:37;;;22506:176;22724:3;;22412:340;;;;22058:700;;;;;21876:882;;;;:::o;8297:150:3:-;8367:4;8390:50;8395:3;8415:23;;;8390:4;:50::i;8615:156::-;8688:4;8711:53;8719:3;8739:23;;;8711:7;:53::i;5562:109::-;5618:16;5653:3;:11;;5646:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5562:109;;;:::o;24211:364:5:-;24289:13;24350:10;24344:4;24337:24;24438:4;24432;24426;24420;24406:12;24399:5;24388:55;24499:6;24491:4;24473:16;24470:26;24463:34;24459:47;24456:103;;;24540:4;24534:11;24525:20;;24456:103;;24211:364;;;:::o;24902:567::-;24982:12;25046:4;25040:11;25086:4;25081:3;25077:14;25071:4;25064:28;25117:10;25112:3;25105:23;25164:33;25158:3;25152:4;25148:14;25141:57;25234:8;25228:3;25222:4;25218:14;25211:32;25330:4;25324;25318;25311;25306:3;25302:14;25288:12;25281:5;25270:65;25256:79;;25391:6;25383:4;25365:16;25362:26;25355:34;25351:47;25348:105;;;-1:-1:-1;;25434:4:5;25428:11;;24902:567;-1:-1:-1;24902:567:5:o;9098:115:3:-;9161:7;9187:19;9195:3;4537:18;;4455:107;9555:156;9629:7;9679:22;9683:3;9695:5;9679:3;:22::i;2206:404::-;2269:4;4343:19;;;:12;;;:19;;;;;;2285:319;;-1:-1:-1;2327:23:3;;;;;;;;:11;:23;;;;;;;;;;;;;2507:18;;2485:19;;;:12;;;:19;;;;;;:40;;;;2539:11;;2285:319;-1:-1:-1;2588:5:3;2581:12;;2778:1388;2844:4;2981:19;;;:12;;;:19;;;;;;3015:15;;3011:1149;;3384:21;3408:14;3421:1;3408:10;:14;:::i;:::-;3456:18;;3384:38;;-1:-1:-1;3436:17:3;;3456:22;;3477:1;;3456:22;:::i;:::-;3436:42;;3510:13;3497:9;:26;3493:398;;3543:17;3563:3;:11;;3575:9;3563:22;;;;;;;;:::i;:::-;;;;;;;;;3543:42;;3714:9;3685:3;:11;;3697:13;3685:26;;;;;;;;:::i;:::-;;;;;;;;;;;;:38;;;;3797:23;;;:12;;;:23;;;;;:36;;;3493:398;3969:17;;:3;;:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;4061:3;:12;;:19;4074:5;4061:19;;;;;;;;;;;4054:26;;;4102:4;4095:11;;;;;;;3011:1149;4144:5;4137:12;;;;;4904:118;4971:7;4997:3;:11;;5009:5;4997:18;;;;;;;;:::i;:::-;;;;;;;;;4990:25;;4904:118;;;;:::o;14:186:14:-;82:20;;142:32;131:44;;121:55;;111:83;;190:1;187;180:12;205:689;300:6;308;316;369:2;357:9;348:7;344:23;340:32;337:52;;;385:1;382;375:12;337:52;408:29;427:9;408:29;:::i;:::-;398:39;;488:2;477:9;473:18;460:32;511:18;552:2;544:6;541:14;538:34;;;568:1;565;558:12;538:34;606:6;595:9;591:22;581:32;;651:7;644:4;640:2;636:13;632:27;622:55;;673:1;670;663:12;622:55;713:2;700:16;739:2;731:6;728:14;725:34;;;755:1;752;745:12;725:34;808:7;803:2;793:6;790:1;786:14;782:2;778:23;774:32;771:45;768:65;;;829:1;826;819:12;768:65;860:2;856;852:11;842:21;;882:6;872:16;;;;;205:689;;;;;:::o;899:332::-;957:6;1010:2;998:9;989:7;985:23;981:32;978:52;;;1026:1;1023;1016:12;978:52;1065:9;1052:23;1115:66;1108:5;1104:78;1097:5;1094:89;1084:117;;1197:1;1194;1187:12;1428:196;1496:20;;1556:42;1545:54;;1535:65;;1525:93;;1614:1;1611;1604:12;1629:260;1697:6;1705;1758:2;1746:9;1737:7;1733:23;1729:32;1726:52;;;1774:1;1771;1764:12;1726:52;1797:29;1816:9;1797:29;:::i;:::-;1787:39;;1845:38;1879:2;1868:9;1864:18;1845:38;:::i;:::-;1835:48;;1629:260;;;;;:::o;1894:186::-;1953:6;2006:2;1994:9;1985:7;1981:23;1977:32;1974:52;;;2022:1;2019;2012:12;1974:52;2045:29;2064:9;2045:29;:::i;2085:186::-;2144:6;2197:2;2185:9;2176:7;2172:23;2168:32;2165:52;;;2213:1;2210;2203:12;2165:52;2236:29;2255:9;2236:29;:::i;2276:681::-;2447:2;2499:21;;;2569:13;;2472:18;;;2591:22;;;2418:4;;2447:2;2670:15;;;;2644:2;2629:18;;;2418:4;2713:218;2727:6;2724:1;2721:13;2713:218;;;2792:13;;2807:42;2788:62;2776:75;;2906:15;;;;2871:12;;;;2749:1;2742:9;2713:218;;;-1:-1:-1;2948:3:14;;2276:681;-1:-1:-1;;;;;;2276:681:14:o;2962:472::-;3057:6;3065;3073;3081;3089;3142:3;3130:9;3121:7;3117:23;3113:33;3110:53;;;3159:1;3156;3149:12;3110:53;3182:29;3201:9;3182:29;:::i;:::-;3172:39;;3230:38;3264:2;3253:9;3249:18;3230:38;:::i;:::-;3220:48;;3287:38;3321:2;3310:9;3306:18;3287:38;:::i;:::-;2962:472;;;;-1:-1:-1;3277:48:14;;3372:2;3357:18;;3344:32;;-1:-1:-1;3423:3:14;3408:19;3395:33;;2962:472;-1:-1:-1;;2962:472:14:o;3660:334::-;3737:6;3745;3753;3806:2;3794:9;3785:7;3781:23;3777:32;3774:52;;;3822:1;3819;3812:12;3774:52;3845:29;3864:9;3845:29;:::i;:::-;3835:39;;3893:38;3927:2;3916:9;3912:18;3893:38;:::i;:::-;3883:48;;3950:38;3984:2;3973:9;3969:18;3950:38;:::i;:::-;3940:48;;3660:334;;;;;:::o;3999:322::-;4076:6;4084;4092;4145:2;4133:9;4124:7;4120:23;4116:32;4113:52;;;4161:1;4158;4151:12;4113:52;4184:29;4203:9;4184:29;:::i;:::-;4174:39;4260:2;4245:18;;4232:32;;-1:-1:-1;4311:2:14;4296:18;;;4283:32;;3999:322;-1:-1:-1;;;3999:322:14:o;4326:118::-;4412:5;4405:13;4398:21;4391:5;4388:32;4378:60;;4434:1;4431;4424:12;4449:750;4533:6;4541;4549;4557;4565;4618:3;4606:9;4597:7;4593:23;4589:33;4586:53;;;4635:1;4632;4625:12;4586:53;4658:29;4677:9;4658:29;:::i;:::-;4648:39;;4737:2;4726:9;4722:18;4709:32;4781:4;4774:5;4770:16;4763:5;4760:27;4750:55;;4801:1;4798;4791:12;4750:55;4824:5;-1:-1:-1;4881:2:14;4866:18;;4853:32;4894:30;4853:32;4894:30;:::i;:::-;4943:7;-1:-1:-1;5002:2:14;4987:18;;4974:32;5015:30;4974:32;5015:30;:::i;:::-;5064:7;-1:-1:-1;5123:3:14;5108:19;;5095:33;5137:30;5095:33;5137:30;:::i;:::-;5186:7;5176:17;;;4449:750;;;;;;;;:::o;5204:254::-;5272:6;5280;5333:2;5321:9;5312:7;5308:23;5304:32;5301:52;;;5349:1;5346;5339:12;5301:52;5372:29;5391:9;5372:29;:::i;:::-;5362:39;5448:2;5433:18;;;;5420:32;;-1:-1:-1;;;5204:254:14:o;5463:260::-;5531:6;5539;5592:2;5580:9;5571:7;5567:23;5563:32;5560:52;;;5608:1;5605;5598:12;5560:52;5631:29;5650:9;5631:29;:::i;5959:348::-;6011:8;6021:6;6075:3;6068:4;6060:6;6056:17;6052:27;6042:55;;6093:1;6090;6083:12;6042:55;-1:-1:-1;6116:20:14;;6159:18;6148:30;;6145:50;;;6191:1;6188;6181:12;6145:50;6228:4;6220:6;6216:17;6204:29;;6280:3;6273:4;6264:6;6256;6252:19;6248:30;6245:39;6242:59;;;6297:1;6294;6287:12;6242:59;5959:348;;;;;:::o;6312:411::-;6383:6;6391;6444:2;6432:9;6423:7;6419:23;6415:32;6412:52;;;6460:1;6457;6450:12;6412:52;6500:9;6487:23;6533:18;6525:6;6522:30;6519:50;;;6565:1;6562;6555:12;6519:50;6604:59;6655:7;6646:6;6635:9;6631:22;6604:59;:::i;:::-;6682:8;;6578:85;;-1:-1:-1;6312:411:14;-1:-1:-1;;;;6312:411:14:o;6728:260::-;6796:6;6804;6857:2;6845:9;6836:7;6832:23;6828:32;6825:52;;;6873:1;6870;6863:12;6825:52;6896:29;6915:9;6896:29;:::i;:::-;6886:39;;6944:38;6978:2;6967:9;6963:18;6944:38;:::i;6993:403::-;7079:6;7087;7095;7103;7156:3;7144:9;7135:7;7131:23;7127:33;7124:53;;;7173:1;7170;7163:12;7124:53;7196:29;7215:9;7196:29;:::i;:::-;7186:39;;7244:38;7278:2;7267:9;7263:18;7244:38;:::i;:::-;7234:48;;7301:38;7335:2;7324:9;7320:18;7301:38;:::i;:::-;6993:403;;;;-1:-1:-1;7291:48:14;;7386:2;7371:18;7358:32;;-1:-1:-1;;6993:403:14:o;7401:357::-;7496:6;7504;7557:2;7545:9;7536:7;7532:23;7528:32;7525:52;;;7573:1;7570;7563:12;7525:52;7596:29;7615:9;7596:29;:::i;:::-;7586:39;;7675:2;7664:9;7660:18;7647:32;7708:1;7701:5;7698:12;7688:40;;7724:1;7721;7714:12;7688:40;7747:5;7737:15;;;7401:357;;;;;:::o;7763:485::-;7843:6;7851;7859;7912:2;7900:9;7891:7;7887:23;7883:32;7880:52;;;7928:1;7925;7918:12;7880:52;7968:9;7955:23;8001:18;7993:6;7990:30;7987:50;;;8033:1;8030;8023:12;7987:50;8072:59;8123:7;8114:6;8103:9;8099:22;8072:59;:::i;:::-;8150:8;;-1:-1:-1;8046:85:14;-1:-1:-1;8204:38:14;;-1:-1:-1;8238:2:14;8223:18;;8204:38;:::i;8442:184::-;8494:77;8491:1;8484:88;8591:4;8588:1;8581:15;8615:4;8612:1;8605:15;8631:184;8683:77;8680:1;8673:88;8780:4;8777:1;8770:15;8804:4;8801:1;8794:15;8820:125;8885:9;;;8906:10;;;8903:36;;;8919:18;;:::i;8950:184::-;9002:77;8999:1;8992:88;9099:4;9096:1;9089:15;9123:4;9120:1;9113:15;9139:245;9206:6;9259:2;9247:9;9238:7;9234:23;9230:32;9227:52;;;9275:1;9272;9265:12;9227:52;9307:9;9301:16;9326:28;9348:5;9326:28;:::i;9389:224::-;9428:3;9456:32;9523:2;9516:5;9512:14;9550:2;9541:7;9538:15;9535:41;;9556:18;;:::i;:::-;9605:1;9592:15;;9389:224;-1:-1:-1;;;9389:224:14:o;9618:449::-;9777:2;9766:9;9759:21;9816:6;9811:2;9800:9;9796:18;9789:34;9873:6;9865;9860:2;9849:9;9845:18;9832:48;9929:1;9900:22;;;9924:2;9896:31;;;9889:42;;;;9983:2;9971:15;;;9988:66;9967:88;9952:104;9948:113;;9618:449;-1:-1:-1;9618:449:14:o;10072:532::-;10301:42;10289:55;;10271:74;;10259:2;10244:18;;10375:1;10364:13;;10354:201;;10411:77;10408:1;10401:88;10512:4;10509:1;10502:15;10540:4;10537:1;10530:15;10354:201;10591:6;10586:2;10575:9;10571:18;10564:34;10072:532;;;;;:::o;10609:274::-;10649:1;10675;10665:189;;10710:77;10707:1;10700:88;10811:4;10808:1;10801:15;10839:4;10836:1;10829:15;10665:189;-1:-1:-1;10868:9:14;;10609:274::o;11098:128::-;11165:9;;;11186:11;;;11183:37;;;11200:18;;:::i;11231:184::-;11283:77;11280:1;11273:88;11380:4;11377:1;11370:15;11404:4;11401:1;11394:15
Swarm Source
ipfs://c104b63905a188c6b1e795f6018b36d9c876d6bd4f6ea96593fb37a009e87c1c
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.