Base Sepolia Testnet

Contract

0x93B7fCbc63ED8a3a24B59e1C3e6649D50B7427c0

Overview

ETH Balance

0 ETH

Multichain Info

N/A
Transaction Hash
Method
Block
From
To

There are no matching entries

1 Internal Transaction found.

Latest 1 internal transaction

Parent Transaction Hash Block From To
182535242024-11-22 11:35:36151 days ago1732275336  Contract Creation0 ETH

Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
MultiSendUnwrapper

Compiler Version
v0.8.21+commit.d9974bed

Optimization Enabled:
Yes with 100 runs

Other Settings:
shanghai EvmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 3 : MultiSendUnwrapper.sol
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.8.17 <0.9.0;

import "./Types.sol";

contract MultiSendUnwrapper is ITransactionUnwrapper {
    uint256 private constant OFFSET_START = 68;

    error UnsupportedMode();
    error MalformedHeader();
    error MalformedBody();

    function unwrap(
        address,
        uint256 value,
        bytes calldata data,
        Enum.Operation operation
    ) external pure returns (UnwrappedTransaction[] memory) {
        if (value != 0) {
            revert UnsupportedMode();
        }
        if (operation != Enum.Operation.DelegateCall) {
            revert UnsupportedMode();
        }
        _validateHeader(data);
        uint256 count = _validateEntries(data);
        return _unwrapEntries(data, count);
    }

    function _validateHeader(bytes calldata data) private pure {
        // first 4 bytes are the selector for multiSend(bytes)
        if (bytes4(data) != IMultiSend.multiSend.selector) {
            revert MalformedHeader();
        }

        // the following 32 bytes are the offset to the bytes param
        // (always 0x20)
        if (bytes32(data[4:]) != bytes32(uint256(0x20))) {
            revert MalformedHeader();
        }

        // the following 32 bytes are the length of the bytes param
        uint256 length = uint256(bytes32(data[36:]));

        // validate that the total calldata length matches
        // it's the 4 + 32 + 32 bytes checked above + the <length> bytes
        // padded to a multiple of 32
        if (4 + _ceil32(32 + 32 + length) != data.length) {
            revert MalformedHeader();
        }
    }

    function _validateEntries(
        bytes calldata data
    ) private pure returns (uint256 count) {
        uint256 offset = OFFSET_START;

        // data is padded to 32 bytes we can't simply do offset < data.length
        for (; offset + 32 < data.length; ) {
            // Per transaction:
            // Operation   1  bytes
            // To          20 bytes
            // Value       32 bytes
            // Length      32 bytes
            // Data        Length bytes
            uint8 operation = uint8(bytes1(data[offset:]));
            if (operation > 1) {
                revert MalformedBody();
            }

            uint256 length = uint256(bytes32(data[offset + 53:]));
            if (offset + 85 + length > data.length) {
                revert MalformedBody();
            }

            offset += 85 + length;
            count++;
        }

        if (count == 0) {
            revert MalformedBody();
        }
    }

    function _unwrapEntries(
        bytes calldata data,
        uint256 count
    ) private pure returns (UnwrappedTransaction[] memory result) {
        result = new UnwrappedTransaction[](count);

        uint256 offset = OFFSET_START;
        for (uint256 i; i < count; ) {
            result[i].operation = Enum.Operation(uint8(bytes1(data[offset:])));
            offset += 1;

            result[i].to = address(bytes20(data[offset:]));
            offset += 20;

            result[i].value = uint256(bytes32(data[offset:]));
            offset += 32;

            uint256 size = uint256(bytes32(data[offset:]));
            offset += 32;

            result[i].dataLocation = offset;
            result[i].dataSize = size;
            offset += size;

            unchecked {
                ++i;
            }
        }
    }

    function _ceil32(uint256 length) private pure returns (uint256) {
        // pad size. Source: http://www.cs.nott.ac.uk/~psarb2/G51MPC/slides/NumberLogic.pdf
        return ((length + 32 - 1) / 32) * 32;
    }
}

File 2 of 3 : Enum.sol
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.7.0 <0.9.0;

/// @title Enum - Collection of enums
/// @author Richard Meissner - <[email protected]>
contract Enum {
    enum Operation {Call, DelegateCall}
}

File 3 of 3 : Types.sol
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.8.17 <0.9.0;

import "@gnosis.pm/safe-contracts/contracts/common/Enum.sol";

interface IMultiSend {
    function multiSend(bytes memory transactions) external payable;
}

struct UnwrappedTransaction {
    Enum.Operation operation;
    address to;
    uint256 value;
    // We wanna deal in calldata slices. We return location, let invoker slice
    uint256 dataLocation;
    uint256 dataSize;
}

interface ITransactionUnwrapper {
    function unwrap(
        address to,
        uint256 value,
        bytes calldata data,
        Enum.Operation operation
    ) external view returns (UnwrappedTransaction[] memory result);
}

interface ICustomCondition {
    function check(
        address to,
        uint256 value,
        bytes calldata data,
        Enum.Operation operation,
        uint256 location,
        uint256 size,
        bytes12 extra
    ) external view returns (bool success, bytes32 reason);
}

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

Contract ABI

API
[{"inputs":[],"name":"MalformedBody","type":"error"},{"inputs":[],"name":"MalformedHeader","type":"error"},{"inputs":[],"name":"UnsupportedMode","type":"error"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"enum Enum.Operation","name":"operation","type":"uint8"}],"name":"unwrap","outputs":[{"components":[{"internalType":"enum Enum.Operation","name":"operation","type":"uint8"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"dataLocation","type":"uint256"},{"internalType":"uint256","name":"dataSize","type":"uint256"}],"internalType":"struct UnwrappedTransaction[]","name":"","type":"tuple[]"}],"stateMutability":"pure","type":"function"}]

608060405234801561000f575f80fd5b506108178061001d5f395ff3fe608060405234801561000f575f80fd5b5060043610610029575f3560e01c8063c7a7b6351461002d575b5f80fd5b61004061003b366004610511565b610056565b60405161004d91906105c8565b60405180910390f35b606084156100775760405163ad6e405560e01b815260040160405180910390fd5b600182600181111561008b5761008b6105b4565b146100a95760405163ad6e405560e01b815260040160405180910390fd5b6100b384846100d6565b5f6100be85856101a1565b90506100cb85858361029d565b979650505050505050565b6346c07f8560e11b6100e8828461065c565b6001600160e01b0319161461011057604051631a751fb760e11b815260040160405180910390fd5b602061011f826004818661068c565b610128916106b3565b1461014657604051631a751fb760e11b815260040160405180910390fd5b5f610154826024818661068c565b61015d916106b3565b90508161017361016e8360406106e4565b6104ca565b61017e9060046106e4565b1461019c57604051631a751fb760e11b815260040160405180910390fd5b505050565b5f60445b826101b18260206106e4565b1015610277575f6101c48483818861068c565b6101cd916106f7565b60f81c905060018111156101f357604051629ec3f960e31b815260040160405180910390fd5b5f85856102018560356106e4565b61020c92829061068c565b610215916106b3565b905084816102248560556106e4565b61022e91906106e4565b111561024c57604051629ec3f960e31b815260040160405180910390fd5b6102578160556106e4565b61026190846106e4565b92508361026d81610725565b94505050506101a5565b815f0361029657604051629ec3f960e31b815260040160405180910390fd5b5092915050565b60608167ffffffffffffffff8111156102b8576102b861073d565b60405190808252806020026020018201604052801561032057816020015b61030d6040805160a08101909152805f81526020015f6001600160a01b031681526020015f81526020015f81526020015f81525090565b8152602001906001900390816102d65790505b50905060445f5b838110156104c15761033b8583818961068c565b610344916106f7565b60f81c6001811115610358576103586105b4565b83828151811061036a5761036a610751565b60200260200101515f01906001811115610386576103866105b4565b90816001811115610399576103996105b4565b9052506103a76001836106e4565b91506103b58583818961068c565b6103be91610765565b60601c8382815181106103d3576103d3610751565b6020908102919091018101516001600160a01b039092169101526103f86014836106e4565b91506104068583818961068c565b61040f916106b3565b5f1c83828151811061042357610423610751565b6020026020010151604001818152505060208261044091906106e4565b91505f61044f8684818a61068c565b610458916106b3565b90506104656020846106e4565b92508284838151811061047a5761047a610751565b602002602001015160600181815250508084838151811061049d5761049d610751565b6020908102919091010151608001526104b681846106e4565b925050600101610327565b50509392505050565b5f602060016104d984836106e4565b6104e39190610798565b6104ed91906107ab565b6104f89060206107ca565b92915050565b80356002811061050c575f80fd5b919050565b5f805f805f60808688031215610525575f80fd5b85356001600160a01b038116811461053b575f80fd5b945060208601359350604086013567ffffffffffffffff8082111561055e575f80fd5b818801915088601f830112610571575f80fd5b81358181111561057f575f80fd5b896020828501011115610590575f80fd5b6020830195508094505050506105a8606087016104fe565b90509295509295909350565b634e487b7160e01b5f52602160045260245ffd5b602080825282518282018190525f91906040908185019086840185805b8381101561064e57825180516002811061060d57634e487b7160e01b84526021600452602484fd5b8652808801516001600160a01b0316888701528681015187870152606080820151908701526080908101519086015260a090940193918601916001016105e5565b509298975050505050505050565b6001600160e01b031981358181169160048510156106845780818660040360031b1b83161692505b505092915050565b5f808585111561069a575f80fd5b838611156106a6575f80fd5b5050820193919092039150565b803560208310156104f8575f19602084900360031b1b1692915050565b634e487b7160e01b5f52601160045260245ffd5b808201808211156104f8576104f86106d0565b6001600160f81b031981358181169160018510156106845760019490940360031b84901b1690921692915050565b5f60018201610736576107366106d0565b5060010190565b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b6bffffffffffffffffffffffff1981358181169160148510156106845760149490940360031b84901b1690921692915050565b818103818111156104f8576104f86106d0565b5f826107c557634e487b7160e01b5f52601260045260245ffd5b500490565b80820281158282048414176104f8576104f86106d056fea2646970667358221220fdbe66738b4a25a36e5fbd476d551f3c9657dd12c046459067c1471f52efa0f764736f6c63430008150033

Deployed Bytecode

0x608060405234801561000f575f80fd5b5060043610610029575f3560e01c8063c7a7b6351461002d575b5f80fd5b61004061003b366004610511565b610056565b60405161004d91906105c8565b60405180910390f35b606084156100775760405163ad6e405560e01b815260040160405180910390fd5b600182600181111561008b5761008b6105b4565b146100a95760405163ad6e405560e01b815260040160405180910390fd5b6100b384846100d6565b5f6100be85856101a1565b90506100cb85858361029d565b979650505050505050565b6346c07f8560e11b6100e8828461065c565b6001600160e01b0319161461011057604051631a751fb760e11b815260040160405180910390fd5b602061011f826004818661068c565b610128916106b3565b1461014657604051631a751fb760e11b815260040160405180910390fd5b5f610154826024818661068c565b61015d916106b3565b90508161017361016e8360406106e4565b6104ca565b61017e9060046106e4565b1461019c57604051631a751fb760e11b815260040160405180910390fd5b505050565b5f60445b826101b18260206106e4565b1015610277575f6101c48483818861068c565b6101cd916106f7565b60f81c905060018111156101f357604051629ec3f960e31b815260040160405180910390fd5b5f85856102018560356106e4565b61020c92829061068c565b610215916106b3565b905084816102248560556106e4565b61022e91906106e4565b111561024c57604051629ec3f960e31b815260040160405180910390fd5b6102578160556106e4565b61026190846106e4565b92508361026d81610725565b94505050506101a5565b815f0361029657604051629ec3f960e31b815260040160405180910390fd5b5092915050565b60608167ffffffffffffffff8111156102b8576102b861073d565b60405190808252806020026020018201604052801561032057816020015b61030d6040805160a08101909152805f81526020015f6001600160a01b031681526020015f81526020015f81526020015f81525090565b8152602001906001900390816102d65790505b50905060445f5b838110156104c15761033b8583818961068c565b610344916106f7565b60f81c6001811115610358576103586105b4565b83828151811061036a5761036a610751565b60200260200101515f01906001811115610386576103866105b4565b90816001811115610399576103996105b4565b9052506103a76001836106e4565b91506103b58583818961068c565b6103be91610765565b60601c8382815181106103d3576103d3610751565b6020908102919091018101516001600160a01b039092169101526103f86014836106e4565b91506104068583818961068c565b61040f916106b3565b5f1c83828151811061042357610423610751565b6020026020010151604001818152505060208261044091906106e4565b91505f61044f8684818a61068c565b610458916106b3565b90506104656020846106e4565b92508284838151811061047a5761047a610751565b602002602001015160600181815250508084838151811061049d5761049d610751565b6020908102919091010151608001526104b681846106e4565b925050600101610327565b50509392505050565b5f602060016104d984836106e4565b6104e39190610798565b6104ed91906107ab565b6104f89060206107ca565b92915050565b80356002811061050c575f80fd5b919050565b5f805f805f60808688031215610525575f80fd5b85356001600160a01b038116811461053b575f80fd5b945060208601359350604086013567ffffffffffffffff8082111561055e575f80fd5b818801915088601f830112610571575f80fd5b81358181111561057f575f80fd5b896020828501011115610590575f80fd5b6020830195508094505050506105a8606087016104fe565b90509295509295909350565b634e487b7160e01b5f52602160045260245ffd5b602080825282518282018190525f91906040908185019086840185805b8381101561064e57825180516002811061060d57634e487b7160e01b84526021600452602484fd5b8652808801516001600160a01b0316888701528681015187870152606080820151908701526080908101519086015260a090940193918601916001016105e5565b509298975050505050505050565b6001600160e01b031981358181169160048510156106845780818660040360031b1b83161692505b505092915050565b5f808585111561069a575f80fd5b838611156106a6575f80fd5b5050820193919092039150565b803560208310156104f8575f19602084900360031b1b1692915050565b634e487b7160e01b5f52601160045260245ffd5b808201808211156104f8576104f86106d0565b6001600160f81b031981358181169160018510156106845760019490940360031b84901b1690921692915050565b5f60018201610736576107366106d0565b5060010190565b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b6bffffffffffffffffffffffff1981358181169160148510156106845760149490940360031b84901b1690921692915050565b818103818111156104f8576104f86106d0565b5f826107c557634e487b7160e01b5f52601260045260245ffd5b500490565b80820281158282048414176104f8576104f86106d056fea2646970667358221220fdbe66738b4a25a36e5fbd476d551f3c9657dd12c046459067c1471f52efa0f764736f6c63430008150033

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