Overview
APE Balance
0.00081 APE
APE Value
Less Than $0.01 (@ $1.30/APE)More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Delegate All | 4434491 | 10 days ago | IN | 0.00081 APE | 0.00400502 |
Latest 1 internal transaction
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
4351415 | 11 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 Name:
DelegateRegistry
Compiler Version
v0.8.21+commit.d9974bed
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: CC0-1.0 pragma solidity ^0.8.21; import {IDelegateRegistry as IDelegateRegistry} from "./IDelegateRegistry.sol"; import {RegistryHashes as Hashes} from "./libraries/RegistryHashes.sol"; import {RegistryStorage as Storage} from "./libraries/RegistryStorage.sol"; import {RegistryOps as Ops} from "./libraries/RegistryOps.sol"; /** * @title DelegateRegistry * @custom:version 2.0 * @custom:coauthor foobar (0xfoobar) * @custom:coauthor mireynolds * @notice A standalone immutable registry storing delegated permissions from one address to another */ contract DelegateRegistry is IDelegateRegistry { /// @dev Only this mapping should be used to verify delegations; the other mapping arrays are for enumerations mapping(bytes32 delegationHash => bytes32[5] delegationStorage) internal delegations; /// @dev Vault delegation enumeration outbox, for pushing new hashes only mapping(address from => bytes32[] delegationHashes) internal outgoingDelegationHashes; /// @dev Delegate enumeration inbox, for pushing new hashes only mapping(address to => bytes32[] delegationHashes) internal incomingDelegationHashes; /** * ----------- WRITE ----------- */ /// @inheritdoc IDelegateRegistry function multicall(bytes[] calldata data) external payable override returns (bytes[] memory results) { results = new bytes[](data.length); bool success; unchecked { for (uint256 i = 0; i < data.length; ++i) { //slither-disable-next-line calls-loop,delegatecall-loop (success, results[i]) = address(this).delegatecall(data[i]); if (!success) revert MulticallFailed(); } } } /// @inheritdoc IDelegateRegistry function delegateAll(address to, bytes32 rights, bool enable) external payable override returns (bytes32 hash) { hash = Hashes.allHash(msg.sender, rights, to); bytes32 location = Hashes.location(hash); address loadedFrom = _loadFrom(location); if (enable) { if (loadedFrom == Storage.DELEGATION_EMPTY) { _pushDelegationHashes(msg.sender, to, hash); _writeDelegationAddresses(location, msg.sender, to, address(0)); if (rights != "") _writeDelegation(location, Storage.POSITIONS_RIGHTS, rights); } else if (loadedFrom == Storage.DELEGATION_REVOKED) { _updateFrom(location, msg.sender); } } else if (loadedFrom == msg.sender) { _updateFrom(location, Storage.DELEGATION_REVOKED); } emit DelegateAll(msg.sender, to, rights, enable); } /// @inheritdoc IDelegateRegistry function delegateContract(address to, address contract_, bytes32 rights, bool enable) external payable override returns (bytes32 hash) { hash = Hashes.contractHash(msg.sender, rights, to, contract_); bytes32 location = Hashes.location(hash); address loadedFrom = _loadFrom(location); if (enable) { if (loadedFrom == Storage.DELEGATION_EMPTY) { _pushDelegationHashes(msg.sender, to, hash); _writeDelegationAddresses(location, msg.sender, to, contract_); if (rights != "") _writeDelegation(location, Storage.POSITIONS_RIGHTS, rights); } else if (loadedFrom == Storage.DELEGATION_REVOKED) { _updateFrom(location, msg.sender); } } else if (loadedFrom == msg.sender) { _updateFrom(location, Storage.DELEGATION_REVOKED); } emit DelegateContract(msg.sender, to, contract_, rights, enable); } /// @inheritdoc IDelegateRegistry function delegateERC721(address to, address contract_, uint256 tokenId, bytes32 rights, bool enable) external payable override returns (bytes32 hash) { hash = Hashes.erc721Hash(msg.sender, rights, to, tokenId, contract_); bytes32 location = Hashes.location(hash); address loadedFrom = _loadFrom(location); if (enable) { if (loadedFrom == Storage.DELEGATION_EMPTY) { _pushDelegationHashes(msg.sender, to, hash); _writeDelegationAddresses(location, msg.sender, to, contract_); _writeDelegation(location, Storage.POSITIONS_TOKEN_ID, tokenId); if (rights != "") _writeDelegation(location, Storage.POSITIONS_RIGHTS, rights); } else if (loadedFrom == Storage.DELEGATION_REVOKED) { _updateFrom(location, msg.sender); } } else if (loadedFrom == msg.sender) { _updateFrom(location, Storage.DELEGATION_REVOKED); } emit DelegateERC721(msg.sender, to, contract_, tokenId, rights, enable); } // @inheritdoc IDelegateRegistry function delegateERC20(address to, address contract_, bytes32 rights, uint256 amount) external payable override returns (bytes32 hash) { hash = Hashes.erc20Hash(msg.sender, rights, to, contract_); bytes32 location = Hashes.location(hash); address loadedFrom = _loadFrom(location); if (amount != 0) { if (loadedFrom == Storage.DELEGATION_EMPTY) { _pushDelegationHashes(msg.sender, to, hash); _writeDelegationAddresses(location, msg.sender, to, contract_); _writeDelegation(location, Storage.POSITIONS_AMOUNT, amount); if (rights != "") _writeDelegation(location, Storage.POSITIONS_RIGHTS, rights); } else if (loadedFrom == Storage.DELEGATION_REVOKED) { _updateFrom(location, msg.sender); _writeDelegation(location, Storage.POSITIONS_AMOUNT, amount); } else if (loadedFrom == msg.sender) { _writeDelegation(location, Storage.POSITIONS_AMOUNT, amount); } } else if (loadedFrom == msg.sender) { _updateFrom(location, Storage.DELEGATION_REVOKED); _writeDelegation(location, Storage.POSITIONS_AMOUNT, uint256(0)); } emit DelegateERC20(msg.sender, to, contract_, rights, amount); } /// @inheritdoc IDelegateRegistry function delegateERC1155(address to, address contract_, uint256 tokenId, bytes32 rights, uint256 amount) external payable override returns (bytes32 hash) { hash = Hashes.erc1155Hash(msg.sender, rights, to, tokenId, contract_); bytes32 location = Hashes.location(hash); address loadedFrom = _loadFrom(location); if (amount != 0) { if (loadedFrom == Storage.DELEGATION_EMPTY) { _pushDelegationHashes(msg.sender, to, hash); _writeDelegationAddresses(location, msg.sender, to, contract_); _writeDelegation(location, Storage.POSITIONS_TOKEN_ID, tokenId); _writeDelegation(location, Storage.POSITIONS_AMOUNT, amount); if (rights != "") _writeDelegation(location, Storage.POSITIONS_RIGHTS, rights); } else if (loadedFrom == Storage.DELEGATION_REVOKED) { _updateFrom(location, msg.sender); _writeDelegation(location, Storage.POSITIONS_AMOUNT, amount); } else if (loadedFrom == msg.sender) { _writeDelegation(location, Storage.POSITIONS_AMOUNT, amount); } } else if (loadedFrom == msg.sender) { _updateFrom(location, Storage.DELEGATION_REVOKED); _writeDelegation(location, Storage.POSITIONS_AMOUNT, uint256(0)); } emit DelegateERC1155(msg.sender, to, contract_, tokenId, rights, amount); } /// @dev Transfer native token out function sweep() external { assembly ("memory-safe") { // This hardcoded address is a CREATE2 factory counterfactual smart contract wallet that will always accept native token transfers let result := call(gas(), 0x000000dE1E80ea5a234FB5488fee2584251BC7e8, selfbalance(), 0, 0, 0, 0) } } /** * ----------- CHECKS ----------- */ /// @inheritdoc IDelegateRegistry function checkDelegateForAll(address to, address from, bytes32 rights) external view override returns (bool valid) { if (!_invalidFrom(from)) { valid = _validateFrom(Hashes.allLocation(from, "", to), from); if (!Ops.or(rights == "", valid)) valid = _validateFrom(Hashes.allLocation(from, rights, to), from); } assembly ("memory-safe") { // Only first 32 bytes of scratch space is accessed mstore(0, iszero(iszero(valid))) // Compiler cleans dirty booleans on the stack to 1, so do the same here return(0, 32) // Direct return, skips Solidity's redundant copying to save gas } } /// @inheritdoc IDelegateRegistry function checkDelegateForContract(address to, address from, address contract_, bytes32 rights) external view override returns (bool valid) { if (!_invalidFrom(from)) { valid = _validateFrom(Hashes.allLocation(from, "", to), from) || _validateFrom(Hashes.contractLocation(from, "", to, contract_), from); if (!Ops.or(rights == "", valid)) { valid = _validateFrom(Hashes.allLocation(from, rights, to), from) || _validateFrom(Hashes.contractLocation(from, rights, to, contract_), from); } } assembly ("memory-safe") { // Only first 32 bytes of scratch space is accessed mstore(0, iszero(iszero(valid))) // Compiler cleans dirty booleans on the stack to 1, so do the same here return(0, 32) // Direct return, skips Solidity's redundant copying to save gas } } /// @inheritdoc IDelegateRegistry function checkDelegateForERC721(address to, address from, address contract_, uint256 tokenId, bytes32 rights) external view override returns (bool valid) { if (!_invalidFrom(from)) { valid = _validateFrom(Hashes.allLocation(from, "", to), from) || _validateFrom(Hashes.contractLocation(from, "", to, contract_), from) || _validateFrom(Hashes.erc721Location(from, "", to, tokenId, contract_), from); if (!Ops.or(rights == "", valid)) { valid = _validateFrom(Hashes.allLocation(from, rights, to), from) || _validateFrom(Hashes.contractLocation(from, rights, to, contract_), from) || _validateFrom(Hashes.erc721Location(from, rights, to, tokenId, contract_), from); } } assembly ("memory-safe") { // Only first 32 bytes of scratch space is accessed mstore(0, iszero(iszero(valid))) // Compiler cleans dirty booleans on the stack to 1, so do the same here return(0, 32) // Direct return, skips Solidity's redundant copying to save gas } } /// @inheritdoc IDelegateRegistry function checkDelegateForERC20(address to, address from, address contract_, bytes32 rights) external view override returns (uint256 amount) { if (!_invalidFrom(from)) { amount = (_validateFrom(Hashes.allLocation(from, "", to), from) || _validateFrom(Hashes.contractLocation(from, "", to, contract_), from)) ? type(uint256).max : _loadDelegationUint(Hashes.erc20Location(from, "", to, contract_), Storage.POSITIONS_AMOUNT); if (!Ops.or(rights == "", amount == type(uint256).max)) { uint256 rightsBalance = (_validateFrom(Hashes.allLocation(from, rights, to), from) || _validateFrom(Hashes.contractLocation(from, rights, to, contract_), from)) ? type(uint256).max : _loadDelegationUint(Hashes.erc20Location(from, rights, to, contract_), Storage.POSITIONS_AMOUNT); amount = Ops.max(rightsBalance, amount); } } assembly ("memory-safe") { mstore(0, amount) // Only first 32 bytes of scratch space being accessed return(0, 32) // Direct return, skips Solidity's redundant copying to save gas } } /// @inheritdoc IDelegateRegistry function checkDelegateForERC1155(address to, address from, address contract_, uint256 tokenId, bytes32 rights) external view override returns (uint256 amount) { if (!_invalidFrom(from)) { amount = (_validateFrom(Hashes.allLocation(from, "", to), from) || _validateFrom(Hashes.contractLocation(from, "", to, contract_), from)) ? type(uint256).max : _loadDelegationUint(Hashes.erc1155Location(from, "", to, tokenId, contract_), Storage.POSITIONS_AMOUNT); if (!Ops.or(rights == "", amount == type(uint256).max)) { uint256 rightsBalance = (_validateFrom(Hashes.allLocation(from, rights, to), from) || _validateFrom(Hashes.contractLocation(from, rights, to, contract_), from)) ? type(uint256).max : _loadDelegationUint(Hashes.erc1155Location(from, rights, to, tokenId, contract_), Storage.POSITIONS_AMOUNT); amount = Ops.max(rightsBalance, amount); } } assembly ("memory-safe") { mstore(0, amount) // Only first 32 bytes of scratch space is accessed return(0, 32) // Direct return, skips Solidity's redundant copying to save gas } } /** * ----------- ENUMERATIONS ----------- */ /// @inheritdoc IDelegateRegistry function getIncomingDelegations(address to) external view override returns (Delegation[] memory delegations_) { delegations_ = _getValidDelegationsFromHashes(incomingDelegationHashes[to]); } /// @inheritdoc IDelegateRegistry function getOutgoingDelegations(address from) external view returns (Delegation[] memory delegations_) { delegations_ = _getValidDelegationsFromHashes(outgoingDelegationHashes[from]); } /// @inheritdoc IDelegateRegistry function getIncomingDelegationHashes(address to) external view returns (bytes32[] memory delegationHashes) { delegationHashes = _getValidDelegationHashesFromHashes(incomingDelegationHashes[to]); } /// @inheritdoc IDelegateRegistry function getOutgoingDelegationHashes(address from) external view returns (bytes32[] memory delegationHashes) { delegationHashes = _getValidDelegationHashesFromHashes(outgoingDelegationHashes[from]); } /// @inheritdoc IDelegateRegistry function getDelegationsFromHashes(bytes32[] calldata hashes) external view returns (Delegation[] memory delegations_) { delegations_ = new Delegation[](hashes.length); unchecked { for (uint256 i = 0; i < hashes.length; ++i) { bytes32 location = Hashes.location(hashes[i]); address from = _loadFrom(location); if (_invalidFrom(from)) { delegations_[i] = Delegation({type_: DelegationType.NONE, to: address(0), from: address(0), rights: "", amount: 0, contract_: address(0), tokenId: 0}); } else { (, address to, address contract_) = _loadDelegationAddresses(location); delegations_[i] = Delegation({ type_: Hashes.decodeType(hashes[i]), to: to, from: from, rights: _loadDelegationBytes32(location, Storage.POSITIONS_RIGHTS), amount: _loadDelegationUint(location, Storage.POSITIONS_AMOUNT), contract_: contract_, tokenId: _loadDelegationUint(location, Storage.POSITIONS_TOKEN_ID) }); } } } } /** * ----------- EXTERNAL STORAGE ACCESS ----------- */ function readSlot(bytes32 location) external view returns (bytes32 contents) { assembly { contents := sload(location) } } function readSlots(bytes32[] calldata locations) external view returns (bytes32[] memory contents) { uint256 length = locations.length; contents = new bytes32[](length); bytes32 tempLocation; bytes32 tempValue; unchecked { for (uint256 i = 0; i < length; ++i) { tempLocation = locations[i]; assembly { tempValue := sload(tempLocation) } contents[i] = tempValue; } } } /** * ----------- ERC165 ----------- */ /// @notice Query if a contract implements an ERC-165 interface /// @param interfaceId The interface identifier /// @return valid Whether the queried interface is supported function supportsInterface(bytes4 interfaceId) external pure returns (bool) { return Ops.or(interfaceId == type(IDelegateRegistry).interfaceId, interfaceId == 0x01ffc9a7); } /** * ----------- INTERNAL ----------- */ /// @dev Helper function to push new delegation hashes to the incoming and outgoing hashes mappings function _pushDelegationHashes(address from, address to, bytes32 delegationHash) internal { outgoingDelegationHashes[from].push(delegationHash); incomingDelegationHashes[to].push(delegationHash); } /// @dev Helper function that writes bytes32 data to delegation data location at array position function _writeDelegation(bytes32 location, uint256 position, bytes32 data) internal { assembly { sstore(add(location, position), data) } } /// @dev Helper function that writes uint256 data to delegation data location at array position function _writeDelegation(bytes32 location, uint256 position, uint256 data) internal { assembly { sstore(add(location, position), data) } } /// @dev Helper function that writes addresses according to the packing rule for delegation storage function _writeDelegationAddresses(bytes32 location, address from, address to, address contract_) internal { (bytes32 firstSlot, bytes32 secondSlot) = Storage.packAddresses(from, to, contract_); uint256 firstPacked = Storage.POSITIONS_FIRST_PACKED; uint256 secondPacked = Storage.POSITIONS_SECOND_PACKED; assembly { sstore(add(location, firstPacked), firstSlot) sstore(add(location, secondPacked), secondSlot) } } /// @dev Helper function that writes `from` while preserving the rest of the storage slot function _updateFrom(bytes32 location, address from) internal { uint256 firstPacked = Storage.POSITIONS_FIRST_PACKED; uint256 cleanAddress = Storage.CLEAN_ADDRESS; uint256 cleanUpper12Bytes = type(uint256).max << 160; assembly { let slot := and(sload(add(location, firstPacked)), cleanUpper12Bytes) sstore(add(location, firstPacked), or(slot, and(from, cleanAddress))) } } /// @dev Helper function that takes an array of delegation hashes and returns an array of Delegation structs with their onchain information function _getValidDelegationsFromHashes(bytes32[] storage hashes) internal view returns (Delegation[] memory delegations_) { uint256 count = 0; uint256 hashesLength = hashes.length; bytes32 hash; bytes32[] memory filteredHashes = new bytes32[](hashesLength); unchecked { for (uint256 i = 0; i < hashesLength; ++i) { hash = hashes[i]; if (_invalidFrom(_loadFrom(Hashes.location(hash)))) continue; filteredHashes[count++] = hash; } delegations_ = new Delegation[](count); bytes32 location; for (uint256 i = 0; i < count; ++i) { hash = filteredHashes[i]; location = Hashes.location(hash); (address from, address to, address contract_) = _loadDelegationAddresses(location); delegations_[i] = Delegation({ type_: Hashes.decodeType(hash), to: to, from: from, rights: _loadDelegationBytes32(location, Storage.POSITIONS_RIGHTS), amount: _loadDelegationUint(location, Storage.POSITIONS_AMOUNT), contract_: contract_, tokenId: _loadDelegationUint(location, Storage.POSITIONS_TOKEN_ID) }); } } } /// @dev Helper function that takes an array of delegation hashes and returns an array of valid delegation hashes function _getValidDelegationHashesFromHashes(bytes32[] storage hashes) internal view returns (bytes32[] memory validHashes) { uint256 count = 0; uint256 hashesLength = hashes.length; bytes32 hash; bytes32[] memory filteredHashes = new bytes32[](hashesLength); unchecked { for (uint256 i = 0; i < hashesLength; ++i) { hash = hashes[i]; if (_invalidFrom(_loadFrom(Hashes.location(hash)))) continue; filteredHashes[count++] = hash; } validHashes = new bytes32[](count); for (uint256 i = 0; i < count; ++i) { validHashes[i] = filteredHashes[i]; } } } /// @dev Helper function that loads delegation data from a particular array position and returns as bytes32 function _loadDelegationBytes32(bytes32 location, uint256 position) internal view returns (bytes32 data) { assembly { data := sload(add(location, position)) } } /// @dev Helper function that loads delegation data from a particular array position and returns as uint256 function _loadDelegationUint(bytes32 location, uint256 position) internal view returns (uint256 data) { assembly { data := sload(add(location, position)) } } // @dev Helper function that loads the from address from storage according to the packing rule for delegation storage function _loadFrom(bytes32 location) internal view returns (address) { bytes32 data; uint256 firstPacked = Storage.POSITIONS_FIRST_PACKED; assembly { data := sload(add(location, firstPacked)) } return Storage.unpackAddress(data); } /// @dev Helper function to establish whether a delegation is enabled function _validateFrom(bytes32 location, address from) internal view returns (bool) { return (from == _loadFrom(location)); } /// @dev Helper function that loads the address for the delegation according to the packing rule for delegation storage function _loadDelegationAddresses(bytes32 location) internal view returns (address from, address to, address contract_) { bytes32 firstSlot; bytes32 secondSlot; uint256 firstPacked = Storage.POSITIONS_FIRST_PACKED; uint256 secondPacked = Storage.POSITIONS_SECOND_PACKED; assembly { firstSlot := sload(add(location, firstPacked)) secondSlot := sload(add(location, secondPacked)) } (from, to, contract_) = Storage.unpackAddresses(firstSlot, secondSlot); } function _invalidFrom(address from) internal pure returns (bool) { return Ops.or(from == Storage.DELEGATION_EMPTY, from == Storage.DELEGATION_REVOKED); } }
// SPDX-License-Identifier: CC0-1.0 pragma solidity >=0.8.13; /** * @title IDelegateRegistry * @custom:version 2.0 * @custom:author foobar (0xfoobar) * @notice A standalone immutable registry storing delegated permissions from one address to another */ interface IDelegateRegistry { /// @notice Delegation type, NONE is used when a delegation does not exist or is revoked enum DelegationType { NONE, ALL, CONTRACT, ERC721, ERC20, ERC1155 } /// @notice Struct for returning delegations struct Delegation { DelegationType type_; address to; address from; bytes32 rights; address contract_; uint256 tokenId; uint256 amount; } /// @notice Emitted when an address delegates or revokes rights for their entire wallet event DelegateAll(address indexed from, address indexed to, bytes32 rights, bool enable); /// @notice Emitted when an address delegates or revokes rights for a contract address event DelegateContract(address indexed from, address indexed to, address indexed contract_, bytes32 rights, bool enable); /// @notice Emitted when an address delegates or revokes rights for an ERC721 tokenId event DelegateERC721(address indexed from, address indexed to, address indexed contract_, uint256 tokenId, bytes32 rights, bool enable); /// @notice Emitted when an address delegates or revokes rights for an amount of ERC20 tokens event DelegateERC20(address indexed from, address indexed to, address indexed contract_, bytes32 rights, uint256 amount); /// @notice Emitted when an address delegates or revokes rights for an amount of an ERC1155 tokenId event DelegateERC1155(address indexed from, address indexed to, address indexed contract_, uint256 tokenId, bytes32 rights, uint256 amount); /// @notice Thrown if multicall calldata is malformed error MulticallFailed(); /** * ----------- WRITE ----------- */ /** * @notice Call multiple functions in the current contract and return the data from all of them if they all succeed * @param data The encoded function data for each of the calls to make to this contract * @return results The results from each of the calls passed in via data */ function multicall(bytes[] calldata data) external payable returns (bytes[] memory results); /** * @notice Allow the delegate to act on behalf of `msg.sender` for all contracts * @param to The address to act as delegate * @param rights Specific subdelegation rights granted to the delegate, pass an empty bytestring to encompass all rights * @param enable Whether to enable or disable this delegation, true delegates and false revokes * @return delegationHash The unique identifier of the delegation */ function delegateAll(address to, bytes32 rights, bool enable) external payable returns (bytes32 delegationHash); /** * @notice Allow the delegate to act on behalf of `msg.sender` for a specific contract * @param to The address to act as delegate * @param contract_ The contract whose rights are being delegated * @param rights Specific subdelegation rights granted to the delegate, pass an empty bytestring to encompass all rights * @param enable Whether to enable or disable this delegation, true delegates and false revokes * @return delegationHash The unique identifier of the delegation */ function delegateContract(address to, address contract_, bytes32 rights, bool enable) external payable returns (bytes32 delegationHash); /** * @notice Allow the delegate to act on behalf of `msg.sender` for a specific ERC721 token * @param to The address to act as delegate * @param contract_ The contract whose rights are being delegated * @param tokenId The token id to delegate * @param rights Specific subdelegation rights granted to the delegate, pass an empty bytestring to encompass all rights * @param enable Whether to enable or disable this delegation, true delegates and false revokes * @return delegationHash The unique identifier of the delegation */ function delegateERC721(address to, address contract_, uint256 tokenId, bytes32 rights, bool enable) external payable returns (bytes32 delegationHash); /** * @notice Allow the delegate to act on behalf of `msg.sender` for a specific amount of ERC20 tokens * @dev The actual amount is not encoded in the hash, just the existence of a amount (since it is an upper bound) * @param to The address to act as delegate * @param contract_ The address for the fungible token contract * @param rights Specific subdelegation rights granted to the delegate, pass an empty bytestring to encompass all rights * @param amount The amount to delegate, > 0 delegates and 0 revokes * @return delegationHash The unique identifier of the delegation */ function delegateERC20(address to, address contract_, bytes32 rights, uint256 amount) external payable returns (bytes32 delegationHash); /** * @notice Allow the delegate to act on behalf of `msg.sender` for a specific amount of ERC1155 tokens * @dev The actual amount is not encoded in the hash, just the existence of a amount (since it is an upper bound) * @param to The address to act as delegate * @param contract_ The address of the contract that holds the token * @param tokenId The token id to delegate * @param rights Specific subdelegation rights granted to the delegate, pass an empty bytestring to encompass all rights * @param amount The amount of that token id to delegate, > 0 delegates and 0 revokes * @return delegationHash The unique identifier of the delegation */ function delegateERC1155(address to, address contract_, uint256 tokenId, bytes32 rights, uint256 amount) external payable returns (bytes32 delegationHash); /** * ----------- CHECKS ----------- */ /** * @notice Check if `to` is a delegate of `from` for the entire wallet * @param to The potential delegate address * @param from The potential address who delegated rights * @param rights Specific rights to check for, pass the zero value to ignore subdelegations and check full delegations only * @return valid Whether delegate is granted to act on the from's behalf */ function checkDelegateForAll(address to, address from, bytes32 rights) external view returns (bool); /** * @notice Check if `to` is a delegate of `from` for the specified `contract_` or the entire wallet * @param to The delegated address to check * @param contract_ The specific contract address being checked * @param from The cold wallet who issued the delegation * @param rights Specific rights to check for, pass the zero value to ignore subdelegations and check full delegations only * @return valid Whether delegate is granted to act on from's behalf for entire wallet or that specific contract */ function checkDelegateForContract(address to, address from, address contract_, bytes32 rights) external view returns (bool); /** * @notice Check if `to` is a delegate of `from` for the specific `contract` and `tokenId`, the entire `contract_`, or the entire wallet * @param to The delegated address to check * @param contract_ The specific contract address being checked * @param tokenId The token id for the token to delegating * @param from The wallet that issued the delegation * @param rights Specific rights to check for, pass the zero value to ignore subdelegations and check full delegations only * @return valid Whether delegate is granted to act on from's behalf for entire wallet, that contract, or that specific tokenId */ function checkDelegateForERC721(address to, address from, address contract_, uint256 tokenId, bytes32 rights) external view returns (bool); /** * @notice Returns the amount of ERC20 tokens the delegate is granted rights to act on the behalf of * @param to The delegated address to check * @param contract_ The address of the token contract * @param from The cold wallet who issued the delegation * @param rights Specific rights to check for, pass the zero value to ignore subdelegations and check full delegations only * @return balance The delegated balance, which will be 0 if the delegation does not exist */ function checkDelegateForERC20(address to, address from, address contract_, bytes32 rights) external view returns (uint256); /** * @notice Returns the amount of a ERC1155 tokens the delegate is granted rights to act on the behalf of * @param to The delegated address to check * @param contract_ The address of the token contract * @param tokenId The token id to check the delegated amount of * @param from The cold wallet who issued the delegation * @param rights Specific rights to check for, pass the zero value to ignore subdelegations and check full delegations only * @return balance The delegated balance, which will be 0 if the delegation does not exist */ function checkDelegateForERC1155(address to, address from, address contract_, uint256 tokenId, bytes32 rights) external view returns (uint256); /** * ----------- ENUMERATIONS ----------- */ /** * @notice Returns all enabled delegations a given delegate has received * @param to The address to retrieve delegations for * @return delegations Array of Delegation structs */ function getIncomingDelegations(address to) external view returns (Delegation[] memory delegations); /** * @notice Returns all enabled delegations an address has given out * @param from The address to retrieve delegations for * @return delegations Array of Delegation structs */ function getOutgoingDelegations(address from) external view returns (Delegation[] memory delegations); /** * @notice Returns all hashes associated with enabled delegations an address has received * @param to The address to retrieve incoming delegation hashes for * @return delegationHashes Array of delegation hashes */ function getIncomingDelegationHashes(address to) external view returns (bytes32[] memory delegationHashes); /** * @notice Returns all hashes associated with enabled delegations an address has given out * @param from The address to retrieve outgoing delegation hashes for * @return delegationHashes Array of delegation hashes */ function getOutgoingDelegationHashes(address from) external view returns (bytes32[] memory delegationHashes); /** * @notice Returns the delegations for a given array of delegation hashes * @param delegationHashes is an array of hashes that correspond to delegations * @return delegations Array of Delegation structs, return empty structs for nonexistent or revoked delegations */ function getDelegationsFromHashes(bytes32[] calldata delegationHashes) external view returns (Delegation[] memory delegations); /** * ----------- STORAGE ACCESS ----------- */ /** * @notice Allows external contracts to read arbitrary storage slots */ function readSlot(bytes32 location) external view returns (bytes32); /** * @notice Allows external contracts to read an arbitrary array of storage slots */ function readSlots(bytes32[] calldata locations) external view returns (bytes32[] memory); }
// SPDX-License-Identifier: CC0-1.0 pragma solidity ^0.8.21; import {IDelegateRegistry} from "../IDelegateRegistry.sol"; /** * @title Library for calculating the hashes and storage locations used in the delegate registry * * The encoding for the 5 types of delegate registry hashes should be as follows: * * ALL: keccak256(abi.encodePacked(rights, from, to)) * CONTRACT: keccak256(abi.encodePacked(rights, from, to, contract_)) * ERC721: keccak256(abi.encodePacked(rights, from, to, contract_, tokenId)) * ERC20: keccak256(abi.encodePacked(rights, from, to, contract_)) * ERC1155: keccak256(abi.encodePacked(rights, from, to, contract_, tokenId)) * * To avoid collisions between the hashes with respect to type, the hash is shifted left by one byte * and the last byte is then encoded with a unique number for the delegation type * */ library RegistryHashes { /// @dev Used to delete everything but the last byte of a 32 byte word with and(word, EXTRACT_LAST_BYTE) uint256 internal constant EXTRACT_LAST_BYTE = 0xff; /// @dev Constants for the delegate registry delegation type enumeration uint256 internal constant ALL_TYPE = 1; uint256 internal constant CONTRACT_TYPE = 2; uint256 internal constant ERC721_TYPE = 3; uint256 internal constant ERC20_TYPE = 4; uint256 internal constant ERC1155_TYPE = 5; /// @dev Constant for the location of the delegations array in the delegate registry, defined to be zero uint256 internal constant DELEGATION_SLOT = 0; /** * @notice Helper function to decode last byte of a delegation hash into its delegation type enum * @param inputHash The bytehash to decode the type from * @return decodedType The delegation type */ function decodeType(bytes32 inputHash) internal pure returns (IDelegateRegistry.DelegationType decodedType) { assembly { decodedType := and(inputHash, EXTRACT_LAST_BYTE) } } /** * @notice Helper function that computes the storage location of a particular delegation array * @dev Storage keys further down the array can be obtained by adding computedLocation with the element position * @dev Follows the solidity storage location encoding for a mapping(bytes32 => fixedArray) at the position of the delegationSlot * @param inputHash The bytehash to decode the type from * @return computedLocation is the storage key of the delegation array at position 0 */ function location(bytes32 inputHash) internal pure returns (bytes32 computedLocation) { assembly ("memory-safe") { // This block only allocates memory in the scratch space mstore(0, inputHash) mstore(32, DELEGATION_SLOT) computedLocation := keccak256(0, 64) // Run keccak256 over bytes in scratch space to obtain the storage key } } /** * @notice Helper function to compute delegation hash for `DelegationType.ALL` * @dev Equivalent to `keccak256(abi.encodePacked(rights, from, to))` then left-shift by 1 byte and write the delegation type to the cleaned last byte * @dev Will not revert if `from` or `to` are > uint160, any input larger than uint160 for `from` and `to` will be cleaned to its lower 20 bytes * @param from The address making the delegation * @param rights The rights specified by the delegation * @param to The address receiving the delegation * @return hash The delegation parameters encoded with ALL_TYPE */ function allHash(address from, bytes32 rights, address to) internal pure returns (bytes32 hash) { assembly ("memory-safe") { // This block only allocates memory after the free memory pointer let ptr := mload(64) // Load the free memory pointer // Lay out the variables from last to first, agnostic to upper 96 bits of address words. mstore(add(ptr, 40), to) mstore(add(ptr, 20), from) mstore(ptr, rights) hash := or(shl(8, keccak256(ptr, 72)), ALL_TYPE) // Keccak-hashes the packed encoding, left-shifts by one byte, then writes type to the lowest-order byte } } /** * @notice Helper function to compute delegation location for `DelegationType.ALL` * @dev Equivalent to `location(allHash(rights, from, to))` * @dev Will not revert if `from` or `to` are > uint160, any input larger than uint160 for `from` and `to` will be cleaned to its lower 20 bytes * @param from The address making the delegation * @param rights The rights specified by the delegation * @param to The address receiving the delegation * @return computedLocation The storage location of the all delegation with those parameters in the delegations mapping */ function allLocation(address from, bytes32 rights, address to) internal pure returns (bytes32 computedLocation) { assembly ("memory-safe") { // This block only allocates memory after the free memory pointer and in the scratch space let ptr := mload(64) // Load the free memory pointer // Lay out the variables from last to first, agnostic to upper 96 bits of address words. mstore(add(ptr, 40), to) mstore(add(ptr, 20), from) mstore(ptr, rights) mstore(0, or(shl(8, keccak256(ptr, 72)), ALL_TYPE)) // Computes `allHash`, then stores the result in scratch space mstore(32, DELEGATION_SLOT) computedLocation := keccak256(0, 64) // Runs keccak over the scratch space to obtain the storage key } } /** * @notice Helper function to compute delegation hash for `DelegationType.CONTRACT` * @dev Equivalent to keccak256(abi.encodePacked(rights, from, to, contract_)) left-shifted by 1 then last byte overwritten with CONTRACT_TYPE * @dev Will not revert if `from`, `to` or `contract_` are > uint160, these inputs will be cleaned to their lower 20 bytes * @param from The address making the delegation * @param rights The rights specified by the delegation * @param to The address receiving the delegation * @param contract_ The address of the contract specified by the delegation * @return hash The delegation parameters encoded with CONTRACT_TYPE */ function contractHash(address from, bytes32 rights, address to, address contract_) internal pure returns (bytes32 hash) { assembly ("memory-safe") { // This block only allocates memory after the free memory pointer let ptr := mload(64) // Load the free memory pointer // Lay out the variables from last to first, agnostic to upper 96 bits of address words. mstore(add(ptr, 60), contract_) mstore(add(ptr, 40), to) mstore(add(ptr, 20), from) mstore(ptr, rights) hash := or(shl(8, keccak256(ptr, 92)), CONTRACT_TYPE) // Keccak-hashes the packed encoding, left-shifts by one byte, then writes type to the lowest-order byte } } /** * @notice Helper function to compute delegation location for `DelegationType.CONTRACT` * @dev Equivalent to `location(contractHash(rights, from, to, contract_))` * @dev Will not revert if `from`, `to` or `contract_` are > uint160, these inputs will be cleaned to their lower 20 bytes * @param from The address making the delegation * @param rights The rights specified by the delegation * @param to The address receiving the delegation * @param contract_ The address of the contract specified by the delegation * @return computedLocation The storage location of the contract delegation with those parameters in the delegations mapping */ function contractLocation(address from, bytes32 rights, address to, address contract_) internal pure returns (bytes32 computedLocation) { assembly ("memory-safe") { // This block only allocates memory after the free memory pointer and in the scratch space let ptr := mload(64) // Load free memory pointer // Lay out the variables from last to first, agnostic to upper 96 bits of address words. mstore(add(ptr, 60), contract_) mstore(add(ptr, 40), to) mstore(add(ptr, 20), from) mstore(ptr, rights) mstore(0, or(shl(8, keccak256(ptr, 92)), CONTRACT_TYPE)) // Computes `contractHash`, then stores the result in scratch space mstore(32, DELEGATION_SLOT) computedLocation := keccak256(0, 64) // Runs keccak over the scratch space to obtain the storage key } } /** * @notice Helper function to compute delegation hash for `DelegationType.ERC721` * @dev Equivalent to `keccak256(abi.encodePacked(rights, from, to, contract_, tokenId)) left-shifted by 1 then last byte overwritten with ERC721_TYPE * @dev Will not revert if `from`, `to` or `contract_` are > uint160, these inputs will be cleaned to their lower 20 bytes * @param from The address making the delegation * @param rights The rights specified by the delegation * @param to The address receiving the delegation * @param tokenId The id of the token specified by the delegation * @param contract_ The address of the contract specified by the delegation * @return hash The delegation parameters encoded with ERC721_TYPE */ function erc721Hash(address from, bytes32 rights, address to, uint256 tokenId, address contract_) internal pure returns (bytes32 hash) { assembly ("memory-safe") { // This block only allocates memory after the free memory pointer let ptr := mload(64) // Cache the free memory pointer. // Lay out the variables from last to first, agnostic to upper 96 bits of address words. mstore(add(ptr, 92), tokenId) mstore(add(ptr, 60), contract_) mstore(add(ptr, 40), to) mstore(add(ptr, 20), from) mstore(ptr, rights) hash := or(shl(8, keccak256(ptr, 124)), ERC721_TYPE) // Keccak-hashes the packed encoding, left-shifts by one byte, then writes type to the lowest-order byte } } /** * @notice Helper function to compute delegation location for `DelegationType.ERC721` * @dev Equivalent to `location(ERC721Hash(rights, from, to, contract_, tokenId))` * @dev Will not revert if `from`, `to` or `contract_` are > uint160, these inputs will be cleaned to their lower 20 bytes * @param from The address making the delegation * @param rights The rights specified by the delegation * @param to The address receiving the delegation * @param tokenId The id of the ERC721 token * @param contract_ The address of the ERC721 token contract * @return computedLocation The storage location of the ERC721 delegation with those parameters in the delegations mapping */ function erc721Location(address from, bytes32 rights, address to, uint256 tokenId, address contract_) internal pure returns (bytes32 computedLocation) { assembly ("memory-safe") { // This block only allocates memory after the free memory pointer and in the scratch space let ptr := mload(64) // Cache the free memory pointer. // Lay out the variables from last to first, agnostic to upper 96 bits of address words. mstore(add(ptr, 92), tokenId) mstore(add(ptr, 60), contract_) mstore(add(ptr, 40), to) mstore(add(ptr, 20), from) mstore(ptr, rights) mstore(0, or(shl(8, keccak256(ptr, 124)), ERC721_TYPE)) // Computes erc721Hash, then stores the result in scratch space mstore(32, DELEGATION_SLOT) computedLocation := keccak256(0, 64) // Runs keccak256 over the scratch space to obtain the storage key } } /** * @notice Helper function to compute delegation hash for `DelegationType.ERC20` * @dev Equivalent to `keccak256(abi.encodePacked(rights, from, to, contract_))` with the last byte overwritten with ERC20_TYPE * @dev Will not revert if `from`, `to` or `contract_` are > uint160, these inputs will be cleaned to their lower 20 bytes * @param from The address making the delegation * @param rights The rights specified by the delegation * @param to The address receiving the delegation * @param contract_ The address of the ERC20 token contract * @return hash The parameters encoded with ERC20_TYPE */ function erc20Hash(address from, bytes32 rights, address to, address contract_) internal pure returns (bytes32 hash) { assembly ("memory-safe") { // This block only allocates memory after the free memory pointer let ptr := mload(64) // Load free memory pointer // Lay out the variables from last to first, agnostic to upper 96 bits of address words. mstore(add(ptr, 60), contract_) mstore(add(ptr, 40), to) mstore(add(ptr, 20), from) mstore(ptr, rights) hash := or(shl(8, keccak256(ptr, 92)), ERC20_TYPE) // Keccak-hashes the packed encoding, left-shifts by one byte, then writes type to the lowest-order byte } } /** * @notice Helper function to compute delegation location for `DelegationType.ERC20` * @dev Equivalent to `location(ERC20Hash(rights, from, to, contract_))` * @dev Will not revert if `from`, `to` or `contract_` are > uint160, these inputs will be cleaned to their lower 20 bytes * @param from The address making the delegation * @param rights The rights specified by the delegation * @param to The address receiving the delegation * @param contract_ The address of the ERC20 token contract * @return computedLocation The storage location of the ERC20 delegation with those parameters in the delegations mapping */ function erc20Location(address from, bytes32 rights, address to, address contract_) internal pure returns (bytes32 computedLocation) { assembly ("memory-safe") { // This block only allocates memory after the free memory pointer and in the scratch space let ptr := mload(64) // Loads the free memory pointer // Lay out the variables from last to first, agnostic to upper 96 bits of address words. mstore(add(ptr, 60), contract_) mstore(add(ptr, 40), to) mstore(add(ptr, 20), from) mstore(ptr, rights) mstore(0, or(shl(8, keccak256(ptr, 92)), ERC20_TYPE)) // Computes erc20Hash, then stores the result in scratch space mstore(32, DELEGATION_SLOT) computedLocation := keccak256(0, 64) // Runs keccak over the scratch space to obtain the storage key } } /** * @notice Helper function to compute delegation hash for `DelegationType.ERC1155` * @dev Equivalent to keccak256(abi.encodePacked(rights, from, to, contract_, tokenId)) left-shifted with the last byte overwritten with ERC1155_TYPE * @dev Will not revert if `from`, `to` or `contract_` are > uint160, these inputs will be cleaned to their lower 20 bytes * @param from The address making the delegation * @param rights The rights specified by the delegation * @param to The address receiving the delegation * @param tokenId The id of the ERC1155 token * @param contract_ The address of the ERC1155 token contract * @return hash The parameters encoded with ERC1155_TYPE */ function erc1155Hash(address from, bytes32 rights, address to, uint256 tokenId, address contract_) internal pure returns (bytes32 hash) { assembly ("memory-safe") { // This block only allocates memory after the free memory pointer let ptr := mload(64) // Load the free memory pointer. // Lay out the variables from last to first, agnostic to upper 96 bits of address words. mstore(add(ptr, 92), tokenId) mstore(add(ptr, 60), contract_) mstore(add(ptr, 40), to) mstore(add(ptr, 20), from) mstore(ptr, rights) hash := or(shl(8, keccak256(ptr, 124)), ERC1155_TYPE) // Keccak-hashes the packed encoding, left-shifts by one byte, then writes type to the lowest-order byte } } /** * @notice Helper function to compute delegation location for `DelegationType.ERC1155` * @dev Equivalent to `location(ERC1155Hash(rights, from, to, contract_, tokenId))` * @dev Will not revert if `from`, `to` or `contract_` are > uint160, these inputs will be cleaned to their lower 20 bytes * @param from The address making the delegation * @param rights The rights specified by the delegation * @param to The address receiving the delegation * @param tokenId The id of the ERC1155 token * @param contract_ The address of the ERC1155 token contract * @return computedLocation The storage location of the ERC1155 delegation with those parameters in the delegations mapping */ function erc1155Location(address from, bytes32 rights, address to, uint256 tokenId, address contract_) internal pure returns (bytes32 computedLocation) { assembly ("memory-safe") { // This block only allocates memory after the free memory pointer and in the scratch space let ptr := mload(64) // Cache the free memory pointer. // Lay out the variables from last to first, agnostic to upper 96 bits of address words. mstore(add(ptr, 92), tokenId) mstore(add(ptr, 60), contract_) mstore(add(ptr, 40), to) mstore(add(ptr, 20), from) mstore(ptr, rights) mstore(0, or(shl(8, keccak256(ptr, 124)), ERC1155_TYPE)) // Computes erc1155Hash, then stores the result in scratch space mstore(32, DELEGATION_SLOT) computedLocation := keccak256(0, 64) // Runs keccak over the scratch space to obtain the storage key } } }
// SPDX-License-Identifier: CC0-1.0 pragma solidity ^0.8.21; library RegistryStorage { /// @dev Standardizes `from` storage flags to prevent double-writes in the delegation in/outbox if the same delegation is revoked and rewritten address internal constant DELEGATION_EMPTY = address(0); address internal constant DELEGATION_REVOKED = address(1); /// @dev Standardizes storage positions of delegation data uint256 internal constant POSITIONS_FIRST_PACKED = 0; // | 4 bytes empty | first 8 bytes of contract address | 20 bytes of from address | uint256 internal constant POSITIONS_SECOND_PACKED = 1; // | last 12 bytes of contract address | 20 bytes of to address | uint256 internal constant POSITIONS_RIGHTS = 2; uint256 internal constant POSITIONS_TOKEN_ID = 3; uint256 internal constant POSITIONS_AMOUNT = 4; /// @dev Used to clean address types of dirty bits with `and(address, CLEAN_ADDRESS)` uint256 internal constant CLEAN_ADDRESS = 0x00ffffffffffffffffffffffffffffffffffffffff; /// @dev Used to clean everything but the first 8 bytes of an address uint256 internal constant CLEAN_FIRST8_BYTES_ADDRESS = 0xffffffffffffffff << 96; /// @dev Used to clean everything but the first 8 bytes of an address in the packed position uint256 internal constant CLEAN_PACKED8_BYTES_ADDRESS = 0xffffffffffffffff << 160; /** * @notice Helper function that packs from, to, and contract_ address to into the two slot configuration * @param from The address making the delegation * @param to The address receiving the delegation * @param contract_ The contract address associated with the delegation (optional) * @return firstPacked The firstPacked storage configured with the parameters * @return secondPacked The secondPacked storage configured with the parameters * @dev Will not revert if `from`, `to`, and `contract_` are > uint160, any inputs with dirty bits outside the last 20 bytes will be cleaned */ function packAddresses(address from, address to, address contract_) internal pure returns (bytes32 firstPacked, bytes32 secondPacked) { assembly { firstPacked := or(shl(64, and(contract_, CLEAN_FIRST8_BYTES_ADDRESS)), and(from, CLEAN_ADDRESS)) secondPacked := or(shl(160, contract_), and(to, CLEAN_ADDRESS)) } } /** * @notice Helper function that unpacks from, to, and contract_ address inside the firstPacked secondPacked storage configuration * @param firstPacked The firstPacked storage to be decoded * @param secondPacked The secondPacked storage to be decoded * @return from The address making the delegation * @return to The address receiving the delegation * @return contract_ The contract address associated with the delegation * @dev Will not revert if `from`, `to`, and `contract_` are > uint160, any inputs with dirty bits outside the last 20 bytes will be cleaned */ function unpackAddresses(bytes32 firstPacked, bytes32 secondPacked) internal pure returns (address from, address to, address contract_) { assembly { from := and(firstPacked, CLEAN_ADDRESS) to := and(secondPacked, CLEAN_ADDRESS) contract_ := or(shr(64, and(firstPacked, CLEAN_PACKED8_BYTES_ADDRESS)), shr(160, secondPacked)) } } /** * @notice Helper function that can unpack the from or to address from their respective packed slots in the registry * @param packedSlot The slot containing the from or to address * @return unpacked The `from` or `to` address * @dev Will not work if you want to obtain the contract address, use unpackAddresses */ function unpackAddress(bytes32 packedSlot) internal pure returns (address unpacked) { assembly { unpacked := and(packedSlot, CLEAN_ADDRESS) } } }
// SPDX-License-Identifier: CC0-1.0 pragma solidity ^0.8.21; library RegistryOps { /// @dev `x > y ? x : y`. function max(uint256 x, uint256 y) internal pure returns (uint256 z) { assembly { // `gt(y, x)` will evaluate to 1 if `y > x`, else 0. // // If `y > x`: // `x ^ ((x ^ y) * 1) = x ^ (x ^ y) = (x ^ x) ^ y = 0 ^ y = y`. // otherwise: // `x ^ ((x ^ y) * 0) = x ^ 0 = x`. z := xor(x, mul(xor(x, y), gt(y, x))) } } /// @dev `x & y`. function and(bool x, bool y) internal pure returns (bool z) { assembly { z := and(iszero(iszero(x)), iszero(iszero(y))) // Compiler cleans dirty booleans on the stack to 1, so do the same here } } /// @dev `x | y`. function or(bool x, bool y) internal pure returns (bool z) { assembly { z := or(iszero(iszero(x)), iszero(iszero(y))) // Compiler cleans dirty booleans on the stack to 1, so do the same here } } }
{ "remappings": [ "ds-test/=lib/forge-std/lib/ds-test/src/", "forge-std/=lib/forge-std/src/", "murky/=lib/murky/src/", "openzeppelin/=lib/openzeppelin-contracts/contracts/" ], "optimizer": { "enabled": true, "runs": 9999999 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "none", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "evmVersion": "paris", "viaIR": false, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"name":"MulticallFailed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"bytes32","name":"rights","type":"bytes32"},{"indexed":false,"internalType":"bool","name":"enable","type":"bool"}],"name":"DelegateAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"address","name":"contract_","type":"address"},{"indexed":false,"internalType":"bytes32","name":"rights","type":"bytes32"},{"indexed":false,"internalType":"bool","name":"enable","type":"bool"}],"name":"DelegateContract","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"address","name":"contract_","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"rights","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"DelegateERC1155","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"address","name":"contract_","type":"address"},{"indexed":false,"internalType":"bytes32","name":"rights","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"DelegateERC20","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"address","name":"contract_","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"rights","type":"bytes32"},{"indexed":false,"internalType":"bool","name":"enable","type":"bool"}],"name":"DelegateERC721","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"bytes32","name":"rights","type":"bytes32"}],"name":"checkDelegateForAll","outputs":[{"internalType":"bool","name":"valid","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"contract_","type":"address"},{"internalType":"bytes32","name":"rights","type":"bytes32"}],"name":"checkDelegateForContract","outputs":[{"internalType":"bool","name":"valid","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"contract_","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes32","name":"rights","type":"bytes32"}],"name":"checkDelegateForERC1155","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"contract_","type":"address"},{"internalType":"bytes32","name":"rights","type":"bytes32"}],"name":"checkDelegateForERC20","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"contract_","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes32","name":"rights","type":"bytes32"}],"name":"checkDelegateForERC721","outputs":[{"internalType":"bool","name":"valid","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"bytes32","name":"rights","type":"bytes32"},{"internalType":"bool","name":"enable","type":"bool"}],"name":"delegateAll","outputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"contract_","type":"address"},{"internalType":"bytes32","name":"rights","type":"bytes32"},{"internalType":"bool","name":"enable","type":"bool"}],"name":"delegateContract","outputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"contract_","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes32","name":"rights","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"delegateERC1155","outputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"contract_","type":"address"},{"internalType":"bytes32","name":"rights","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"delegateERC20","outputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"contract_","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes32","name":"rights","type":"bytes32"},{"internalType":"bool","name":"enable","type":"bool"}],"name":"delegateERC721","outputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"hashes","type":"bytes32[]"}],"name":"getDelegationsFromHashes","outputs":[{"components":[{"internalType":"enum IDelegateRegistry.DelegationType","name":"type_","type":"uint8"},{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"bytes32","name":"rights","type":"bytes32"},{"internalType":"address","name":"contract_","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct IDelegateRegistry.Delegation[]","name":"delegations_","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"getIncomingDelegationHashes","outputs":[{"internalType":"bytes32[]","name":"delegationHashes","type":"bytes32[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"getIncomingDelegations","outputs":[{"components":[{"internalType":"enum IDelegateRegistry.DelegationType","name":"type_","type":"uint8"},{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"bytes32","name":"rights","type":"bytes32"},{"internalType":"address","name":"contract_","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct IDelegateRegistry.Delegation[]","name":"delegations_","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"}],"name":"getOutgoingDelegationHashes","outputs":[{"internalType":"bytes32[]","name":"delegationHashes","type":"bytes32[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"}],"name":"getOutgoingDelegations","outputs":[{"components":[{"internalType":"enum IDelegateRegistry.DelegationType","name":"type_","type":"uint8"},{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"bytes32","name":"rights","type":"bytes32"},{"internalType":"address","name":"contract_","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct IDelegateRegistry.Delegation[]","name":"delegations_","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"multicall","outputs":[{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"location","type":"bytes32"}],"name":"readSlot","outputs":[{"internalType":"bytes32","name":"contents","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"locations","type":"bytes32[]"}],"name":"readSlots","outputs":[{"internalType":"bytes32[]","name":"contents","type":"bytes32[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"sweep","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b5061273e806100206000396000f3fe60806040526004361061015e5760003560e01c80638988eea9116100c0578063b9f3687411610074578063d90e73ab11610059578063d90e73ab14610383578063e839bd5314610396578063e8e834a9146103b657600080fd5b8063b9f3687414610343578063ba63c8171461036357600080fd5b8063ac9650d8116100a5578063ac9650d8146102f0578063b18e2bbb14610310578063b87058751461032357600080fd5b80638988eea9146102bd578063ab764683146102dd57600080fd5b806335faa416116101175780634705ed38116100fc5780634705ed381461025d57806351525e9a1461027d57806361451a301461029d57600080fd5b806335faa4161461021957806342f87c251461023057600080fd5b806301ffc9a71161014857806301ffc9a7146101b6578063063182a5146101e657806330ff31401461020657600080fd5b80623c2ba61461016357806301a920a014610189575b600080fd5b6101766101713660046120b4565b6103d5565b6040519081526020015b60405180910390f35b34801561019557600080fd5b506101a96101a43660046120f6565b610637565b6040516101809190612118565b3480156101c257600080fd5b506101d66101d136600461215c565b61066e565b6040519015158152602001610180565b3480156101f257600080fd5b506101a96102013660046120f6565b6106e1565b6101766102143660046121ae565b610712565b34801561022557600080fd5b5061022e6108f9565b005b34801561023c57600080fd5b5061025061024b3660046120f6565b610917565b6040516101809190612219565b34801561026957600080fd5b50610250610278366004612368565b610948565b34801561028957600080fd5b506102506102983660046120f6565b610bf0565b3480156102a957600080fd5b506101a96102b8366004612368565b610c21565b3480156102c957600080fd5b506101d66102d83660046123aa565b610cc6565b6101766102eb3660046123f5565b610dd8565b6103036102fe366004612368565b611056565b6040516101809190612442565b61017661031e366004612510565b61118d565b34801561032f57600080fd5b5061017661033e366004612567565b6113bd565b34801561034f57600080fd5b506101d661035e366004612567565b6115d8565b34801561036f57600080fd5b5061017661037e3660046123aa565b611767565b6101766103913660046125bc565b61192d565b3480156103a257600080fd5b506101d66103b1366004612609565b611b3f565b3480156103c257600080fd5b506101766103d1366004612645565b5490565b60408051603c810185905260288101869052336014820152838152605c902060081b6004176000818152602081905291909120805473ffffffffffffffffffffffffffffffffffffffff1683156105865773ffffffffffffffffffffffffffffffffffffffff81166104ec57336000818152600160208181526040808420805480850182559085528285200188905573ffffffffffffffffffffffffffffffffffffffff8c1680855260028352818520805480860182559086529290942090910187905589901b7bffffffffffffffff000000000000000000000000000000000000000016909217845560a088901b17908301556104d582600486910155565b84156104e7576104e782600287910155565b6105d4565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff82160161055d5781547fffffffffffffffffffffffff000000000000000000000000000000000000000016331782556104e782600486910155565b3373ffffffffffffffffffffffffffffffffffffffff8216036104e7576104e782600486910155565b3373ffffffffffffffffffffffffffffffffffffffff8216036105d45781547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001178255600060048301555b604080518681526020810186905273ffffffffffffffffffffffffffffffffffffffff80891692908a169133917f6ebd000dfc4dc9df04f723f827bae7694230795e8f22ed4af438e074cc982d1891015b60405180910390a45050949350505050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260016020526040902060609061066890611bc2565b92915050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000083169081147f5f68bc5a0000000000000000000000000000000000000000000000000000000090911417610668565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260026020526040902060609061066890611bc2565b60408051602881018590523360148201528381526048902060081b6001176000818152602081905291909120805473ffffffffffffffffffffffffffffffffffffffff1683156108555773ffffffffffffffffffffffffffffffffffffffff81166107eb57336000818152600160208181526040808420805480850182559085528285200188905573ffffffffffffffffffffffffffffffffffffffff8b16808552600283529084208054808501825590855291909320018690559184559083015584156107e6576107e682600287910155565b61089c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff8216016107e65781547fffffffffffffffffffffffff0000000000000000000000000000000000000000163317825561089c565b3373ffffffffffffffffffffffffffffffffffffffff82160361089c5781547fffffffffffffffffffffffff00000000000000000000000000000000000000001660011782555b60408051868152851515602082015273ffffffffffffffffffffffffffffffffffffffff88169133917fda3ef6410e30373a9137f83f9781a8129962b6882532b7c229de2e39de423227910160405180910390a350509392505050565b6000806000804770de1e80ea5a234fb5488fee2584251bc7e85af150565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260026020526040902060609061066890611d41565b60608167ffffffffffffffff8111156109635761096361265e565b6040519080825280602002602001820160405280156109e857816020015b6040805160e08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816109815790505b50905060005b82811015610be9576000610a25858584818110610a0d57610a0d61268d565b90506020020135600090815260208190526040902090565b90506000610a47825473ffffffffffffffffffffffffffffffffffffffff1690565b9050610a528161200f565b15610ab6576040805160e08101909152806000815260006020820181905260408201819052606082018190526080820181905260a0820181905260c0909101528451859085908110610aa657610aa661268d565b6020026020010181905250610bdf565b815460018301546040805160e08101825273ffffffffffffffffffffffffffffffffffffffff83169360a09390931c9290911c73ffffffffffffffff00000000000000000000000016919091179080610b278a8a89818110610b1a57610b1a61268d565b9050602002013560ff1690565b6005811115610b3857610b386121ea565b81526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff168152602001610b80866002015490565b81526020018273ffffffffffffffffffffffffffffffffffffffff168152602001610bac866003015490565b8152602001610bbc866004015490565b815250868681518110610bd157610bd161268d565b602002602001018190525050505b50506001016109ee565b5092915050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260016020526040902060609061066890611d41565b6060818067ffffffffffffffff811115610c3d57610c3d61265e565b604051908082528060200260200182016040528015610c66578160200160208202803683370190505b50915060008060005b83811015610cbc57868682818110610c8957610c8961268d565b9050602002013592508254915081858281518110610ca957610ca961268d565b6020908102919091010152600101610c6f565b5050505092915050565b6000610cd18461200f565b610dcc576040805160288101879052601481018690526000808252604890912060081b6001178152602081905220610d0a905b85612035565b80610d4a575060408051603c810185905260288101879052601481018690526000808252605c90912060081b6002178152602081905220610d4a90610d04565b9050801515821517610dcc576040805160288101879052601481018690528381526048902060081b6001176000908152602081905220610d8990610d04565b80610dc9575060408051603c81018590526028810187905260148101869052838152605c902060081b6002176000908152602081905220610dc990610d04565b90505b80151560005260206000f35b60408051605c8101859052603c810186905260288101879052336014820152838152607c902060081b6005176000818152602081905291909120805473ffffffffffffffffffffffffffffffffffffffff168315610f9c5773ffffffffffffffffffffffffffffffffffffffff8116610f0257336000818152600160208181526040808420805480850182559085528285200188905573ffffffffffffffffffffffffffffffffffffffff8d168085526002835281852080548086018255908652929094209091018790558a901b7bffffffffffffffff000000000000000000000000000000000000000016909217845560a089901b1790830155610edf82600388910155565b610eeb82600486910155565b8415610efd57610efd82600287910155565b610fea565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff821601610f735781547fffffffffffffffffffffffff00000000000000000000000000000000000000001633178255610efd82600486910155565b3373ffffffffffffffffffffffffffffffffffffffff821603610efd57610efd82600486910155565b3373ffffffffffffffffffffffffffffffffffffffff821603610fea5781547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001178255600060048301555b604080518781526020810187905290810185905273ffffffffffffffffffffffffffffffffffffffff80891691908a169033907f27ab1adc9bca76301ed7a691320766dfa4b4b1aa32c9e05cf789611be7f8c75f906060015b60405180910390a4505095945050505050565b60608167ffffffffffffffff8111156110715761107161265e565b6040519080825280602002602001820160405280156110a457816020015b606081526020019060019003908161108f5790505b5090506000805b8381101561118557308585838181106110c6576110c661268d565b90506020028101906110d891906126bc565b6040516110e6929190612721565b600060405180830381855af49150503d8060008114611121576040519150601f19603f3d011682016040523d82523d6000602084013e611126565b606091505b508483815181106111395761113961268d565b602090810291909101015291508161117d576040517f4d6a232800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001016110ab565b505092915050565b60408051605c8101859052603c810186905260288101879052336014820152838152607c902060081b6003176000818152602081905291909120805473ffffffffffffffffffffffffffffffffffffffff1683156113155773ffffffffffffffffffffffffffffffffffffffff81166112ab57336000818152600160208181526040808420805480850182559085528285200188905573ffffffffffffffffffffffffffffffffffffffff8d168085526002835281852080548086018255908652929094209091018790558a901b7bffffffffffffffff000000000000000000000000000000000000000016909217845560a089901b179083015561129482600388910155565b84156112a6576112a682600287910155565b61135c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff8216016112a65781547fffffffffffffffffffffffff0000000000000000000000000000000000000000163317825561135c565b3373ffffffffffffffffffffffffffffffffffffffff82160361135c5781547fffffffffffffffffffffffff00000000000000000000000000000000000000001660011782555b60408051878152602081018790528515159181019190915273ffffffffffffffffffffffffffffffffffffffff80891691908a169033907f15e7a1bdcd507dd632d797d38e60cc5a9c0749b9a63097a215c4d006126825c690606001611043565b60006113c88561200f565b6115ce576040805160288101889052601481018790526000808252604890912060081b6001178152602081905220611401905b86612035565b80611441575060408051603c810186905260288101889052601481018790526000808252605c90912060081b6002178152602081905220611441906113fb565b61148e5760408051605c8101859052603c810186905260288101889052601481018790526000808252607c90912060081b6005178152602081905220611489905b6004015490565b6114b0565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81148215176115ce576040805160288101889052601481018790528381526048902060081b60011760009081526020819052908120611513905b87612035565b80611553575060408051603c81018790526028810189905260148101889052848152605c902060081b60021760009081526020819052206115539061150d565b61159d5760408051605c8101869052603c81018790526028810189905260148101889052848152607c902060081b600517600090815260208190522061159890611482565b6115bf565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b90508181108282180281189150505b8060005260206000f35b60006115e38561200f565b610dcc576040805160288101889052601481018790526000808252604890912060081b600117815260208190522061161a906113fb565b8061165a575060408051603c810186905260288101889052601481018790526000808252605c90912060081b600217815260208190522061165a906113fb565b806116a1575060408051605c8101859052603c810186905260288101889052601481018790526000808252607c90912060081b60031781526020819052206116a1906113fb565b9050801515821517610dcc576040805160288101889052601481018790528381526048902060081b60011760009081526020819052206116e0906113fb565b80611720575060408051603c81018690526028810188905260148101879052838152605c902060081b6002176000908152602081905220611720906113fb565b80610dc9575060408051605c8101859052603c81018690526028810188905260148101879052838152607c902060081b6003176000908152602081905220610dc9906113fb565b60006117728461200f565b6115ce576040805160288101879052601481018690526000808252604890912060081b60011781526020819052206117a990610d04565b806117e9575060408051603c810185905260288101879052601481018690526000808252605c90912060081b60021781526020819052206117e990610d04565b61182c5760408051603c810185905260288101879052601481018690526000808252605c90912060081b600417815260208190522061182790611482565b61184e565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81148215176115ce576040805160288101879052601481018690528381526048902060081b600117600090815260208190529081206118af906113fb565b806118ef575060408051603c81018690526028810188905260148101879052848152605c902060081b60021760009081526020819052206118ef906113fb565b61159d5760408051603c81018690526028810188905260148101879052848152605c902060081b600417600090815260208190522061159890611482565b60408051603c810185905260288101869052336014820152838152605c902060081b6002176000818152602081905291909120805473ffffffffffffffffffffffffffffffffffffffff168315611aa25773ffffffffffffffffffffffffffffffffffffffff8116611a3857336000818152600160208181526040808420805480850182559085528285200188905573ffffffffffffffffffffffffffffffffffffffff8c1680855260028352818520805480860182559086529290942090910187905589901b7bffffffffffffffff000000000000000000000000000000000000000016909217845560a088901b17908301558415611a3357611a3382600287910155565b611ae9565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff821601611a335781547fffffffffffffffffffffffff00000000000000000000000000000000000000001633178255611ae9565b3373ffffffffffffffffffffffffffffffffffffffff821603611ae95781547fffffffffffffffffffffffff00000000000000000000000000000000000000001660011782555b60408051868152851515602082015273ffffffffffffffffffffffffffffffffffffffff80891692908a169133917f021be15e24de4afc43cfb5d0ba95ca38e0783571e05c12bbe6aece8842ae82df9101610625565b6000611b4a8361200f565b610dcc576040805160288101869052601481018590526000808252604890912060081b6001178152602081905220611b83905b84612035565b9050801515821517610dcc576040805160288101869052601481018590528381526048902060081b6001176000908152602081905220610dc990611b7d565b805460609060009081808267ffffffffffffffff811115611be557611be561265e565b604051908082528060200260200182016040528015611c0e578160200160208202803683370190505b50905060005b83811015611ca757868181548110611c2e57611c2e61268d565b90600052602060002001549250611c75611c70611c5685600090815260208190526040902090565b5473ffffffffffffffffffffffffffffffffffffffff1690565b61200f565b611c9f5782828680600101975081518110611c9257611c9261268d565b6020026020010181815250505b600101611c14565b508367ffffffffffffffff811115611cc157611cc161265e565b604051908082528060200260200182016040528015611cea578160200160208202803683370190505b50945060005b84811015611d3757818181518110611d0a57611d0a61268d565b6020026020010151868281518110611d2457611d2461268d565b6020908102919091010152600101611cf0565b5050505050919050565b805460609060009081808267ffffffffffffffff811115611d6457611d6461265e565b604051908082528060200260200182016040528015611d8d578160200160208202803683370190505b50905060005b83811015611e0757868181548110611dad57611dad61268d565b90600052602060002001549250611dd5611c70611c5685600090815260208190526040902090565b611dff5782828680600101975081518110611df257611df261268d565b6020026020010181815250505b600101611d93565b508367ffffffffffffffff811115611e2157611e2161265e565b604051908082528060200260200182016040528015611ea657816020015b6040805160e08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181611e3f5790505b5094506000805b8581101561200457828181518110611ec757611ec761268d565b60200260200101519350611ee684600090815260208190526040902090565b805460018201546040805160e08101825293955073ffffffffffffffffffffffffffffffffffffffff808416949083169360a09390931c9290911c73ffffffffffffffff0000000000000000000000001691909117908060ff89166005811115611f5257611f526121ea565b81526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff168152602001611f9a876002015490565b81526020018273ffffffffffffffffffffffffffffffffffffffff168152602001611fc6876003015490565b8152602001611fd6876004015490565b8152508a8581518110611feb57611feb61268d565b6020026020010181905250505050806001019050611ead565b505050505050919050565b6000600173ffffffffffffffffffffffffffffffffffffffff8316908114901517610668565b6000612055835473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614905092915050565b803573ffffffffffffffffffffffffffffffffffffffff811681146120af57600080fd5b919050565b600080600080608085870312156120ca57600080fd5b6120d38561208b565b93506120e16020860161208b565b93969395505050506040820135916060013590565b60006020828403121561210857600080fd5b6121118261208b565b9392505050565b6020808252825182820181905260009190848201906040850190845b8181101561215057835183529284019291840191600101612134565b50909695505050505050565b60006020828403121561216e57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461211157600080fd5b803580151581146120af57600080fd5b6000806000606084860312156121c357600080fd5b6121cc8461208b565b9250602084013591506121e16040850161219e565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208082528251828201819052600091906040908185019086840185805b8381101561230e578251805160068110612278577f4e487b710000000000000000000000000000000000000000000000000000000084526021600452602484fd5b86528088015173ffffffffffffffffffffffffffffffffffffffff1688870152868101516122bd8888018273ffffffffffffffffffffffffffffffffffffffff169052565b506060818101519087015260808082015173ffffffffffffffffffffffffffffffffffffffff169087015260a0808201519087015260c0908101519086015260e09094019391860191600101612237565b509298975050505050505050565b60008083601f84011261232e57600080fd5b50813567ffffffffffffffff81111561234657600080fd5b6020830191508360208260051b850101111561236157600080fd5b9250929050565b6000806020838503121561237b57600080fd5b823567ffffffffffffffff81111561239257600080fd5b61239e8582860161231c565b90969095509350505050565b600080600080608085870312156123c057600080fd5b6123c98561208b565b93506123d76020860161208b565b92506123e56040860161208b565b9396929550929360600135925050565b600080600080600060a0868803121561240d57600080fd5b6124168661208b565b94506124246020870161208b565b94979496505050506040830135926060810135926080909101359150565b6000602080830181845280855180835260408601915060408160051b87010192508387016000805b83811015612502577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc089870301855282518051808852835b818110156124bd578281018a01518982018b015289016124a2565b508781018901849052601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690960187019550938601939186019160010161246a565b509398975050505050505050565b600080600080600060a0868803121561252857600080fd5b6125318661208b565b945061253f6020870161208b565b9350604086013592506060860135915061255b6080870161219e565b90509295509295909350565b600080600080600060a0868803121561257f57600080fd5b6125888661208b565b94506125966020870161208b565b93506125a46040870161208b565b94979396509394606081013594506080013592915050565b600080600080608085870312156125d257600080fd5b6125db8561208b565b93506125e96020860161208b565b9250604085013591506125fe6060860161219e565b905092959194509250565b60008060006060848603121561261e57600080fd5b6126278461208b565b92506126356020850161208b565b9150604084013590509250925092565b60006020828403121561265757600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126126f157600080fd5b83018035915067ffffffffffffffff82111561270c57600080fd5b60200191503681900382131561236157600080fd5b818382376000910190815291905056fea164736f6c6343000815000a
Deployed Bytecode
0x60806040526004361061015e5760003560e01c80638988eea9116100c0578063b9f3687411610074578063d90e73ab11610059578063d90e73ab14610383578063e839bd5314610396578063e8e834a9146103b657600080fd5b8063b9f3687414610343578063ba63c8171461036357600080fd5b8063ac9650d8116100a5578063ac9650d8146102f0578063b18e2bbb14610310578063b87058751461032357600080fd5b80638988eea9146102bd578063ab764683146102dd57600080fd5b806335faa416116101175780634705ed38116100fc5780634705ed381461025d57806351525e9a1461027d57806361451a301461029d57600080fd5b806335faa4161461021957806342f87c251461023057600080fd5b806301ffc9a71161014857806301ffc9a7146101b6578063063182a5146101e657806330ff31401461020657600080fd5b80623c2ba61461016357806301a920a014610189575b600080fd5b6101766101713660046120b4565b6103d5565b6040519081526020015b60405180910390f35b34801561019557600080fd5b506101a96101a43660046120f6565b610637565b6040516101809190612118565b3480156101c257600080fd5b506101d66101d136600461215c565b61066e565b6040519015158152602001610180565b3480156101f257600080fd5b506101a96102013660046120f6565b6106e1565b6101766102143660046121ae565b610712565b34801561022557600080fd5b5061022e6108f9565b005b34801561023c57600080fd5b5061025061024b3660046120f6565b610917565b6040516101809190612219565b34801561026957600080fd5b50610250610278366004612368565b610948565b34801561028957600080fd5b506102506102983660046120f6565b610bf0565b3480156102a957600080fd5b506101a96102b8366004612368565b610c21565b3480156102c957600080fd5b506101d66102d83660046123aa565b610cc6565b6101766102eb3660046123f5565b610dd8565b6103036102fe366004612368565b611056565b6040516101809190612442565b61017661031e366004612510565b61118d565b34801561032f57600080fd5b5061017661033e366004612567565b6113bd565b34801561034f57600080fd5b506101d661035e366004612567565b6115d8565b34801561036f57600080fd5b5061017661037e3660046123aa565b611767565b6101766103913660046125bc565b61192d565b3480156103a257600080fd5b506101d66103b1366004612609565b611b3f565b3480156103c257600080fd5b506101766103d1366004612645565b5490565b60408051603c810185905260288101869052336014820152838152605c902060081b6004176000818152602081905291909120805473ffffffffffffffffffffffffffffffffffffffff1683156105865773ffffffffffffffffffffffffffffffffffffffff81166104ec57336000818152600160208181526040808420805480850182559085528285200188905573ffffffffffffffffffffffffffffffffffffffff8c1680855260028352818520805480860182559086529290942090910187905589901b7bffffffffffffffff000000000000000000000000000000000000000016909217845560a088901b17908301556104d582600486910155565b84156104e7576104e782600287910155565b6105d4565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff82160161055d5781547fffffffffffffffffffffffff000000000000000000000000000000000000000016331782556104e782600486910155565b3373ffffffffffffffffffffffffffffffffffffffff8216036104e7576104e782600486910155565b3373ffffffffffffffffffffffffffffffffffffffff8216036105d45781547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001178255600060048301555b604080518681526020810186905273ffffffffffffffffffffffffffffffffffffffff80891692908a169133917f6ebd000dfc4dc9df04f723f827bae7694230795e8f22ed4af438e074cc982d1891015b60405180910390a45050949350505050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260016020526040902060609061066890611bc2565b92915050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000083169081147f5f68bc5a0000000000000000000000000000000000000000000000000000000090911417610668565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260026020526040902060609061066890611bc2565b60408051602881018590523360148201528381526048902060081b6001176000818152602081905291909120805473ffffffffffffffffffffffffffffffffffffffff1683156108555773ffffffffffffffffffffffffffffffffffffffff81166107eb57336000818152600160208181526040808420805480850182559085528285200188905573ffffffffffffffffffffffffffffffffffffffff8b16808552600283529084208054808501825590855291909320018690559184559083015584156107e6576107e682600287910155565b61089c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff8216016107e65781547fffffffffffffffffffffffff0000000000000000000000000000000000000000163317825561089c565b3373ffffffffffffffffffffffffffffffffffffffff82160361089c5781547fffffffffffffffffffffffff00000000000000000000000000000000000000001660011782555b60408051868152851515602082015273ffffffffffffffffffffffffffffffffffffffff88169133917fda3ef6410e30373a9137f83f9781a8129962b6882532b7c229de2e39de423227910160405180910390a350509392505050565b6000806000804770de1e80ea5a234fb5488fee2584251bc7e85af150565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260026020526040902060609061066890611d41565b60608167ffffffffffffffff8111156109635761096361265e565b6040519080825280602002602001820160405280156109e857816020015b6040805160e08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816109815790505b50905060005b82811015610be9576000610a25858584818110610a0d57610a0d61268d565b90506020020135600090815260208190526040902090565b90506000610a47825473ffffffffffffffffffffffffffffffffffffffff1690565b9050610a528161200f565b15610ab6576040805160e08101909152806000815260006020820181905260408201819052606082018190526080820181905260a0820181905260c0909101528451859085908110610aa657610aa661268d565b6020026020010181905250610bdf565b815460018301546040805160e08101825273ffffffffffffffffffffffffffffffffffffffff83169360a09390931c9290911c73ffffffffffffffff00000000000000000000000016919091179080610b278a8a89818110610b1a57610b1a61268d565b9050602002013560ff1690565b6005811115610b3857610b386121ea565b81526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff168152602001610b80866002015490565b81526020018273ffffffffffffffffffffffffffffffffffffffff168152602001610bac866003015490565b8152602001610bbc866004015490565b815250868681518110610bd157610bd161268d565b602002602001018190525050505b50506001016109ee565b5092915050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260016020526040902060609061066890611d41565b6060818067ffffffffffffffff811115610c3d57610c3d61265e565b604051908082528060200260200182016040528015610c66578160200160208202803683370190505b50915060008060005b83811015610cbc57868682818110610c8957610c8961268d565b9050602002013592508254915081858281518110610ca957610ca961268d565b6020908102919091010152600101610c6f565b5050505092915050565b6000610cd18461200f565b610dcc576040805160288101879052601481018690526000808252604890912060081b6001178152602081905220610d0a905b85612035565b80610d4a575060408051603c810185905260288101879052601481018690526000808252605c90912060081b6002178152602081905220610d4a90610d04565b9050801515821517610dcc576040805160288101879052601481018690528381526048902060081b6001176000908152602081905220610d8990610d04565b80610dc9575060408051603c81018590526028810187905260148101869052838152605c902060081b6002176000908152602081905220610dc990610d04565b90505b80151560005260206000f35b60408051605c8101859052603c810186905260288101879052336014820152838152607c902060081b6005176000818152602081905291909120805473ffffffffffffffffffffffffffffffffffffffff168315610f9c5773ffffffffffffffffffffffffffffffffffffffff8116610f0257336000818152600160208181526040808420805480850182559085528285200188905573ffffffffffffffffffffffffffffffffffffffff8d168085526002835281852080548086018255908652929094209091018790558a901b7bffffffffffffffff000000000000000000000000000000000000000016909217845560a089901b1790830155610edf82600388910155565b610eeb82600486910155565b8415610efd57610efd82600287910155565b610fea565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff821601610f735781547fffffffffffffffffffffffff00000000000000000000000000000000000000001633178255610efd82600486910155565b3373ffffffffffffffffffffffffffffffffffffffff821603610efd57610efd82600486910155565b3373ffffffffffffffffffffffffffffffffffffffff821603610fea5781547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001178255600060048301555b604080518781526020810187905290810185905273ffffffffffffffffffffffffffffffffffffffff80891691908a169033907f27ab1adc9bca76301ed7a691320766dfa4b4b1aa32c9e05cf789611be7f8c75f906060015b60405180910390a4505095945050505050565b60608167ffffffffffffffff8111156110715761107161265e565b6040519080825280602002602001820160405280156110a457816020015b606081526020019060019003908161108f5790505b5090506000805b8381101561118557308585838181106110c6576110c661268d565b90506020028101906110d891906126bc565b6040516110e6929190612721565b600060405180830381855af49150503d8060008114611121576040519150601f19603f3d011682016040523d82523d6000602084013e611126565b606091505b508483815181106111395761113961268d565b602090810291909101015291508161117d576040517f4d6a232800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001016110ab565b505092915050565b60408051605c8101859052603c810186905260288101879052336014820152838152607c902060081b6003176000818152602081905291909120805473ffffffffffffffffffffffffffffffffffffffff1683156113155773ffffffffffffffffffffffffffffffffffffffff81166112ab57336000818152600160208181526040808420805480850182559085528285200188905573ffffffffffffffffffffffffffffffffffffffff8d168085526002835281852080548086018255908652929094209091018790558a901b7bffffffffffffffff000000000000000000000000000000000000000016909217845560a089901b179083015561129482600388910155565b84156112a6576112a682600287910155565b61135c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff8216016112a65781547fffffffffffffffffffffffff0000000000000000000000000000000000000000163317825561135c565b3373ffffffffffffffffffffffffffffffffffffffff82160361135c5781547fffffffffffffffffffffffff00000000000000000000000000000000000000001660011782555b60408051878152602081018790528515159181019190915273ffffffffffffffffffffffffffffffffffffffff80891691908a169033907f15e7a1bdcd507dd632d797d38e60cc5a9c0749b9a63097a215c4d006126825c690606001611043565b60006113c88561200f565b6115ce576040805160288101889052601481018790526000808252604890912060081b6001178152602081905220611401905b86612035565b80611441575060408051603c810186905260288101889052601481018790526000808252605c90912060081b6002178152602081905220611441906113fb565b61148e5760408051605c8101859052603c810186905260288101889052601481018790526000808252607c90912060081b6005178152602081905220611489905b6004015490565b6114b0565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81148215176115ce576040805160288101889052601481018790528381526048902060081b60011760009081526020819052908120611513905b87612035565b80611553575060408051603c81018790526028810189905260148101889052848152605c902060081b60021760009081526020819052206115539061150d565b61159d5760408051605c8101869052603c81018790526028810189905260148101889052848152607c902060081b600517600090815260208190522061159890611482565b6115bf565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b90508181108282180281189150505b8060005260206000f35b60006115e38561200f565b610dcc576040805160288101889052601481018790526000808252604890912060081b600117815260208190522061161a906113fb565b8061165a575060408051603c810186905260288101889052601481018790526000808252605c90912060081b600217815260208190522061165a906113fb565b806116a1575060408051605c8101859052603c810186905260288101889052601481018790526000808252607c90912060081b60031781526020819052206116a1906113fb565b9050801515821517610dcc576040805160288101889052601481018790528381526048902060081b60011760009081526020819052206116e0906113fb565b80611720575060408051603c81018690526028810188905260148101879052838152605c902060081b6002176000908152602081905220611720906113fb565b80610dc9575060408051605c8101859052603c81018690526028810188905260148101879052838152607c902060081b6003176000908152602081905220610dc9906113fb565b60006117728461200f565b6115ce576040805160288101879052601481018690526000808252604890912060081b60011781526020819052206117a990610d04565b806117e9575060408051603c810185905260288101879052601481018690526000808252605c90912060081b60021781526020819052206117e990610d04565b61182c5760408051603c810185905260288101879052601481018690526000808252605c90912060081b600417815260208190522061182790611482565b61184e565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81148215176115ce576040805160288101879052601481018690528381526048902060081b600117600090815260208190529081206118af906113fb565b806118ef575060408051603c81018690526028810188905260148101879052848152605c902060081b60021760009081526020819052206118ef906113fb565b61159d5760408051603c81018690526028810188905260148101879052848152605c902060081b600417600090815260208190522061159890611482565b60408051603c810185905260288101869052336014820152838152605c902060081b6002176000818152602081905291909120805473ffffffffffffffffffffffffffffffffffffffff168315611aa25773ffffffffffffffffffffffffffffffffffffffff8116611a3857336000818152600160208181526040808420805480850182559085528285200188905573ffffffffffffffffffffffffffffffffffffffff8c1680855260028352818520805480860182559086529290942090910187905589901b7bffffffffffffffff000000000000000000000000000000000000000016909217845560a088901b17908301558415611a3357611a3382600287910155565b611ae9565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff821601611a335781547fffffffffffffffffffffffff00000000000000000000000000000000000000001633178255611ae9565b3373ffffffffffffffffffffffffffffffffffffffff821603611ae95781547fffffffffffffffffffffffff00000000000000000000000000000000000000001660011782555b60408051868152851515602082015273ffffffffffffffffffffffffffffffffffffffff80891692908a169133917f021be15e24de4afc43cfb5d0ba95ca38e0783571e05c12bbe6aece8842ae82df9101610625565b6000611b4a8361200f565b610dcc576040805160288101869052601481018590526000808252604890912060081b6001178152602081905220611b83905b84612035565b9050801515821517610dcc576040805160288101869052601481018590528381526048902060081b6001176000908152602081905220610dc990611b7d565b805460609060009081808267ffffffffffffffff811115611be557611be561265e565b604051908082528060200260200182016040528015611c0e578160200160208202803683370190505b50905060005b83811015611ca757868181548110611c2e57611c2e61268d565b90600052602060002001549250611c75611c70611c5685600090815260208190526040902090565b5473ffffffffffffffffffffffffffffffffffffffff1690565b61200f565b611c9f5782828680600101975081518110611c9257611c9261268d565b6020026020010181815250505b600101611c14565b508367ffffffffffffffff811115611cc157611cc161265e565b604051908082528060200260200182016040528015611cea578160200160208202803683370190505b50945060005b84811015611d3757818181518110611d0a57611d0a61268d565b6020026020010151868281518110611d2457611d2461268d565b6020908102919091010152600101611cf0565b5050505050919050565b805460609060009081808267ffffffffffffffff811115611d6457611d6461265e565b604051908082528060200260200182016040528015611d8d578160200160208202803683370190505b50905060005b83811015611e0757868181548110611dad57611dad61268d565b90600052602060002001549250611dd5611c70611c5685600090815260208190526040902090565b611dff5782828680600101975081518110611df257611df261268d565b6020026020010181815250505b600101611d93565b508367ffffffffffffffff811115611e2157611e2161265e565b604051908082528060200260200182016040528015611ea657816020015b6040805160e08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181611e3f5790505b5094506000805b8581101561200457828181518110611ec757611ec761268d565b60200260200101519350611ee684600090815260208190526040902090565b805460018201546040805160e08101825293955073ffffffffffffffffffffffffffffffffffffffff808416949083169360a09390931c9290911c73ffffffffffffffff0000000000000000000000001691909117908060ff89166005811115611f5257611f526121ea565b81526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff168152602001611f9a876002015490565b81526020018273ffffffffffffffffffffffffffffffffffffffff168152602001611fc6876003015490565b8152602001611fd6876004015490565b8152508a8581518110611feb57611feb61268d565b6020026020010181905250505050806001019050611ead565b505050505050919050565b6000600173ffffffffffffffffffffffffffffffffffffffff8316908114901517610668565b6000612055835473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614905092915050565b803573ffffffffffffffffffffffffffffffffffffffff811681146120af57600080fd5b919050565b600080600080608085870312156120ca57600080fd5b6120d38561208b565b93506120e16020860161208b565b93969395505050506040820135916060013590565b60006020828403121561210857600080fd5b6121118261208b565b9392505050565b6020808252825182820181905260009190848201906040850190845b8181101561215057835183529284019291840191600101612134565b50909695505050505050565b60006020828403121561216e57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461211157600080fd5b803580151581146120af57600080fd5b6000806000606084860312156121c357600080fd5b6121cc8461208b565b9250602084013591506121e16040850161219e565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208082528251828201819052600091906040908185019086840185805b8381101561230e578251805160068110612278577f4e487b710000000000000000000000000000000000000000000000000000000084526021600452602484fd5b86528088015173ffffffffffffffffffffffffffffffffffffffff1688870152868101516122bd8888018273ffffffffffffffffffffffffffffffffffffffff169052565b506060818101519087015260808082015173ffffffffffffffffffffffffffffffffffffffff169087015260a0808201519087015260c0908101519086015260e09094019391860191600101612237565b509298975050505050505050565b60008083601f84011261232e57600080fd5b50813567ffffffffffffffff81111561234657600080fd5b6020830191508360208260051b850101111561236157600080fd5b9250929050565b6000806020838503121561237b57600080fd5b823567ffffffffffffffff81111561239257600080fd5b61239e8582860161231c565b90969095509350505050565b600080600080608085870312156123c057600080fd5b6123c98561208b565b93506123d76020860161208b565b92506123e56040860161208b565b9396929550929360600135925050565b600080600080600060a0868803121561240d57600080fd5b6124168661208b565b94506124246020870161208b565b94979496505050506040830135926060810135926080909101359150565b6000602080830181845280855180835260408601915060408160051b87010192508387016000805b83811015612502577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc089870301855282518051808852835b818110156124bd578281018a01518982018b015289016124a2565b508781018901849052601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690960187019550938601939186019160010161246a565b509398975050505050505050565b600080600080600060a0868803121561252857600080fd5b6125318661208b565b945061253f6020870161208b565b9350604086013592506060860135915061255b6080870161219e565b90509295509295909350565b600080600080600060a0868803121561257f57600080fd5b6125888661208b565b94506125966020870161208b565b93506125a46040870161208b565b94979396509394606081013594506080013592915050565b600080600080608085870312156125d257600080fd5b6125db8561208b565b93506125e96020860161208b565b9250604085013591506125fe6060860161219e565b905092959194509250565b60008060006060848603121561261e57600080fd5b6126278461208b565b92506126356020850161208b565b9150604084013590509250925092565b60006020828403121561265757600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126126f157600080fd5b83018035915067ffffffffffffffff82111561270c57600080fd5b60200191503681900382131561236157600080fd5b818382376000910190815291905056fea164736f6c6343000815000a
Deployed Bytecode Sourcemap
584:22865:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4842:1318;;;;;;:::i;:::-;;:::i;:::-;;;763:25:5;;;751:2;736:18;4842:1318:0;;;;;;;;14200:212;;;;;;;;;;-1:-1:-1;14200:212:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;16734:185::-;;;;;;;;;;-1:-1:-1;16734:185:0;;;;;:::i;:::-;;:::i;:::-;;;2129:14:5;;2122:22;2104:41;;2092:2;2077:18;16734:185:0;1964:187:5;13948:208:0;;;;;;;;;;-1:-1:-1;13948:208:0;;;;;:::i;:::-;;:::i;1788:901::-;;;;;;:::i;:::-;;:::i;7689:330::-;;;;;;;;;;;;;:::i;:::-;;13461:202;;;;;;;;;;-1:-1:-1;13461:202:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;14456:1269::-;;;;;;;;;;-1:-1:-1;14456:1269:0;;;;;:::i;:::-;;:::i;13707:197::-;;;;;;;;;;-1:-1:-1;13707:197:0;;;;;:::i;:::-;;:::i;15961:527::-;;;;;;;;;;-1:-1:-1;15961:527:0;;;;;:::i;:::-;;:::i;8835:879::-;;;;;;;;;;-1:-1:-1;8835:879:0;;;;;:::i;:::-;;:::i;6204:1440::-;;;;;;:::i;:::-;;:::i;1264:480::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;3733:1066::-;;;;;;:::i;:::-;;:::i;12129:1227::-;;;;;;;;;;-1:-1:-1;12129:1227:0;;;;;:::i;:::-;;:::i;9758:1094::-;;;;;;;;;;-1:-1:-1;9758:1094:0;;;;;:::i;:::-;;:::i;10896:1189::-;;;;;;;;;;-1:-1:-1;10896:1189:0;;;;;:::i;:::-;;:::i;2733:956::-;;;;;;:::i;:::-;;:::i;8118:673::-;;;;;;;;;;-1:-1:-1;8118:673:0;;;;;:::i;:::-;;:::i;15802:153::-;;;;;;;;;;-1:-1:-1;15802:153:0;;;;;:::i;:::-;15924:15;;15802:153;4842:1318;12857:2:2;12851:9;;13018:2;13009:12;;13002:31;;;13062:2;13053:12;;13046:24;;;5011:10:0;-1:-1:-1;13090:12:2;;13083:26;13122:19;;;13187:2;13172:18;;13169:1;13165:26;13193:10;13162:42;-1:-1:-1;2700:20:2;;;-1:-1:-1;2733:27:2;;;2793:16;;;;22299:33:0;;3883:13:4;3867:30;5159:11:0;;5155:928;;5190:38;;;5186:699;;5270:10;17186:30;;;;:24;:30;;;;;;;;:51;;;;;;;;;;;;;;;;;:30;17247:28;;;;;:24;:28;;;;;:49;;;;;;;;;;;;;;;;;;;;2216:51:4;;;;;2213:81;;;18327:45:0;;2330:3:4;2326:19;;;2323:47;18392:27:0;;;18385:47;5389:60;5406:8;865:1:4;5442:6:0;17811:23;;17804:37;17686:171;5389:60;5471:12;;5467:78;;5485:60;5502:8;759:1:4;5538:6:0;17811:23;;17804:37;17686:171;5485:60;5155:928;;5186:699;5570:40;;;;;5566:319;;18837:33;;18764:24;18833:57;5652:10;18938:33;18903:69;;5681:60;5698:8;865:1:4;5734:6:0;17811:23;;17804:37;17686:171;5566:319;5780:10;5766:24;;;;5762:123;;5810:60;5827:8;865:1:4;5863:6:0;17811:23;;17804:37;17686:171;5155:928;5919:10;5905:24;;;;5901:182;;18837:33;;18764:24;18833:57;356:1:4;18938:33:0;18903:69;;6069:1;865::4;17811:23:0;;17804:37;6008:64;6097:56;;;10286:25:5;;;10342:2;10327:18;;10320:34;;;6097:56:0;;;;;;;;;6111:10;;6097:56;;10259:18:5;6097:56:0;;;;;;;;4977:1183;;4842:1318;;;;;;:::o;14200:212::-;14374:30;;;;;;;:24;:30;;;;;14274:33;;14338:67;;:35;:67::i;:::-;14319:86;14200:212;-1:-1:-1;;14200:212:0:o;16734:185::-;16804:4;16886:25;16834:50;;;16886:25;;;16849:35;16834:50;;;919:40:3;16827:85:0;822:226:3;13948:208:0;14120:28;;;;;;;:24;:28;;;;;14020:33;;14084:65;;:35;:65::i;1788:901::-;3780:2:2;3774:9;;3945:2;3936:12;;3929:24;;;1931:10:0;3982:2:2;3973:12;;3966:26;4005:19;;;4070:2;4055:18;;4052:1;4048:26;4076:8;4045:40;-1:-1:-1;2700:20:2;;;-1:-1:-1;2733:27:2;;;2793:16;;;;22299:33:0;;3883:13:4;3867:30;2064:561:0;;;;2094:38;;;2090:415;;2174:10;17186:30;;;;:24;:30;;;;;;;;:51;;;;;;;;;;;;;;;;;:30;17247:28;;;;;:24;:28;;;;;:49;;;;;;;;;;;;;;;;;;18327:45;;;18392:27;;;18385:47;2298:12;;2294:78;;2312:60;2329:8;759:1:4;2365:6:0;17811:23;;17804:37;17686:171;2312:60;2064:561;;2090:415;2397:40;;;;;2393:112;;18837:33;;18764:24;18833:57;2479:10;18938:33;18903:69;;2064:561;;;2539:10;2525:24;;;;2521:104;;18837:33;;18764:24;18833:57;356:1:4;18938:33:0;18903:69;;2565:49;2639:43;;;10533:25:5;;;10601:14;;10594:22;10589:2;10574:18;;10567:50;2639:43:0;;;;2651:10;;2639:43;;10506:18:5;2639:43:0;;;;;;;1899:790;;1788:901;;;;;:::o;7689:330::-;8001:1;;;;7977:13;7933:42;7926:5;7921:82;;7689:330::o;13461:202::-;13627:28;;;;;;;:24;:28;;;;;13537:32;;13596:60;;:30;:60::i;14456:1269::-;14540:32;14616:6;14599:31;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14599:31:0;;;;;;;;;;;;;;;14584:46;;14669:9;14664:1045;14684:17;;;14664:1045;;;14726:16;14745:26;14761:6;;14768:1;14761:9;;;;;;;:::i;:::-;;;;;;;2556:24:2;2700:20;;;2740:2;2733:27;;;2806:2;2793:16;;;2496:400;14745:26:0;14726:45;;14789:12;14804:19;14814:8;22299:33;3883:13:4;3867:30;;22105:287:0;14804:19;14789:34;;14845:18;14858:4;14845:12;:18::i;:::-;14841:854;;;14905:132;;;;;;;;;;-1:-1:-1;14905:132:0;;14957:1;14905:132;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14887:15;;:12;;14900:1;;14887:15;;;;;;:::i;:::-;;;;;;:150;;;;14841:854;;;23086:33;;623:1:4;23152:27:0;;23146:34;3295:2:4;15194:482:0;;;;;;;3197:13:4;3230:32;;;3351:3;3347:22;;;;3291:54;;;;;;3288:82;;;;;15194:482:0;15238:28;15256:6;;15263:1;15256:9;;;;;;;:::i;:::-;;;;;;;1940:17:2;1925:33;;1769:205;15238:28:0;15194:482;;;;;;;;:::i;:::-;;;;;15296:2;15194:482;;;;;;15330:4;15194:482;;;;;;15368:58;15391:8;759:1:4;21630:23:0;21624:30;;21478:192;15368:58;15194:482;;;;15552:9;15194:482;;;;;;15596:57;15616:8;813:1:4;21630:23:0;21624:30;;21478:192;15596:57;15194:482;;;;15460:55;15480:8;865:1:4;21630:23:0;21624:30;;21478:192;15460:55;15194:482;;;15176:12;15189:1;15176:15;;;;;;;;:::i;:::-;;;;;;:500;;;;15062:633;;14841:854;-1:-1:-1;;14703:3:0;;14664:1045;;;;14456:1269;;;;:::o;13707:197::-;13866:30;;;;;;;:24;:30;;;;;13776:32;;13835:62;;:30;:62::i;15961:527::-;16033:25;16087:9;;16124:21;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;16124:21:0;;16113:32;;16155:20;16185:17;16241:9;16236:236;16260:6;16256:1;:10;16236:236;;;16306:9;;16316:1;16306:12;;;;;;;:::i;:::-;;;;;;;16291:27;;16386:12;16380:19;16367:32;;16448:9;16434:8;16443:1;16434:11;;;;;;;;:::i;:::-;;;;;;;;;;:23;16268:3;;16236:236;;;;16060:428;;;15961:527;;;;:::o;8835:879::-;8962:10;8989:18;9002:4;8989:12;:18::i;:::-;8984:406;;5100:2:2;5094:9;;5265:2;5256:12;;5249:24;;;5302:2;5293:12;;5286:26;;;-1:-1:-1;5325:19:2;;;5392:2;5377:18;;;5374:1;5370:26;5398:8;5367:40;5357:51;;-1:-1:-1;5484:27:2;;;5544:16;9031:53:0;;9045:32;9079:4;9031:13;:53::i;:::-;:126;;;-1:-1:-1;8085:2:2;8079:9;;8246:2;8237:12;;8230:31;;;8290:2;8281:12;;8274:24;;;-1:-1:-1;8318:12:2;;8311:26;;;9102:48:0;8350:19:2;;;8417:2;8402:18;;;8399:1;8395:26;8423:13;8392:45;8382:56;;-1:-1:-1;8519:27:2;;;8579:16;9088:69:0;;9102:48;7780:895:2;9088:69:0;9023:134;-1:-1:-1;948:9:3;;941:17;9183:12:0;;919:40:3;9171:209:0;;5100:2:2;5094:9;;5265:2;5256:12;;5249:24;;;5302:2;5293:12;;5286:26;;;5325:19;;;5392:2;5377:18;;5374:1;5370:26;5398:8;5367:40;-1:-1:-1;5357:51:2;;;-1:-1:-1;5484:27:2;;;5544:16;9231:57:0;;9245:36;4819:821:2;9231:57:0;:134;;;-1:-1:-1;8085:2:2;8079:9;;8246:2;8237:12;;8230:31;;;8290:2;8281:12;;8274:24;;;-1:-1:-1;8318:12:2;;8311:26;;;8350:19;;;8417:2;8402:18;;8399:1;8395:26;8423:13;8392:45;7890:24;8382:56;;;-1:-1:-1;8519:27:2;;;8579:16;9292:73:0;;9306:52;7780:895:2;9292:73:0;9223:142;;9171:209;9526:5;9519:13;9512:21;9509:1;9502:32;9630:2;9627:1;9620:13;6204:1440;15900:2:2;15894:9;;16066:2;16057:12;;16050:29;;;16108:2;16099:12;;16092:31;;;16152:2;16143:12;;16136:24;;;6394:10:0;-1:-1:-1;16180:12:2;;16173:26;16212:19;;;16277:3;16262:19;;16259:1;16255:27;16284:12;16252:45;-1:-1:-1;2700:20:2;;;-1:-1:-1;2733:27:2;;;2793:16;;;;22299:33:0;;3883:13:4;3867:30;6551:11:0;;6547:1009;;6582:38;;;6578:780;;6662:10;17186:30;;;;:24;:30;;;;;;;;:51;;;;;;;;;;;;;;;;;:30;17247:28;;;;;:24;:28;;;;;:49;;;;;;;;;;;;;;;;;;;;2216:51:4;;;;;2213:81;;;18327:45:0;;2330:3:4;2326:19;;;2323:47;18392:27:0;;;18385:47;6781:63;6798:8;813:1:4;6836:7:0;17811:23;;17804:37;17686:171;6781:63;6862:60;6879:8;865:1:4;6915:6:0;17811:23;;17804:37;17686:171;6862:60;6944:12;;6940:78;;6958:60;6975:8;759:1:4;7011:6:0;17811:23;;17804:37;17686:171;6958:60;6547:1009;;6578:780;7043:40;;;;;7039:319;;18837:33;;18764:24;18833:57;7125:10;18938:33;18903:69;;7154:60;7171:8;865:1:4;7207:6:0;17811:23;;17804:37;17686:171;7039:319;7253:10;7239:24;;;;7235:123;;7283:60;7300:8;865:1:4;7336:6:0;17811:23;;17804:37;17686:171;6547:1009;7392:10;7378:24;;;;7374:182;;18837:33;;18764:24;18833:57;356:1:4;18938:33:0;18903:69;;7542:1;865::4;17811:23:0;;17804:37;7481:64;7570:67;;;11208:25:5;;;11264:2;11249:18;;11242:34;;;11292:18;;;11285:34;;;7570:67:0;;;;;;;;;7586:10;;7570:67;;11196:2:5;11181:18;7570:67:0;;;;;;;;6358:1286;;6204:1440;;;;;;;:::o;1264:480::-;1341:22;1397:4;1385:24;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1375:34:0;-1:-1:-1;1419:12:0;;1465:263;1485:15;;;1465:263;;;1630:4;1649;;1654:1;1649:7;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;1622:35;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1608:7;1616:1;1608:10;;;;;;;;:::i;:::-;;;;;;;;;;1598:59;;-1:-1:-1;1598:59:0;1675:38;;1696:17;;;;;;;;;;;;;;1675:38;1502:3;;1465:263;;;;1365:379;1264:480;;;;:::o;3733:1066::-;9732:2:2;9726:9;;9899:2;9890:12;;9883:29;;;9941:2;9932:12;;9925:31;;;9985:2;9976:12;;9969:24;;;3918:10:0;-1:-1:-1;10013:12:2;;10006:26;10045:19;;;10110:3;10095:19;;10092:1;10088:27;10117:11;10085:44;-1:-1:-1;2700:20:2;;;-1:-1:-1;2733:27:2;;;2793:16;;;;22299:33:0;;3883:13:4;3867:30;4071:641:0;;;;4101:38;;;4097:495;;4181:10;17186:30;;;;:24;:30;;;;;;;;:51;;;;;;;;;;;;;;;;;:30;17247:28;;;;;:24;:28;;;;;:49;;;;;;;;;;;;;;;;;;;;2216:51:4;;;;;2213:81;;;18327:45:0;;2330:3:4;2326:19;;;2323:47;18392:27:0;;;18385:47;4300:63;4317:8;813:1:4;4355:7:0;17811:23;;17804:37;17686:171;4300:63;4385:12;;4381:78;;4399:60;4416:8;759:1:4;4452:6:0;17811:23;;17804:37;17686:171;4399:60;4071:641;;4097:495;4484:40;;;;;4480:112;;18837:33;;18764:24;18833:57;4566:10;18938:33;18903:69;;4071:641;;;4626:10;4612:24;;;;4608:104;;18837:33;;18764:24;18833:57;356:1:4;18938:33:0;18903:69;;4652:49;4726:66;;;12387:25:5;;;12443:2;12428:18;;12421:34;;;12498:14;;12491:22;12471:18;;;12464:50;;;;4726:66:0;;;;;;;;;4741:10;;4726:66;;12375:2:5;12360:18;4726:66:0;12191:329:5;12129:1227:0;12272:14;12303:18;12316:4;12303:12;:18::i;:::-;12298:834;;5100:2:2;5094:9;;5265:2;5256:12;;5249:24;;;5302:2;5293:12;;5286:26;;;-1:-1:-1;5325:19:2;;;5392:2;5377:18;;;5374:1;5370:26;5398:8;5367:40;5357:51;;-1:-1:-1;5484:27:2;;;5544:16;12347:53:0;;12361:32;12395:4;12347:13;:53::i;:::-;:126;;;-1:-1:-1;8085:2:2;8079:9;;8246:2;8237:12;;8230:31;;;8290:2;8281:12;;8274:24;;;-1:-1:-1;8318:12:2;;8311:26;;;12418:48:0;8350:19:2;;;8417:2;8402:18;;;8399:1;8395:26;8423:13;8392:45;8382:56;;-1:-1:-1;8519:27:2;;;8579:16;12404:69:0;;12418:48;7780:895:2;12404:69:0;12346:286;;17478:2:2;17472:9;;17645:2;17636:12;;17629:29;;;17687:2;17678:12;;17671:31;;;17731:2;17722:12;;17715:24;;;-1:-1:-1;17759:12:2;;17752:26;;;12549:56:0;17791:19:2;;;17858:3;17843:19;;;17840:1;17836:27;17865:12;17833:45;17823:56;;-1:-1:-1;17957:27:2;;;18017:16;12529:103:0;;12549:56;865:1:4;21630:23:0;21624:30;;21478:192;12529:103;12346:286;;;12493:17;12346:286;12337:295;-1:-1:-1;12682:17:0;12672:27;;12658:12;;919:40:3;12646:476:0;;5100:2:2;5094:9;;5265:2;5256:12;;5249:24;;;5302:2;5293:12;;5286:26;;;5325:19;;;5392:2;5377:18;;5374:1;5370:26;5398:8;5367:40;-1:-1:-1;5357:51:2;;;-1:-1:-1;5484:27:2;;;5544:16;;;12745:57:0;;12759:36;12797:4;12745:13;:57::i;:::-;:134;;;-1:-1:-1;8085:2:2;8079:9;;8246:2;8237:12;;8230:31;;;8290:2;8281:12;;8274:24;;;-1:-1:-1;8318:12:2;;8311:26;;;8350:19;;;8417:2;8402:18;;8399:1;8395:26;8423:13;8392:45;7890:24;8382:56;;;-1:-1:-1;8519:27:2;;;8579:16;12806:73:0;;12820:52;7780:895:2;12806:73:0;12744:306;;17478:2:2;17472:9;;17645:2;17636:12;;17629:29;;;17687:2;17678:12;;17671:31;;;17731:2;17722:12;;17715:24;;;-1:-1:-1;17759:12:2;;17752:26;;;17791:19;;;17858:3;17843:19;;17840:1;17836:27;17865:12;17833:45;17283:24;17823:56;;;-1:-1:-1;17957:27:2;;;18017:16;12943:107:0;;12963:60;17157:956:2;12943:107:0;12744:306;;;12903:17;12744:306;12720:330;-1:-1:-1;;;;501:9:3;;;497:24;490:32;;13068:39:0;;12702:420;12646:476;13190:6;13187:1;13180:17;13272:2;13269:1;13262:13;9758:1094;9900:10;9927:18;9940:4;9927:12;:18::i;:::-;9922:606;;5100:2:2;5094:9;;5265:2;5256:12;;5249:24;;;5302:2;5293:12;;5286:26;;;-1:-1:-1;5325:19:2;;;5392:2;5377:18;;;5374:1;5370:26;5398:8;5367:40;5357:51;;-1:-1:-1;5484:27:2;;;5544:16;9969:53:0;;9983:32;4819:821:2;9969:53:0;:126;;;-1:-1:-1;8085:2:2;8079:9;;8246:2;8237:12;;8230:31;;;8290:2;8281:12;;8274:24;;;-1:-1:-1;8318:12:2;;8311:26;;;10040:48:0;8350:19:2;;;8417:2;8402:18;;;8399:1;8395:26;8423:13;8392:45;8382:56;;-1:-1:-1;8519:27:2;;;8579:16;10026:69:0;;10040:48;7780:895:2;10026:69:0;9969:222;;;-1:-1:-1;11304:2:2;11298:9;;11471:2;11462:12;;11455:29;;;11513:2;11504:12;;11497:31;;;11557:2;11548:12;;11541:24;;;-1:-1:-1;11585:12:2;;11578:26;;;10129:55:0;11617:19:2;;;11684:3;11669:19;;;11666:1;11662:27;11691:11;11659:44;11649:55;;-1:-1:-1;11781:27:2;;;11841:16;10115:76:0;;10129:55;10984:956:2;10115:76:0;9961:230;-1:-1:-1;948:9:3;;941:17;10217:12:0;;919:40:3;10205:313:0;;5100:2:2;5094:9;;5265:2;5256:12;;5249:24;;;5302:2;5293:12;;5286:26;;;5325:19;;;5392:2;5377:18;;5374:1;5370:26;5398:8;5367:40;-1:-1:-1;5357:51:2;;;-1:-1:-1;5484:27:2;;;5544:16;10265:57:0;;10279:36;4819:821:2;10265:57:0;:134;;;-1:-1:-1;8085:2:2;8079:9;;8246:2;8237:12;;8230:31;;;8290:2;8281:12;;8274:24;;;-1:-1:-1;8318:12:2;;8311:26;;;8350:19;;;8417:2;8402:18;;8399:1;8395:26;8423:13;8392:45;7890:24;8382:56;;;-1:-1:-1;8519:27:2;;;8579:16;10326:73:0;;10340:52;7780:895:2;10326:73:0;10265:238;;;-1:-1:-1;11304:2:2;11298:9;;11471:2;11462:12;;11455:29;;;11513:2;11504:12;;11497:31;;;11557:2;11548:12;;11541:24;;;-1:-1:-1;11585:12:2;;11578:26;;;11617:19;;;11684:3;11669:19;;11666:1;11662:27;11691:11;11659:44;11109:24;11649:55;;;-1:-1:-1;11781:27:2;;;11841:16;10423:80:0;;10437:59;10984:956:2;10896:1189:0;11020:14;11051:18;11064:4;11051:12;:18::i;:::-;11046:812;;5100:2:2;5094:9;;5265:2;5256:12;;5249:24;;;5302:2;5293:12;;5286:26;;;-1:-1:-1;5325:19:2;;;5392:2;5377:18;;;5374:1;5370:26;5398:8;5367:40;5357:51;;-1:-1:-1;5484:27:2;;;5544:16;11095:53:0;;11109:32;4819:821:2;11095:53:0;:126;;;-1:-1:-1;8085:2:2;8079:9;;8246:2;8237:12;;8230:31;;;8290:2;8281:12;;8274:24;;;-1:-1:-1;8318:12:2;;8311:26;;;11166:48:0;8350:19:2;;;8417:2;8402:18;;;8399:1;8395:26;8423:13;8392:45;8382:56;;-1:-1:-1;8519:27:2;;;8579:16;11152:69:0;;11166:48;7780:895:2;11152:69:0;11094:275;;14299:2:2;14293:9;;14465:2;14456:12;;14449:31;;;14509:2;14500:12;;14493:24;;;-1:-1:-1;14537:12:2;;14530:26;;;11297:45:0;14569:19:2;;;14636:2;14621:18;;;14618:1;14614:26;14642:10;14611:42;14601:53;;-1:-1:-1;14730:27:2;;;14790:16;11277:92:0;;11297:45;13997:889:2;11277:92:0;11094:275;;;11241:17;11094:275;11085:284;-1:-1:-1;11419:17:0;11409:27;;11395:12;;919:40:3;11383:465:0;;5100:2:2;5094:9;;5265:2;5256:12;;5249:24;;;5302:2;5293:12;;5286:26;;;5325:19;;;5392:2;5377:18;;5374:1;5370:26;5398:8;5367:40;-1:-1:-1;5357:51:2;;;-1:-1:-1;5484:27:2;;;5544:16;;;11482:57:0;;11496:36;4819:821:2;11482:57:0;:134;;;-1:-1:-1;8085:2:2;8079:9;;8246:2;8237:12;;8230:31;;;8290:2;8281:12;;8274:24;;;-1:-1:-1;8318:12:2;;8311:26;;;8350:19;;;8417:2;8402:18;;8399:1;8395:26;8423:13;8392:45;7890:24;8382:56;;;-1:-1:-1;8519:27:2;;;8579:16;11543:73:0;;11557:52;7780:895:2;11543:73:0;11481:295;;14299:2:2;14293:9;;14465:2;14456:12;;14449:31;;;14509:2;14500:12;;14493:24;;;-1:-1:-1;14537:12:2;;14530:26;;;14569:19;;;14636:2;14621:18;;14618:1;14614:26;14642:10;14611:42;14104:24;14601:53;;;-1:-1:-1;14730:27:2;;;14790:16;11680:96:0;;11700:49;13997:889:2;2733:956:0;6608:2:2;6602:9;;6773:2;6764:12;;6757:31;;;6817:2;6808:12;;6801:24;;;2905:10:0;-1:-1:-1;6845:12:2;;6838:26;6877:19;;;6942:2;6927:18;;6924:1;6920:26;6948:13;6917:45;-1:-1:-1;2700:20:2;;;-1:-1:-1;2733:27:2;;;2793:16;;;;22299:33:0;;3883:13:4;3867:30;3049:560:0;;;;3079:38;;;3075:414;;3159:10;17186:30;;;;:24;:30;;;;;;;;:51;;;;;;;;;;;;;;;;;:30;17247:28;;;;;:24;:28;;;;;:49;;;;;;;;;;;;;;;;;;;;2216:51:4;;;;;2213:81;;;18327:45:0;;2330:3:4;2326:19;;;2323:47;18392:27:0;;;18385:47;3282:12;;3278:78;;3296:60;3313:8;759:1:4;3349:6:0;17811:23;;17804:37;17686:171;3296:60;3049:560;;3075:414;3381:40;;;;;3377:112;;18837:33;;18764:24;18833:57;3463:10;18938:33;18903:69;;3049:560;;;3523:10;3509:24;;;;3505:104;;18837:33;;18764:24;18833:57;356:1:4;18938:33:0;18903:69;;3549:49;3623:59;;;10533:25:5;;;10601:14;;10594:22;10589:2;10574:18;;10567:50;3623:59:0;;;;;;;;;3640:10;;3623:59;;10506:18:5;3623:59:0;10365:258:5;8118:673:0;8221:10;8248:18;8261:4;8248:12;:18::i;:::-;8243:224;;5100:2:2;5094:9;;5265:2;5256:12;;5249:24;;;5302:2;5293:12;;5286:26;;;-1:-1:-1;5325:19:2;;;5392:2;5377:18;;;5374:1;5370:26;5398:8;5367:40;5357:51;;-1:-1:-1;5484:27:2;;;5544:16;8290:53:0;;8304:32;8338:4;8290:13;:53::i;:::-;8282:61;-1:-1:-1;948:9:3;;941:17;8369:12:0;;919:40:3;8357:99:0;;5100:2:2;5094:9;;5265:2;5256:12;;5249:24;;;5302:2;5293:12;;5286:26;;;5325:19;;;5392:2;5377:18;;5374:1;5370:26;5398:8;5367:40;-1:-1:-1;5357:51:2;;;-1:-1:-1;5484:27:2;;;5544:16;8399:57:0;;8413:36;4819:821:2;20638:722:0;20822:13;;20732:28;;20772:13;;;;20822;20901:27;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;20901:27:0;;20867:61;;20967:9;20962:218;20986:12;20982:1;:16;20962:218;;;21030:6;21037:1;21030:9;;;;;;;;:::i;:::-;;;;;;;;;21023:16;;21061:46;21074:32;21084:21;21100:4;2556:24:2;2700:20;;;2740:2;2733:27;;;2806:2;2793:16;;;2496:400;21084:21:0;22299:33;3883:13:4;3867:30;;22105:287:0;21074:32;21061:12;:46::i;:::-;21109:8;21057:60;21161:4;21135:14;21150:7;;;;;;21135:23;;;;;;;;:::i;:::-;;;;;;:30;;;;;20962:218;21000:3;;20962:218;;;;21221:5;21207:20;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;21207:20:0;;21193:34;;21246:9;21241:103;21265:5;21261:1;:9;21241:103;;;21312:14;21327:1;21312:17;;;;;;;;:::i;:::-;;;;;;;21295:11;21307:1;21295:14;;;;;;;;:::i;:::-;;;;;;;;;;:34;21272:3;;21241:103;;;;20762:598;;;;20638:722;;;:::o;19138:1376::-;19321:13;;19227:32;;19271:13;;;;19321;19400:27;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;19400:27:0;;19366:61;;19466:9;19461:218;19485:12;19481:1;:16;19461:218;;;19529:6;19536:1;19529:9;;;;;;;;:::i;:::-;;;;;;;;;19522:16;;19560:46;19573:32;19583:21;19599:4;2556:24:2;2700:20;;;2740:2;2733:27;;;2806:2;2793:16;;;2496:400;19560:46:0;19608:8;19556:60;19660:4;19634:14;19649:7;;;;;;19634:23;;;;;;;;:::i;:::-;;;;;;:30;;;;;19461:218;19499:3;;19461:218;;;;19724:5;19707:23;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19707:23:0;;;;;;;;;;;;;;-1:-1:-1;19692:38:0;-1:-1:-1;19744:16:0;;19774:724;19798:5;19794:1;:9;19774:724;;;19835:14;19850:1;19835:17;;;;;;;;:::i;:::-;;;;;;;19828:24;;19881:21;19897:4;2556:24:2;2700:20;;;2740:2;2733:27;;;2806:2;2793:16;;;2496:400;19881:21:0;23086:33;;623:1:4;23152:27:0;;23146:34;3295:2:4;20038:445:0;;;;;;;23086:33;;-1:-1:-1;3197:13:4;3180:31;;;;3230:32;;;;3351:3;3347:22;;;;3291:54;;;;;;3288:82;;;;;20038:445:0;1940:17:2;1925:33;;20038:445:0;;;;;;;;:::i;:::-;;;;;20127:2;20038:445;;;;;;20157:4;20038:445;;;;;;20191:58;20214:8;759:1:4;21630:23:0;21624:30;;21478:192;20191:58;20038:445;;;;20367:9;20038:445;;;;;;20407:57;20427:8;813:1:4;21630:23:0;21624:30;;21478:192;20407:57;20038:445;;;;20279:55;20299:8;865:1:4;21630:23:0;21624:30;;21478:192;20279:55;20038:445;;;20020:12;20033:1;20020:15;;;;;;;;:::i;:::-;;;;;;:463;;;;19810:688;;;19805:3;;;;;19774:724;;;;19437:1071;19261:1253;;;;19138:1376;;;:::o;23282:165::-;23341:4;356:1:4;23371:32:0;;;23405:34;;;23371:32;;919:40:3;23364:76:0;822:226:3;22472:137:0;22550:4;22582:19;22592:8;22299:33;3883:13:4;3867:30;;22105:287:0;22582:19;22574:27;;:4;:27;;;22566:36;;22472:137;;;;:::o;14:196:5:-;82:20;;142:42;131:54;;121:65;;111:93;;200:1;197;190:12;111:93;14:196;;;:::o;215:397::-;301:6;309;317;325;378:3;366:9;357:7;353:23;349:33;346:53;;;395:1;392;385:12;346:53;418:29;437:9;418:29;:::i;:::-;408:39;;466:38;500:2;489:9;485:18;466:38;:::i;:::-;215:397;;456:48;;-1:-1:-1;;;;551:2:5;536:18;;523:32;;602:2;587:18;574:32;;215:397::o;799:186::-;858:6;911:2;899:9;890:7;886:23;882:32;879:52;;;927:1;924;917:12;879:52;950:29;969:9;950:29;:::i;:::-;940:39;799:186;-1:-1:-1;;;799:186:5:o;990:632::-;1161:2;1213:21;;;1283:13;;1186:18;;;1305:22;;;1132:4;;1161:2;1384:15;;;;1358:2;1343:18;;;1132:4;1427:169;1441:6;1438:1;1435:13;1427:169;;;1502:13;;1490:26;;1571:15;;;;1536:12;;;;1463:1;1456:9;1427:169;;;-1:-1:-1;1613:3:5;;990:632;-1:-1:-1;;;;;;990:632:5:o;1627:332::-;1685:6;1738:2;1726:9;1717:7;1713:23;1709:32;1706:52;;;1754:1;1751;1744:12;1706:52;1793:9;1780:23;1843:66;1836:5;1832:78;1825:5;1822:89;1812:117;;1925:1;1922;1915:12;2156:160;2221:20;;2277:13;;2270:21;2260:32;;2250:60;;2306:1;2303;2296:12;2321:322;2395:6;2403;2411;2464:2;2452:9;2443:7;2439:23;2435:32;2432:52;;;2480:1;2477;2470:12;2432:52;2503:29;2522:9;2503:29;:::i;:::-;2493:39;;2579:2;2568:9;2564:18;2551:32;2541:42;;2602:35;2633:2;2622:9;2618:18;2602:35;:::i;:::-;2592:45;;2321:322;;;;;:::o;2648:184::-;2700:77;2697:1;2690:88;2797:4;2794:1;2787:15;2821:4;2818:1;2811:15;2969:1618;3196:2;3248:21;;;3318:13;;3221:18;;;3340:22;;;3167:4;;3196:2;3381;;3399:18;;;;3440:15;;;3167:4;;3504:1057;3520:6;3515:3;3512:15;3504:1057;;;3589:6;3583:13;3625:2;3619:9;3658:1;3654:2;3651:9;3641:217;;3702:77;3699:1;3692:88;3807:4;3804:1;3797:15;3839:4;3836:1;3829:15;3641:217;3871:15;;3930:11;;;3924:18;3944:42;3920:67;3906:12;;;3899:89;4027:11;;;4021:18;4052:46;4085:12;;;4021:18;2914:42;2903:54;2891:67;;2837:127;4052:46;-1:-1:-1;4121:4:5;4165:11;;;4159:18;4145:12;;;4138:40;4201:4;4246:11;;;4240:18;2914:42;2903:54;4306:12;;;2891:67;4342:4;4386:11;;;4380:18;4366:12;;;4359:40;4422:4;4466:11;;;4460:18;4446:12;;;4439:40;4508:4;4499:14;;;;4536:15;;;;3546:1;3537:11;3504:1057;;;-1:-1:-1;4578:3:5;;2969:1618;-1:-1:-1;;;;;;;;2969:1618:5:o;4592:367::-;4655:8;4665:6;4719:3;4712:4;4704:6;4700:17;4696:27;4686:55;;4737:1;4734;4727:12;4686:55;-1:-1:-1;4760:20:5;;4803:18;4792:30;;4789:50;;;4835:1;4832;4825:12;4789:50;4872:4;4864:6;4860:17;4848:29;;4932:3;4925:4;4915:6;4912:1;4908:14;4900:6;4896:27;4892:38;4889:47;4886:67;;;4949:1;4946;4939:12;4886:67;4592:367;;;;;:::o;4964:437::-;5050:6;5058;5111:2;5099:9;5090:7;5086:23;5082:32;5079:52;;;5127:1;5124;5117:12;5079:52;5167:9;5154:23;5200:18;5192:6;5189:30;5186:50;;;5232:1;5229;5222:12;5186:50;5271:70;5333:7;5324:6;5313:9;5309:22;5271:70;:::i;:::-;5360:8;;5245:96;;-1:-1:-1;4964:437:5;-1:-1:-1;;;;4964:437:5:o;5406:403::-;5492:6;5500;5508;5516;5569:3;5557:9;5548:7;5544:23;5540:33;5537:53;;;5586:1;5583;5576:12;5537:53;5609:29;5628:9;5609:29;:::i;:::-;5599:39;;5657:38;5691:2;5680:9;5676:18;5657:38;:::i;:::-;5647:48;;5714:38;5748:2;5737:9;5733:18;5714:38;:::i;:::-;5406:403;;;;-1:-1:-1;5704:48:5;;5799:2;5784:18;5771:32;;-1:-1:-1;;5406:403:5:o;5814:466::-;5909:6;5917;5925;5933;5941;5994:3;5982:9;5973:7;5969:23;5965:33;5962:53;;;6011:1;6008;6001:12;5962:53;6034:29;6053:9;6034:29;:::i;:::-;6024:39;;6082:38;6116:2;6105:9;6101:18;6082:38;:::i;:::-;5814:466;;6072:48;;-1:-1:-1;;;;6167:2:5;6152:18;;6139:32;;6218:2;6203:18;;6190:32;;6269:3;6254:19;;;6241:33;;-1:-1:-1;5814:466:5:o;6738:1319::-;6898:4;6927:2;6967;6956:9;6952:18;6997:2;6986:9;6979:21;7020:6;7055;7049:13;7086:6;7078;7071:22;7124:2;7113:9;7109:18;7102:25;;7186:2;7176:6;7173:1;7169:14;7158:9;7154:30;7150:39;7136:53;;7224:2;7216:6;7212:15;7245:1;7266;7276:752;7292:6;7287:3;7284:15;7276:752;;;7385:66;7373:9;7365:6;7361:22;7357:95;7352:3;7345:108;7482:6;7476:13;7524:2;7518:9;7555:8;7547:6;7540:24;7588:1;7602:157;7618:8;7613:3;7610:17;7602:157;;;7726:12;;;7722:21;;7716:28;7693:16;;;7689:25;;7682:63;7637:12;;7602:157;;;-1:-1:-1;7783:21:5;;;7779:30;;7772:41;;;7870:2;7856:17;7875:66;7852:90;7840:103;;;7836:112;;;-1:-1:-1;8006:12:5;;;;7971:15;;;;7318:1;7309:11;7276:752;;;-1:-1:-1;8045:6:5;;6738:1319;-1:-1:-1;;;;;;;;6738:1319:5:o;8062:466::-;8154:6;8162;8170;8178;8186;8239:3;8227:9;8218:7;8214:23;8210:33;8207:53;;;8256:1;8253;8246:12;8207:53;8279:29;8298:9;8279:29;:::i;:::-;8269:39;;8327:38;8361:2;8350:9;8346:18;8327:38;:::i;:::-;8317:48;;8412:2;8401:9;8397:18;8384:32;8374:42;;8463:2;8452:9;8448:18;8435:32;8425:42;;8486:36;8517:3;8506:9;8502:19;8486:36;:::i;:::-;8476:46;;8062:466;;;;;;;;:::o;8533:472::-;8628:6;8636;8644;8652;8660;8713:3;8701:9;8692:7;8688:23;8684:33;8681:53;;;8730:1;8727;8720:12;8681:53;8753:29;8772:9;8753:29;:::i;:::-;8743:39;;8801:38;8835:2;8824:9;8820:18;8801:38;:::i;:::-;8791:48;;8858:38;8892:2;8881:9;8877:18;8858:38;:::i;:::-;8533:472;;;;-1:-1:-1;8848:48:5;;8943:2;8928:18;;8915:32;;-1:-1:-1;8994:3:5;8979:19;8966:33;;8533:472;-1:-1:-1;;8533:472:5:o;9192:397::-;9275:6;9283;9291;9299;9352:3;9340:9;9331:7;9327:23;9323:33;9320:53;;;9369:1;9366;9359:12;9320:53;9392:29;9411:9;9392:29;:::i;:::-;9382:39;;9440:38;9474:2;9463:9;9459:18;9440:38;:::i;:::-;9430:48;;9525:2;9514:9;9510:18;9497:32;9487:42;;9548:35;9579:2;9568:9;9564:18;9548:35;:::i;:::-;9538:45;;9192:397;;;;;;;:::o;9594:328::-;9671:6;9679;9687;9740:2;9728:9;9719:7;9715:23;9711:32;9708:52;;;9756:1;9753;9746:12;9708:52;9779:29;9798:9;9779:29;:::i;:::-;9769:39;;9827:38;9861:2;9850:9;9846:18;9827:38;:::i;:::-;9817:48;;9912:2;9901:9;9897:18;9884:32;9874:42;;9594:328;;;;;:::o;9927:180::-;9986:6;10039:2;10027:9;10018:7;10014:23;10010:32;10007:52;;;10055:1;10052;10045:12;10007:52;-1:-1:-1;10078:23:5;;9927:180;-1:-1:-1;9927:180:5:o;10628:184::-;10680:77;10677:1;10670:88;10777:4;10774:1;10767:15;10801:4;10798:1;10791:15;10817:184;10869:77;10866:1;10859:88;10966:4;10963:1;10956:15;10990:4;10987:1;10980:15;11330:580;11407:4;11413:6;11473:11;11460:25;11563:66;11552:8;11536:14;11532:29;11528:102;11508:18;11504:127;11494:155;;11645:1;11642;11635:12;11494:155;11672:33;;11724:20;;;-1:-1:-1;11767:18:5;11756:30;;11753:50;;;11799:1;11796;11789:12;11753:50;11832:4;11820:17;;-1:-1:-1;11863:14:5;11859:27;;;11849:38;;11846:58;;;11900:1;11897;11890:12;11915:271;12098:6;12090;12085:3;12072:33;12054:3;12124:16;;12149:13;;;12124:16;11915:271;-1:-1:-1;11915:271:5:o
Swarm Source
none://164736f6c6343000815000a
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 97.27% | $3,418.67 | 4.485 | $15,332.72 | |
BSC | 2.07% | $620.21 | 0.5263 | $326.44 | |
POL | 0.30% | $0.54048 | 87 | $47.02 | |
LINEA | 0.18% | $3,417.02 | 0.00812 | $27.75 | |
BASE | 0.14% | $3,418.2 | 0.0063 | $21.53 | |
AVAX | 0.02% | $43.25 | 0.0713 | $3.08 | |
OP | 0.01% | $3,417.56 | 0.00058 | $1.98 | |
SCROLL | <0.01% | $3,418.67 | 0.00041 | $1.4 | |
ARB | <0.01% | $3,417.61 | 0.00018 | $0.615171 | |
BLAST | <0.01% | $3,418.08 | 0.00002 | $0.068362 | |
FTM | <0.01% | $1.13 | 0.0184 | $0.0207 | |
MANTLE | <0.01% | $0.828129 | 0.0107 | $0.008886 | |
CELO | <0.01% | $0.843496 | 0.00462 | $0.003897 | |
GNO | <0.01% | $0.999711 | 0.00323 | $0.003229 | |
GLMR | <0.01% | $0.270553 | 0.00691 | $0.00187 | |
APE | Ape (APE) | <0.01% | $1.3 | 0.00081 | $0.001052 |
[ Download: CSV Export ]
[ 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.