ETH Price: $3,477.97 (+6.05%)
Gas: 10 Gwei

Contract

0xBAf2127B49fC93CbcA6269FAdE0F7F31dF4c88a7
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
0x60806040141285242022-02-02 19:30:43894 days ago1643830243IN
 Create: MerkleValidator
0 ETH0.07854848214.87460468

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.8.11+commit.d7f03943

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license
/**
 *Submitted for verification at Etherscan.io on 2022-02-02
*/

pragma solidity 0.8.11;

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 calldata 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 InvalidProof is thrown on invalid proofs.
    error InvalidProof();

    /// @dev UnnecessaryProof is thrown in cases where a proof is supplied without a valid root to match against (root = 0)
    error UnnecessaryProof();

    /// @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[] calldata proof
    ) 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 UnnecessaryProof();
    	}

    	// 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[] calldata proof
    ) 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 UnnecessaryProof();
        }

        // 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[] calldata proof
    ) 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 UnnecessaryProof();
        }

        // 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
    ) private 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 InvalidProof();
        }
    }

    /// @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
    ) private pure returns (bytes32 value) {
        assembly {
            mstore(0x00, a)
            mstore(0x20, b)
            value := keccak256(0x00, 0x40)
        }
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"name":"InvalidProof","type":"error"},{"inputs":[],"name":"UnnecessaryProof","type":"error"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"contract IERC1155","name":"token","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32","name":"root","type":"bytes32"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"matchERC1155UsingCriteria","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"contract IERC721","name":"token","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes32","name":"root","type":"bytes32"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"matchERC721UsingCriteria","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"contract IERC721","name":"token","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes32","name":"root","type":"bytes32"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"matchERC721WithSafeTransferUsingCriteria","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]

608060405234801561001057600080fd5b506105a7806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806396809f9014610046578063c5a0236e1461006d578063fb16a59514610080575b600080fd5b61005961005436600461040b565b610093565b604051901515815260200160405180910390f35b61005961007b3660046104a3565b61018b565b61005961008e3660046104a3565b61026e565b600083156100de576100d9868585858080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061031592505050565b6100fd565b81156100fd57604051630aa5fe8760e21b815260040160405180910390fd5b604051637921219560e11b81526001600160a01b038a811660048301528981166024830152604482018890526064820187905260a06084830152600060a483015288169063f242432a9060c401600060405180830381600087803b15801561016457600080fd5b505af1158015610178573d6000803e3d6000fd5b5060019c9b505050505050505050505050565b600083156101d6576101d1858585858080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061031592505050565b6101f5565b81156101f557604051630aa5fe8760e21b815260040160405180910390fd5b604051632142170760e11b81526001600160a01b0389811660048301528881166024830152604482018790528716906342842e0e906064015b600060405180830381600087803b15801561024857600080fd5b505af115801561025c573d6000803e3d6000fd5b5060019b9a5050505050505050505050565b600083156102b9576102b4858585858080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061031592505050565b6102d8565b81156102d857604051630aa5fe8760e21b815260040160405180910390fd5b6040516323b872dd60e01b81526001600160a01b0389811660048301528881166024830152604482018790528716906323b872dd9060640161022e565b8260005b825181101561038057600083828151811061033657610336610532565b6020026020010151905080831161035c576000838152602082905260409020925061036d565b600081815260208490526040902092505b508061037881610548565b915050610319565b508281146103a1576040516309bde33960e01b815260040160405180910390fd5b50505050565b6001600160a01b03811681146103bc57600080fd5b50565b60008083601f8401126103d157600080fd5b50813567ffffffffffffffff8111156103e957600080fd5b6020830191508360208260051b850101111561040457600080fd5b9250929050565b60008060008060008060008060e0898b03121561042757600080fd5b8835610432816103a7565b97506020890135610442816103a7565b96506040890135610452816103a7565b9550606089013594506080890135935060a0890135925060c089013567ffffffffffffffff81111561048357600080fd5b61048f8b828c016103bf565b999c989b5096995094979396929594505050565b600080600080600080600060c0888a0312156104be57600080fd5b87356104c9816103a7565b965060208801356104d9816103a7565b955060408801356104e9816103a7565b9450606088013593506080880135925060a088013567ffffffffffffffff81111561051357600080fd5b61051f8a828b016103bf565b989b979a50959850939692959293505050565b634e487b7160e01b600052603260045260246000fd5b600060001982141561056a57634e487b7160e01b600052601160045260246000fd5b506001019056fea2646970667358221220e6cf71991f63f255d99126efab306f570f1cc3406b760338dc086217926e186764736f6c634300080b0033

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106100415760003560e01c806396809f9014610046578063c5a0236e1461006d578063fb16a59514610080575b600080fd5b61005961005436600461040b565b610093565b604051901515815260200160405180910390f35b61005961007b3660046104a3565b61018b565b61005961008e3660046104a3565b61026e565b600083156100de576100d9868585858080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061031592505050565b6100fd565b81156100fd57604051630aa5fe8760e21b815260040160405180910390fd5b604051637921219560e11b81526001600160a01b038a811660048301528981166024830152604482018890526064820187905260a06084830152600060a483015288169063f242432a9060c401600060405180830381600087803b15801561016457600080fd5b505af1158015610178573d6000803e3d6000fd5b5060019c9b505050505050505050505050565b600083156101d6576101d1858585858080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061031592505050565b6101f5565b81156101f557604051630aa5fe8760e21b815260040160405180910390fd5b604051632142170760e11b81526001600160a01b0389811660048301528881166024830152604482018790528716906342842e0e906064015b600060405180830381600087803b15801561024857600080fd5b505af115801561025c573d6000803e3d6000fd5b5060019b9a5050505050505050505050565b600083156102b9576102b4858585858080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061031592505050565b6102d8565b81156102d857604051630aa5fe8760e21b815260040160405180910390fd5b6040516323b872dd60e01b81526001600160a01b0389811660048301528881166024830152604482018790528716906323b872dd9060640161022e565b8260005b825181101561038057600083828151811061033657610336610532565b6020026020010151905080831161035c576000838152602082905260409020925061036d565b600081815260208490526040902092505b508061037881610548565b915050610319565b508281146103a1576040516309bde33960e01b815260040160405180910390fd5b50505050565b6001600160a01b03811681146103bc57600080fd5b50565b60008083601f8401126103d157600080fd5b50813567ffffffffffffffff8111156103e957600080fd5b6020830191508360208260051b850101111561040457600080fd5b9250929050565b60008060008060008060008060e0898b03121561042757600080fd5b8835610432816103a7565b97506020890135610442816103a7565b96506040890135610452816103a7565b9550606089013594506080890135935060a0890135925060c089013567ffffffffffffffff81111561048357600080fd5b61048f8b828c016103bf565b999c989b5096995094979396929594505050565b600080600080600080600060c0888a0312156104be57600080fd5b87356104c9816103a7565b965060208801356104d9816103a7565b955060408801356104e9816103a7565b9450606088013593506080880135925060a088013567ffffffffffffffff81111561051357600080fd5b61051f8a828b016103bf565b989b979a50959850939692959293505050565b634e487b7160e01b600052603260045260246000fd5b600060001982141561056a57634e487b7160e01b600052601160045260246000fd5b506001019056fea2646970667358221220e6cf71991f63f255d99126efab306f570f1cc3406b760338dc086217926e186764736f6c634300080b0033

Deployed Bytecode Sourcemap

586:6407:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4693:682;;;;;;:::i;:::-;;:::i;:::-;;;1769:14:1;;1762:22;1744:41;;1732:2;1717:18;4693:682:0;;;;;;;3122:659;;;;;;:::i;:::-;;:::i;1672:606::-;;;;;;:::i;:::-;;:::i;4693:682::-;4931:4;5026:18;;5022:224;;5061:34;5074:7;5083:4;5089:5;;5061:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5061:12:0;;-1:-1:-1;;;5061:34:0:i;:::-;5022:224;;;5117:17;;5113:133;;5216:18;;-1:-1:-1;;;5216:18:0;;;;;;;;;;;5113:133;5290:53;;-1:-1:-1;;;5290:53:0;;-1:-1:-1;;;;;3159:15:1;;;5290:53:0;;;3141:34:1;3211:15;;;3191:18;;;3184:43;3243:18;;;3236:34;;;3286:18;;;3279:34;;;3121:3;3329:19;;;3322:32;-1:-1:-1;3370:19:1;;;3363:30;5290:22:0;;;;;3410:19:1;;5290:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5363:4:0;;4693:682;-1:-1:-1;;;;;;;;;;;;4693:682:0:o;3122:659::-;3349:4;3444:18;;3440:224;;3479:34;3492:7;3501:4;3507:5;;3479:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3479:12:0;;-1:-1:-1;;;3479:34:0:i;:::-;3440:224;;;3535:17;;3531:133;;3634:18;;-1:-1:-1;;;3634:18:0;;;;;;;;;;;3531:133;3708:41;;-1:-1:-1;;;3708:41:0;;-1:-1:-1;;;;;3698:15:1;;;3708:41:0;;;3680:34:1;3750:15;;;3730:18;;;3723:43;3782:18;;;3775:34;;;3708:22:0;;;;;3615:18:1;;3708:41:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3769:4:0;;3122:659;-1:-1:-1;;;;;;;;;;;3122:659:0:o;1672:606::-;1883:4;1972:18;;1968:200;;2001:34;2014:7;2023:4;2029:5;;2001:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;2001:12:0;;-1:-1:-1;;;2001:34:0:i;:::-;1968:200;;;2054:17;;2050:118;;2141:18;;-1:-1:-1;;;2141:18:0;;;;;;;;;;;2050:118;2209:37;;-1:-1:-1;;;2209:37:0;;-1:-1:-1;;;;;3698:15:1;;;2209:37:0;;;3680:34:1;3750:15;;;3730:18;;;3723:43;3782:18;;;3775:34;;;2209:18:0;;;;;3615::1;;2209:37:0;3440:375:1;5698:767:0;5861:4;5830:20;5877:497;5901:5;:12;5897:1;:16;5877:497;;;5935:20;5958:5;5964:1;5958:8;;;;;;;;:::i;:::-;;;;;;;5935:31;;6001:12;5985;:28;5981:382;;6834:13;6884:15;;;6920:4;6913:15;;;6967:4;6951:21;;6113:57;;5981:382;;;6834:13;6884:15;;;6920:4;6913:15;;;6967:4;6951:21;;6290:57;;5981:382;-1:-1:-1;5915:3:0;;;;:::i;:::-;;;;5877:497;;;;6404:4;6388:12;:20;6384:74;;6432:14;;-1:-1:-1;;;6432:14:0;;;;;;;;;;;6384:74;5819:646;5698:767;;;:::o;14:131:1:-;-1:-1:-1;;;;;89:31:1;;79:42;;69:70;;135:1;132;125:12;69:70;14:131;:::o;150:367::-;213:8;223:6;277:3;270:4;262:6;258:17;254:27;244:55;;295:1;292;285:12;244:55;-1:-1:-1;318:20:1;;361:18;350:30;;347:50;;;393:1;390;383:12;347:50;430:4;422:6;418:17;406:29;;490:3;483:4;473:6;470:1;466:14;458:6;454:27;450:38;447:47;444:67;;;507:1;504;497:12;444:67;150:367;;;;;:::o;522:1077::-;677:6;685;693;701;709;717;725;733;786:3;774:9;765:7;761:23;757:33;754:53;;;803:1;800;793:12;754:53;842:9;829:23;861:31;886:5;861:31;:::i;:::-;911:5;-1:-1:-1;968:2:1;953:18;;940:32;981:33;940:32;981:33;:::i;:::-;1033:7;-1:-1:-1;1092:2:1;1077:18;;1064:32;1105:33;1064:32;1105:33;:::i;:::-;1157:7;-1:-1:-1;1211:2:1;1196:18;;1183:32;;-1:-1:-1;1262:3:1;1247:19;;1234:33;;-1:-1:-1;1314:3:1;1299:19;;1286:33;;-1:-1:-1;1370:3:1;1355:19;;1342:33;1398:18;1387:30;;1384:50;;;1430:1;1427;1420:12;1384:50;1469:70;1531:7;1522:6;1511:9;1507:22;1469:70;:::i;:::-;522:1077;;;;-1:-1:-1;522:1077:1;;-1:-1:-1;522:1077:1;;;;;;1558:8;-1:-1:-1;;;522:1077:1:o;1796:1007::-;1941:6;1949;1957;1965;1973;1981;1989;2042:3;2030:9;2021:7;2017:23;2013:33;2010:53;;;2059:1;2056;2049:12;2010:53;2098:9;2085:23;2117:31;2142:5;2117:31;:::i;:::-;2167:5;-1:-1:-1;2224:2:1;2209:18;;2196:32;2237:33;2196:32;2237:33;:::i;:::-;2289:7;-1:-1:-1;2348:2:1;2333:18;;2320:32;2361:33;2320:32;2361:33;:::i;:::-;2413:7;-1:-1:-1;2467:2:1;2452:18;;2439:32;;-1:-1:-1;2518:3:1;2503:19;;2490:33;;-1:-1:-1;2574:3:1;2559:19;;2546:33;2602:18;2591:30;;2588:50;;;2634:1;2631;2624:12;2588:50;2673:70;2735:7;2726:6;2715:9;2711:22;2673:70;:::i;:::-;1796:1007;;;;-1:-1:-1;1796:1007:1;;-1:-1:-1;1796:1007:1;;;;2647:96;;-1:-1:-1;;;1796:1007:1:o;3820:127::-;3881:10;3876:3;3872:20;3869:1;3862:31;3912:4;3909:1;3902:15;3936:4;3933:1;3926:15;3952:232;3991:3;-1:-1:-1;;4012:17:1;;4009:140;;;4071:10;4066:3;4062:20;4059:1;4052:31;4106:4;4103:1;4096:15;4134:4;4131:1;4124:15;4009:140;-1:-1:-1;4176:1:1;4165:13;;3952:232::o

Swarm Source

ipfs://e6cf71991f63f255d99126efab306f570f1cc3406b760338dc086217926e1867

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

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