Overview
APE Balance
0 APE
APE Value
$0.00More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Name:
ERC721Module
Compiler Version
v0.8.19+commit.7dd6d404
Optimization Enabled:
Yes with 500 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.19; import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import "../interfaces/core/IModule.sol"; import "../core/Lockers.sol" as Lockers; import "../helpers/Utils.sol"; /// @title Cyan Wallet ERC721 Module - A Cyan wallet's ERC721 token handling module. /// @author Bulgantamir Gankhuyag - <[email protected]> /// @author Naranbayar Uuganbayar - <[email protected]> contract ERC721Module is IModule { bytes4 private constant ERC721_APPROVE = IERC721.approve.selector; bytes4 private constant ERC721_SET_APPROVAL_FOR_ALL = IERC721.setApprovalForAll.selector; bytes4 private constant ERC721_TRANSFER_FROM = IERC721.transferFrom.selector; bytes4 private constant ERC721_SAFE_TRANSFER_FROM = bytes4(keccak256("safeTransferFrom(address,address,uint256)")); bytes4 private constant ERC721_SAFE_TRANSFER_FROM_BYTES = bytes4(keccak256("safeTransferFrom(address,address,uint256,bytes)")); event SetLockedERC721Token(address collection, uint256 tokenId, bool isLocked); /// @inheritdoc IModule function handleTransaction( address collection, uint256 value, bytes calldata data ) public payable virtual override returns (bytes memory) { bytes4 funcHash = Utils.parseFunctionSelector(data); if ( funcHash == ERC721_TRANSFER_FROM || funcHash == ERC721_SAFE_TRANSFER_FROM || funcHash == ERC721_SAFE_TRANSFER_FROM_BYTES ) { uint256 tokenId = Utils.getUint256At(data, 0x44); require(!getIsLocked(collection, tokenId), "Cannot perform this action on locked token."); } if (funcHash == ERC721_APPROVE) { uint256 tokenId = Utils.getUint256At(data, 0x24); require(!getIsLocked(collection, tokenId), "Cannot perform this action on locked token."); } require(funcHash != ERC721_SET_APPROVAL_FOR_ALL, "Cannot perform this action."); return Utils._execute(collection, value, data); } function getIsLocked(address collection, uint256 tokenId) internal view virtual returns (bool) { return Lockers.isLockedByCyanPlanERC721(collection, tokenId); } /// @notice Allows operators to lock/unlock the token. /// @param collection Collection address. /// @param tokenId Token id. /// @param isLocked Boolean represents lock/unlock. function setLockedERC721Token( address collection, uint256 tokenId, bool isLocked ) public { Lockers.CyanPlanLockerERC721 storage locker = Lockers.getCyanPlanLockerERC721(); require(locker.tokens[collection][tokenId] != isLocked, "Token already in given state."); IERC721 erc721 = IERC721(collection); if (erc721.getApproved(tokenId) != address(0)) { erc721.approve(address(0), tokenId); } locker.tokens[collection][tokenId] = isLocked; if (isLocked) { ++locker.count[collection]; } else { --locker.count[collection]; } emit SetLockedERC721Token(collection, tokenId, isLocked); } /// @notice Allows operators to transfer out non locked ERC721 tokens. /// Note: Can only transfer if token is not locked. /// @param collection Collection address. /// @param tokenId Token ID. /// @param to Receiver address. function transferNonLockedERC721( address collection, uint256 tokenId, address to ) external returns (bytes memory) { require(!Lockers.isLockedERC721(collection, tokenId), "Cannot perform this action on locked token."); bytes memory data = abi.encodeWithSelector(ERC721_SAFE_TRANSFER_FROM, address(this), to, tokenId); return Utils._execute(collection, 0, data); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.19; // keccak256("wallet.YugaModule.lockedApe") bytes32 constant APE_PLAN_LOCKER_SLOT = 0x010881fa8a1edce184936a8e4e08060bba49cb5145c9b396e6e80c0c6b0e1269; // keccak256("wallet.ERC721Module.lockedERC721") bytes32 constant CYAN_PLAN_LOCKER_SLOT_ERC721 = 0x25888debd3e1e584ccaebe1162c7763ec457a94078c5d0d9a1d32a926ff9973c; // keccak256("wallet.ERC1155Module.lockedERC1155") bytes32 constant CYAN_PLAN_LOCKER_SLOT_ERC1155 = 0xdcc609ac7fc3b6a216ce1445788736c9dbe88a58b25a13af71623e6da931efa0; // keccak256("wallet.CryptoPunksModule.lockedCryptoPunks") bytes32 constant CRYPTO_PUNKS_PLAN_LOCKER_SLOT = 0x67ae504a494a1bd5120fdcd8b3565de046d61ac7bb95311090f1976ec179a99a; struct ApePlanLocker { /// @notice Map of the locked tokens. /// Note: Collection Address => Token ID => Lock state mapping(address => mapping(uint256 => uint8)) tokens; } struct CyanPlanLockerERC721 { /// @notice Locked tokens count of the collection. /// Note: Collection Address => Number of locked tokens mapping(address => uint256) count; /// @notice Map of the locked tokens. /// Note: Collection Address => Token ID => isLocked mapping(address => mapping(uint256 => bool)) tokens; } struct CyanPlanLockerCryptoPunks { /// @notice Locked tokens count of the CryptoPunks. /// Note: Number of locked tokens uint256 count; /// @notice Map of the locked tokens. /// Note: CryptoPunk index => isLocked mapping(uint256 => bool) tokens; } struct CyanPlanLockerERC1155 { /// @notice Map of the locked ERC1155 tokens. /// Note: Collection Address => Token ID => amount mapping(address => mapping(uint256 => uint256)) tokens; } /// @notice Checks whether the NFT is locked or not. This method checks both ERC721 lock and ApePlan lock. /// @param collection Collection address. /// @param tokenId Token ID. /// @return isLocked Whether the token is locked or not. function isLockedERC721(address collection, uint256 tokenId) view returns (bool) { return isLockedByCyanPlanERC721(collection, tokenId) || isLockedByApePlan(collection, tokenId); } /// @notice Checks whether the ERC721 token is locked or not. /// @param collection Collection address. /// @param tokenId Token ID. /// @return isLocked Whether the token is locked or not. function isLockedByCyanPlanERC721(address collection, uint256 tokenId) view returns (bool) { return getCyanPlanLockerERC721().tokens[collection][tokenId]; } /// @notice Checks whether the CryptoPunks token is locked or not. /// @param tokenId Token ID. /// @return isLocked Whether the token is locked or not. function isLockedByCryptoPunkPlan(uint256 tokenId) view returns (bool) { return getCyanPlanLockerCryptoPunks().tokens[tokenId]; } /// @notice Checks whether the BAYC, MAYC or BAKC token is locked or not. /// @param collection Ape collection address. /// @param tokenId Token ID. /// @return isLocked Whether the token is ape locked or not. function isLockedByApePlan(address collection, uint256 tokenId) view returns (bool) { return getApePlanLocker().tokens[collection][tokenId] != 0; } /// @notice Returns amount of locked ERC1155Token items. /// @param collection Collection address. /// @param tokenId Token ID. /// @return isLocked Whether the token is locked or not. function getLockedERC1155Amount(address collection, uint256 tokenId) view returns (uint256) { return getCyanPlanLockerERC1155().tokens[collection][tokenId]; } /// @notice Returns ape lock state. /// @param collection Ape collection address. /// @param tokenId Token ID. /// @return Ape locks state. function getApeLockState(address collection, uint256 tokenId) view returns (uint8) { return getApePlanLocker().tokens[collection][tokenId]; } /// @dev Returns the map of the locked ERC721 tokens. /// @return result CyanPlanLockerERC721 struct of the locked tokens. /// Note: Collection Address => Token ID => isLocked function getCyanPlanLockerERC721() pure returns (CyanPlanLockerERC721 storage result) { assembly { result.slot := CYAN_PLAN_LOCKER_SLOT_ERC721 } } /// @dev Returns the map of the locked ERC1155 tokens. /// @return result CyanPlanERC1155Locker struct of the locked tokens. /// Note: Collection Address => Token ID => locked amount function getCyanPlanLockerERC1155() pure returns (CyanPlanLockerERC1155 storage result) { assembly { result.slot := CYAN_PLAN_LOCKER_SLOT_ERC1155 } } /// @dev Returns the map of the locked Crypto Punks. /// @return result CryptoPunksPlanLocker struct of the locked tokens. /// Note: CryptoPunk index => isLocked function getCyanPlanLockerCryptoPunks() pure returns (CyanPlanLockerCryptoPunks storage result) { assembly { result.slot := CRYPTO_PUNKS_PLAN_LOCKER_SLOT } } /// @dev Returns the map of the locked tokens. /// @return result ApePlanLocker struct of the locked tokens. /// Note: Collection Address => Token ID => Lock state function getApePlanLocker() pure returns (ApePlanLocker storage result) { assembly { result.slot := APE_PLAN_LOCKER_SLOT } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.19; library Utils { /// @notice Executes a transaction to the given address. /// @param to Target address. /// @param value Native token value to be sent to the address. /// @param data Data to be sent to the address. /// @return result Result of the transaciton. function _execute( address to, uint256 value, bytes memory data ) internal returns (bytes memory result) { assembly { let success := call(gas(), to, value, add(data, 0x20), mload(data), 0, 0) mstore(result, returndatasize()) returndatacopy(add(result, 0x20), 0, returndatasize()) if eq(success, 0) { revert(add(result, 0x20), returndatasize()) } } } /// @notice Recover signer address from signature. /// @param signedHash Arbitrary length data signed on the behalf of the wallet. /// @param signature Signature byte array associated with signedHash. /// @return Recovered signer address. function recoverSigner(bytes32 signedHash, bytes memory signature) internal pure returns (address) { uint8 v; bytes32 r; bytes32 s; // we jump 32 (0x20) as the first slot of bytes contains the length // we jump 65 (0x41) per signature // for v we load 32 bytes ending with v (the first 31 come from s) then apply a mask assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } require(v == 27 || v == 28, "Bad v value in signature."); address recoveredAddress = ecrecover(signedHash, v, r, s); require(recoveredAddress != address(0), "ecrecover returned 0."); return recoveredAddress; } /// @notice Helper method to parse the function selector from data. /// @param data Any data to be parsed, mostly calldata of transaction. /// @return result Parsed function sighash. function parseFunctionSelector(bytes memory data) internal pure returns (bytes4 result) { require(data.length >= 4, "Invalid data."); assembly { result := mload(add(data, 0x20)) } } /// @notice Parse uint256 from given data. /// @param data Any data to be parsed, mostly calldata of transaction. /// @param position Position in the data. /// @return result Uint256 parsed from given data. function getUint256At(bytes memory data, uint8 position) internal pure returns (uint256 result) { assembly { result := mload(add(data, add(position, 0x20))) } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.19; interface IModule { /// @notice Executes given transaction data to given address. /// @param to Target contract address. /// @param value Value of the given transaction. /// @param data Calldata of the transaction. /// @return Result of the execution. function handleTransaction( address to, uint256 value, bytes calldata data ) external payable returns (bytes memory); }
{ "optimizer": { "enabled": true, "runs": 500 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"collection","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isLocked","type":"bool"}],"name":"SetLockedERC721Token","type":"event"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"handleTransaction","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bool","name":"isLocked","type":"bool"}],"name":"setLockedERC721Token","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"transferNonLockedERC721","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50610a79806100206000396000f3fe6080604052600436106100345760003560e01c806324d2eb41146100395780638cf755891461005b578063ab6a377b14610091575b600080fd5b34801561004557600080fd5b5061005961005436600461088b565b6100a4565b005b34801561006757600080fd5b5061007b6100763660046108d2565b610328565b6040516100889190610909565b60405180910390f35b61007b61009f366004610957565b61040c565b6001600160a01b03831660009081527f25888debd3e1e584ccaebe1162c7763ec457a94078c5d0d9a1d32a926ff9973d602090815260408083208584529091529020547f25888debd3e1e584ccaebe1162c7763ec457a94078c5d0d9a1d32a926ff9973c9082151560ff9091161515036101655760405162461bcd60e51b815260206004820152601d60248201527f546f6b656e20616c726561647920696e20676976656e2073746174652e00000060448201526064015b60405180910390fd5b60405163020604bf60e21b81526004810184905284906000906001600160a01b0383169063081812fc90602401602060405180830381865afa1580156101af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101d391906109e0565b6001600160a01b0316146102435760405163095ea7b360e01b815260006004820152602481018590526001600160a01b0382169063095ea7b390604401600060405180830381600087803b15801561022a57600080fd5b505af115801561023e573d6000803e3d6000fd5b505050505b6001600160a01b038516600090815260018301602090815260408083208784529091529020805460ff191684158015919091179091556102ac576001600160a01b038516600090815260208390526040812080549091906102a390610a13565b909155506102d7565b6001600160a01b038516600090815260208390526040812080549091906102d290610a2c565b909155505b604080516001600160a01b0387168152602081018690528415158183015290517f711ce7f6a2e36a77cf93e5ec797edf5c00f54041473000bda8e291a6656ff4c99181900360600190a15050505050565b60606103348484610755565b156103955760405162461bcd60e51b815260206004820152602b60248201527f43616e6e6f7420706572666f726d207468697320616374696f6e206f6e206c6f60448201526a31b5b2b2103a37b5b2b71760a91b606482015260840161015c565b604080513060248201526001600160a01b038416604482015260648082018690528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16632142170760e11b179052610403856000836107f1565b95945050505050565b6060600061044f84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061081f92505050565b90506001600160e01b031981166323b872dd60e01b148061048057506001600160e01b03198116632142170760e11b145b8061049b57506001600160e01b03198116635c46a7ef60e11b145b156105995760006104e485858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506044925061086b915050565b905061053687826001600160a01b03821660009081527f25888debd3e1e584ccaebe1162c7763ec457a94078c5d0d9a1d32a926ff9973d6020908152604080832084845290915281205460ff166107ea565b156105975760405162461bcd60e51b815260206004820152602b60248201527f43616e6e6f7420706572666f726d207468697320616374696f6e206f6e206c6f60448201526a31b5b2b2103a37b5b2b71760a91b606482015260840161015c565b505b63f6a1584d60e01b6001600160e01b03198216016106aa5760006105f585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506024925061086b915050565b905061064787826001600160a01b03821660009081527f25888debd3e1e584ccaebe1162c7763ec457a94078c5d0d9a1d32a926ff9973d6020908152604080832084845290915281205460ff166107ea565b156106a85760405162461bcd60e51b815260206004820152602b60248201527f43616e6e6f7420706572666f726d207468697320616374696f6e206f6e206c6f60448201526a31b5b2b2103a37b5b2b71760a91b606482015260840161015c565b505b635dd34b9b60e01b6001600160e01b031982160161070a5760405162461bcd60e51b815260206004820152601b60248201527f43616e6e6f7420706572666f726d207468697320616374696f6e2e0000000000604482015260640161015c565b61074b868686868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506107f192505050565b9695505050505050565b6001600160a01b03821660009081527f25888debd3e1e584ccaebe1162c7763ec457a94078c5d0d9a1d32a926ff9973d6020908152604080832084845290915281205460ff16806107ea57506001600160a01b03831660009081527f010881fa8a1edce184936a8e4e08060bba49cb5145c9b396e6e80c0c6b0e12696020908152604080832085845290915290205460ff1615155b9392505050565b606060008083516020850186885af13d82523d6000602084013e80610817573d60208301fd5b509392505050565b60006004825110156108635760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b2103230ba309760991b604482015260640161015c565b506020015190565b016020015190565b6001600160a01b038116811461088857600080fd5b50565b6000806000606084860312156108a057600080fd5b83356108ab81610873565b925060208401359150604084013580151581146108c757600080fd5b809150509250925092565b6000806000606084860312156108e757600080fd5b83356108f281610873565b92506020840135915060408401356108c781610873565b600060208083528351808285015260005b818110156109365785810183015185820160400152820161091a565b506000604082860101526040601f19601f8301168501019250505092915050565b6000806000806060858703121561096d57600080fd5b843561097881610873565b935060208501359250604085013567ffffffffffffffff8082111561099c57600080fd5b818701915087601f8301126109b057600080fd5b8135818111156109bf57600080fd5b8860208285010111156109d157600080fd5b95989497505060200194505050565b6000602082840312156109f257600080fd5b81516107ea81610873565b634e487b7160e01b600052601160045260246000fd5b600060018201610a2557610a256109fd565b5060010190565b600081610a3b57610a3b6109fd565b50600019019056fea26469706673582212202a5a116fbe4fa80fdd7552fb99ea9513b175382cbf53a4098c0821ff08f9a2bc64736f6c63430008130033
Deployed Bytecode
0x6080604052600436106100345760003560e01c806324d2eb41146100395780638cf755891461005b578063ab6a377b14610091575b600080fd5b34801561004557600080fd5b5061005961005436600461088b565b6100a4565b005b34801561006757600080fd5b5061007b6100763660046108d2565b610328565b6040516100889190610909565b60405180910390f35b61007b61009f366004610957565b61040c565b6001600160a01b03831660009081527f25888debd3e1e584ccaebe1162c7763ec457a94078c5d0d9a1d32a926ff9973d602090815260408083208584529091529020547f25888debd3e1e584ccaebe1162c7763ec457a94078c5d0d9a1d32a926ff9973c9082151560ff9091161515036101655760405162461bcd60e51b815260206004820152601d60248201527f546f6b656e20616c726561647920696e20676976656e2073746174652e00000060448201526064015b60405180910390fd5b60405163020604bf60e21b81526004810184905284906000906001600160a01b0383169063081812fc90602401602060405180830381865afa1580156101af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101d391906109e0565b6001600160a01b0316146102435760405163095ea7b360e01b815260006004820152602481018590526001600160a01b0382169063095ea7b390604401600060405180830381600087803b15801561022a57600080fd5b505af115801561023e573d6000803e3d6000fd5b505050505b6001600160a01b038516600090815260018301602090815260408083208784529091529020805460ff191684158015919091179091556102ac576001600160a01b038516600090815260208390526040812080549091906102a390610a13565b909155506102d7565b6001600160a01b038516600090815260208390526040812080549091906102d290610a2c565b909155505b604080516001600160a01b0387168152602081018690528415158183015290517f711ce7f6a2e36a77cf93e5ec797edf5c00f54041473000bda8e291a6656ff4c99181900360600190a15050505050565b60606103348484610755565b156103955760405162461bcd60e51b815260206004820152602b60248201527f43616e6e6f7420706572666f726d207468697320616374696f6e206f6e206c6f60448201526a31b5b2b2103a37b5b2b71760a91b606482015260840161015c565b604080513060248201526001600160a01b038416604482015260648082018690528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16632142170760e11b179052610403856000836107f1565b95945050505050565b6060600061044f84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061081f92505050565b90506001600160e01b031981166323b872dd60e01b148061048057506001600160e01b03198116632142170760e11b145b8061049b57506001600160e01b03198116635c46a7ef60e11b145b156105995760006104e485858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506044925061086b915050565b905061053687826001600160a01b03821660009081527f25888debd3e1e584ccaebe1162c7763ec457a94078c5d0d9a1d32a926ff9973d6020908152604080832084845290915281205460ff166107ea565b156105975760405162461bcd60e51b815260206004820152602b60248201527f43616e6e6f7420706572666f726d207468697320616374696f6e206f6e206c6f60448201526a31b5b2b2103a37b5b2b71760a91b606482015260840161015c565b505b63f6a1584d60e01b6001600160e01b03198216016106aa5760006105f585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506024925061086b915050565b905061064787826001600160a01b03821660009081527f25888debd3e1e584ccaebe1162c7763ec457a94078c5d0d9a1d32a926ff9973d6020908152604080832084845290915281205460ff166107ea565b156106a85760405162461bcd60e51b815260206004820152602b60248201527f43616e6e6f7420706572666f726d207468697320616374696f6e206f6e206c6f60448201526a31b5b2b2103a37b5b2b71760a91b606482015260840161015c565b505b635dd34b9b60e01b6001600160e01b031982160161070a5760405162461bcd60e51b815260206004820152601b60248201527f43616e6e6f7420706572666f726d207468697320616374696f6e2e0000000000604482015260640161015c565b61074b868686868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506107f192505050565b9695505050505050565b6001600160a01b03821660009081527f25888debd3e1e584ccaebe1162c7763ec457a94078c5d0d9a1d32a926ff9973d6020908152604080832084845290915281205460ff16806107ea57506001600160a01b03831660009081527f010881fa8a1edce184936a8e4e08060bba49cb5145c9b396e6e80c0c6b0e12696020908152604080832085845290915290205460ff1615155b9392505050565b606060008083516020850186885af13d82523d6000602084013e80610817573d60208301fd5b509392505050565b60006004825110156108635760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b2103230ba309760991b604482015260640161015c565b506020015190565b016020015190565b6001600160a01b038116811461088857600080fd5b50565b6000806000606084860312156108a057600080fd5b83356108ab81610873565b925060208401359150604084013580151581146108c757600080fd5b809150509250925092565b6000806000606084860312156108e757600080fd5b83356108f281610873565b92506020840135915060408401356108c781610873565b600060208083528351808285015260005b818110156109365785810183015185820160400152820161091a565b506000604082860101526040601f19601f8301168501019250505092915050565b6000806000806060858703121561096d57600080fd5b843561097881610873565b935060208501359250604085013567ffffffffffffffff8082111561099c57600080fd5b818701915087601f8301126109b057600080fd5b8135818111156109bf57600080fd5b8860208285010111156109d157600080fd5b95989497505060200194505050565b6000602082840312156109f257600080fd5b81516107ea81610873565b634e487b7160e01b600052601160045260246000fd5b600060018201610a2557610a256109fd565b5060010190565b600081610a3b57610a3b6109fd565b50600019019056fea26469706673582212202a5a116fbe4fa80fdd7552fb99ea9513b175382cbf53a4098c0821ff08f9a2bc64736f6c63430008130033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.