Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
Multichain Info
N/A
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
18253524 | 151 days ago | Contract Creation | 0 ETH |
Loading...
Loading
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)
// 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; } }
// 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} }
// 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); }
{ "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"}]
Contract Creation Code
608060405234801561000f575f80fd5b506108178061001d5f395ff3fe608060405234801561000f575f80fd5b5060043610610029575f3560e01c8063c7a7b6351461002d575b5f80fd5b61004061003b366004610511565b610056565b60405161004d91906105c8565b60405180910390f35b606084156100775760405163ad6e405560e01b815260040160405180910390fd5b600182600181111561008b5761008b6105b4565b146100a95760405163ad6e405560e01b815260040160405180910390fd5b6100b384846100d6565b5f6100be85856101a1565b90506100cb85858361029d565b979650505050505050565b6346c07f8560e11b6100e8828461065c565b6001600160e01b0319161461011057604051631a751fb760e11b815260040160405180910390fd5b602061011f826004818661068c565b610128916106b3565b1461014657604051631a751fb760e11b815260040160405180910390fd5b5f610154826024818661068c565b61015d916106b3565b90508161017361016e8360406106e4565b6104ca565b61017e9060046106e4565b1461019c57604051631a751fb760e11b815260040160405180910390fd5b505050565b5f60445b826101b18260206106e4565b1015610277575f6101c48483818861068c565b6101cd916106f7565b60f81c905060018111156101f357604051629ec3f960e31b815260040160405180910390fd5b5f85856102018560356106e4565b61020c92829061068c565b610215916106b3565b905084816102248560556106e4565b61022e91906106e4565b111561024c57604051629ec3f960e31b815260040160405180910390fd5b6102578160556106e4565b61026190846106e4565b92508361026d81610725565b94505050506101a5565b815f0361029657604051629ec3f960e31b815260040160405180910390fd5b5092915050565b60608167ffffffffffffffff8111156102b8576102b861073d565b60405190808252806020026020018201604052801561032057816020015b61030d6040805160a08101909152805f81526020015f6001600160a01b031681526020015f81526020015f81526020015f81525090565b8152602001906001900390816102d65790505b50905060445f5b838110156104c15761033b8583818961068c565b610344916106f7565b60f81c6001811115610358576103586105b4565b83828151811061036a5761036a610751565b60200260200101515f01906001811115610386576103866105b4565b90816001811115610399576103996105b4565b9052506103a76001836106e4565b91506103b58583818961068c565b6103be91610765565b60601c8382815181106103d3576103d3610751565b6020908102919091018101516001600160a01b039092169101526103f86014836106e4565b91506104068583818961068c565b61040f916106b3565b5f1c83828151811061042357610423610751565b6020026020010151604001818152505060208261044091906106e4565b91505f61044f8684818a61068c565b610458916106b3565b90506104656020846106e4565b92508284838151811061047a5761047a610751565b602002602001015160600181815250508084838151811061049d5761049d610751565b6020908102919091010151608001526104b681846106e4565b925050600101610327565b50509392505050565b5f602060016104d984836106e4565b6104e39190610798565b6104ed91906107ab565b6104f89060206107ca565b92915050565b80356002811061050c575f80fd5b919050565b5f805f805f60808688031215610525575f80fd5b85356001600160a01b038116811461053b575f80fd5b945060208601359350604086013567ffffffffffffffff8082111561055e575f80fd5b818801915088601f830112610571575f80fd5b81358181111561057f575f80fd5b896020828501011115610590575f80fd5b6020830195508094505050506105a8606087016104fe565b90509295509295909350565b634e487b7160e01b5f52602160045260245ffd5b602080825282518282018190525f91906040908185019086840185805b8381101561064e57825180516002811061060d57634e487b7160e01b84526021600452602484fd5b8652808801516001600160a01b0316888701528681015187870152606080820151908701526080908101519086015260a090940193918601916001016105e5565b509298975050505050505050565b6001600160e01b031981358181169160048510156106845780818660040360031b1b83161692505b505092915050565b5f808585111561069a575f80fd5b838611156106a6575f80fd5b5050820193919092039150565b803560208310156104f8575f19602084900360031b1b1692915050565b634e487b7160e01b5f52601160045260245ffd5b808201808211156104f8576104f86106d0565b6001600160f81b031981358181169160018510156106845760019490940360031b84901b1690921692915050565b5f60018201610736576107366106d0565b5060010190565b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b6bffffffffffffffffffffffff1981358181169160148510156106845760149490940360031b84901b1690921692915050565b818103818111156104f8576104f86106d0565b5f826107c557634e487b7160e01b5f52601260045260245ffd5b500490565b80820281158282048414176104f8576104f86106d056fea2646970667358221220fdbe66738b4a25a36e5fbd476d551f3c9657dd12c046459067c1471f52efa0f764736f6c63430008150033
Deployed Bytecode
0x608060405234801561000f575f80fd5b5060043610610029575f3560e01c8063c7a7b6351461002d575b5f80fd5b61004061003b366004610511565b610056565b60405161004d91906105c8565b60405180910390f35b606084156100775760405163ad6e405560e01b815260040160405180910390fd5b600182600181111561008b5761008b6105b4565b146100a95760405163ad6e405560e01b815260040160405180910390fd5b6100b384846100d6565b5f6100be85856101a1565b90506100cb85858361029d565b979650505050505050565b6346c07f8560e11b6100e8828461065c565b6001600160e01b0319161461011057604051631a751fb760e11b815260040160405180910390fd5b602061011f826004818661068c565b610128916106b3565b1461014657604051631a751fb760e11b815260040160405180910390fd5b5f610154826024818661068c565b61015d916106b3565b90508161017361016e8360406106e4565b6104ca565b61017e9060046106e4565b1461019c57604051631a751fb760e11b815260040160405180910390fd5b505050565b5f60445b826101b18260206106e4565b1015610277575f6101c48483818861068c565b6101cd916106f7565b60f81c905060018111156101f357604051629ec3f960e31b815260040160405180910390fd5b5f85856102018560356106e4565b61020c92829061068c565b610215916106b3565b905084816102248560556106e4565b61022e91906106e4565b111561024c57604051629ec3f960e31b815260040160405180910390fd5b6102578160556106e4565b61026190846106e4565b92508361026d81610725565b94505050506101a5565b815f0361029657604051629ec3f960e31b815260040160405180910390fd5b5092915050565b60608167ffffffffffffffff8111156102b8576102b861073d565b60405190808252806020026020018201604052801561032057816020015b61030d6040805160a08101909152805f81526020015f6001600160a01b031681526020015f81526020015f81526020015f81525090565b8152602001906001900390816102d65790505b50905060445f5b838110156104c15761033b8583818961068c565b610344916106f7565b60f81c6001811115610358576103586105b4565b83828151811061036a5761036a610751565b60200260200101515f01906001811115610386576103866105b4565b90816001811115610399576103996105b4565b9052506103a76001836106e4565b91506103b58583818961068c565b6103be91610765565b60601c8382815181106103d3576103d3610751565b6020908102919091018101516001600160a01b039092169101526103f86014836106e4565b91506104068583818961068c565b61040f916106b3565b5f1c83828151811061042357610423610751565b6020026020010151604001818152505060208261044091906106e4565b91505f61044f8684818a61068c565b610458916106b3565b90506104656020846106e4565b92508284838151811061047a5761047a610751565b602002602001015160600181815250508084838151811061049d5761049d610751565b6020908102919091010151608001526104b681846106e4565b925050600101610327565b50509392505050565b5f602060016104d984836106e4565b6104e39190610798565b6104ed91906107ab565b6104f89060206107ca565b92915050565b80356002811061050c575f80fd5b919050565b5f805f805f60808688031215610525575f80fd5b85356001600160a01b038116811461053b575f80fd5b945060208601359350604086013567ffffffffffffffff8082111561055e575f80fd5b818801915088601f830112610571575f80fd5b81358181111561057f575f80fd5b896020828501011115610590575f80fd5b6020830195508094505050506105a8606087016104fe565b90509295509295909350565b634e487b7160e01b5f52602160045260245ffd5b602080825282518282018190525f91906040908185019086840185805b8381101561064e57825180516002811061060d57634e487b7160e01b84526021600452602484fd5b8652808801516001600160a01b0316888701528681015187870152606080820151908701526080908101519086015260a090940193918601916001016105e5565b509298975050505050505050565b6001600160e01b031981358181169160048510156106845780818660040360031b1b83161692505b505092915050565b5f808585111561069a575f80fd5b838611156106a6575f80fd5b5050820193919092039150565b803560208310156104f8575f19602084900360031b1b1692915050565b634e487b7160e01b5f52601160045260245ffd5b808201808211156104f8576104f86106d0565b6001600160f81b031981358181169160018510156106845760019490940360031b84901b1690921692915050565b5f60018201610736576107366106d0565b5060010190565b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b6bffffffffffffffffffffffff1981358181169160148510156106845760149490940360031b84901b1690921692915050565b818103818111156104f8576104f86106d0565b5f826107c557634e487b7160e01b5f52601260045260245ffd5b500490565b80820281158282048414176104f8576104f86106d056fea2646970667358221220fdbe66738b4a25a36e5fbd476d551f3c9657dd12c046459067c1471f52efa0f764736f6c63430008150033
Loading...
Loading
Loading...
Loading
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.