Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 1,341 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Redeem Elemental... | 21458241 | 3 days ago | IN | 0 ETH | 0.00090051 | ||||
Redeem Elemental... | 21432462 | 7 days ago | IN | 0 ETH | 0.0078943 | ||||
Redeem Elemental... | 21393090 | 12 days ago | IN | 0 ETH | 0.00573813 | ||||
Redeem Elemental... | 21393077 | 12 days ago | IN | 0 ETH | 0.00787815 | ||||
Redeem Derivativ... | 20952196 | 74 days ago | IN | 0 ETH | 0.00148087 | ||||
Redeem Derivativ... | 20622416 | 120 days ago | IN | 0 ETH | 0.00019753 | ||||
Redeem Derivativ... | 20601371 | 123 days ago | IN | 0 ETH | 0.00063639 | ||||
Redeem Derivativ... | 20451746 | 144 days ago | IN | 0 ETH | 0.00014211 | ||||
Redeem Derivativ... | 20303300 | 164 days ago | IN | 0 ETH | 0.00033966 | ||||
Redeem Derivativ... | 20289889 | 166 days ago | IN | 0 ETH | 0.00038158 | ||||
Redeem Derivativ... | 20247892 | 172 days ago | IN | 0 ETH | 0.00037799 | ||||
Redeem Elemental... | 20092695 | 194 days ago | IN | 0 ETH | 0.00104363 | ||||
Redeem Derivativ... | 20050305 | 200 days ago | IN | 0 ETH | 0.00168598 | ||||
Redeem Elemental... | 20036042 | 202 days ago | IN | 0 ETH | 0.00517778 | ||||
Redeem Derivativ... | 19853195 | 227 days ago | IN | 0 ETH | 0.0003893 | ||||
Redeem Derivativ... | 19664726 | 254 days ago | IN | 0 ETH | 0.00084065 | ||||
Redeem Derivativ... | 19644934 | 256 days ago | IN | 0 ETH | 0.0013741 | ||||
Redeem Derivativ... | 19598420 | 263 days ago | IN | 0 ETH | 0.0016461 | ||||
Redeem Elemental... | 19508779 | 276 days ago | IN | 0 ETH | 0.00275513 | ||||
Redeem Derivativ... | 19508766 | 276 days ago | IN | 0 ETH | 0.00823315 | ||||
Redeem Derivativ... | 19449871 | 284 days ago | IN | 0 ETH | 0.00446042 | ||||
Redeem Derivativ... | 19312317 | 303 days ago | IN | 0 ETH | 0.00967369 | ||||
Redeem Elemental... | 19065657 | 338 days ago | IN | 0 ETH | 0.00436564 | ||||
Redeem Elemental... | 19065652 | 338 days ago | IN | 0 ETH | 0.00650185 | ||||
Redeem Elemental... | 19065644 | 338 days ago | IN | 0 ETH | 0.00708676 |
Advanced mode: Intended for advanced users or developers and will display all Internal Transactions including zero value transfers. Name tag integration is not available in advanced view.
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
||||
---|---|---|---|---|---|---|---|
21458241 | 3 days ago | 0 ETH | |||||
21458241 | 3 days ago | 0 ETH | |||||
21458241 | 3 days ago | 0 ETH | |||||
21432462 | 7 days ago | 0 ETH | |||||
21432462 | 7 days ago | 0 ETH | |||||
21432462 | 7 days ago | 0 ETH | |||||
21432462 | 7 days ago | 0 ETH | |||||
21432462 | 7 days ago | 0 ETH | |||||
21432462 | 7 days ago | 0 ETH | |||||
21432462 | 7 days ago | 0 ETH | |||||
21432462 | 7 days ago | 0 ETH | |||||
21432462 | 7 days ago | 0 ETH | |||||
21432462 | 7 days ago | 0 ETH | |||||
21393090 | 12 days ago | 0 ETH | |||||
21393090 | 12 days ago | 0 ETH | |||||
21393090 | 12 days ago | 0 ETH | |||||
21393090 | 12 days ago | 0 ETH | |||||
21393090 | 12 days ago | 0 ETH | |||||
21393090 | 12 days ago | 0 ETH | |||||
21393090 | 12 days ago | 0 ETH | |||||
21393077 | 12 days ago | 0 ETH | |||||
21393077 | 12 days ago | 0 ETH | |||||
21393077 | 12 days ago | 0 ETH | |||||
21393077 | 12 days ago | 0 ETH | |||||
21393077 | 12 days ago | 0 ETH |
Loading...
Loading
Contract Name:
DoubleDrop
Compiler Version
v0.8.16+commit.07a7930e
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.16; import "openzeppelin-contracts/contracts/token/ERC721/IERC721.sol"; import "openzeppelin-contracts/contracts/access/Ownable.sol"; import "./IDoubleDropNFT.sol"; import "./IDoubleDrop.sol"; import "./IProvenance.sol"; import "./SignedRedeemer.sol"; /// @title The Hashmasks Double Drop /// @author fancyrats.io /** * @notice Holders of Hashmasks NFTs can redeem Hashmasks Elementals, Derivatives, or burn their masks to get both! * Holders can only choose one redemption option per Hashmask NFT. * Once a selection is made, that NFT cannot be used to redeem again! Choose wisely! */ /** * @dev Hashmasks holders must set approval for this contract in order to "burn". * The original Hashmasks contract does not have burn functionality, so we move masks into the 0xdEaD wallet. * Elementals and Derivatives contracts must be deployed and addresses set prior to activating redemption. */ contract DoubleDrop is IDoubleDrop, Ownable, SignedRedeemer { event ElementalsRedeemed(uint256[] indexed tokenIds, address indexed redeemer); event DerivativesRedeemed(uint256[] indexed tokenIds, address indexed redeemer); event HashmasksBurned(uint256[] indexed tokenIds, address indexed redeemer); address private constant BURN_ADDRESS = 0x000000000000000000000000000000000000dEaD; bool public isActive; bool public contractsInitialized; uint256 public elementalsProvenance; mapping(uint256 => bool) public redeemedHashmasks; IERC721 public hashmasks; IDoubleDropNFT public derivatives; IDoubleDropNFT public elementals; constructor(address signer_) Ownable() SignedRedeemer(signer_) {} /// @notice Redeem Hashmasks Elementals NFTs /// @dev Resulting Elementals will have matching token IDs. /// @param signature Signed message from our website that validates token ownership /// @param tokenIds Ordered array of Hashmasks NFT ids used to claim the Elementals. function redeemElementals(bytes calldata signature, uint256[] calldata tokenIds) public isValidRedemption(signature, tokenIds) { emit ElementalsRedeemed(tokenIds, msg.sender); elementals.redeem(tokenIds, msg.sender); } /// @notice Redeem Hashmasks Derivatives NFTs /// @dev Resulting Derivatives will have matching token IDs. /// @param signature Signed message from our website that validates token ownership /// @param tokenIds Ordered array of Hashmasks NFT ids used to claim the Derivatives. function redeemDerivatives(bytes calldata signature, uint256[] calldata tokenIds) public isValidRedemption(signature, tokenIds) { emit DerivativesRedeemed(tokenIds, msg.sender); derivatives.redeem(tokenIds, msg.sender); } /** * @notice Burns Hashmasks and redeems one elemental and one derivative per Hashmask burned. * Requires this contract to be approved as an operator for the Hashmasks tokens provided. * CAUTION: ONLY APPROVE OR SETAPPROVALFORALL FROM THEHASHMASKS.COM * CAUTION: THIS ACTION IS PERMANENT. Holders will not be able to retrieve their burned Hashmask NFTs. */ /** * @dev Resulting Derivatives and Elementals will have matching token IDs. * Approval must be managed on the frontend. */ /// @param signature Signed message from our website that validates token ownership /// @param tokenIds Ordered array of Hashmasks NFT ids to burn and use for double redemption function burnMasksForDoubleRedemption(bytes calldata signature, uint256[] calldata tokenIds) public isValidRedemption(signature, tokenIds) { emit HashmasksBurned(tokenIds, msg.sender); emit ElementalsRedeemed(tokenIds, msg.sender); emit DerivativesRedeemed(tokenIds, msg.sender); _burnMasks(tokenIds); elementals.redeem(tokenIds, msg.sender); derivatives.redeem(tokenIds, msg.sender); } /** * @notice Sets the Derivatives and Elementals contract addresses for redemption. * Caller must be contract owner. * CAUTION: ADDRESSES CAN ONLY BE SET ONCE. */ /// @dev derivativesAddress and elementalsAddress must conform to IDoubleDropNFT /// @param hashmasksAddress The Hashmasks NFT contract address /// @param derivativesAddress The Hashmasks Derivatives NFT contract address /// @param elementalsAddress The Hashmasks Elementals NFT contract address function setTokenContracts(address hashmasksAddress, address derivativesAddress, address elementalsAddress) public onlyOwner { if (contractsInitialized) revert ContractsAlreadyInitialized(); if (hashmasksAddress == address(0) || derivativesAddress == address(0) || elementalsAddress == address(0)) { revert ContractsCannotBeNull(); } contractsInitialized = true; hashmasks = IERC721(hashmasksAddress); derivatives = IDoubleDropNFT(derivativesAddress); elementals = IDoubleDropNFT(elementalsAddress); } /** * @notice Asks the ProvenanceGenerator for a random number * Caller must be contract owner * Can only be set once */ /// @dev Provenance implementation uses chainlink, so that will need setup first /// @param generatorAddress Contract conforming to IProvenance function setRandomProvenance(address generatorAddress) public onlyOwner { if (elementalsProvenance != 0) revert ElementalsProvenanceAlreadySet(); if (generatorAddress == address(0)) revert ProvenanceContractCannotBeNull(); IProvenance provenanceGenerator = IProvenance(generatorAddress); elementalsProvenance = provenanceGenerator.getRandomProvenance(); if (elementalsProvenance == 0) revert ElementalsProvenanceNotSet(); } /** * @notice Sets the known signer address used by the redemption backend to validate ownership * Caller must be contract owner. */ /// @dev signer is responsible for signing redemption messages on the backend /// @param signer_ public address to expected to sign redemption signatures function setSigner(address signer_) public onlyOwner { _setSigner(signer_); } /** * @notice Turn on/off Double Drop redemption. * Starts out paused. * Caller must be contract owner. */ /// @dev setTokenContracts must be called prior to activating. /// @param isActive_ updated redemption active status. false to pause. true to resume. function setIsActive(bool isActive_) public onlyOwner { if (address(hashmasks) == address(0) || address(derivatives) == address(0) || address(elementals) == address(0)) { revert ContractsNotInitialized(); } if (elementalsProvenance == 0) revert ElementalsProvenanceNotSet(); isActive = isActive_; } function _burnMasks(uint256[] calldata tokenIds) private { for (uint256 i = 0; i < tokenIds.length; i++) { hashmasks.safeTransferFrom(msg.sender, BURN_ADDRESS, tokenIds[i]); } } modifier isValidRedemption(bytes calldata signature, uint256[] calldata tokenIds) { if (!isActive) revert RedemptionNotActive(); if (!validateSignature(signature, tokenIds, msg.sender)) revert InvalidSignature(); for (uint256 i = 0; i < tokenIds.length; i++) { if (hashmasks.ownerOf(tokenIds[i]) != msg.sender) revert NotTokenOwner(); if (redeemedHashmasks[tokenIds[i]]) revert TokenAlreadyRedeemed(); redeemedHashmasks[tokenIds[i]] = true; } _; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// 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/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; import "../Strings.sol"; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } else if (error == RecoverError.InvalidSignatureV) { revert("ECDSA: invalid signature 'v' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { // Check the signature length // - case 65: r,s,v signature (standard) // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._ if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else if (signature.length == 64) { bytes32 r; bytes32 vs; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) vs := mload(add(signature, 0x40)) } return tryRecover(hash, r, vs); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } if (v != 27 && v != 28) { return (address(0), RecoverError.InvalidSignatureV); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } }
// 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.16; interface IDoubleDrop { /** * Elementals provenance contract cannot be null */ error ProvenanceContractCannotBeNull(); /** * Elementals provenance not set */ error ElementalsProvenanceNotSet(); /** * Elementals provenance already set */ error ElementalsProvenanceAlreadySet(); /** * Redemption contracts already set */ error ContractsAlreadyInitialized(); /** * Redemption contracts cannot be NULL */ error ContractsCannotBeNull(); /** * Redemption contracts are not yet set */ error ContractsNotInitialized(); /** * Redemption is not active */ error RedemptionNotActive(); /** * Invalid signature provided */ error InvalidSignature(); /** * Hashmask token already used for redemption */ error TokenAlreadyRedeemed(); /** * Address is not the token owner */ error NotTokenOwner(); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.16; interface IDoubleDropNFT { /** * The token does not exist. */ error URIQueryForNonexistentToken(); /** * Metadata frozen. Cannot set new base URI. */ error MetadataFrozen(); /** * Cannot set redeemer contract multiple times */ error RedeemerAlreadySet(); /** * Redeemer contract not set */ error RedeemerNotSet(); /** * Only the redeemer contract can mint */ error OnlyRedeemerCanMint(); function redeem(uint256[] calldata _tokenIds, address _to) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.16; interface IProvenance { function getRandomProvenance() external returns (uint256); error ProvenanceAlreadyRequested(); error ProvenanceAlreadyGenerated(); error ProvenanceNotGenerated(); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.16; import "openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol"; contract SignedRedeemer { using ECDSA for bytes32; address public signer; constructor(address signer_) { signer = signer_; } /** * @notice Uses ECDSA to validate the provided signature was signed by the known address. */ /** * @dev For a given unique ordered array of tokenIds, * a valid signature is a message keccack256(abi.encode(owner, tokenIds)) signed by the known address. */ /// @param signature Signed message /// @param tokenIds ordered unique array of tokenIds encoded in the signed message /// @param to token owner encoded in the signed message function validateSignature( bytes memory signature, uint256[] calldata tokenIds, // must be in numeric order address to ) public view returns (bool) { bytes memory message = abi.encode(to, tokenIds); bytes32 messageHash = ECDSA.toEthSignedMessageHash(keccak256(message)); address recovered = messageHash.recover(signature); return signer == recovered; } function _setSigner(address signer_) internal { signer = signer_; } }
{ "remappings": [ "ERC721A/=lib/ERC721A/contracts/", "chainlink/=lib/chainlink/", "ds-test/=lib/solmate/lib/ds-test/src/", "forge-std/=lib/forge-std/src/", "openzeppelin-contracts/=lib/openzeppelin-contracts/", "solmate/=lib/solmate/src/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "bytecodeHash": "ipfs" }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "london", "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"signer_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ContractsAlreadyInitialized","type":"error"},{"inputs":[],"name":"ContractsCannotBeNull","type":"error"},{"inputs":[],"name":"ContractsNotInitialized","type":"error"},{"inputs":[],"name":"ElementalsProvenanceAlreadySet","type":"error"},{"inputs":[],"name":"ElementalsProvenanceNotSet","type":"error"},{"inputs":[],"name":"InvalidSignature","type":"error"},{"inputs":[],"name":"NotTokenOwner","type":"error"},{"inputs":[],"name":"ProvenanceContractCannotBeNull","type":"error"},{"inputs":[],"name":"RedemptionNotActive","type":"error"},{"inputs":[],"name":"TokenAlreadyRedeemed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"indexed":true,"internalType":"address","name":"redeemer","type":"address"}],"name":"DerivativesRedeemed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"indexed":true,"internalType":"address","name":"redeemer","type":"address"}],"name":"ElementalsRedeemed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"indexed":true,"internalType":"address","name":"redeemer","type":"address"}],"name":"HashmasksBurned","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"burnMasksForDoubleRedemption","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contractsInitialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"derivatives","outputs":[{"internalType":"contract IDoubleDropNFT","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"elementals","outputs":[{"internalType":"contract IDoubleDropNFT","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"elementalsProvenance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hashmasks","outputs":[{"internalType":"contract IERC721","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"redeemDerivatives","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"redeemElementals","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"redeemedHashmasks","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"isActive_","type":"bool"}],"name":"setIsActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"generatorAddress","type":"address"}],"name":"setRandomProvenance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"signer_","type":"address"}],"name":"setSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"hashmasksAddress","type":"address"},{"internalType":"address","name":"derivativesAddress","type":"address"},{"internalType":"address","name":"elementalsAddress","type":"address"}],"name":"setTokenContracts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"signer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"address","name":"to","type":"address"}],"name":"validateSignature","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b506040516118fe3803806118fe83398101604081905261002f916100af565b806100393361005f565b600180546001600160a01b0319166001600160a01b0392909216919091179055506100df565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000602082840312156100c157600080fd5b81516001600160a01b03811681146100d857600080fd5b9392505050565b611810806100ee6000396000f3fe608060405234801561001057600080fd5b50600436106101215760003560e01c80637ab4757d116100ad578063a8a5cad311610071578063a8a5cad314610267578063c7c3f2a21461027a578063c8daa2511461028d578063d4f986d7146102a0578063f2fde38b146102b457600080fd5b80637ab4757d1461020a57806384e7e3db1461021d5780638da5cb5b1461023057806391b7c74014610241578063a04d4e361461025457600080fd5b80632908afc9116100f45780632908afc9146101b25780632e146249146101c9578063693d33fe146101dc5780636c19e783146101ef578063715018a61461020257600080fd5b8063156cfedb1461012657806322f3e2d41461015e578063238ac933146101725780632750fc781461019d575b600080fd5b6101496101343660046113d3565b60036020526000908152604090205460ff1681565b60405190151581526020015b60405180910390f35b60015461014990600160a01b900460ff1681565b600154610185906001600160a01b031681565b6040516001600160a01b039091168152602001610155565b6101b06101ab3660046113ec565b6102c7565b005b6101bb60025481565b604051908152602001610155565b600454610185906001600160a01b031681565b600554610185906001600160a01b031681565b6101b06101fd36600461143a565b610366565b6101b061038f565b600654610185906001600160a01b031681565b6101b061022b366004611457565b6103a3565b6000546001600160a01b0316610185565b61014961024f3660046114fd565b610475565b6101b061026236600461143a565b610529565b6101b06102753660046115ea565b61060b565b6101b06102883660046115ea565b6108b5565b6101b061029b3660046115ea565b610b23565b60015461014990600160a81b900460ff1681565b6101b06102c236600461143a565b610e85565b6102cf610f00565b6004546001600160a01b031615806102f057506005546001600160a01b0316155b8061030457506006546001600160a01b0316155b156103255760405160016220ee2d60e01b0319815260040160405180910390fd5b600254600003610348576040516372c7e25960e11b815260040160405180910390fd5b60018054911515600160a01b0260ff60a01b19909216919091179055565b61036e610f00565b600180546001600160a01b0319166001600160a01b03831617905550565b50565b610397610f00565b6103a16000610f5a565b565b6103ab610f00565b600154600160a81b900460ff16156103d6576040516317df678160e31b815260040160405180910390fd5b6001600160a01b03831615806103f357506001600160a01b038216155b8061040557506001600160a01b038116155b156104235760405163bec8d64160e01b815260040160405180910390fd5b6001805460ff60a81b1916600160a81b179055600480546001600160a01b039485166001600160a01b031991821617909155600580549385169382169390931790925560068054919093169116179055565b60008082858560405160200161048d939291906116b3565b604051602081830303815290604052905060006104fe82805190602001206040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b9050600061050c8289610faa565b6001546001600160a01b0391821691161498975050505050505050565b610531610f00565b6002541561055257604051630e87849960e21b815260040160405180910390fd5b6001600160a01b038116610579576040516321fc97c960e11b815260040160405180910390fd5b6000819050806001600160a01b031663aa192b216040518163ffffffff1660e01b81526004016020604051808303816000875af11580156105be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105e291906116e1565b6002819055600003610607576040516372c7e25960e11b815260040160405180910390fd5b5050565b83838383600160149054906101000a900460ff1661063c57604051632644396160e21b815260040160405180910390fd5b61068084848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250869250859150339050610475565b61069d57604051638baa579f60e01b815260040160405180910390fd5b60005b818110156108025760045433906001600160a01b0316636352211e8585858181106106cd576106cd6116fa565b905060200201356040518263ffffffff1660e01b81526004016106f291815260200190565b602060405180830381865afa15801561070f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107339190611710565b6001600160a01b03161461075a576040516359dc379f60e01b815260040160405180910390fd5b60036000848484818110610770576107706116fa565b602090810292909201358352508101919091526040016000205460ff16156107ab57604051631bd64ea560e01b815260040160405180910390fd5b6001600360008585858181106107c3576107c36116fa565b90506020020135815260200190815260200160002060006101000a81548160ff02191690831515021790555080806107fa90611743565b9150506106a0565b506040513390610815908890889061175c565b604051908190038120907f9f2d6403c0ea9925db709c74725b585c90423bd3bf4be9ef44a780a8ca5643cc90600090a360065460405163249723e960e11b81526001600160a01b039091169063492e47d29061087990899089903390600401611785565b600060405180830381600087803b15801561089357600080fd5b505af11580156108a7573d6000803e3d6000fd5b505050505050505050505050565b83838383600160149054906101000a900460ff166108e657604051632644396160e21b815260040160405180910390fd5b61092a84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250869250859150339050610475565b61094757604051638baa579f60e01b815260040160405180910390fd5b60005b81811015610aac5760045433906001600160a01b0316636352211e858585818110610977576109776116fa565b905060200201356040518263ffffffff1660e01b815260040161099c91815260200190565b602060405180830381865afa1580156109b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109dd9190611710565b6001600160a01b031614610a04576040516359dc379f60e01b815260040160405180910390fd5b60036000848484818110610a1a57610a1a6116fa565b602090810292909201358352508101919091526040016000205460ff1615610a5557604051631bd64ea560e01b815260040160405180910390fd5b600160036000858585818110610a6d57610a6d6116fa565b90506020020135815260200190815260200160002060006101000a81548160ff0219169083151502179055508080610aa490611743565b91505061094a565b506040513390610abf908890889061175c565b604051908190038120907f32d0cbdf3dad73cc997f09da5a05a94895f5fe85dc85827745aadfbff874b54690600090a360055460405163249723e960e11b81526001600160a01b039091169063492e47d29061087990899089903390600401611785565b83838383600160149054906101000a900460ff16610b5457604051632644396160e21b815260040160405180910390fd5b610b9884848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250869250859150339050610475565b610bb557604051638baa579f60e01b815260040160405180910390fd5b60005b81811015610d1a5760045433906001600160a01b0316636352211e858585818110610be557610be56116fa565b905060200201356040518263ffffffff1660e01b8152600401610c0a91815260200190565b602060405180830381865afa158015610c27573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c4b9190611710565b6001600160a01b031614610c72576040516359dc379f60e01b815260040160405180910390fd5b60036000848484818110610c8857610c886116fa565b602090810292909201358352508101919091526040016000205460ff1615610cc357604051631bd64ea560e01b815260040160405180910390fd5b600160036000858585818110610cdb57610cdb6116fa565b90506020020135815260200190815260200160002060006101000a81548160ff0219169083151502179055508080610d1290611743565b915050610bb8565b506040513390610d2d908890889061175c565b604051908190038120907ff9c45a6f876b3d517dce7be4dd43bb0192285da872abd84217c1364d171065e290600090a36040513390610d6f908890889061175c565b604051908190038120907f9f2d6403c0ea9925db709c74725b585c90423bd3bf4be9ef44a780a8ca5643cc90600090a36040513390610db1908890889061175c565b604051908190038120907f32d0cbdf3dad73cc997f09da5a05a94895f5fe85dc85827745aadfbff874b54690600090a3610deb8686610fd0565b60065460405163249723e960e11b81526001600160a01b039091169063492e47d290610e1f90899089903390600401611785565b600060405180830381600087803b158015610e3957600080fd5b505af1158015610e4d573d6000803e3d6000fd5b505060055460405163249723e960e11b81526001600160a01b03909116925063492e47d2915061087990899089903390600401611785565b610e8d610f00565b6001600160a01b038116610ef75760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b61038c81610f5a565b6000546001600160a01b031633146103a15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610eee565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000806000610fb98585611089565b91509150610fc6816110f7565b5090505b92915050565b60005b81811015611084576004546001600160a01b03166342842e0e3361dead868686818110611002576110026116fa565b6040516001600160e01b031960e088901b1681526001600160a01b03958616600482015294909316602485015250602090910201356044820152606401600060405180830381600087803b15801561105957600080fd5b505af115801561106d573d6000803e3d6000fd5b50505050808061107c90611743565b915050610fd3565b505050565b60008082516041036110bf5760208301516040840151606085015160001a6110b3878285856112ad565b945094505050506110f0565b82516040036110e857602083015160408401516110dd86838361139a565b9350935050506110f0565b506000905060025b9250929050565b600081600481111561110b5761110b6117b1565b036111135750565b6001816004811115611127576111276117b1565b036111745760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610eee565b6002816004811115611188576111886117b1565b036111d55760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610eee565b60038160048111156111e9576111e96117b1565b036112415760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610eee565b6004816004811115611255576112556117b1565b0361038c5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610eee565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156112e45750600090506003611391565b8460ff16601b141580156112fc57508460ff16601c14155b1561130d5750600090506004611391565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015611361573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661138a57600060019250925050611391565b9150600090505b94509492505050565b6000806001600160ff1b038316816113b760ff86901c601b6117c7565b90506113c5878288856112ad565b935093505050935093915050565b6000602082840312156113e557600080fd5b5035919050565b6000602082840312156113fe57600080fd5b8135801515811461140e57600080fd5b9392505050565b6001600160a01b038116811461038c57600080fd5b803561143581611415565b919050565b60006020828403121561144c57600080fd5b813561140e81611415565b60008060006060848603121561146c57600080fd5b833561147781611415565b9250602084013561148781611415565b9150604084013561149781611415565b809150509250925092565b634e487b7160e01b600052604160045260246000fd5b60008083601f8401126114ca57600080fd5b50813567ffffffffffffffff8111156114e257600080fd5b6020830191508360208260051b85010111156110f057600080fd5b6000806000806060858703121561151357600080fd5b843567ffffffffffffffff8082111561152b57600080fd5b818701915087601f83011261153f57600080fd5b813581811115611551576115516114a2565b604051601f8201601f19908116603f01168101908382118183101715611579576115796114a2565b816040528281528a602084870101111561159257600080fd5b8260208601602083013760006020848301015280985050505060208701359150808211156115bf57600080fd5b506115cc878288016114b8565b90945092506115df90506040860161142a565b905092959194509250565b6000806000806040858703121561160057600080fd5b843567ffffffffffffffff8082111561161857600080fd5b818701915087601f83011261162c57600080fd5b81358181111561163b57600080fd5b88602082850101111561164d57600080fd5b60209283019650945090860135908082111561166857600080fd5b50611675878288016114b8565b95989497509550505050565b81835260006001600160fb1b0383111561169a57600080fd5b8260051b80836020870137939093016020019392505050565b6001600160a01b03841681526040602082018190526000906116d89083018486611681565b95945050505050565b6000602082840312156116f357600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561172257600080fd5b815161140e81611415565b634e487b7160e01b600052601160045260246000fd5b6000600182016117555761175561172d565b5060010190565b60006001600160fb1b0383111561177257600080fd5b8260051b80858437919091019392505050565b604081526000611799604083018587611681565b905060018060a01b0383166020830152949350505050565b634e487b7160e01b600052602160045260246000fd5b80820180821115610fca57610fca61172d56fea2646970667358221220845b6ec6b55914377d43ec06663c0327d86f931725471d4c23e0781a72141f1264736f6c634300081000330000000000000000000000002bdb254079d55220bd093f9568b685c5af4da140
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101215760003560e01c80637ab4757d116100ad578063a8a5cad311610071578063a8a5cad314610267578063c7c3f2a21461027a578063c8daa2511461028d578063d4f986d7146102a0578063f2fde38b146102b457600080fd5b80637ab4757d1461020a57806384e7e3db1461021d5780638da5cb5b1461023057806391b7c74014610241578063a04d4e361461025457600080fd5b80632908afc9116100f45780632908afc9146101b25780632e146249146101c9578063693d33fe146101dc5780636c19e783146101ef578063715018a61461020257600080fd5b8063156cfedb1461012657806322f3e2d41461015e578063238ac933146101725780632750fc781461019d575b600080fd5b6101496101343660046113d3565b60036020526000908152604090205460ff1681565b60405190151581526020015b60405180910390f35b60015461014990600160a01b900460ff1681565b600154610185906001600160a01b031681565b6040516001600160a01b039091168152602001610155565b6101b06101ab3660046113ec565b6102c7565b005b6101bb60025481565b604051908152602001610155565b600454610185906001600160a01b031681565b600554610185906001600160a01b031681565b6101b06101fd36600461143a565b610366565b6101b061038f565b600654610185906001600160a01b031681565b6101b061022b366004611457565b6103a3565b6000546001600160a01b0316610185565b61014961024f3660046114fd565b610475565b6101b061026236600461143a565b610529565b6101b06102753660046115ea565b61060b565b6101b06102883660046115ea565b6108b5565b6101b061029b3660046115ea565b610b23565b60015461014990600160a81b900460ff1681565b6101b06102c236600461143a565b610e85565b6102cf610f00565b6004546001600160a01b031615806102f057506005546001600160a01b0316155b8061030457506006546001600160a01b0316155b156103255760405160016220ee2d60e01b0319815260040160405180910390fd5b600254600003610348576040516372c7e25960e11b815260040160405180910390fd5b60018054911515600160a01b0260ff60a01b19909216919091179055565b61036e610f00565b600180546001600160a01b0319166001600160a01b03831617905550565b50565b610397610f00565b6103a16000610f5a565b565b6103ab610f00565b600154600160a81b900460ff16156103d6576040516317df678160e31b815260040160405180910390fd5b6001600160a01b03831615806103f357506001600160a01b038216155b8061040557506001600160a01b038116155b156104235760405163bec8d64160e01b815260040160405180910390fd5b6001805460ff60a81b1916600160a81b179055600480546001600160a01b039485166001600160a01b031991821617909155600580549385169382169390931790925560068054919093169116179055565b60008082858560405160200161048d939291906116b3565b604051602081830303815290604052905060006104fe82805190602001206040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b9050600061050c8289610faa565b6001546001600160a01b0391821691161498975050505050505050565b610531610f00565b6002541561055257604051630e87849960e21b815260040160405180910390fd5b6001600160a01b038116610579576040516321fc97c960e11b815260040160405180910390fd5b6000819050806001600160a01b031663aa192b216040518163ffffffff1660e01b81526004016020604051808303816000875af11580156105be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105e291906116e1565b6002819055600003610607576040516372c7e25960e11b815260040160405180910390fd5b5050565b83838383600160149054906101000a900460ff1661063c57604051632644396160e21b815260040160405180910390fd5b61068084848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250869250859150339050610475565b61069d57604051638baa579f60e01b815260040160405180910390fd5b60005b818110156108025760045433906001600160a01b0316636352211e8585858181106106cd576106cd6116fa565b905060200201356040518263ffffffff1660e01b81526004016106f291815260200190565b602060405180830381865afa15801561070f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107339190611710565b6001600160a01b03161461075a576040516359dc379f60e01b815260040160405180910390fd5b60036000848484818110610770576107706116fa565b602090810292909201358352508101919091526040016000205460ff16156107ab57604051631bd64ea560e01b815260040160405180910390fd5b6001600360008585858181106107c3576107c36116fa565b90506020020135815260200190815260200160002060006101000a81548160ff02191690831515021790555080806107fa90611743565b9150506106a0565b506040513390610815908890889061175c565b604051908190038120907f9f2d6403c0ea9925db709c74725b585c90423bd3bf4be9ef44a780a8ca5643cc90600090a360065460405163249723e960e11b81526001600160a01b039091169063492e47d29061087990899089903390600401611785565b600060405180830381600087803b15801561089357600080fd5b505af11580156108a7573d6000803e3d6000fd5b505050505050505050505050565b83838383600160149054906101000a900460ff166108e657604051632644396160e21b815260040160405180910390fd5b61092a84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250869250859150339050610475565b61094757604051638baa579f60e01b815260040160405180910390fd5b60005b81811015610aac5760045433906001600160a01b0316636352211e858585818110610977576109776116fa565b905060200201356040518263ffffffff1660e01b815260040161099c91815260200190565b602060405180830381865afa1580156109b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109dd9190611710565b6001600160a01b031614610a04576040516359dc379f60e01b815260040160405180910390fd5b60036000848484818110610a1a57610a1a6116fa565b602090810292909201358352508101919091526040016000205460ff1615610a5557604051631bd64ea560e01b815260040160405180910390fd5b600160036000858585818110610a6d57610a6d6116fa565b90506020020135815260200190815260200160002060006101000a81548160ff0219169083151502179055508080610aa490611743565b91505061094a565b506040513390610abf908890889061175c565b604051908190038120907f32d0cbdf3dad73cc997f09da5a05a94895f5fe85dc85827745aadfbff874b54690600090a360055460405163249723e960e11b81526001600160a01b039091169063492e47d29061087990899089903390600401611785565b83838383600160149054906101000a900460ff16610b5457604051632644396160e21b815260040160405180910390fd5b610b9884848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250869250859150339050610475565b610bb557604051638baa579f60e01b815260040160405180910390fd5b60005b81811015610d1a5760045433906001600160a01b0316636352211e858585818110610be557610be56116fa565b905060200201356040518263ffffffff1660e01b8152600401610c0a91815260200190565b602060405180830381865afa158015610c27573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c4b9190611710565b6001600160a01b031614610c72576040516359dc379f60e01b815260040160405180910390fd5b60036000848484818110610c8857610c886116fa565b602090810292909201358352508101919091526040016000205460ff1615610cc357604051631bd64ea560e01b815260040160405180910390fd5b600160036000858585818110610cdb57610cdb6116fa565b90506020020135815260200190815260200160002060006101000a81548160ff0219169083151502179055508080610d1290611743565b915050610bb8565b506040513390610d2d908890889061175c565b604051908190038120907ff9c45a6f876b3d517dce7be4dd43bb0192285da872abd84217c1364d171065e290600090a36040513390610d6f908890889061175c565b604051908190038120907f9f2d6403c0ea9925db709c74725b585c90423bd3bf4be9ef44a780a8ca5643cc90600090a36040513390610db1908890889061175c565b604051908190038120907f32d0cbdf3dad73cc997f09da5a05a94895f5fe85dc85827745aadfbff874b54690600090a3610deb8686610fd0565b60065460405163249723e960e11b81526001600160a01b039091169063492e47d290610e1f90899089903390600401611785565b600060405180830381600087803b158015610e3957600080fd5b505af1158015610e4d573d6000803e3d6000fd5b505060055460405163249723e960e11b81526001600160a01b03909116925063492e47d2915061087990899089903390600401611785565b610e8d610f00565b6001600160a01b038116610ef75760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b61038c81610f5a565b6000546001600160a01b031633146103a15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610eee565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000806000610fb98585611089565b91509150610fc6816110f7565b5090505b92915050565b60005b81811015611084576004546001600160a01b03166342842e0e3361dead868686818110611002576110026116fa565b6040516001600160e01b031960e088901b1681526001600160a01b03958616600482015294909316602485015250602090910201356044820152606401600060405180830381600087803b15801561105957600080fd5b505af115801561106d573d6000803e3d6000fd5b50505050808061107c90611743565b915050610fd3565b505050565b60008082516041036110bf5760208301516040840151606085015160001a6110b3878285856112ad565b945094505050506110f0565b82516040036110e857602083015160408401516110dd86838361139a565b9350935050506110f0565b506000905060025b9250929050565b600081600481111561110b5761110b6117b1565b036111135750565b6001816004811115611127576111276117b1565b036111745760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610eee565b6002816004811115611188576111886117b1565b036111d55760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610eee565b60038160048111156111e9576111e96117b1565b036112415760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610eee565b6004816004811115611255576112556117b1565b0361038c5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610eee565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156112e45750600090506003611391565b8460ff16601b141580156112fc57508460ff16601c14155b1561130d5750600090506004611391565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015611361573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661138a57600060019250925050611391565b9150600090505b94509492505050565b6000806001600160ff1b038316816113b760ff86901c601b6117c7565b90506113c5878288856112ad565b935093505050935093915050565b6000602082840312156113e557600080fd5b5035919050565b6000602082840312156113fe57600080fd5b8135801515811461140e57600080fd5b9392505050565b6001600160a01b038116811461038c57600080fd5b803561143581611415565b919050565b60006020828403121561144c57600080fd5b813561140e81611415565b60008060006060848603121561146c57600080fd5b833561147781611415565b9250602084013561148781611415565b9150604084013561149781611415565b809150509250925092565b634e487b7160e01b600052604160045260246000fd5b60008083601f8401126114ca57600080fd5b50813567ffffffffffffffff8111156114e257600080fd5b6020830191508360208260051b85010111156110f057600080fd5b6000806000806060858703121561151357600080fd5b843567ffffffffffffffff8082111561152b57600080fd5b818701915087601f83011261153f57600080fd5b813581811115611551576115516114a2565b604051601f8201601f19908116603f01168101908382118183101715611579576115796114a2565b816040528281528a602084870101111561159257600080fd5b8260208601602083013760006020848301015280985050505060208701359150808211156115bf57600080fd5b506115cc878288016114b8565b90945092506115df90506040860161142a565b905092959194509250565b6000806000806040858703121561160057600080fd5b843567ffffffffffffffff8082111561161857600080fd5b818701915087601f83011261162c57600080fd5b81358181111561163b57600080fd5b88602082850101111561164d57600080fd5b60209283019650945090860135908082111561166857600080fd5b50611675878288016114b8565b95989497509550505050565b81835260006001600160fb1b0383111561169a57600080fd5b8260051b80836020870137939093016020019392505050565b6001600160a01b03841681526040602082018190526000906116d89083018486611681565b95945050505050565b6000602082840312156116f357600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561172257600080fd5b815161140e81611415565b634e487b7160e01b600052601160045260246000fd5b6000600182016117555761175561172d565b5060010190565b60006001600160fb1b0383111561177257600080fd5b8260051b80858437919091019392505050565b604081526000611799604083018587611681565b905060018060a01b0383166020830152949350505050565b634e487b7160e01b600052602160045260246000fd5b80820180821115610fca57610fca61172d56fea2646970667358221220845b6ec6b55914377d43ec06663c0327d86f931725471d4c23e0781a72141f1264736f6c63430008100033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000002bdb254079d55220bd093f9568b685c5af4da140
-----Decoded View---------------
Arg [0] : signer_ (address): 0x2BdB254079d55220bd093f9568B685c5af4da140
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000002bdb254079d55220bd093f9568b685c5af4da140
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ 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.