ETH Price: $1,791.00 (+10.02%)

Contract

0x17d8a54D35842133b123a6e6Fc57d51338A4Aee5
 

Overview

ETH Balance

0 ETH

ETH Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

Please try again later

Parent Transaction Hash Block From To
View All Internal Transactions

Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Delegate

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 20000 runs

Other Settings:
london EvmVersion
File 1 of 3 : Delegate.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

import "./lib/Constants.sol";
import { OrderType, Transfer } from "./lib/Structs.sol";

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

    address private immutable _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 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 3 : 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_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 OracleSignatures_size = 0x59;
uint256 constant OracleSignatures_s_offset = 0x20;
uint256 constant OracleSignatures_v_offset = 0x40;
uint256 constant OracleSignatures_blockNumber_offset = 0x41;
uint256 constant OracleSignatures_oracle_offset = 0x45;

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 3 of 3 : Structs.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

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

struct TakeAskSingle {
    Order order;
    Exchange exchange;
    FeeRate takerFee;
    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
}

/*
Reference only; struct is composed manually using calldata formatting in execution
struct ExecutionBatch { // Size: 0x80
    address taker; // 0x00
    OrderType orderType; // 0x20
    Transfer[] transfers; // 0x40
    uint256 length; // 0x60
}
*/

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 totalTakerFee;
    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 takerFeeAmount; // 0x80
    uint256 protocolFeeAmount; // 0xa0
    StateUpdate stateUpdate; // 0xc0
}

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

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

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

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

Settings
{
  "remappings": [
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
    "forge-std/=lib/forge-std/src/",
    "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
    "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
    "solidity-helpers/=lib/solidity-helpers/src/",
    "solmate/=lib/solmate/src/",
    "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/",
    "openzeppelin/=lib/openzeppelin-contracts-upgradeable/contracts/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 20000
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs"
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "london",
  "viaIR": false,
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"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"}]

60a060405234801561001057600080fd5b5060405161049838038061049883398101604081905261002f91610040565b6001600160a01b0316608052610070565b60006020828403121561005257600080fd5b81516001600160a01b038116811461006957600080fd5b9392505050565b60805161040e61008a60003960006073015261040e6000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063a1ccb98e14610030575b600080fd5b61004361003e3660046102a9565b610059565b6040516100509190610363565b60405180910390f35b60603373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146100ca576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81831015610104576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8167ffffffffffffffff81111561011d5761011d6103a9565b604051908082528060200260200182016040528015610146578160200160208202803683370190505b50905060005b8281101561029f5760405160a082028601608081013580801561017657600181146101f957600080fd5b7f42842e0e0000000000000000000000000000000000000000000000000000000084528980156101ad57600181146101c057600080fd5b602485018c9052833560048601526101cf565b600485018c9052833560248601525b506020830135604485015260608301356000806064876000855af160208088028901015250610290565b7ff242432a000000000000000000000000000000000000000000000000000000008452898015610230576001811461024357600080fd5b83356004860152602485018c9052610252565b83356024860152600485018c90525b5060a06084850152600060a48501526020830135604485015260408301356064850152606083013560008060c4876000855af1602080880289010152505b5050505080600101905061014c565b5095945050505050565b6000806000806000608086880312156102c157600080fd5b853573ffffffffffffffffffffffffffffffffffffffff811681146102e557600080fd5b94506020860135600281106102f957600080fd5b9350604086013567ffffffffffffffff8082111561031657600080fd5b818801915088601f83011261032a57600080fd5b81358181111561033957600080fd5b89602060a08302850101111561034e57600080fd5b96999598505060200195606001359392505050565b6020808252825182820181905260009190848201906040850190845b8181101561039d57835115158352928401929184019160010161037f565b50909695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea2646970667358221220d4727c239f3fdbb02a0bdc76fb2ad38e8eb4649b63f47693dc2e37f95ee0f06a64736f6c634300081100330000000000000000000000000f41639352b190f352baddd32856038f1c230ced

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063a1ccb98e14610030575b600080fd5b61004361003e3660046102a9565b610059565b6040516100509190610363565b60405180910390f35b60603373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000f41639352b190f352baddd32856038f1c230ced16146100ca576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81831015610104576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8167ffffffffffffffff81111561011d5761011d6103a9565b604051908082528060200260200182016040528015610146578160200160208202803683370190505b50905060005b8281101561029f5760405160a082028601608081013580801561017657600181146101f957600080fd5b7f42842e0e0000000000000000000000000000000000000000000000000000000084528980156101ad57600181146101c057600080fd5b602485018c9052833560048601526101cf565b600485018c9052833560248601525b506020830135604485015260608301356000806064876000855af160208088028901015250610290565b7ff242432a000000000000000000000000000000000000000000000000000000008452898015610230576001811461024357600080fd5b83356004860152602485018c9052610252565b83356024860152600485018c90525b5060a06084850152600060a48501526020830135604485015260408301356064850152606083013560008060c4876000855af1602080880289010152505b5050505080600101905061014c565b5095945050505050565b6000806000806000608086880312156102c157600080fd5b853573ffffffffffffffffffffffffffffffffffffffff811681146102e557600080fd5b94506020860135600281106102f957600080fd5b9350604086013567ffffffffffffffff8082111561031657600080fd5b818801915088601f83011261032a57600080fd5b81358181111561033957600080fd5b89602060a08302850101111561034e57600080fd5b96999598505060200195606001359392505050565b6020808252825182820181905260009190848201906040850190845b8181101561039d57835115158352928401929184019160010161037f565b50909695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea2646970667358221220d4727c239f3fdbb02a0bdc76fb2ad38e8eb4649b63f47693dc2e37f95ee0f06a64736f6c63430008110033

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

0000000000000000000000000f41639352b190f352baddd32856038f1c230ced

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

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000000f41639352b190f352baddd32856038f1c230ced


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
Loading...
Loading

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.