ETH Price: $3,357.68 (+2.90%)
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

1 Internal Transaction found.

Latest 1 internal transaction

Advanced mode:
Parent Transaction Hash Block
From
To
186542562023-11-26 7:07:23432 days ago1700982443  Contract Creation0 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Delegate

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 4 : Delegate.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "../lib/Constants.sol";
import {AssetType, OrderType, Transfer} from "../lib/Structs.sol";

contract Delegate is ReentrancyGuard {
    error Unauthorized();
    error InvalidLength();

    address private _EXCHANGE;

    constructor(address exchange) {
        _EXCHANGE = exchange;
    }

    modifier onlyApproved() {
        if (msg.sender != _EXCHANGE) {
            revert Unauthorized();
        }
        _;
    }

    function transfer(address taker, OrderType orderType, Transfer[] calldata transfers, uint256 length)
        external
        onlyApproved
        nonReentrant
        returns (bool[] memory successful)
    {
        if (transfers.length < length) {
            revert InvalidLength();
        }
        successful = new bool[](length);

        for (uint256 i; i < length;) {
            assembly {
                let calldataPointer := mload(0x40)
                let transfersPointer := add(transfers.offset, mul(Transfer_size, i))

                let assetType := calldataload(add(transfersPointer, Transfer_assetType_offset))
                switch assetType
                case 0 {
                    // AssetType_ERC721
                    mstore(calldataPointer, ERC721_safeTransferFrom_selector)
                    switch orderType
                    case 0 {
                        // OrderType_ASK; taker is recipient
                        mstore(add(calldataPointer, ERC721_safeTransferFrom_to_offset), taker)
                        mstore(
                            add(calldataPointer, ERC721_safeTransferFrom_from_offset),
                            calldataload(add(transfersPointer, Transfer_trader_offset))
                        )
                    }
                    case 1 {
                        // OrderType_BID; taker is sender
                        mstore(add(calldataPointer, ERC721_safeTransferFrom_from_offset), taker)
                        mstore(
                            add(calldataPointer, ERC721_safeTransferFrom_to_offset),
                            calldataload(add(transfersPointer, Transfer_trader_offset))
                        )
                    }
                    default { revert(0, 0) }

                    mstore(
                        add(calldataPointer, ERC721_safeTransferFrom_id_offset),
                        calldataload(add(transfersPointer, Transfer_id_offset))
                    )
                    let collection := calldataload(add(transfersPointer, Transfer_collection_offset))
                    let success := call(gas(), collection, 0, calldataPointer, ERC721_safeTransferFrom_size, 0, 0)
                    mstore(add(add(successful, 0x20), mul(0x20, i)), success)
                }
                case 1 {
                    // AssetType_ERC1155
                    mstore(calldataPointer, ERC1155_safeTransferFrom_selector)
                    switch orderType
                    case 0 {
                        // OrderType_ASK; taker is recipient
                        mstore(
                            add(calldataPointer, ERC1155_safeTransferFrom_from_offset),
                            calldataload(add(transfersPointer, Transfer_trader_offset))
                        )
                        mstore(add(calldataPointer, ERC1155_safeTransferFrom_to_offset), taker)
                    }
                    case 1 {
                        // OrderType_BID; taker is sender
                        mstore(
                            add(calldataPointer, ERC1155_safeTransferFrom_to_offset),
                            calldataload(add(transfersPointer, Transfer_trader_offset))
                        )
                        mstore(add(calldataPointer, ERC1155_safeTransferFrom_from_offset), taker)
                    }
                    default { revert(0, 0) }

                    mstore(add(calldataPointer, ERC1155_safeTransferFrom_data_pointer_offset), 0xa0)
                    mstore(add(calldataPointer, ERC1155_safeTransferFrom_data_offset), 0)
                    mstore(
                        add(calldataPointer, ERC1155_safeTransferFrom_id_offset),
                        calldataload(add(transfersPointer, Transfer_id_offset))
                    )
                    mstore(
                        add(calldataPointer, ERC1155_safeTransferFrom_amount_offset),
                        calldataload(add(transfersPointer, Transfer_amount_offset))
                    )
                    let collection := calldataload(add(transfersPointer, Transfer_collection_offset))
                    let success := call(gas(), collection, 0, calldataPointer, ERC1155_safeTransferFrom_size, 0, 0)
                    mstore(add(add(successful, 0x20), mul(0x20, i)), success)
                }
                default { revert(0, 0) }
            }
            unchecked {
                ++i;
            }
        }
    }
}

File 2 of 4 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be _NOT_ENTERED
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;
    }

    function _nonReentrantAfter() private {
        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
     * `nonReentrant` function in the call stack.
     */
    function _reentrancyGuardEntered() internal view returns (bool) {
        return _status == _ENTERED;
    }
}

File 3 of 4 : Constants.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

uint256 constant Bytes1_shift = 0xf8;
uint256 constant Bytes4_shift = 0xe0;
uint256 constant Bytes20_shift = 0x60;
uint256 constant One_word = 0x20;

uint256 constant Memory_pointer = 0x40;

uint256 constant AssetType_ERC721 = 0;
uint256 constant AssetType_ERC1155 = 1;

uint256 constant OrderType_ASK = 0;
uint256 constant OrderType_BID = 1;

uint256 constant Pool_withdrawFrom_selector = 0x9555a94200000000000000000000000000000000000000000000000000000000;
uint256 constant Pool_withdrawFrom_from_offset = 0x04;
uint256 constant Pool_withdrawFrom_to_offset = 0x24;
uint256 constant Pool_withdrawFrom_amount_offset = 0x44;
uint256 constant Pool_withdrawFrom_size = 0x64;

uint256 constant Pool_deposit_to_selector = 0xf340fa0100000000000000000000000000000000000000000000000000000000;
uint256 constant Pool_deposit_user_offset = 0x04;
uint256 constant Pool_deposit_size = 0x24;

uint256 constant ERC20_transferFrom_selector = 0x23b872dd00000000000000000000000000000000000000000000000000000000;
uint256 constant ERC721_safeTransferFrom_selector = 0x42842e0e00000000000000000000000000000000000000000000000000000000;
uint256 constant ERC1155_safeTransferFrom_selector = 0xf242432a00000000000000000000000000000000000000000000000000000000;
uint256 constant ERC20_transferFrom_size = 0x64;
uint256 constant ERC721_safeTransferFrom_size = 0x64;
uint256 constant ERC1155_safeTransferFrom_size = 0xc4;

uint256 constant Signatures_size = 0x41;
uint256 constant Signatures_s_offset = 0x20;
uint256 constant Signatures_v_offset = 0x40;

uint256 constant ERC20_transferFrom_from_offset = 0x4;
uint256 constant ERC20_transferFrom_to_offset = 0x24;
uint256 constant ERC20_transferFrom_amount_offset = 0x44;

uint256 constant ERC721_safeTransferFrom_from_offset = 0x4;
uint256 constant ERC721_safeTransferFrom_to_offset = 0x24;
uint256 constant ERC721_safeTransferFrom_id_offset = 0x44;

uint256 constant ERC1155_safeTransferFrom_from_offset = 0x4;
uint256 constant ERC1155_safeTransferFrom_to_offset = 0x24;
uint256 constant ERC1155_safeTransferFrom_id_offset = 0x44;
uint256 constant ERC1155_safeTransferFrom_amount_offset = 0x64;
uint256 constant ERC1155_safeTransferFrom_data_pointer_offset = 0x84;
uint256 constant ERC1155_safeTransferFrom_data_offset = 0xa4;

uint256 constant Delegate_transfer_selector = 0xa1ccb98e00000000000000000000000000000000000000000000000000000000;
uint256 constant Delegate_transfer_calldata_offset = 0x1c;

uint256 constant Order_size = 0x100;
uint256 constant Order_trader_offset = 0x00;
uint256 constant Order_collection_offset = 0x20;
uint256 constant Order_listingsRoot_offset = 0x40;
uint256 constant Order_numberOfListings_offset = 0x60;
uint256 constant Order_expirationTime_offset = 0x80;
uint256 constant Order_assetType_offset = 0xa0;
uint256 constant Order_makerFee_offset = 0xc0;
uint256 constant Order_salt_offset = 0xe0;

uint256 constant Exchange_size = 0x80;
uint256 constant Exchange_askIndex_offset = 0x00;
uint256 constant Exchange_proof_offset = 0x20;
uint256 constant Exchange_maker_offset = 0x40;
uint256 constant Exchange_taker_offset = 0x60;

uint256 constant BidExchange_size = 0x80;
uint256 constant BidExchange_askIndex_offset = 0x00;
uint256 constant BidExchange_proof_offset = 0x20;
uint256 constant BidExchange_maker_offset = 0x40;
uint256 constant BidExchange_taker_offset = 0x60;

uint256 constant Listing_size = 0x80;
uint256 constant Listing_index_offset = 0x00;
uint256 constant Listing_tokenId_offset = 0x20;
uint256 constant Listing_amount_offset = 0x40;
uint256 constant Listing_price_offset = 0x60;

uint256 constant Taker_size = 0x40;
uint256 constant Taker_tokenId_offset = 0x00;
uint256 constant Taker_amount_offset = 0x20;

uint256 constant StateUpdate_size = 0x80;
uint256 constant StateUpdate_salt_offset = 0x20;
uint256 constant StateUpdate_leaf_offset = 0x40;
uint256 constant StateUpdate_value_offset = 0x60;

uint256 constant Transfer_size = 0xa0;
uint256 constant Transfer_trader_offset = 0x00;
uint256 constant Transfer_id_offset = 0x20;
uint256 constant Transfer_amount_offset = 0x40;
uint256 constant Transfer_collection_offset = 0x60;
uint256 constant Transfer_assetType_offset = 0x80;

uint256 constant ExecutionBatch_selector_offset = 0x20;
uint256 constant ExecutionBatch_calldata_offset = 0x40;
uint256 constant ExecutionBatch_base_size = 0xa0; // size of the executionBatch without the flattened dynamic elements
uint256 constant ExecutionBatch_taker_offset = 0x00;
uint256 constant ExecutionBatch_orderType_offset = 0x20;
uint256 constant ExecutionBatch_transfers_pointer_offset = 0x40;
uint256 constant ExecutionBatch_length_offset = 0x60;
uint256 constant ExecutionBatch_transfers_offset = 0x80;

File 4 of 4 : Structs.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

struct TakeAsk {
    Order[] orders;
    Exchange[] exchanges;
    bytes signatures;
    address tokenRecipient;
}

struct TakeAskSingle {
    Order order;
    Exchange exchange;
    bytes signature;
    address tokenRecipient;
}

struct TakeBid {
    Order[] orders;
    Exchange[] exchanges;
    FeeRate takerFee;
    bytes signatures;
}

struct TakeBidSingle {
    Order order;
    Exchange exchange;
    FeeRate takerFee;
    bytes signature;
}

enum AssetType {
    ERC721,
    ERC1155
}

enum OrderType {
    ASK,
    BID
}

struct Exchange { // Size: 0x80
    uint256 index; // 0x00
    bytes32[] proof; // 0x20
    Listing listing; // 0x40
    Taker taker; // 0x60
}

struct Listing { // Size: 0x80
    uint256 index; // 0x00
    uint256 tokenId; // 0x20
    uint256 amount; // 0x40
    uint256 price; // 0x60
}

struct Taker { // Size: 0x40
    uint256 tokenId; // 0x00
    uint256 amount; // 0x20
}

struct Order { // Size: 0x100
    address trader; // 0x00
    address collection; // 0x20
    bytes32 listingsRoot; // 0x40
    uint256 numberOfListings; // 0x60
    uint256 expirationTime; // 0x80
    AssetType assetType; // 0xa0
    FeeRate makerFee; // 0xc0
    uint256 salt; // 0xe0
}

struct Transfer { // Size: 0xa0
    address trader; // 0x00
    uint256 id; // 0x20
    uint256 amount; // 0x40
    address collection; // 0x60
    AssetType assetType; // 0x80
}

struct FungibleTransfers {
    uint256 totalProtocolFee;
    uint256 totalSellerTransfer;
    uint256 feeRecipientId;
    uint256 makerId;
    address[] feeRecipients;
    address[] makers;
    uint256[] makerTransfers;
    uint256[] feeTransfers;
    AtomicExecution[] executions;
}

struct AtomicExecution { // Size: 0xe0
    uint256 makerId; // 0x00
    uint256 sellerAmount; // 0x20
    uint256 makerFeeRecipientId; // 0x40
    uint256 makerFeeAmount; // 0x60
    uint256 protocolFeeAmount; // 0x80
    StateUpdate stateUpdate; // 0xa0
}

struct StateUpdate { // Size: 0xa0
    address trader; // 0x00
    bytes32 hash; // 0x20
    uint256 index; // 0x40
    uint256 value; // 0x60
    uint256 maxAmount; // 0x80
}

struct Fees { // Size: 0x20
    FeeRate protocolFee; // 0x00
}

struct FeeRate { // Size: 0x40
    address recipient; // 0x00
    uint16 rate; // 0x20
}

struct Cancel {
    bytes32 hash;
    uint256 index;
    uint256 amount;
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "viaIR": true,
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"exchange","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InvalidLength","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[{"internalType":"address","name":"taker","type":"address"},{"internalType":"enum OrderType","name":"orderType","type":"uint8"},{"components":[{"internalType":"address","name":"trader","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"collection","type":"address"},{"internalType":"enum AssetType","name":"assetType","type":"uint8"}],"internalType":"struct Transfer[]","name":"transfers","type":"tuple[]"},{"internalType":"uint256","name":"length","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool[]","name":"successful","type":"bool[]"}],"stateMutability":"nonpayable","type":"function"}]

60803461007557601f61044c38819003918201601f19168301916001600160401b0383118484101761007a5780849260209460405283398101031261007557516001600160a01b0381169081900361007557600160005560018060a01b031960015416176001556040516103bb90816100918239f35b600080fd5b634e487b7160e01b600052604160045260246000fdfe6080604052600436101561001257600080fd5b6000803560e01c63a1ccb98e1461002857600080fd5b346100ba5760803660031901126100ba57600435906001600160a01b03821682036100ba576024359160028310156100bd576044359267ffffffffffffffff928385116100ba57366023860112156100ba5784600401359384116100ba5736602460a08602870101116100ba576100b66100aa606435866024890186886100fe565b604051918291826100c1565b0390f35b80fd5b5080fd5b6020908160408183019282815285518094520193019160005b8281106100e8575050505090565b83511515855293810193928101926001016100da565b9193909360019260018060a01b0384541633036102e257600094600286541461029d578390600287551061028b576101398397969597610331565b94875b848110610159575050505050509091506101566001600055565b90565b6040805160a0838102870190608082013580156102115760011461017b578c80fd5b637921219560e11b83528580156101ed57600114610197578c80fd5b9b60c48a95949382809d9e9f8560609183973560248601528c60048601525b60848501528260a4850152602097888201356044860152810135606485015201355af1908260051b8b0101525b019796959761013c565b509b60c48a95949382809d9e9f8560609183973560048601528c60248601526101b6565b5050632142170760e11b8252915083801561026c57600114610231578a80fd5b908a80606484889d9e9c9d60048d98970152843560248201525b82606060209687810135604485015201355af1908260051b8b0101526101e3565b50908a80606484889d9e9c9d60248d989701528435600482015261024b565b60405163251f56a160e21b8152600490fd5b60405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606490fd5b6040516282b42960e81b8152600490fd5b50634e487b7160e01b600052604160045260246000fd5b60209067ffffffffffffffff8111610324575b60051b0190565b61032c6102f3565b61031d565b9061033b8261030a565b60405190601f1990601f018116820167ffffffffffffffff811183821017610378575b60405283825261036e829461030a565b0190602036910137565b6103806102f3565b61035e56fea26469706673582212208dba9bb8521bbf9e8b09360ce26526ba09b14d8cccf2e0f4c358ec5b1a3028aa64736f6c634300081100330000000000000000000000000000000d11df8303bf1a221786693aaac473ff36

Deployed Bytecode

0x6080604052600436101561001257600080fd5b6000803560e01c63a1ccb98e1461002857600080fd5b346100ba5760803660031901126100ba57600435906001600160a01b03821682036100ba576024359160028310156100bd576044359267ffffffffffffffff928385116100ba57366023860112156100ba5784600401359384116100ba5736602460a08602870101116100ba576100b66100aa606435866024890186886100fe565b604051918291826100c1565b0390f35b80fd5b5080fd5b6020908160408183019282815285518094520193019160005b8281106100e8575050505090565b83511515855293810193928101926001016100da565b9193909360019260018060a01b0384541633036102e257600094600286541461029d578390600287551061028b576101398397969597610331565b94875b848110610159575050505050509091506101566001600055565b90565b6040805160a0838102870190608082013580156102115760011461017b578c80fd5b637921219560e11b83528580156101ed57600114610197578c80fd5b9b60c48a95949382809d9e9f8560609183973560248601528c60048601525b60848501528260a4850152602097888201356044860152810135606485015201355af1908260051b8b0101525b019796959761013c565b509b60c48a95949382809d9e9f8560609183973560048601528c60248601526101b6565b5050632142170760e11b8252915083801561026c57600114610231578a80fd5b908a80606484889d9e9c9d60048d98970152843560248201525b82606060209687810135604485015201355af1908260051b8b0101526101e3565b50908a80606484889d9e9c9d60248d989701528435600482015261024b565b60405163251f56a160e21b8152600490fd5b60405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606490fd5b6040516282b42960e81b8152600490fd5b50634e487b7160e01b600052604160045260246000fd5b60209067ffffffffffffffff8111610324575b60051b0190565b61032c6102f3565b61031d565b9061033b8261030a565b60405190601f1990601f018116820167ffffffffffffffff811183821017610378575b60405283825261036e829461030a565b0190602036910137565b6103806102f3565b61035e56fea26469706673582212208dba9bb8521bbf9e8b09360ce26526ba09b14d8cccf2e0f4c358ec5b1a3028aa64736f6c63430008110033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000000000000d11df8303bf1a221786693aaac473ff36

-----Decoded View---------------
Arg [0] : exchange (address): 0x0000000d11dF8303bf1a221786693aAaC473FF36

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000d11df8303bf1a221786693aaac473ff36


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.