ETH Price: $2,254.04 (-0.03%)
Gas: 61 Gwei

Contract

0x5D01D08834283885b97c4A9EEF16631707C83F9b
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Sponsored

Transaction Hash
Method
Block
From
To
Value
0x60806040147367352022-05-08 14:58:34577 days 23 hrs ago1652021914IN
 Create: MerkleValidator
0 ETH0.0183419742.70918423

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
MerkleValidator

Compiler Version
v0.4.26+commit.4563c3fc

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, Apache-2.0 license
/**
 *Submitted for verification at Etherscan.io on 2022-05-24
*/

// File: contracts/MerkleValidator.sol

pragma solidity 0.4.26;

interface IERC721 {
    function safeTransferFrom(address from, address to, uint256 tokenId) external;
    function transferFrom(address from, address to, uint256 tokenId) external;
}

interface IERC1155 {
    function safeTransferFrom(address from, address to, uint256 tokenId, uint256 amount, bytes data) external;
}

/// @title MerkleValidator enables matching trait-based and collection-based orders for ERC721 and ERC1155 tokens.
/// @author 0age
/// @dev This contract is intended to be called during atomicMatch_ via DELEGATECALL.
contract MerkleValidator {

    /// @dev Match an ERC721 order, ensuring that the supplied proof demonstrates inclusion of the tokenId in the associated merkle root.
    /// @param from The account to transfer the ERC721 token from — this token must first be approved on the seller's AuthenticatedProxy contract.
    /// @param to The account to transfer the ERC721 token to.
    /// @param token The ERC721 token to transfer.
    /// @param tokenId The ERC721 tokenId to transfer.
    /// @param root A merkle root derived from each valid tokenId — set to 0 to indicate a collection-level or tokenId-specific order.
    /// @param proof A proof that the supplied tokenId is contained within the associated merkle root. Must be length 0 if root is not set.
    /// @return A boolean indicating a successful match and transfer.
    function matchERC721UsingCriteria(
        address from,
        address to,
        IERC721 token,
        uint256 tokenId,
        bytes32 root,
        bytes32[] proof
    ) payable external returns (bool) {
        // Proof verification is performed when there's a non-zero root.
        if (root != bytes32(0)) {
            verifyProof(tokenId, root, proof);
        } else if (proof.length != 0) {
            // A root of zero should never have a proof.
            revert("expect no proof");
        }

        // Transfer the token.
        token.transferFrom(from, to, tokenId);

        return true;
    }

    /// @dev Match an ERC721 order using `safeTransferFrom`, ensuring that the supplied proof demonstrates inclusion of the tokenId in the associated merkle root.
    /// @param from The account to transfer the ERC721 token from — this token must first be approved on the seller's AuthenticatedProxy contract.
    /// @param to The account to transfer the ERC721 token to.
    /// @param token The ERC721 token to transfer.
    /// @param tokenId The ERC721 tokenId to transfer.
    /// @param root A merkle root derived from each valid tokenId — set to 0 to indicate a collection-level or tokenId-specific order.
    /// @param proof A proof that the supplied tokenId is contained within the associated merkle root. Must be length 0 if root is not set.
    /// @return A boolean indicating a successful match and transfer.
    function matchERC721WithSafeTransferUsingCriteria(
        address from,
        address to,
        IERC721 token,
        uint256 tokenId,
        bytes32 root,
        bytes32[] proof
    ) payable external returns (bool) {
        // Proof verification is performed when there's a non-zero root.
        if (root != bytes32(0)) {
            verifyProof(tokenId, root, proof);
        } else if (proof.length != 0) {
            // A root of zero should never have a proof.
            revert("expect no proof");
        }

        // Transfer the token.
        token.safeTransferFrom(from, to, tokenId);

        return true;
    }

    /// @dev Match an ERC1155 order, ensuring that the supplied proof demonstrates inclusion of the tokenId in the associated merkle root.
    /// @param from The account to transfer the ERC1155 token from — this token must first be approved on the seller's AuthenticatedProxy contract.
    /// @param to The account to transfer the ERC1155 token to.
    /// @param token The ERC1155 token to transfer.
    /// @param tokenId The ERC1155 tokenId to transfer.
    /// @param amount The amount of ERC1155 tokens with the given tokenId to transfer.
    /// @param root A merkle root derived from each valid tokenId — set to 0 to indicate a collection-level or tokenId-specific order.
    /// @param proof A proof that the supplied tokenId is contained within the associated merkle root. Must be length 0 if root is not set.
    /// @return A boolean indicating a successful match and transfer.
    function matchERC1155UsingCriteria(
        address from,
        address to,
        IERC1155 token,
        uint256 tokenId,
        uint256 amount,
        bytes32 root,
        bytes32[] proof
    ) payable external returns (bool) {
        // Proof verification is performed when there's a non-zero root.
        if (root != bytes32(0)) {
            verifyProof(tokenId, root, proof);
        } else if (proof.length != 0) {
            // A root of zero should never have a proof.
            revert("expect no proof");
        }

        // Transfer the token.
        token.safeTransferFrom(from, to, tokenId, amount, "");

        return true;
    }

    /// @dev Ensure that a given tokenId is contained within a supplied merkle root using a supplied proof.
    /// @param leaf The tokenId.
    /// @param root A merkle root derived from each valid tokenId.
    /// @param proof A proof that the supplied tokenId is contained within the associated merkle root.
    function verifyProof(
        uint256 leaf,
        bytes32 root,
        bytes32[] memory proof
    ) public pure {
        bytes32 computedHash = bytes32(leaf);
        for (uint256 i = 0; i < proof.length; i++) {
            bytes32 proofElement = proof[i];
            if (computedHash <= proofElement) {
                // Hash(current computed hash + current element of the proof)
                computedHash = efficientHash(computedHash, proofElement);
            } else {
                // Hash(current element of the proof + current computed hash)
                computedHash = efficientHash(proofElement, computedHash);
            }
        }
        if (computedHash != root) {
            revert("invalid proof");
        }
    }

    function calculateProof(
        uint256 leafA,
        uint256 leafB
    ) public pure returns(bytes32) {
        bytes32 computedHashA = bytes32(leafA);
        bytes32 computedHashB = bytes32(leafB);

        bytes32 proof;
        if (computedHashA <= computedHashB) {
            // Hash(current computed hash + current element of the proof)
            proof = efficientHash(computedHashA, computedHashB);
        } else {
            // Hash(current element of the proof + current computed hash)
            proof = efficientHash(computedHashB, computedHashA);
        }
        return proof;
    }

    /// @dev Efficiently hash two bytes32 elements using memory scratch space.
    /// @param a The first element included in the hash.
    /// @param b The second element included in the hash.
    /// @return value The resultant hash of the two bytes32 elements.
    function efficientHash(
        bytes32 a,
        bytes32 b
    ) public pure returns (bytes32 value) {
        assembly {
            mstore(0x00, a)
            mstore(0x20, b)
            value := keccak256(0x00, 0x40)
        }
    }
}

Contract Security Audit

Contract ABI

[{"constant":true,"inputs":[{"name":"leafA","type":"uint256"},{"name":"leafB","type":"uint256"}],"name":"calculateProof","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"token","type":"address"},{"name":"tokenId","type":"uint256"},{"name":"amount","type":"uint256"},{"name":"root","type":"bytes32"},{"name":"proof","type":"bytes32[]"}],"name":"matchERC1155UsingCriteria","outputs":[{"name":"","type":"bool"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"a","type":"bytes32"},{"name":"b","type":"bytes32"}],"name":"efficientHash","outputs":[{"name":"value","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"leaf","type":"uint256"},{"name":"root","type":"bytes32"},{"name":"proof","type":"bytes32[]"}],"name":"verifyProof","outputs":[],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"token","type":"address"},{"name":"tokenId","type":"uint256"},{"name":"root","type":"bytes32"},{"name":"proof","type":"bytes32[]"}],"name":"matchERC721WithSafeTransferUsingCriteria","outputs":[{"name":"","type":"bool"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"token","type":"address"},{"name":"tokenId","type":"uint256"},{"name":"root","type":"bytes32"},{"name":"proof","type":"bytes32[]"}],"name":"matchERC721UsingCriteria","outputs":[{"name":"","type":"bool"}],"payable":true,"stateMutability":"payable","type":"function"}]

608060405234801561001057600080fd5b506106d7806100206000396000f3006080604052600436106100775763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166312fbeafe811461007c57806396809f90146100a9578063bd9c7e4414610103578063c48555c41461011e578063c5a0236e1461017e578063fb16a595146101c0575b600080fd5b34801561008857600080fd5b50610097600435602435610202565b60408051918252519081900360200190f35b6100ef6004803573ffffffffffffffffffffffffffffffffffffffff90811691602480358316926044351691606435916084359160a4359160c435908101910135610235565b604080519115158252519081900360200190f35b34801561010f57600080fd5b50610097600435602435610389565b34801561012a57600080fd5b50604080516020600460443581810135838102808601850190965280855261017c9583359560248035963696956064959394920192918291850190849080828437509497506103989650505050505050565b005b6100ef6004803573ffffffffffffffffffffffffffffffffffffffff90811691602480358316926044351691606435916084359160a43591820191013561044f565b6100ef6004803573ffffffffffffffffffffffffffffffffffffffff90811691602480358316926044351691606435916084359160a435918201910135610590565b600082828281831161021f576102188383610389565b905061022c565b6102298284610389565b90505b95945050505050565b6000831561027a57610275868585858080602002602001604051908101604052809392919081815260200183836020028082843750610398945050505050565b6102d0565b81156102d0576040805160e560020a62461bcd02815260206004820152600f60248201527f657870656374206e6f2070726f6f660000000000000000000000000000000000604482015290519081900360640190fd5b604080517ff242432a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8b811660048301528a81166024830152604482018990526064820188905260a06084830152600060a483018190529251908a169263f242432a9260e4808201939182900301818387803b15801561036257600080fd5b505af1158015610376573d6000803e3d6000fd5b5060019c9b505050505050505050505050565b60009182526020526040902090565b826000805b83518210156103f05783828151811015156103b457fe5b6020908102909101015190508083116103d8576103d18382610389565b92506103e5565b6103e28184610389565b92505b60019091019061039d565b828514610447576040805160e560020a62461bcd02815260206004820152600d60248201527f696e76616c69642070726f6f6600000000000000000000000000000000000000604482015290519081900360640190fd5b505050505050565b600083156104945761048f858585858080602002602001604051908101604052809392919081815260200183836020028082843750610398945050505050565b6104ea565b81156104ea576040805160e560020a62461bcd02815260206004820152600f60248201527f657870656374206e6f2070726f6f660000000000000000000000000000000000604482015290519081900360640190fd5b604080517f42842e0e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a811660048301528981166024830152604482018890529151918816916342842e0e9160648082019260009290919082900301818387803b15801561056a57600080fd5b505af115801561057e573d6000803e3d6000fd5b5060019b9a5050505050505050505050565b600083156105d5576105d0858585858080602002602001604051908101604052809392919081815260200183836020028082843750610398945050505050565b61062b565b811561062b576040805160e560020a62461bcd02815260206004820152600f60248201527f657870656374206e6f2070726f6f660000000000000000000000000000000000604482015290519081900360640190fd5b604080517f23b872dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a811660048301528981166024830152604482018890529151918816916323b872dd9160648082019260009290919082900301818387803b15801561056a57600080fd00a165627a7a7230582004447884251df6b701dff252815ffd82669ac541a364ae3f9f131710c2a338aa0029

Deployed Bytecode

0x6080604052600436106100775763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166312fbeafe811461007c57806396809f90146100a9578063bd9c7e4414610103578063c48555c41461011e578063c5a0236e1461017e578063fb16a595146101c0575b600080fd5b34801561008857600080fd5b50610097600435602435610202565b60408051918252519081900360200190f35b6100ef6004803573ffffffffffffffffffffffffffffffffffffffff90811691602480358316926044351691606435916084359160a4359160c435908101910135610235565b604080519115158252519081900360200190f35b34801561010f57600080fd5b50610097600435602435610389565b34801561012a57600080fd5b50604080516020600460443581810135838102808601850190965280855261017c9583359560248035963696956064959394920192918291850190849080828437509497506103989650505050505050565b005b6100ef6004803573ffffffffffffffffffffffffffffffffffffffff90811691602480358316926044351691606435916084359160a43591820191013561044f565b6100ef6004803573ffffffffffffffffffffffffffffffffffffffff90811691602480358316926044351691606435916084359160a435918201910135610590565b600082828281831161021f576102188383610389565b905061022c565b6102298284610389565b90505b95945050505050565b6000831561027a57610275868585858080602002602001604051908101604052809392919081815260200183836020028082843750610398945050505050565b6102d0565b81156102d0576040805160e560020a62461bcd02815260206004820152600f60248201527f657870656374206e6f2070726f6f660000000000000000000000000000000000604482015290519081900360640190fd5b604080517ff242432a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8b811660048301528a81166024830152604482018990526064820188905260a06084830152600060a483018190529251908a169263f242432a9260e4808201939182900301818387803b15801561036257600080fd5b505af1158015610376573d6000803e3d6000fd5b5060019c9b505050505050505050505050565b60009182526020526040902090565b826000805b83518210156103f05783828151811015156103b457fe5b6020908102909101015190508083116103d8576103d18382610389565b92506103e5565b6103e28184610389565b92505b60019091019061039d565b828514610447576040805160e560020a62461bcd02815260206004820152600d60248201527f696e76616c69642070726f6f6600000000000000000000000000000000000000604482015290519081900360640190fd5b505050505050565b600083156104945761048f858585858080602002602001604051908101604052809392919081815260200183836020028082843750610398945050505050565b6104ea565b81156104ea576040805160e560020a62461bcd02815260206004820152600f60248201527f657870656374206e6f2070726f6f660000000000000000000000000000000000604482015290519081900360640190fd5b604080517f42842e0e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a811660048301528981166024830152604482018890529151918816916342842e0e9160648082019260009290919082900301818387803b15801561056a57600080fd5b505af115801561057e573d6000803e3d6000fd5b5060019b9a5050505050505050505050565b600083156105d5576105d0858585858080602002602001604051908101604052809392919081815260200183836020028082843750610398945050505050565b61062b565b811561062b576040805160e560020a62461bcd02815260206004820152600f60248201527f657870656374206e6f2070726f6f660000000000000000000000000000000000604482015290519081900360640190fd5b604080517f23b872dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a811660048301528981166024830152604482018890529151918816916323b872dd9160648082019260009290919082900301818387803b15801561056a57600080fd00a165627a7a7230582004447884251df6b701dff252815ffd82669ac541a364ae3f9f131710c2a338aa0029

Deployed Bytecode Sourcemap

619:6818:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6290:621;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;6290:621:0;;;;;;;;;;;;;;;;;;;;;;;4514:680;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7187:247;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;7187:247:0;;;;;;;5517:765;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;5517:765:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5517:765:0;;-1:-1:-1;5517:765:0;;-1:-1:-1;;;;;;;5517:765:0;;;2945:657;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1464:637;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6290:621;6389:7;6441:5;6490;6389:7;6537:30;;;6533:348;;6667:43;6681:13;6696;6667;:43::i;:::-;6659:51;;6533:348;;;6826:43;6840:13;6855;6826;:43::i;:::-;6818:51;;6533:348;6898:5;6290:621;-1:-1:-1;;;;;6290:621:0:o;4514:680::-;4751:4;4846:18;;4842:223;;4881:33;4893:7;4902:4;4908:5;;4881:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;4881:11:0;;-1:-1:-1;;;;;4881:33:0:i;:::-;4842:223;;;4936:17;;4932:133;;5028:25;;;-1:-1:-1;;;;;5028:25:0;;;;;;;;;;;;;;;;;;;;;;;;;;;4932:133;5109:53;;;;;;:22;:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5109:53:0;;;;;;;;:22;;;;;;:53;;;;;;;;;;;-1:-1:-1;5109:22:0;:53;;;5:2:-1;;;;30:1;27;20:12;5:2;5109:53:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;5182:4:0;;4514:680;-1:-1:-1;;;;;;;;;;;;4514:680:0:o;7187:247::-;7278:13;7328:15;;;7364:4;7357:15;7411:4;7395:21;;;7313:114::o;5517:765::-;5678:4;5647:20;;5694:495;5718:5;:12;5714:1;:16;5694:495;;;5775:5;5781:1;5775:8;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5802:28:0;;;5798:380;;5945:41;5959:12;5973;5945:13;:41::i;:::-;5930:56;;5798:380;;;6121:41;6135:12;6149;6121:13;:41::i;:::-;6106:56;;5798:380;5732:3;;;;;5694:495;;;6203:20;;;6199:76;;6240:23;;;-1:-1:-1;;;;;6240:23:0;;;;;;;;;;;;;;;;;;;;;;;;;;;6199:76;5517:765;;;;;;:::o;2945:657::-;3171:4;3266:18;;3262:223;;3301:33;3313:7;3322:4;3328:5;;3301:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3301:11:0;;-1:-1:-1;;;;;3301:33:0:i;:::-;3262:223;;;3356:17;;3352:133;;3448:25;;;-1:-1:-1;;;;;3448:25:0;;;;;;;;;;;;;;;;;;;;;;;;;;;3352:133;3529:41;;;;;;:22;:41;;;;;;;;;;;;;;;;;;;;;;:22;;;;;;:41;;;;;-1:-1:-1;;3529:41:0;;;;;;;;-1:-1:-1;3529:22:0;:41;;;5:2:-1;;;;30:1;27;20:12;5:2;3529:41:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;3590:4:0;;2945:657;-1:-1:-1;;;;;;;;;;;2945:657:0:o;1464:637::-;1674:4;1769:18;;1765:223;;1804:33;1816:7;1825:4;1831:5;;1804:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1804:11:0;;-1:-1:-1;;;;;1804:33:0:i;:::-;1765:223;;;1859:17;;1855:133;;1951:25;;;-1:-1:-1;;;;;1951:25:0;;;;;;;;;;;;;;;;;;;;;;;;;;;1855:133;2032:37;;;;;;:18;:37;;;;;;;;;;;;;;;;;;;;;;:18;;;;;;:37;;;;;-1:-1:-1;;2032:37:0;;;;;;;;-1:-1:-1;2032:18:0;:37;;;5:2:-1;;;;30:1;27;20:12

Swarm Source

bzzr://04447884251df6b701dff252815ffd82669ac541a364ae3f9f131710c2a338aa

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.

Validator Index Block Amount
View All Withdrawals

Txn Hash Block Value Eth2 PubKey Valid
View All Deposits
[ 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.