From ddee16ebaed86bbc92b1a92449659762b0e4727d Mon Sep 17 00:00:00 2001 From: xtools-at Date: Wed, 20 Mar 2024 12:48:46 +0000 Subject: [PATCH] chore: zkevm multicall deployment --- contracts/Multicall3.sol | 242 +++++++ deploy/Multicall.js | 22 + deployments/imtbl-zkevm-testnet/.chainId | 1 + .../imtbl-zkevm-testnet/Multicall3.json | 592 ++++++++++++++++++ .../2c4045da9263c8058401050467beca99.json | 35 ++ deployments/imtbl-zkevm/.chainId | 1 + deployments/imtbl-zkevm/Multicall3.json | 592 ++++++++++++++++++ .../b36a7d608ba9b8cba9935e17cb428950.json | 36 ++ hardhat.config.js | 11 + 9 files changed, 1532 insertions(+) create mode 100644 contracts/Multicall3.sol create mode 100644 deploy/Multicall.js create mode 100644 deployments/imtbl-zkevm-testnet/.chainId create mode 100644 deployments/imtbl-zkevm-testnet/Multicall3.json create mode 100644 deployments/imtbl-zkevm-testnet/solcInputs/2c4045da9263c8058401050467beca99.json create mode 100644 deployments/imtbl-zkevm/.chainId create mode 100644 deployments/imtbl-zkevm/Multicall3.json create mode 100644 deployments/imtbl-zkevm/solcInputs/b36a7d608ba9b8cba9935e17cb428950.json diff --git a/contracts/Multicall3.sol b/contracts/Multicall3.sol new file mode 100644 index 00000000..5cbfc97a --- /dev/null +++ b/contracts/Multicall3.sol @@ -0,0 +1,242 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.23; + +/// @title Multicall3 +/// @notice Aggregate results from multiple function calls +/// @dev Multicall & Multicall2 backwards-compatible +/// @dev Aggregate methods are marked `payable` to save 24 gas per call +/// @author Michael Elliot +/// @author Joshua Levine +/// @author Nick Johnson +/// @author Andreas Bigger +/// @author Matt Solomon +contract Multicall3 { + struct Call { + address target; + bytes callData; + } + + struct Call3 { + address target; + bool allowFailure; + bytes callData; + } + + struct Call3Value { + address target; + bool allowFailure; + uint value; + bytes callData; + } + + struct Result { + bool success; + bytes returnData; + } + + /// @notice Backwards-compatible call aggregation with Multicall + /// @param calls An array of Call structs + /// @return blockNumber The block number where the calls were executed + /// @return returnData An array of bytes containing the responses + function aggregate(Call[] calldata calls) public payable returns (uint blockNumber, bytes[] memory returnData) { + blockNumber = block.number; + uint length = calls.length; + returnData = new bytes[](length); + Call calldata call; + for (uint i = 0; i < length; ) { + bool success; + call = calls[i]; + (success, returnData[i]) = call.target.call(call.callData); + require(success, "Multicall3: call failed"); + unchecked { + ++i; + } + } + } + + /// @notice Backwards-compatible with Multicall2 + /// @notice Aggregate calls without requiring success + /// @param requireSuccess If true, require all calls to succeed + /// @param calls An array of Call structs + /// @return returnData An array of Result structs + function tryAggregate(bool requireSuccess, Call[] calldata calls) public payable returns (Result[] memory returnData) { + uint length = calls.length; + returnData = new Result[](length); + Call calldata call; + for (uint i = 0; i < length; ) { + Result memory result = returnData[i]; + call = calls[i]; + (result.success, result.returnData) = call.target.call(call.callData); + if (requireSuccess) require(result.success, "Multicall3: call failed"); + unchecked { + ++i; + } + } + } + + /// @notice Backwards-compatible with Multicall2 + /// @notice Aggregate calls and allow failures using tryAggregate + /// @param calls An array of Call structs + /// @return blockNumber The block number where the calls were executed + /// @return blockHash The hash of the block where the calls were executed + /// @return returnData An array of Result structs + function tryBlockAndAggregate(bool requireSuccess, Call[] calldata calls) + public + payable + returns ( + uint blockNumber, + bytes32 blockHash, + Result[] memory returnData + ) + { + blockNumber = block.number; + blockHash = blockhash(block.number); + returnData = tryAggregate(requireSuccess, calls); + } + + /// @notice Backwards-compatible with Multicall2 + /// @notice Aggregate calls and allow failures using tryAggregate + /// @param calls An array of Call structs + /// @return blockNumber The block number where the calls were executed + /// @return blockHash The hash of the block where the calls were executed + /// @return returnData An array of Result structs + function blockAndAggregate(Call[] calldata calls) + public + payable + returns ( + uint blockNumber, + bytes32 blockHash, + Result[] memory returnData + ) + { + (blockNumber, blockHash, returnData) = tryBlockAndAggregate(true, calls); + } + + /// @notice Aggregate calls, ensuring each returns success if required + /// @param calls An array of Call3 structs + /// @return returnData An array of Result structs + function aggregate3(Call3[] calldata calls) public payable returns (Result[] memory returnData) { + uint length = calls.length; + returnData = new Result[](length); + Call3 calldata calli; + for (uint i = 0; i < length; ) { + Result memory result = returnData[i]; + calli = calls[i]; + (result.success, result.returnData) = calli.target.call(calli.callData); + assembly { + // Revert if the call fails and failure is not allowed + // `allowFailure := calldataload(add(calli, 0x20))` and `success := mload(result)` + if iszero(or(calldataload(add(calli, 0x20)), mload(result))) { + // set "Error(string)" signature: bytes32(bytes4(keccak256("Error(string)"))) + mstore(0x00, 0x08c379a000000000000000000000000000000000000000000000000000000000) + // set data offset + mstore(0x04, 0x0000000000000000000000000000000000000000000000000000000000000020) + // set length of revert string + mstore(0x24, 0x0000000000000000000000000000000000000000000000000000000000000017) + // set revert string: bytes32(abi.encodePacked("Multicall3: call failed")) + mstore(0x44, 0x4d756c746963616c6c333a2063616c6c206661696c6564000000000000000000) + revert(0x00, 0x64) + } + } + unchecked { + ++i; + } + } + } + + /// @notice Aggregate calls with a msg value + /// @notice Reverts if msg.value is less than the sum of the call values + /// @param calls An array of Call3Value structs + /// @return returnData An array of Result structs + function aggregate3Value(Call3Value[] calldata calls) public payable returns (Result[] memory returnData) { + uint valAccumulator; + uint length = calls.length; + returnData = new Result[](length); + Call3Value calldata calli; + for (uint i = 0; i < length; ) { + Result memory result = returnData[i]; + calli = calls[i]; + uint val = calli.value; + // Humanity will be a Type V Kardashev Civilization before this overflows - andreas + // ~ 10^25 Wei in existence << ~ 10^76 size uint fits in a uint256 + unchecked { + valAccumulator += val; + } + (result.success, result.returnData) = calli.target.call{value: val}(calli.callData); + assembly { + // Revert if the call fails and failure is not allowed + // `allowFailure := calldataload(add(calli, 0x20))` and `success := mload(result)` + if iszero(or(calldataload(add(calli, 0x20)), mload(result))) { + // set "Error(string)" signature: bytes32(bytes4(keccak256("Error(string)"))) + mstore(0x00, 0x08c379a000000000000000000000000000000000000000000000000000000000) + // set data offset + mstore(0x04, 0x0000000000000000000000000000000000000000000000000000000000000020) + // set length of revert string + mstore(0x24, 0x0000000000000000000000000000000000000000000000000000000000000017) + // set revert string: bytes32(abi.encodePacked("Multicall3: call failed")) + mstore(0x44, 0x4d756c746963616c6c333a2063616c6c206661696c6564000000000000000000) + revert(0x00, 0x84) + } + } + unchecked { + ++i; + } + } + // Finally, make sure the msg.value = SUM(call[0...i].value) + require(msg.value == valAccumulator, "Multicall3: value mismatch"); + } + + /// @notice Returns the block hash for the given block number + /// @param blockNumber The block number + function getBlockHash(uint blockNumber) public view returns (bytes32 blockHash) { + blockHash = blockhash(blockNumber); + } + + /// @notice Returns the block number + function getBlockNumber() public view returns (uint blockNumber) { + blockNumber = block.number; + } + + /// @notice Returns the block coinbase + function getCurrentBlockCoinbase() public view returns (address coinbase) { + coinbase = block.coinbase; + } + + /// @notice Returns the block difficulty + function getCurrentBlockDifficulty() public view returns (uint difficulty) { + difficulty = block.difficulty; + } + + /// @notice Returns the block gas limit + function getCurrentBlockGasLimit() public view returns (uint gaslimit) { + gaslimit = block.gaslimit; + } + + /// @notice Returns the block timestamp + function getCurrentBlockTimestamp() public view returns (uint timestamp) { + timestamp = block.timestamp; + } + + /// @notice Returns the (ETH) balance of a given address + function getEthBalance(address addr) public view returns (uint balance) { + balance = addr.balance; + } + + /// @notice Returns the block hash of the last block + function getLastBlockHash() public view returns (bytes32 blockHash) { + unchecked { + blockHash = blockhash(block.number - 1); + } + } + + /// @notice Gets the base fee of the given block + /// @notice Can revert if the BASEFEE opcode is not implemented by the given chain + function getBasefee() public view returns (uint basefee) { + basefee = block.basefee; + } + + /// @notice Returns the chain id + function getChainId() public view returns (uint chainid) { + chainid = block.chainid; + } +} diff --git a/deploy/Multicall.js b/deploy/Multicall.js new file mode 100644 index 00000000..8c579a24 --- /dev/null +++ b/deploy/Multicall.js @@ -0,0 +1,22 @@ +module.exports = async function ({ deployments, getNamedAccounts }) { + const { deploy } = deployments + const { deployer } = await getNamedAccounts() + + const gasOverrides = { + maxFeePerGas: "15000000005", // 15 gwei + maxPriorityFeePerGas: "10000000005", // 10 gwei + } + + console.log(`>>> your address: ${deployer}`) + + console.log(`deploying Multicall3`) + await deploy("Multicall3", { + from: deployer, + args: [], + log: true, + waitConfirmations: 1, + ...gasOverrides, + }) +} + +module.exports.tags = ["Multicall"] diff --git a/deployments/imtbl-zkevm-testnet/.chainId b/deployments/imtbl-zkevm-testnet/.chainId new file mode 100644 index 00000000..6df8164a --- /dev/null +++ b/deployments/imtbl-zkevm-testnet/.chainId @@ -0,0 +1 @@ +13473 \ No newline at end of file diff --git a/deployments/imtbl-zkevm-testnet/Multicall3.json b/deployments/imtbl-zkevm-testnet/Multicall3.json new file mode 100644 index 00000000..00717695 --- /dev/null +++ b/deployments/imtbl-zkevm-testnet/Multicall3.json @@ -0,0 +1,592 @@ +{ + "address": "0x2CC787Ed364600B0222361C4188308Fa8E68bA60", + "abi": [ + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + } + ], + "internalType": "struct Multicall3.Call[]", + "name": "calls", + "type": "tuple[]" + } + ], + "name": "aggregate", + "outputs": [ + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + }, + { + "internalType": "bytes[]", + "name": "returnData", + "type": "bytes[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bool", + "name": "allowFailure", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + } + ], + "internalType": "struct Multicall3.Call3[]", + "name": "calls", + "type": "tuple[]" + } + ], + "name": "aggregate3", + "outputs": [ + { + "components": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "returnData", + "type": "bytes" + } + ], + "internalType": "struct Multicall3.Result[]", + "name": "returnData", + "type": "tuple[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bool", + "name": "allowFailure", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + } + ], + "internalType": "struct Multicall3.Call3Value[]", + "name": "calls", + "type": "tuple[]" + } + ], + "name": "aggregate3Value", + "outputs": [ + { + "components": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "returnData", + "type": "bytes" + } + ], + "internalType": "struct Multicall3.Result[]", + "name": "returnData", + "type": "tuple[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + } + ], + "internalType": "struct Multicall3.Call[]", + "name": "calls", + "type": "tuple[]" + } + ], + "name": "blockAndAggregate", + "outputs": [ + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "blockHash", + "type": "bytes32" + }, + { + "components": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "returnData", + "type": "bytes" + } + ], + "internalType": "struct Multicall3.Result[]", + "name": "returnData", + "type": "tuple[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "getBasefee", + "outputs": [ + { + "internalType": "uint256", + "name": "basefee", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + } + ], + "name": "getBlockHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "blockHash", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBlockNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getChainId", + "outputs": [ + { + "internalType": "uint256", + "name": "chainid", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCurrentBlockCoinbase", + "outputs": [ + { + "internalType": "address", + "name": "coinbase", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCurrentBlockDifficulty", + "outputs": [ + { + "internalType": "uint256", + "name": "difficulty", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCurrentBlockGasLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "gaslimit", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCurrentBlockTimestamp", + "outputs": [ + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "getEthBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getLastBlockHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "blockHash", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "requireSuccess", + "type": "bool" + }, + { + "components": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + } + ], + "internalType": "struct Multicall3.Call[]", + "name": "calls", + "type": "tuple[]" + } + ], + "name": "tryAggregate", + "outputs": [ + { + "components": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "returnData", + "type": "bytes" + } + ], + "internalType": "struct Multicall3.Result[]", + "name": "returnData", + "type": "tuple[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "requireSuccess", + "type": "bool" + }, + { + "components": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + } + ], + "internalType": "struct Multicall3.Call[]", + "name": "calls", + "type": "tuple[]" + } + ], + "name": "tryBlockAndAggregate", + "outputs": [ + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "blockHash", + "type": "bytes32" + }, + { + "components": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "returnData", + "type": "bytes" + } + ], + "internalType": "struct Multicall3.Result[]", + "name": "returnData", + "type": "tuple[]" + } + ], + "stateMutability": "payable", + "type": "function" + } + ], + "transactionHash": "0x5a020f70ad6494178b4661c72676d8b6e6bde0b325fda1ec1dccb23f395b6d6b", + "receipt": { + "to": null, + "from": "0xbFb53a2c470cdb4FF32eE4F18A93B98F9f55D0E1", + "contractAddress": "0x2CC787Ed364600B0222361C4188308Fa8E68bA60", + "transactionIndex": 0, + "gasUsed": "853939", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xed73df328367e6d2b4c2ae736d0c1dd2ce883801841ec8afa2c46b7b9ab9fb46", + "transactionHash": "0x5a020f70ad6494178b4661c72676d8b6e6bde0b325fda1ec1dccb23f395b6d6b", + "logs": [], + "blockNumber": 5977391, + "cumulativeGasUsed": "853939", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "2c4045da9263c8058401050467beca99", + "metadata": "{\"compiler\":{\"version\":\"0.8.23+commit.f704f362\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Call[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"aggregate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"returnData\",\"type\":\"bytes[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowFailure\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Call3[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"aggregate3\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowFailure\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Call3Value[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"aggregate3Value\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Call[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"blockAndAggregate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBasefee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"basefee\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"}],\"name\":\"getBlockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getChainId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainid\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockCoinbase\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"coinbase\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockDifficulty\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"difficulty\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockGasLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"gaslimit\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockTimestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"getEthBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLastBlockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"requireSuccess\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Call[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"tryAggregate\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"requireSuccess\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Call[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"tryBlockAndAggregate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Michael Elliot Joshua Levine Nick Johnson Andreas Bigger Matt Solomon \",\"details\":\"Multicall & Multicall2 backwards-compatibleAggregate methods are marked `payable` to save 24 gas per call\",\"kind\":\"dev\",\"methods\":{\"aggregate((address,bytes)[])\":{\"params\":{\"calls\":\"An array of Call structs\"},\"returns\":{\"blockNumber\":\"The block number where the calls were executed\",\"returnData\":\"An array of bytes containing the responses\"}},\"aggregate3((address,bool,bytes)[])\":{\"params\":{\"calls\":\"An array of Call3 structs\"},\"returns\":{\"returnData\":\"An array of Result structs\"}},\"aggregate3Value((address,bool,uint256,bytes)[])\":{\"params\":{\"calls\":\"An array of Call3Value structs\"},\"returns\":{\"returnData\":\"An array of Result structs\"}},\"blockAndAggregate((address,bytes)[])\":{\"params\":{\"calls\":\"An array of Call structs\"},\"returns\":{\"blockHash\":\"The hash of the block where the calls were executed\",\"blockNumber\":\"The block number where the calls were executed\",\"returnData\":\"An array of Result structs\"}},\"getBlockHash(uint256)\":{\"params\":{\"blockNumber\":\"The block number\"}},\"tryAggregate(bool,(address,bytes)[])\":{\"params\":{\"calls\":\"An array of Call structs\",\"requireSuccess\":\"If true, require all calls to succeed\"},\"returns\":{\"returnData\":\"An array of Result structs\"}},\"tryBlockAndAggregate(bool,(address,bytes)[])\":{\"params\":{\"calls\":\"An array of Call structs\"},\"returns\":{\"blockHash\":\"The hash of the block where the calls were executed\",\"blockNumber\":\"The block number where the calls were executed\",\"returnData\":\"An array of Result structs\"}}},\"title\":\"Multicall3\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"aggregate((address,bytes)[])\":{\"notice\":\"Backwards-compatible call aggregation with Multicall\"},\"aggregate3((address,bool,bytes)[])\":{\"notice\":\"Aggregate calls, ensuring each returns success if required\"},\"aggregate3Value((address,bool,uint256,bytes)[])\":{\"notice\":\"Aggregate calls with a msg valueReverts if msg.value is less than the sum of the call values\"},\"blockAndAggregate((address,bytes)[])\":{\"notice\":\"Backwards-compatible with Multicall2Aggregate calls and allow failures using tryAggregate\"},\"getBasefee()\":{\"notice\":\"Gets the base fee of the given blockCan revert if the BASEFEE opcode is not implemented by the given chain\"},\"getBlockHash(uint256)\":{\"notice\":\"Returns the block hash for the given block number\"},\"getBlockNumber()\":{\"notice\":\"Returns the block number\"},\"getChainId()\":{\"notice\":\"Returns the chain id\"},\"getCurrentBlockCoinbase()\":{\"notice\":\"Returns the block coinbase\"},\"getCurrentBlockDifficulty()\":{\"notice\":\"Returns the block difficulty\"},\"getCurrentBlockGasLimit()\":{\"notice\":\"Returns the block gas limit\"},\"getCurrentBlockTimestamp()\":{\"notice\":\"Returns the block timestamp\"},\"getEthBalance(address)\":{\"notice\":\"Returns the (ETH) balance of a given address\"},\"getLastBlockHash()\":{\"notice\":\"Returns the block hash of the last block\"},\"tryAggregate(bool,(address,bytes)[])\":{\"notice\":\"Backwards-compatible with Multicall2Aggregate calls without requiring success\"},\"tryBlockAndAggregate(bool,(address,bytes)[])\":{\"notice\":\"Backwards-compatible with Multicall2Aggregate calls and allow failures using tryAggregate\"}},\"notice\":\"Aggregate results from multiple function calls\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Multicall3.sol\":\"Multicall3\"},\"evmVersion\":\"shanghai\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000000},\"remappings\":[]},\"sources\":{\"contracts/Multicall3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.23;\\n\\n/// @title Multicall3\\n/// @notice Aggregate results from multiple function calls\\n/// @dev Multicall & Multicall2 backwards-compatible\\n/// @dev Aggregate methods are marked `payable` to save 24 gas per call\\n/// @author Michael Elliot \\n/// @author Joshua Levine \\n/// @author Nick Johnson \\n/// @author Andreas Bigger \\n/// @author Matt Solomon \\ncontract Multicall3 {\\n struct Call {\\n address target;\\n bytes callData;\\n }\\n\\n struct Call3 {\\n address target;\\n bool allowFailure;\\n bytes callData;\\n }\\n\\n struct Call3Value {\\n address target;\\n bool allowFailure;\\n uint value;\\n bytes callData;\\n }\\n\\n struct Result {\\n bool success;\\n bytes returnData;\\n }\\n\\n /// @notice Backwards-compatible call aggregation with Multicall\\n /// @param calls An array of Call structs\\n /// @return blockNumber The block number where the calls were executed\\n /// @return returnData An array of bytes containing the responses\\n function aggregate(Call[] calldata calls) public payable returns (uint blockNumber, bytes[] memory returnData) {\\n blockNumber = block.number;\\n uint length = calls.length;\\n returnData = new bytes[](length);\\n Call calldata call;\\n for (uint i = 0; i < length; ) {\\n bool success;\\n call = calls[i];\\n (success, returnData[i]) = call.target.call(call.callData);\\n require(success, \\\"Multicall3: call failed\\\");\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /// @notice Backwards-compatible with Multicall2\\n /// @notice Aggregate calls without requiring success\\n /// @param requireSuccess If true, require all calls to succeed\\n /// @param calls An array of Call structs\\n /// @return returnData An array of Result structs\\n function tryAggregate(bool requireSuccess, Call[] calldata calls) public payable returns (Result[] memory returnData) {\\n uint length = calls.length;\\n returnData = new Result[](length);\\n Call calldata call;\\n for (uint i = 0; i < length; ) {\\n Result memory result = returnData[i];\\n call = calls[i];\\n (result.success, result.returnData) = call.target.call(call.callData);\\n if (requireSuccess) require(result.success, \\\"Multicall3: call failed\\\");\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /// @notice Backwards-compatible with Multicall2\\n /// @notice Aggregate calls and allow failures using tryAggregate\\n /// @param calls An array of Call structs\\n /// @return blockNumber The block number where the calls were executed\\n /// @return blockHash The hash of the block where the calls were executed\\n /// @return returnData An array of Result structs\\n function tryBlockAndAggregate(bool requireSuccess, Call[] calldata calls)\\n public\\n payable\\n returns (\\n uint blockNumber,\\n bytes32 blockHash,\\n Result[] memory returnData\\n )\\n {\\n blockNumber = block.number;\\n blockHash = blockhash(block.number);\\n returnData = tryAggregate(requireSuccess, calls);\\n }\\n\\n /// @notice Backwards-compatible with Multicall2\\n /// @notice Aggregate calls and allow failures using tryAggregate\\n /// @param calls An array of Call structs\\n /// @return blockNumber The block number where the calls were executed\\n /// @return blockHash The hash of the block where the calls were executed\\n /// @return returnData An array of Result structs\\n function blockAndAggregate(Call[] calldata calls)\\n public\\n payable\\n returns (\\n uint blockNumber,\\n bytes32 blockHash,\\n Result[] memory returnData\\n )\\n {\\n (blockNumber, blockHash, returnData) = tryBlockAndAggregate(true, calls);\\n }\\n\\n /// @notice Aggregate calls, ensuring each returns success if required\\n /// @param calls An array of Call3 structs\\n /// @return returnData An array of Result structs\\n function aggregate3(Call3[] calldata calls) public payable returns (Result[] memory returnData) {\\n uint length = calls.length;\\n returnData = new Result[](length);\\n Call3 calldata calli;\\n for (uint i = 0; i < length; ) {\\n Result memory result = returnData[i];\\n calli = calls[i];\\n (result.success, result.returnData) = calli.target.call(calli.callData);\\n assembly {\\n // Revert if the call fails and failure is not allowed\\n // `allowFailure := calldataload(add(calli, 0x20))` and `success := mload(result)`\\n if iszero(or(calldataload(add(calli, 0x20)), mload(result))) {\\n // set \\\"Error(string)\\\" signature: bytes32(bytes4(keccak256(\\\"Error(string)\\\")))\\n mstore(0x00, 0x08c379a000000000000000000000000000000000000000000000000000000000)\\n // set data offset\\n mstore(0x04, 0x0000000000000000000000000000000000000000000000000000000000000020)\\n // set length of revert string\\n mstore(0x24, 0x0000000000000000000000000000000000000000000000000000000000000017)\\n // set revert string: bytes32(abi.encodePacked(\\\"Multicall3: call failed\\\"))\\n mstore(0x44, 0x4d756c746963616c6c333a2063616c6c206661696c6564000000000000000000)\\n revert(0x00, 0x64)\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /// @notice Aggregate calls with a msg value\\n /// @notice Reverts if msg.value is less than the sum of the call values\\n /// @param calls An array of Call3Value structs\\n /// @return returnData An array of Result structs\\n function aggregate3Value(Call3Value[] calldata calls) public payable returns (Result[] memory returnData) {\\n uint valAccumulator;\\n uint length = calls.length;\\n returnData = new Result[](length);\\n Call3Value calldata calli;\\n for (uint i = 0; i < length; ) {\\n Result memory result = returnData[i];\\n calli = calls[i];\\n uint val = calli.value;\\n // Humanity will be a Type V Kardashev Civilization before this overflows - andreas\\n // ~ 10^25 Wei in existence << ~ 10^76 size uint fits in a uint256\\n unchecked {\\n valAccumulator += val;\\n }\\n (result.success, result.returnData) = calli.target.call{value: val}(calli.callData);\\n assembly {\\n // Revert if the call fails and failure is not allowed\\n // `allowFailure := calldataload(add(calli, 0x20))` and `success := mload(result)`\\n if iszero(or(calldataload(add(calli, 0x20)), mload(result))) {\\n // set \\\"Error(string)\\\" signature: bytes32(bytes4(keccak256(\\\"Error(string)\\\")))\\n mstore(0x00, 0x08c379a000000000000000000000000000000000000000000000000000000000)\\n // set data offset\\n mstore(0x04, 0x0000000000000000000000000000000000000000000000000000000000000020)\\n // set length of revert string\\n mstore(0x24, 0x0000000000000000000000000000000000000000000000000000000000000017)\\n // set revert string: bytes32(abi.encodePacked(\\\"Multicall3: call failed\\\"))\\n mstore(0x44, 0x4d756c746963616c6c333a2063616c6c206661696c6564000000000000000000)\\n revert(0x00, 0x84)\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n // Finally, make sure the msg.value = SUM(call[0...i].value)\\n require(msg.value == valAccumulator, \\\"Multicall3: value mismatch\\\");\\n }\\n\\n /// @notice Returns the block hash for the given block number\\n /// @param blockNumber The block number\\n function getBlockHash(uint blockNumber) public view returns (bytes32 blockHash) {\\n blockHash = blockhash(blockNumber);\\n }\\n\\n /// @notice Returns the block number\\n function getBlockNumber() public view returns (uint blockNumber) {\\n blockNumber = block.number;\\n }\\n\\n /// @notice Returns the block coinbase\\n function getCurrentBlockCoinbase() public view returns (address coinbase) {\\n coinbase = block.coinbase;\\n }\\n\\n /// @notice Returns the block difficulty\\n function getCurrentBlockDifficulty() public view returns (uint difficulty) {\\n difficulty = block.difficulty;\\n }\\n\\n /// @notice Returns the block gas limit\\n function getCurrentBlockGasLimit() public view returns (uint gaslimit) {\\n gaslimit = block.gaslimit;\\n }\\n\\n /// @notice Returns the block timestamp\\n function getCurrentBlockTimestamp() public view returns (uint timestamp) {\\n timestamp = block.timestamp;\\n }\\n\\n /// @notice Returns the (ETH) balance of a given address\\n function getEthBalance(address addr) public view returns (uint balance) {\\n balance = addr.balance;\\n }\\n\\n /// @notice Returns the block hash of the last block\\n function getLastBlockHash() public view returns (bytes32 blockHash) {\\n unchecked {\\n blockHash = blockhash(block.number - 1);\\n }\\n }\\n\\n /// @notice Gets the base fee of the given block\\n /// @notice Can revert if the BASEFEE opcode is not implemented by the given chain\\n function getBasefee() public view returns (uint basefee) {\\n basefee = block.basefee;\\n }\\n\\n /// @notice Returns the chain id\\n function getChainId() public view returns (uint chainid) {\\n chainid = block.chainid;\\n }\\n}\\n\",\"keccak256\":\"0x9d63b6b74d69d85a4b2ae4f0daf6477c03e892e31fc5f11308ec18d23a656499\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561000f575f80fd5b50610e838061001d5f395ff3fe6080604052600436106100ef575f3560e01c80634d2301cc11610087578063a8b0574e11610057578063a8b0574e1461024d578063bce38bd714610267578063c3077fa91461027a578063ee82ac5e1461028d575f80fd5b80634d2301cc146101e257806372425d9d1461021657806382ad56cb1461022857806386d516e81461023b575f80fd5b80633408e470116100c25780633408e4701461018a578063399542e91461019c5780633e64a696146101be57806342cbb15c146101d0575f80fd5b80630f28c97d146100f3578063174dea7114610114578063252dba421461013457806327e86d6e14610155575b5f80fd5b3480156100fe575f80fd5b50425b6040519081526020015b60405180910390f35b610127610122366004610a52565b6102ab565b60405161010b9190610b7c565b610147610142366004610a52565b6104d7565b60405161010b929190610b95565b348015610160575f80fd5b50437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0140610101565b348015610195575f80fd5b5046610101565b6101af6101aa366004610c1d565b610672565b60405161010b93929190610c72565b3480156101c9575f80fd5b5048610101565b3480156101db575f80fd5b5043610101565b3480156101ed575f80fd5b506101016101fc366004610c99565b73ffffffffffffffffffffffffffffffffffffffff163190565b348015610221575f80fd5b5044610101565b610127610236366004610a52565b61068d565b348015610246575f80fd5b5045610101565b348015610258575f80fd5b5060405141815260200161010b565b610127610275366004610c1d565b610833565b6101af610288366004610a52565b6109ec565b348015610298575f80fd5b506101016102a7366004610ccc565b4090565b60605f828067ffffffffffffffff8111156102c8576102c8610ce3565b60405190808252806020026020018201604052801561030d57816020015b604080518082019091525f8152606060208201528152602001906001900390816102e65790505b509250365f5b8281101561045f575f85828151811061032e5761032e610d10565b6020026020010151905087878381811061034a5761034a610d10565b905060200281019061035c9190610d3d565b6040810135958601959093506103756020850185610c99565b73ffffffffffffffffffffffffffffffffffffffff16816103996060870187610d79565b6040516103a7929190610dda565b5f6040518083038185875af1925050503d805f81146103e1576040519150601f19603f3d011682016040523d82523d5f602084013e6103e6565b606091505b506020808501919091529015158084529085013517610455577f08c379a0000000000000000000000000000000000000000000000000000000005f52602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260845ffd5b5050600101610313565b508234146104ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d756c746963616c6c333a2076616c7565206d69736d6174636800000000000060448201526064015b60405180910390fd5b50505092915050565b436060828067ffffffffffffffff8111156104f4576104f4610ce3565b60405190808252806020026020018201604052801561052757816020015b60608152602001906001900390816105125790505b509150365f5b82811015610668575f87878381811061054857610548610d10565b905060200281019061055a9190610de9565b92506105696020840184610c99565b73ffffffffffffffffffffffffffffffffffffffff1661058c6020850185610d79565b60405161059a929190610dda565b5f604051808303815f865af19150503d805f81146105d3576040519150601f19603f3d011682016040523d82523d5f602084013e6105d8565b606091505b508684815181106105eb576105eb610d10565b602090810291909101015290508061065f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104c5565b5060010161052d565b5050509250929050565b4380406060610682868686610833565b905093509350939050565b6060818067ffffffffffffffff8111156106a9576106a9610ce3565b6040519080825280602002602001820160405280156106ee57816020015b604080518082019091525f8152606060208201528152602001906001900390816106c75790505b509150365f5b828110156104ce575f84828151811061070f5761070f610d10565b6020026020010151905086868381811061072b5761072b610d10565b905060200281019061073d9190610e1b565b925061074c6020840184610c99565b73ffffffffffffffffffffffffffffffffffffffff1661076f6040850185610d79565b60405161077d929190610dda565b5f604051808303815f865af19150503d805f81146107b6576040519150601f19603f3d011682016040523d82523d5f602084013e6107bb565b606091505b50602080840191909152901515808352908401351761082a577f08c379a0000000000000000000000000000000000000000000000000000000005f52602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260645ffd5b506001016106f4565b6060818067ffffffffffffffff81111561084f5761084f610ce3565b60405190808252806020026020018201604052801561089457816020015b604080518082019091525f81526060602082015281526020019060019003908161086d5790505b509150365f5b828110156109e2575f8482815181106108b5576108b5610d10565b602002602001015190508686838181106108d1576108d1610d10565b90506020028101906108e39190610de9565b92506108f26020840184610c99565b73ffffffffffffffffffffffffffffffffffffffff166109156020850185610d79565b604051610923929190610dda565b5f604051808303815f865af19150503d805f811461095c576040519150601f19603f3d011682016040523d82523d5f602084013e610961565b606091505b5060208301521515815287156109d95780516109d9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104c5565b5060010161089a565b5050509392505050565b5f8060606109fc60018686610672565b919790965090945092505050565b5f8083601f840112610a1a575f80fd5b50813567ffffffffffffffff811115610a31575f80fd5b6020830191508360208260051b8501011115610a4b575f80fd5b9250929050565b5f8060208385031215610a63575f80fd5b823567ffffffffffffffff811115610a79575f80fd5b610a8585828601610a0a565b90969095509350505050565b5f81518084525f5b81811015610ab557602081850181015186830182015201610a99565b505f6020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b5f82825180855260208086019550808260051b8401018186015f5b84811015610b6f578583037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001895281518051151584528401516040858501819052610b5b81860183610a91565b9a86019a9450505090830190600101610b0d565b5090979650505050505050565b602081525f610b8e6020830184610af2565b9392505050565b5f6040820184835260206040602085015281855180845260608601915060608160051b8701019350602087015f5b82811015610c0f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0888703018452610bfd868351610a91565b95509284019290840190600101610bc3565b509398975050505050505050565b5f805f60408486031215610c2f575f80fd5b83358015158114610c3e575f80fd5b9250602084013567ffffffffffffffff811115610c59575f80fd5b610c6586828701610a0a565b9497909650939450505050565b838152826020820152606060408201525f610c906060830184610af2565b95945050505050565b5f60208284031215610ca9575f80fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610b8e575f80fd5b5f60208284031215610cdc575f80fd5b5035919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f82357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112610d6f575f80fd5b9190910192915050565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610dac575f80fd5b83018035915067ffffffffffffffff821115610dc6575f80fd5b602001915036819003821315610a4b575f80fd5b818382375f9101908152919050565b5f82357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc1833603018112610d6f575f80fd5b5f82357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1833603018112610d6f575f80fdfea26469706673582212200eaf0cd91de789e77508c60e0547293a26ede4f0c9830fcc4f3d1f30fab2457064736f6c63430008170033", + "deployedBytecode": "0x6080604052600436106100ef575f3560e01c80634d2301cc11610087578063a8b0574e11610057578063a8b0574e1461024d578063bce38bd714610267578063c3077fa91461027a578063ee82ac5e1461028d575f80fd5b80634d2301cc146101e257806372425d9d1461021657806382ad56cb1461022857806386d516e81461023b575f80fd5b80633408e470116100c25780633408e4701461018a578063399542e91461019c5780633e64a696146101be57806342cbb15c146101d0575f80fd5b80630f28c97d146100f3578063174dea7114610114578063252dba421461013457806327e86d6e14610155575b5f80fd5b3480156100fe575f80fd5b50425b6040519081526020015b60405180910390f35b610127610122366004610a52565b6102ab565b60405161010b9190610b7c565b610147610142366004610a52565b6104d7565b60405161010b929190610b95565b348015610160575f80fd5b50437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0140610101565b348015610195575f80fd5b5046610101565b6101af6101aa366004610c1d565b610672565b60405161010b93929190610c72565b3480156101c9575f80fd5b5048610101565b3480156101db575f80fd5b5043610101565b3480156101ed575f80fd5b506101016101fc366004610c99565b73ffffffffffffffffffffffffffffffffffffffff163190565b348015610221575f80fd5b5044610101565b610127610236366004610a52565b61068d565b348015610246575f80fd5b5045610101565b348015610258575f80fd5b5060405141815260200161010b565b610127610275366004610c1d565b610833565b6101af610288366004610a52565b6109ec565b348015610298575f80fd5b506101016102a7366004610ccc565b4090565b60605f828067ffffffffffffffff8111156102c8576102c8610ce3565b60405190808252806020026020018201604052801561030d57816020015b604080518082019091525f8152606060208201528152602001906001900390816102e65790505b509250365f5b8281101561045f575f85828151811061032e5761032e610d10565b6020026020010151905087878381811061034a5761034a610d10565b905060200281019061035c9190610d3d565b6040810135958601959093506103756020850185610c99565b73ffffffffffffffffffffffffffffffffffffffff16816103996060870187610d79565b6040516103a7929190610dda565b5f6040518083038185875af1925050503d805f81146103e1576040519150601f19603f3d011682016040523d82523d5f602084013e6103e6565b606091505b506020808501919091529015158084529085013517610455577f08c379a0000000000000000000000000000000000000000000000000000000005f52602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260845ffd5b5050600101610313565b508234146104ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d756c746963616c6c333a2076616c7565206d69736d6174636800000000000060448201526064015b60405180910390fd5b50505092915050565b436060828067ffffffffffffffff8111156104f4576104f4610ce3565b60405190808252806020026020018201604052801561052757816020015b60608152602001906001900390816105125790505b509150365f5b82811015610668575f87878381811061054857610548610d10565b905060200281019061055a9190610de9565b92506105696020840184610c99565b73ffffffffffffffffffffffffffffffffffffffff1661058c6020850185610d79565b60405161059a929190610dda565b5f604051808303815f865af19150503d805f81146105d3576040519150601f19603f3d011682016040523d82523d5f602084013e6105d8565b606091505b508684815181106105eb576105eb610d10565b602090810291909101015290508061065f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104c5565b5060010161052d565b5050509250929050565b4380406060610682868686610833565b905093509350939050565b6060818067ffffffffffffffff8111156106a9576106a9610ce3565b6040519080825280602002602001820160405280156106ee57816020015b604080518082019091525f8152606060208201528152602001906001900390816106c75790505b509150365f5b828110156104ce575f84828151811061070f5761070f610d10565b6020026020010151905086868381811061072b5761072b610d10565b905060200281019061073d9190610e1b565b925061074c6020840184610c99565b73ffffffffffffffffffffffffffffffffffffffff1661076f6040850185610d79565b60405161077d929190610dda565b5f604051808303815f865af19150503d805f81146107b6576040519150601f19603f3d011682016040523d82523d5f602084013e6107bb565b606091505b50602080840191909152901515808352908401351761082a577f08c379a0000000000000000000000000000000000000000000000000000000005f52602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260645ffd5b506001016106f4565b6060818067ffffffffffffffff81111561084f5761084f610ce3565b60405190808252806020026020018201604052801561089457816020015b604080518082019091525f81526060602082015281526020019060019003908161086d5790505b509150365f5b828110156109e2575f8482815181106108b5576108b5610d10565b602002602001015190508686838181106108d1576108d1610d10565b90506020028101906108e39190610de9565b92506108f26020840184610c99565b73ffffffffffffffffffffffffffffffffffffffff166109156020850185610d79565b604051610923929190610dda565b5f604051808303815f865af19150503d805f811461095c576040519150601f19603f3d011682016040523d82523d5f602084013e610961565b606091505b5060208301521515815287156109d95780516109d9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104c5565b5060010161089a565b5050509392505050565b5f8060606109fc60018686610672565b919790965090945092505050565b5f8083601f840112610a1a575f80fd5b50813567ffffffffffffffff811115610a31575f80fd5b6020830191508360208260051b8501011115610a4b575f80fd5b9250929050565b5f8060208385031215610a63575f80fd5b823567ffffffffffffffff811115610a79575f80fd5b610a8585828601610a0a565b90969095509350505050565b5f81518084525f5b81811015610ab557602081850181015186830182015201610a99565b505f6020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b5f82825180855260208086019550808260051b8401018186015f5b84811015610b6f578583037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001895281518051151584528401516040858501819052610b5b81860183610a91565b9a86019a9450505090830190600101610b0d565b5090979650505050505050565b602081525f610b8e6020830184610af2565b9392505050565b5f6040820184835260206040602085015281855180845260608601915060608160051b8701019350602087015f5b82811015610c0f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0888703018452610bfd868351610a91565b95509284019290840190600101610bc3565b509398975050505050505050565b5f805f60408486031215610c2f575f80fd5b83358015158114610c3e575f80fd5b9250602084013567ffffffffffffffff811115610c59575f80fd5b610c6586828701610a0a565b9497909650939450505050565b838152826020820152606060408201525f610c906060830184610af2565b95945050505050565b5f60208284031215610ca9575f80fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610b8e575f80fd5b5f60208284031215610cdc575f80fd5b5035919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f82357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112610d6f575f80fd5b9190910192915050565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610dac575f80fd5b83018035915067ffffffffffffffff821115610dc6575f80fd5b602001915036819003821315610a4b575f80fd5b818382375f9101908152919050565b5f82357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc1833603018112610d6f575f80fd5b5f82357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1833603018112610d6f575f80fdfea26469706673582212200eaf0cd91de789e77508c60e0547293a26ede4f0c9830fcc4f3d1f30fab2457064736f6c63430008170033", + "devdoc": { + "author": "Michael Elliot Joshua Levine Nick Johnson Andreas Bigger Matt Solomon ", + "details": "Multicall & Multicall2 backwards-compatibleAggregate methods are marked `payable` to save 24 gas per call", + "kind": "dev", + "methods": { + "aggregate((address,bytes)[])": { + "params": { + "calls": "An array of Call structs" + }, + "returns": { + "blockNumber": "The block number where the calls were executed", + "returnData": "An array of bytes containing the responses" + } + }, + "aggregate3((address,bool,bytes)[])": { + "params": { + "calls": "An array of Call3 structs" + }, + "returns": { + "returnData": "An array of Result structs" + } + }, + "aggregate3Value((address,bool,uint256,bytes)[])": { + "params": { + "calls": "An array of Call3Value structs" + }, + "returns": { + "returnData": "An array of Result structs" + } + }, + "blockAndAggregate((address,bytes)[])": { + "params": { + "calls": "An array of Call structs" + }, + "returns": { + "blockHash": "The hash of the block where the calls were executed", + "blockNumber": "The block number where the calls were executed", + "returnData": "An array of Result structs" + } + }, + "getBlockHash(uint256)": { + "params": { + "blockNumber": "The block number" + } + }, + "tryAggregate(bool,(address,bytes)[])": { + "params": { + "calls": "An array of Call structs", + "requireSuccess": "If true, require all calls to succeed" + }, + "returns": { + "returnData": "An array of Result structs" + } + }, + "tryBlockAndAggregate(bool,(address,bytes)[])": { + "params": { + "calls": "An array of Call structs" + }, + "returns": { + "blockHash": "The hash of the block where the calls were executed", + "blockNumber": "The block number where the calls were executed", + "returnData": "An array of Result structs" + } + } + }, + "title": "Multicall3", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "aggregate((address,bytes)[])": { + "notice": "Backwards-compatible call aggregation with Multicall" + }, + "aggregate3((address,bool,bytes)[])": { + "notice": "Aggregate calls, ensuring each returns success if required" + }, + "aggregate3Value((address,bool,uint256,bytes)[])": { + "notice": "Aggregate calls with a msg valueReverts if msg.value is less than the sum of the call values" + }, + "blockAndAggregate((address,bytes)[])": { + "notice": "Backwards-compatible with Multicall2Aggregate calls and allow failures using tryAggregate" + }, + "getBasefee()": { + "notice": "Gets the base fee of the given blockCan revert if the BASEFEE opcode is not implemented by the given chain" + }, + "getBlockHash(uint256)": { + "notice": "Returns the block hash for the given block number" + }, + "getBlockNumber()": { + "notice": "Returns the block number" + }, + "getChainId()": { + "notice": "Returns the chain id" + }, + "getCurrentBlockCoinbase()": { + "notice": "Returns the block coinbase" + }, + "getCurrentBlockDifficulty()": { + "notice": "Returns the block difficulty" + }, + "getCurrentBlockGasLimit()": { + "notice": "Returns the block gas limit" + }, + "getCurrentBlockTimestamp()": { + "notice": "Returns the block timestamp" + }, + "getEthBalance(address)": { + "notice": "Returns the (ETH) balance of a given address" + }, + "getLastBlockHash()": { + "notice": "Returns the block hash of the last block" + }, + "tryAggregate(bool,(address,bytes)[])": { + "notice": "Backwards-compatible with Multicall2Aggregate calls without requiring success" + }, + "tryBlockAndAggregate(bool,(address,bytes)[])": { + "notice": "Backwards-compatible with Multicall2Aggregate calls and allow failures using tryAggregate" + } + }, + "notice": "Aggregate results from multiple function calls", + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/imtbl-zkevm-testnet/solcInputs/2c4045da9263c8058401050467beca99.json b/deployments/imtbl-zkevm-testnet/solcInputs/2c4045da9263c8058401050467beca99.json new file mode 100644 index 00000000..c20f3ceb --- /dev/null +++ b/deployments/imtbl-zkevm-testnet/solcInputs/2c4045da9263c8058401050467beca99.json @@ -0,0 +1,35 @@ +{ + "language": "Solidity", + "sources": { + "contracts/Multicall3.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.23;\n\n/// @title Multicall3\n/// @notice Aggregate results from multiple function calls\n/// @dev Multicall & Multicall2 backwards-compatible\n/// @dev Aggregate methods are marked `payable` to save 24 gas per call\n/// @author Michael Elliot \n/// @author Joshua Levine \n/// @author Nick Johnson \n/// @author Andreas Bigger \n/// @author Matt Solomon \ncontract Multicall3 {\n struct Call {\n address target;\n bytes callData;\n }\n\n struct Call3 {\n address target;\n bool allowFailure;\n bytes callData;\n }\n\n struct Call3Value {\n address target;\n bool allowFailure;\n uint value;\n bytes callData;\n }\n\n struct Result {\n bool success;\n bytes returnData;\n }\n\n /// @notice Backwards-compatible call aggregation with Multicall\n /// @param calls An array of Call structs\n /// @return blockNumber The block number where the calls were executed\n /// @return returnData An array of bytes containing the responses\n function aggregate(Call[] calldata calls) public payable returns (uint blockNumber, bytes[] memory returnData) {\n blockNumber = block.number;\n uint length = calls.length;\n returnData = new bytes[](length);\n Call calldata call;\n for (uint i = 0; i < length; ) {\n bool success;\n call = calls[i];\n (success, returnData[i]) = call.target.call(call.callData);\n require(success, \"Multicall3: call failed\");\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Backwards-compatible with Multicall2\n /// @notice Aggregate calls without requiring success\n /// @param requireSuccess If true, require all calls to succeed\n /// @param calls An array of Call structs\n /// @return returnData An array of Result structs\n function tryAggregate(bool requireSuccess, Call[] calldata calls) public payable returns (Result[] memory returnData) {\n uint length = calls.length;\n returnData = new Result[](length);\n Call calldata call;\n for (uint i = 0; i < length; ) {\n Result memory result = returnData[i];\n call = calls[i];\n (result.success, result.returnData) = call.target.call(call.callData);\n if (requireSuccess) require(result.success, \"Multicall3: call failed\");\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Backwards-compatible with Multicall2\n /// @notice Aggregate calls and allow failures using tryAggregate\n /// @param calls An array of Call structs\n /// @return blockNumber The block number where the calls were executed\n /// @return blockHash The hash of the block where the calls were executed\n /// @return returnData An array of Result structs\n function tryBlockAndAggregate(bool requireSuccess, Call[] calldata calls)\n public\n payable\n returns (\n uint blockNumber,\n bytes32 blockHash,\n Result[] memory returnData\n )\n {\n blockNumber = block.number;\n blockHash = blockhash(block.number);\n returnData = tryAggregate(requireSuccess, calls);\n }\n\n /// @notice Backwards-compatible with Multicall2\n /// @notice Aggregate calls and allow failures using tryAggregate\n /// @param calls An array of Call structs\n /// @return blockNumber The block number where the calls were executed\n /// @return blockHash The hash of the block where the calls were executed\n /// @return returnData An array of Result structs\n function blockAndAggregate(Call[] calldata calls)\n public\n payable\n returns (\n uint blockNumber,\n bytes32 blockHash,\n Result[] memory returnData\n )\n {\n (blockNumber, blockHash, returnData) = tryBlockAndAggregate(true, calls);\n }\n\n /// @notice Aggregate calls, ensuring each returns success if required\n /// @param calls An array of Call3 structs\n /// @return returnData An array of Result structs\n function aggregate3(Call3[] calldata calls) public payable returns (Result[] memory returnData) {\n uint length = calls.length;\n returnData = new Result[](length);\n Call3 calldata calli;\n for (uint i = 0; i < length; ) {\n Result memory result = returnData[i];\n calli = calls[i];\n (result.success, result.returnData) = calli.target.call(calli.callData);\n assembly {\n // Revert if the call fails and failure is not allowed\n // `allowFailure := calldataload(add(calli, 0x20))` and `success := mload(result)`\n if iszero(or(calldataload(add(calli, 0x20)), mload(result))) {\n // set \"Error(string)\" signature: bytes32(bytes4(keccak256(\"Error(string)\")))\n mstore(0x00, 0x08c379a000000000000000000000000000000000000000000000000000000000)\n // set data offset\n mstore(0x04, 0x0000000000000000000000000000000000000000000000000000000000000020)\n // set length of revert string\n mstore(0x24, 0x0000000000000000000000000000000000000000000000000000000000000017)\n // set revert string: bytes32(abi.encodePacked(\"Multicall3: call failed\"))\n mstore(0x44, 0x4d756c746963616c6c333a2063616c6c206661696c6564000000000000000000)\n revert(0x00, 0x64)\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Aggregate calls with a msg value\n /// @notice Reverts if msg.value is less than the sum of the call values\n /// @param calls An array of Call3Value structs\n /// @return returnData An array of Result structs\n function aggregate3Value(Call3Value[] calldata calls) public payable returns (Result[] memory returnData) {\n uint valAccumulator;\n uint length = calls.length;\n returnData = new Result[](length);\n Call3Value calldata calli;\n for (uint i = 0; i < length; ) {\n Result memory result = returnData[i];\n calli = calls[i];\n uint val = calli.value;\n // Humanity will be a Type V Kardashev Civilization before this overflows - andreas\n // ~ 10^25 Wei in existence << ~ 10^76 size uint fits in a uint256\n unchecked {\n valAccumulator += val;\n }\n (result.success, result.returnData) = calli.target.call{value: val}(calli.callData);\n assembly {\n // Revert if the call fails and failure is not allowed\n // `allowFailure := calldataload(add(calli, 0x20))` and `success := mload(result)`\n if iszero(or(calldataload(add(calli, 0x20)), mload(result))) {\n // set \"Error(string)\" signature: bytes32(bytes4(keccak256(\"Error(string)\")))\n mstore(0x00, 0x08c379a000000000000000000000000000000000000000000000000000000000)\n // set data offset\n mstore(0x04, 0x0000000000000000000000000000000000000000000000000000000000000020)\n // set length of revert string\n mstore(0x24, 0x0000000000000000000000000000000000000000000000000000000000000017)\n // set revert string: bytes32(abi.encodePacked(\"Multicall3: call failed\"))\n mstore(0x44, 0x4d756c746963616c6c333a2063616c6c206661696c6564000000000000000000)\n revert(0x00, 0x84)\n }\n }\n unchecked {\n ++i;\n }\n }\n // Finally, make sure the msg.value = SUM(call[0...i].value)\n require(msg.value == valAccumulator, \"Multicall3: value mismatch\");\n }\n\n /// @notice Returns the block hash for the given block number\n /// @param blockNumber The block number\n function getBlockHash(uint blockNumber) public view returns (bytes32 blockHash) {\n blockHash = blockhash(blockNumber);\n }\n\n /// @notice Returns the block number\n function getBlockNumber() public view returns (uint blockNumber) {\n blockNumber = block.number;\n }\n\n /// @notice Returns the block coinbase\n function getCurrentBlockCoinbase() public view returns (address coinbase) {\n coinbase = block.coinbase;\n }\n\n /// @notice Returns the block difficulty\n function getCurrentBlockDifficulty() public view returns (uint difficulty) {\n difficulty = block.difficulty;\n }\n\n /// @notice Returns the block gas limit\n function getCurrentBlockGasLimit() public view returns (uint gaslimit) {\n gaslimit = block.gaslimit;\n }\n\n /// @notice Returns the block timestamp\n function getCurrentBlockTimestamp() public view returns (uint timestamp) {\n timestamp = block.timestamp;\n }\n\n /// @notice Returns the (ETH) balance of a given address\n function getEthBalance(address addr) public view returns (uint balance) {\n balance = addr.balance;\n }\n\n /// @notice Returns the block hash of the last block\n function getLastBlockHash() public view returns (bytes32 blockHash) {\n unchecked {\n blockHash = blockhash(block.number - 1);\n }\n }\n\n /// @notice Gets the base fee of the given block\n /// @notice Can revert if the BASEFEE opcode is not implemented by the given chain\n function getBasefee() public view returns (uint basefee) {\n basefee = block.basefee;\n }\n\n /// @notice Returns the chain id\n function getChainId() public view returns (uint chainid) {\n chainid = block.chainid;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 10000000 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "storageLayout", + "devdoc", + "userdoc", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/imtbl-zkevm/.chainId b/deployments/imtbl-zkevm/.chainId new file mode 100644 index 00000000..284a734f --- /dev/null +++ b/deployments/imtbl-zkevm/.chainId @@ -0,0 +1 @@ +13371 \ No newline at end of file diff --git a/deployments/imtbl-zkevm/Multicall3.json b/deployments/imtbl-zkevm/Multicall3.json new file mode 100644 index 00000000..2ea6a298 --- /dev/null +++ b/deployments/imtbl-zkevm/Multicall3.json @@ -0,0 +1,592 @@ +{ + "address": "0x236bdA4589e44e6850f5aC6a74BfCa398a86c6c0", + "abi": [ + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + } + ], + "internalType": "struct Multicall3.Call[]", + "name": "calls", + "type": "tuple[]" + } + ], + "name": "aggregate", + "outputs": [ + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + }, + { + "internalType": "bytes[]", + "name": "returnData", + "type": "bytes[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bool", + "name": "allowFailure", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + } + ], + "internalType": "struct Multicall3.Call3[]", + "name": "calls", + "type": "tuple[]" + } + ], + "name": "aggregate3", + "outputs": [ + { + "components": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "returnData", + "type": "bytes" + } + ], + "internalType": "struct Multicall3.Result[]", + "name": "returnData", + "type": "tuple[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bool", + "name": "allowFailure", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + } + ], + "internalType": "struct Multicall3.Call3Value[]", + "name": "calls", + "type": "tuple[]" + } + ], + "name": "aggregate3Value", + "outputs": [ + { + "components": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "returnData", + "type": "bytes" + } + ], + "internalType": "struct Multicall3.Result[]", + "name": "returnData", + "type": "tuple[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + } + ], + "internalType": "struct Multicall3.Call[]", + "name": "calls", + "type": "tuple[]" + } + ], + "name": "blockAndAggregate", + "outputs": [ + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "blockHash", + "type": "bytes32" + }, + { + "components": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "returnData", + "type": "bytes" + } + ], + "internalType": "struct Multicall3.Result[]", + "name": "returnData", + "type": "tuple[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "getBasefee", + "outputs": [ + { + "internalType": "uint256", + "name": "basefee", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + } + ], + "name": "getBlockHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "blockHash", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBlockNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getChainId", + "outputs": [ + { + "internalType": "uint256", + "name": "chainid", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCurrentBlockCoinbase", + "outputs": [ + { + "internalType": "address", + "name": "coinbase", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCurrentBlockDifficulty", + "outputs": [ + { + "internalType": "uint256", + "name": "difficulty", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCurrentBlockGasLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "gaslimit", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCurrentBlockTimestamp", + "outputs": [ + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "getEthBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getLastBlockHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "blockHash", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "requireSuccess", + "type": "bool" + }, + { + "components": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + } + ], + "internalType": "struct Multicall3.Call[]", + "name": "calls", + "type": "tuple[]" + } + ], + "name": "tryAggregate", + "outputs": [ + { + "components": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "returnData", + "type": "bytes" + } + ], + "internalType": "struct Multicall3.Result[]", + "name": "returnData", + "type": "tuple[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "requireSuccess", + "type": "bool" + }, + { + "components": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + } + ], + "internalType": "struct Multicall3.Call[]", + "name": "calls", + "type": "tuple[]" + } + ], + "name": "tryBlockAndAggregate", + "outputs": [ + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "blockHash", + "type": "bytes32" + }, + { + "components": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "returnData", + "type": "bytes" + } + ], + "internalType": "struct Multicall3.Result[]", + "name": "returnData", + "type": "tuple[]" + } + ], + "stateMutability": "payable", + "type": "function" + } + ], + "transactionHash": "0x29ad8d5406bc6b775a988c6fae9f26d1995d773cf041c85ca3ed61542e595d7a", + "receipt": { + "to": null, + "from": "0xbFb53a2c470cdb4FF32eE4F18A93B98F9f55D0E1", + "contractAddress": "0x236bdA4589e44e6850f5aC6a74BfCa398a86c6c0", + "transactionIndex": 0, + "gasUsed": "871696", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x374cc5de38b670ed330ada6df16524f30515ebe052d0617e382af5a02c432761", + "transactionHash": "0x29ad8d5406bc6b775a988c6fae9f26d1995d773cf041c85ca3ed61542e595d7a", + "logs": [], + "blockNumber": 4335972, + "cumulativeGasUsed": "871696", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "b36a7d608ba9b8cba9935e17cb428950", + "metadata": "{\"compiler\":{\"version\":\"0.8.23+commit.f704f362\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Call[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"aggregate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"returnData\",\"type\":\"bytes[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowFailure\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Call3[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"aggregate3\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowFailure\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Call3Value[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"aggregate3Value\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Call[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"blockAndAggregate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBasefee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"basefee\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"}],\"name\":\"getBlockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getChainId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainid\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockCoinbase\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"coinbase\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockDifficulty\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"difficulty\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockGasLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"gaslimit\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockTimestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"getEthBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLastBlockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"requireSuccess\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Call[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"tryAggregate\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"requireSuccess\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Call[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"tryBlockAndAggregate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Michael Elliot Joshua Levine Nick Johnson Andreas Bigger Matt Solomon \",\"details\":\"Multicall & Multicall2 backwards-compatibleAggregate methods are marked `payable` to save 24 gas per call\",\"kind\":\"dev\",\"methods\":{\"aggregate((address,bytes)[])\":{\"params\":{\"calls\":\"An array of Call structs\"},\"returns\":{\"blockNumber\":\"The block number where the calls were executed\",\"returnData\":\"An array of bytes containing the responses\"}},\"aggregate3((address,bool,bytes)[])\":{\"params\":{\"calls\":\"An array of Call3 structs\"},\"returns\":{\"returnData\":\"An array of Result structs\"}},\"aggregate3Value((address,bool,uint256,bytes)[])\":{\"params\":{\"calls\":\"An array of Call3Value structs\"},\"returns\":{\"returnData\":\"An array of Result structs\"}},\"blockAndAggregate((address,bytes)[])\":{\"params\":{\"calls\":\"An array of Call structs\"},\"returns\":{\"blockHash\":\"The hash of the block where the calls were executed\",\"blockNumber\":\"The block number where the calls were executed\",\"returnData\":\"An array of Result structs\"}},\"getBlockHash(uint256)\":{\"params\":{\"blockNumber\":\"The block number\"}},\"tryAggregate(bool,(address,bytes)[])\":{\"params\":{\"calls\":\"An array of Call structs\",\"requireSuccess\":\"If true, require all calls to succeed\"},\"returns\":{\"returnData\":\"An array of Result structs\"}},\"tryBlockAndAggregate(bool,(address,bytes)[])\":{\"params\":{\"calls\":\"An array of Call structs\"},\"returns\":{\"blockHash\":\"The hash of the block where the calls were executed\",\"blockNumber\":\"The block number where the calls were executed\",\"returnData\":\"An array of Result structs\"}}},\"title\":\"Multicall3\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"aggregate((address,bytes)[])\":{\"notice\":\"Backwards-compatible call aggregation with Multicall\"},\"aggregate3((address,bool,bytes)[])\":{\"notice\":\"Aggregate calls, ensuring each returns success if required\"},\"aggregate3Value((address,bool,uint256,bytes)[])\":{\"notice\":\"Aggregate calls with a msg valueReverts if msg.value is less than the sum of the call values\"},\"blockAndAggregate((address,bytes)[])\":{\"notice\":\"Backwards-compatible with Multicall2Aggregate calls and allow failures using tryAggregate\"},\"getBasefee()\":{\"notice\":\"Gets the base fee of the given blockCan revert if the BASEFEE opcode is not implemented by the given chain\"},\"getBlockHash(uint256)\":{\"notice\":\"Returns the block hash for the given block number\"},\"getBlockNumber()\":{\"notice\":\"Returns the block number\"},\"getChainId()\":{\"notice\":\"Returns the chain id\"},\"getCurrentBlockCoinbase()\":{\"notice\":\"Returns the block coinbase\"},\"getCurrentBlockDifficulty()\":{\"notice\":\"Returns the block difficulty\"},\"getCurrentBlockGasLimit()\":{\"notice\":\"Returns the block gas limit\"},\"getCurrentBlockTimestamp()\":{\"notice\":\"Returns the block timestamp\"},\"getEthBalance(address)\":{\"notice\":\"Returns the (ETH) balance of a given address\"},\"getLastBlockHash()\":{\"notice\":\"Returns the block hash of the last block\"},\"tryAggregate(bool,(address,bytes)[])\":{\"notice\":\"Backwards-compatible with Multicall2Aggregate calls without requiring success\"},\"tryBlockAndAggregate(bool,(address,bytes)[])\":{\"notice\":\"Backwards-compatible with Multicall2Aggregate calls and allow failures using tryAggregate\"}},\"notice\":\"Aggregate results from multiple function calls\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Multicall3.sol\":\"Multicall3\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000000},\"remappings\":[]},\"sources\":{\"contracts/Multicall3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.23;\\n\\n/// @title Multicall3\\n/// @notice Aggregate results from multiple function calls\\n/// @dev Multicall & Multicall2 backwards-compatible\\n/// @dev Aggregate methods are marked `payable` to save 24 gas per call\\n/// @author Michael Elliot \\n/// @author Joshua Levine \\n/// @author Nick Johnson \\n/// @author Andreas Bigger \\n/// @author Matt Solomon \\ncontract Multicall3 {\\n struct Call {\\n address target;\\n bytes callData;\\n }\\n\\n struct Call3 {\\n address target;\\n bool allowFailure;\\n bytes callData;\\n }\\n\\n struct Call3Value {\\n address target;\\n bool allowFailure;\\n uint value;\\n bytes callData;\\n }\\n\\n struct Result {\\n bool success;\\n bytes returnData;\\n }\\n\\n /// @notice Backwards-compatible call aggregation with Multicall\\n /// @param calls An array of Call structs\\n /// @return blockNumber The block number where the calls were executed\\n /// @return returnData An array of bytes containing the responses\\n function aggregate(Call[] calldata calls) public payable returns (uint blockNumber, bytes[] memory returnData) {\\n blockNumber = block.number;\\n uint length = calls.length;\\n returnData = new bytes[](length);\\n Call calldata call;\\n for (uint i = 0; i < length; ) {\\n bool success;\\n call = calls[i];\\n (success, returnData[i]) = call.target.call(call.callData);\\n require(success, \\\"Multicall3: call failed\\\");\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /// @notice Backwards-compatible with Multicall2\\n /// @notice Aggregate calls without requiring success\\n /// @param requireSuccess If true, require all calls to succeed\\n /// @param calls An array of Call structs\\n /// @return returnData An array of Result structs\\n function tryAggregate(bool requireSuccess, Call[] calldata calls) public payable returns (Result[] memory returnData) {\\n uint length = calls.length;\\n returnData = new Result[](length);\\n Call calldata call;\\n for (uint i = 0; i < length; ) {\\n Result memory result = returnData[i];\\n call = calls[i];\\n (result.success, result.returnData) = call.target.call(call.callData);\\n if (requireSuccess) require(result.success, \\\"Multicall3: call failed\\\");\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /// @notice Backwards-compatible with Multicall2\\n /// @notice Aggregate calls and allow failures using tryAggregate\\n /// @param calls An array of Call structs\\n /// @return blockNumber The block number where the calls were executed\\n /// @return blockHash The hash of the block where the calls were executed\\n /// @return returnData An array of Result structs\\n function tryBlockAndAggregate(bool requireSuccess, Call[] calldata calls)\\n public\\n payable\\n returns (\\n uint blockNumber,\\n bytes32 blockHash,\\n Result[] memory returnData\\n )\\n {\\n blockNumber = block.number;\\n blockHash = blockhash(block.number);\\n returnData = tryAggregate(requireSuccess, calls);\\n }\\n\\n /// @notice Backwards-compatible with Multicall2\\n /// @notice Aggregate calls and allow failures using tryAggregate\\n /// @param calls An array of Call structs\\n /// @return blockNumber The block number where the calls were executed\\n /// @return blockHash The hash of the block where the calls were executed\\n /// @return returnData An array of Result structs\\n function blockAndAggregate(Call[] calldata calls)\\n public\\n payable\\n returns (\\n uint blockNumber,\\n bytes32 blockHash,\\n Result[] memory returnData\\n )\\n {\\n (blockNumber, blockHash, returnData) = tryBlockAndAggregate(true, calls);\\n }\\n\\n /// @notice Aggregate calls, ensuring each returns success if required\\n /// @param calls An array of Call3 structs\\n /// @return returnData An array of Result structs\\n function aggregate3(Call3[] calldata calls) public payable returns (Result[] memory returnData) {\\n uint length = calls.length;\\n returnData = new Result[](length);\\n Call3 calldata calli;\\n for (uint i = 0; i < length; ) {\\n Result memory result = returnData[i];\\n calli = calls[i];\\n (result.success, result.returnData) = calli.target.call(calli.callData);\\n assembly {\\n // Revert if the call fails and failure is not allowed\\n // `allowFailure := calldataload(add(calli, 0x20))` and `success := mload(result)`\\n if iszero(or(calldataload(add(calli, 0x20)), mload(result))) {\\n // set \\\"Error(string)\\\" signature: bytes32(bytes4(keccak256(\\\"Error(string)\\\")))\\n mstore(0x00, 0x08c379a000000000000000000000000000000000000000000000000000000000)\\n // set data offset\\n mstore(0x04, 0x0000000000000000000000000000000000000000000000000000000000000020)\\n // set length of revert string\\n mstore(0x24, 0x0000000000000000000000000000000000000000000000000000000000000017)\\n // set revert string: bytes32(abi.encodePacked(\\\"Multicall3: call failed\\\"))\\n mstore(0x44, 0x4d756c746963616c6c333a2063616c6c206661696c6564000000000000000000)\\n revert(0x00, 0x64)\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /// @notice Aggregate calls with a msg value\\n /// @notice Reverts if msg.value is less than the sum of the call values\\n /// @param calls An array of Call3Value structs\\n /// @return returnData An array of Result structs\\n function aggregate3Value(Call3Value[] calldata calls) public payable returns (Result[] memory returnData) {\\n uint valAccumulator;\\n uint length = calls.length;\\n returnData = new Result[](length);\\n Call3Value calldata calli;\\n for (uint i = 0; i < length; ) {\\n Result memory result = returnData[i];\\n calli = calls[i];\\n uint val = calli.value;\\n // Humanity will be a Type V Kardashev Civilization before this overflows - andreas\\n // ~ 10^25 Wei in existence << ~ 10^76 size uint fits in a uint256\\n unchecked {\\n valAccumulator += val;\\n }\\n (result.success, result.returnData) = calli.target.call{value: val}(calli.callData);\\n assembly {\\n // Revert if the call fails and failure is not allowed\\n // `allowFailure := calldataload(add(calli, 0x20))` and `success := mload(result)`\\n if iszero(or(calldataload(add(calli, 0x20)), mload(result))) {\\n // set \\\"Error(string)\\\" signature: bytes32(bytes4(keccak256(\\\"Error(string)\\\")))\\n mstore(0x00, 0x08c379a000000000000000000000000000000000000000000000000000000000)\\n // set data offset\\n mstore(0x04, 0x0000000000000000000000000000000000000000000000000000000000000020)\\n // set length of revert string\\n mstore(0x24, 0x0000000000000000000000000000000000000000000000000000000000000017)\\n // set revert string: bytes32(abi.encodePacked(\\\"Multicall3: call failed\\\"))\\n mstore(0x44, 0x4d756c746963616c6c333a2063616c6c206661696c6564000000000000000000)\\n revert(0x00, 0x84)\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n // Finally, make sure the msg.value = SUM(call[0...i].value)\\n require(msg.value == valAccumulator, \\\"Multicall3: value mismatch\\\");\\n }\\n\\n /// @notice Returns the block hash for the given block number\\n /// @param blockNumber The block number\\n function getBlockHash(uint blockNumber) public view returns (bytes32 blockHash) {\\n blockHash = blockhash(blockNumber);\\n }\\n\\n /// @notice Returns the block number\\n function getBlockNumber() public view returns (uint blockNumber) {\\n blockNumber = block.number;\\n }\\n\\n /// @notice Returns the block coinbase\\n function getCurrentBlockCoinbase() public view returns (address coinbase) {\\n coinbase = block.coinbase;\\n }\\n\\n /// @notice Returns the block difficulty\\n function getCurrentBlockDifficulty() public view returns (uint difficulty) {\\n difficulty = block.difficulty;\\n }\\n\\n /// @notice Returns the block gas limit\\n function getCurrentBlockGasLimit() public view returns (uint gaslimit) {\\n gaslimit = block.gaslimit;\\n }\\n\\n /// @notice Returns the block timestamp\\n function getCurrentBlockTimestamp() public view returns (uint timestamp) {\\n timestamp = block.timestamp;\\n }\\n\\n /// @notice Returns the (ETH) balance of a given address\\n function getEthBalance(address addr) public view returns (uint balance) {\\n balance = addr.balance;\\n }\\n\\n /// @notice Returns the block hash of the last block\\n function getLastBlockHash() public view returns (bytes32 blockHash) {\\n unchecked {\\n blockHash = blockhash(block.number - 1);\\n }\\n }\\n\\n /// @notice Gets the base fee of the given block\\n /// @notice Can revert if the BASEFEE opcode is not implemented by the given chain\\n function getBasefee() public view returns (uint basefee) {\\n basefee = block.basefee;\\n }\\n\\n /// @notice Returns the chain id\\n function getChainId() public view returns (uint chainid) {\\n chainid = block.chainid;\\n }\\n}\\n\",\"keccak256\":\"0x9d63b6b74d69d85a4b2ae4f0daf6477c03e892e31fc5f11308ec18d23a656499\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50610edb806100206000396000f3fe6080604052600436106100f35760003560e01c80634d2301cc1161008a578063a8b0574e11610059578063a8b0574e1461025a578063bce38bd714610275578063c3077fa914610288578063ee82ac5e1461029b57600080fd5b80634d2301cc146101ec57806372425d9d1461022157806382ad56cb1461023457806386d516e81461024757600080fd5b80633408e470116100c65780633408e47014610191578063399542e9146101a45780633e64a696146101c657806342cbb15c146101d957600080fd5b80630f28c97d146100f8578063174dea711461011a578063252dba421461013a57806327e86d6e1461015b575b600080fd5b34801561010457600080fd5b50425b6040519081526020015b60405180910390f35b61012d610128366004610a85565b6102ba565b6040516101119190610bb7565b61014d610148366004610a85565b6104ef565b604051610111929190610bd1565b34801561016757600080fd5b50437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0140610107565b34801561019d57600080fd5b5046610107565b6101b76101b2366004610c5b565b610690565b60405161011193929190610cb5565b3480156101d257600080fd5b5048610107565b3480156101e557600080fd5b5043610107565b3480156101f857600080fd5b50610107610207366004610cdd565b73ffffffffffffffffffffffffffffffffffffffff163190565b34801561022d57600080fd5b5044610107565b61012d610242366004610a85565b6106ab565b34801561025357600080fd5b5045610107565b34801561026657600080fd5b50604051418152602001610111565b61012d610283366004610c5b565b61085a565b6101b7610296366004610a85565b610a1a565b3480156102a757600080fd5b506101076102b6366004610d13565b4090565b60606000828067ffffffffffffffff8111156102d8576102d8610d2c565b60405190808252806020026020018201604052801561031e57816020015b6040805180820190915260008152606060208201528152602001906001900390816102f65790505b5092503660005b8281101561047757600085828151811061034157610341610d5b565b6020026020010151905087878381811061035d5761035d610d5b565b905060200281019061036f9190610d8a565b6040810135958601959093506103886020850185610cdd565b73ffffffffffffffffffffffffffffffffffffffff16816103ac6060870187610dc8565b6040516103ba929190610e2d565b60006040518083038185875af1925050503d80600081146103f7576040519150601f19603f3d011682016040523d82523d6000602084013e6103fc565b606091505b50602080850191909152901515808452908501351761046d577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260846000fd5b5050600101610325565b508234146104e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d756c746963616c6c333a2076616c7565206d69736d6174636800000000000060448201526064015b60405180910390fd5b50505092915050565b436060828067ffffffffffffffff81111561050c5761050c610d2c565b60405190808252806020026020018201604052801561053f57816020015b606081526020019060019003908161052a5790505b5091503660005b8281101561068657600087878381811061056257610562610d5b565b90506020028101906105749190610e3d565b92506105836020840184610cdd565b73ffffffffffffffffffffffffffffffffffffffff166105a66020850185610dc8565b6040516105b4929190610e2d565b6000604051808303816000865af19150503d80600081146105f1576040519150601f19603f3d011682016040523d82523d6000602084013e6105f6565b606091505b5086848151811061060957610609610d5b565b602090810291909101015290508061067d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b50600101610546565b5050509250929050565b43804060606106a086868661085a565b905093509350939050565b6060818067ffffffffffffffff8111156106c7576106c7610d2c565b60405190808252806020026020018201604052801561070d57816020015b6040805180820190915260008152606060208201528152602001906001900390816106e55790505b5091503660005b828110156104e657600084828151811061073057610730610d5b565b6020026020010151905086868381811061074c5761074c610d5b565b905060200281019061075e9190610e71565b925061076d6020840184610cdd565b73ffffffffffffffffffffffffffffffffffffffff166107906040850185610dc8565b60405161079e929190610e2d565b6000604051808303816000865af19150503d80600081146107db576040519150601f19603f3d011682016040523d82523d6000602084013e6107e0565b606091505b506020808401919091529015158083529084013517610851577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260646000fd5b50600101610714565b6060818067ffffffffffffffff81111561087657610876610d2c565b6040519080825280602002602001820160405280156108bc57816020015b6040805180820190915260008152606060208201528152602001906001900390816108945790505b5091503660005b82811015610a105760008482815181106108df576108df610d5b565b602002602001015190508686838181106108fb576108fb610d5b565b905060200281019061090d9190610e3d565b925061091c6020840184610cdd565b73ffffffffffffffffffffffffffffffffffffffff1661093f6020850185610dc8565b60405161094d929190610e2d565b6000604051808303816000865af19150503d806000811461098a576040519150601f19603f3d011682016040523d82523d6000602084013e61098f565b606091505b506020830152151581528715610a07578051610a07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b506001016108c3565b5050509392505050565b6000806060610a2b60018686610690565b919790965090945092505050565b60008083601f840112610a4b57600080fd5b50813567ffffffffffffffff811115610a6357600080fd5b6020830191508360208260051b8501011115610a7e57600080fd5b9250929050565b60008060208385031215610a9857600080fd5b823567ffffffffffffffff811115610aaf57600080fd5b610abb85828601610a39565b90969095509350505050565b6000815180845260005b81811015610aed57602081850181015186830182015201610ad1565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b600082825180855260208086019550808260051b84010181860160005b84811015610baa578583037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001895281518051151584528401516040858501819052610b9681860183610ac7565b9a86019a9450505090830190600101610b48565b5090979650505050505050565b602081526000610bca6020830184610b2b565b9392505050565b60006040820184835260206040602085015281855180845260608601915060608160051b87010193506020870160005b82811015610c4d577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0888703018452610c3b868351610ac7565b95509284019290840190600101610c01565b509398975050505050505050565b600080600060408486031215610c7057600080fd5b83358015158114610c8057600080fd5b9250602084013567ffffffffffffffff811115610c9c57600080fd5b610ca886828701610a39565b9497909650939450505050565b838152826020820152606060408201526000610cd46060830184610b2b565b95945050505050565b600060208284031215610cef57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610bca57600080fd5b600060208284031215610d2557600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112610dbe57600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610dfd57600080fd5b83018035915067ffffffffffffffff821115610e1857600080fd5b602001915036819003821315610a7e57600080fd5b8183823760009101908152919050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc1833603018112610dbe57600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1833603018112610dbe57600080fdfea2646970667358221220fc0f3c54e2ec039c3eed75b804c56c6a051db0273a088fd0a35d50c6bd0e203464736f6c63430008170033", + "deployedBytecode": "0x6080604052600436106100f35760003560e01c80634d2301cc1161008a578063a8b0574e11610059578063a8b0574e1461025a578063bce38bd714610275578063c3077fa914610288578063ee82ac5e1461029b57600080fd5b80634d2301cc146101ec57806372425d9d1461022157806382ad56cb1461023457806386d516e81461024757600080fd5b80633408e470116100c65780633408e47014610191578063399542e9146101a45780633e64a696146101c657806342cbb15c146101d957600080fd5b80630f28c97d146100f8578063174dea711461011a578063252dba421461013a57806327e86d6e1461015b575b600080fd5b34801561010457600080fd5b50425b6040519081526020015b60405180910390f35b61012d610128366004610a85565b6102ba565b6040516101119190610bb7565b61014d610148366004610a85565b6104ef565b604051610111929190610bd1565b34801561016757600080fd5b50437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0140610107565b34801561019d57600080fd5b5046610107565b6101b76101b2366004610c5b565b610690565b60405161011193929190610cb5565b3480156101d257600080fd5b5048610107565b3480156101e557600080fd5b5043610107565b3480156101f857600080fd5b50610107610207366004610cdd565b73ffffffffffffffffffffffffffffffffffffffff163190565b34801561022d57600080fd5b5044610107565b61012d610242366004610a85565b6106ab565b34801561025357600080fd5b5045610107565b34801561026657600080fd5b50604051418152602001610111565b61012d610283366004610c5b565b61085a565b6101b7610296366004610a85565b610a1a565b3480156102a757600080fd5b506101076102b6366004610d13565b4090565b60606000828067ffffffffffffffff8111156102d8576102d8610d2c565b60405190808252806020026020018201604052801561031e57816020015b6040805180820190915260008152606060208201528152602001906001900390816102f65790505b5092503660005b8281101561047757600085828151811061034157610341610d5b565b6020026020010151905087878381811061035d5761035d610d5b565b905060200281019061036f9190610d8a565b6040810135958601959093506103886020850185610cdd565b73ffffffffffffffffffffffffffffffffffffffff16816103ac6060870187610dc8565b6040516103ba929190610e2d565b60006040518083038185875af1925050503d80600081146103f7576040519150601f19603f3d011682016040523d82523d6000602084013e6103fc565b606091505b50602080850191909152901515808452908501351761046d577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260846000fd5b5050600101610325565b508234146104e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d756c746963616c6c333a2076616c7565206d69736d6174636800000000000060448201526064015b60405180910390fd5b50505092915050565b436060828067ffffffffffffffff81111561050c5761050c610d2c565b60405190808252806020026020018201604052801561053f57816020015b606081526020019060019003908161052a5790505b5091503660005b8281101561068657600087878381811061056257610562610d5b565b90506020028101906105749190610e3d565b92506105836020840184610cdd565b73ffffffffffffffffffffffffffffffffffffffff166105a66020850185610dc8565b6040516105b4929190610e2d565b6000604051808303816000865af19150503d80600081146105f1576040519150601f19603f3d011682016040523d82523d6000602084013e6105f6565b606091505b5086848151811061060957610609610d5b565b602090810291909101015290508061067d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b50600101610546565b5050509250929050565b43804060606106a086868661085a565b905093509350939050565b6060818067ffffffffffffffff8111156106c7576106c7610d2c565b60405190808252806020026020018201604052801561070d57816020015b6040805180820190915260008152606060208201528152602001906001900390816106e55790505b5091503660005b828110156104e657600084828151811061073057610730610d5b565b6020026020010151905086868381811061074c5761074c610d5b565b905060200281019061075e9190610e71565b925061076d6020840184610cdd565b73ffffffffffffffffffffffffffffffffffffffff166107906040850185610dc8565b60405161079e929190610e2d565b6000604051808303816000865af19150503d80600081146107db576040519150601f19603f3d011682016040523d82523d6000602084013e6107e0565b606091505b506020808401919091529015158083529084013517610851577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260646000fd5b50600101610714565b6060818067ffffffffffffffff81111561087657610876610d2c565b6040519080825280602002602001820160405280156108bc57816020015b6040805180820190915260008152606060208201528152602001906001900390816108945790505b5091503660005b82811015610a105760008482815181106108df576108df610d5b565b602002602001015190508686838181106108fb576108fb610d5b565b905060200281019061090d9190610e3d565b925061091c6020840184610cdd565b73ffffffffffffffffffffffffffffffffffffffff1661093f6020850185610dc8565b60405161094d929190610e2d565b6000604051808303816000865af19150503d806000811461098a576040519150601f19603f3d011682016040523d82523d6000602084013e61098f565b606091505b506020830152151581528715610a07578051610a07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b506001016108c3565b5050509392505050565b6000806060610a2b60018686610690565b919790965090945092505050565b60008083601f840112610a4b57600080fd5b50813567ffffffffffffffff811115610a6357600080fd5b6020830191508360208260051b8501011115610a7e57600080fd5b9250929050565b60008060208385031215610a9857600080fd5b823567ffffffffffffffff811115610aaf57600080fd5b610abb85828601610a39565b90969095509350505050565b6000815180845260005b81811015610aed57602081850181015186830182015201610ad1565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b600082825180855260208086019550808260051b84010181860160005b84811015610baa578583037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001895281518051151584528401516040858501819052610b9681860183610ac7565b9a86019a9450505090830190600101610b48565b5090979650505050505050565b602081526000610bca6020830184610b2b565b9392505050565b60006040820184835260206040602085015281855180845260608601915060608160051b87010193506020870160005b82811015610c4d577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0888703018452610c3b868351610ac7565b95509284019290840190600101610c01565b509398975050505050505050565b600080600060408486031215610c7057600080fd5b83358015158114610c8057600080fd5b9250602084013567ffffffffffffffff811115610c9c57600080fd5b610ca886828701610a39565b9497909650939450505050565b838152826020820152606060408201526000610cd46060830184610b2b565b95945050505050565b600060208284031215610cef57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610bca57600080fd5b600060208284031215610d2557600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112610dbe57600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610dfd57600080fd5b83018035915067ffffffffffffffff821115610e1857600080fd5b602001915036819003821315610a7e57600080fd5b8183823760009101908152919050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc1833603018112610dbe57600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1833603018112610dbe57600080fdfea2646970667358221220fc0f3c54e2ec039c3eed75b804c56c6a051db0273a088fd0a35d50c6bd0e203464736f6c63430008170033", + "devdoc": { + "author": "Michael Elliot Joshua Levine Nick Johnson Andreas Bigger Matt Solomon ", + "details": "Multicall & Multicall2 backwards-compatibleAggregate methods are marked `payable` to save 24 gas per call", + "kind": "dev", + "methods": { + "aggregate((address,bytes)[])": { + "params": { + "calls": "An array of Call structs" + }, + "returns": { + "blockNumber": "The block number where the calls were executed", + "returnData": "An array of bytes containing the responses" + } + }, + "aggregate3((address,bool,bytes)[])": { + "params": { + "calls": "An array of Call3 structs" + }, + "returns": { + "returnData": "An array of Result structs" + } + }, + "aggregate3Value((address,bool,uint256,bytes)[])": { + "params": { + "calls": "An array of Call3Value structs" + }, + "returns": { + "returnData": "An array of Result structs" + } + }, + "blockAndAggregate((address,bytes)[])": { + "params": { + "calls": "An array of Call structs" + }, + "returns": { + "blockHash": "The hash of the block where the calls were executed", + "blockNumber": "The block number where the calls were executed", + "returnData": "An array of Result structs" + } + }, + "getBlockHash(uint256)": { + "params": { + "blockNumber": "The block number" + } + }, + "tryAggregate(bool,(address,bytes)[])": { + "params": { + "calls": "An array of Call structs", + "requireSuccess": "If true, require all calls to succeed" + }, + "returns": { + "returnData": "An array of Result structs" + } + }, + "tryBlockAndAggregate(bool,(address,bytes)[])": { + "params": { + "calls": "An array of Call structs" + }, + "returns": { + "blockHash": "The hash of the block where the calls were executed", + "blockNumber": "The block number where the calls were executed", + "returnData": "An array of Result structs" + } + } + }, + "title": "Multicall3", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "aggregate((address,bytes)[])": { + "notice": "Backwards-compatible call aggregation with Multicall" + }, + "aggregate3((address,bool,bytes)[])": { + "notice": "Aggregate calls, ensuring each returns success if required" + }, + "aggregate3Value((address,bool,uint256,bytes)[])": { + "notice": "Aggregate calls with a msg valueReverts if msg.value is less than the sum of the call values" + }, + "blockAndAggregate((address,bytes)[])": { + "notice": "Backwards-compatible with Multicall2Aggregate calls and allow failures using tryAggregate" + }, + "getBasefee()": { + "notice": "Gets the base fee of the given blockCan revert if the BASEFEE opcode is not implemented by the given chain" + }, + "getBlockHash(uint256)": { + "notice": "Returns the block hash for the given block number" + }, + "getBlockNumber()": { + "notice": "Returns the block number" + }, + "getChainId()": { + "notice": "Returns the chain id" + }, + "getCurrentBlockCoinbase()": { + "notice": "Returns the block coinbase" + }, + "getCurrentBlockDifficulty()": { + "notice": "Returns the block difficulty" + }, + "getCurrentBlockGasLimit()": { + "notice": "Returns the block gas limit" + }, + "getCurrentBlockTimestamp()": { + "notice": "Returns the block timestamp" + }, + "getEthBalance(address)": { + "notice": "Returns the (ETH) balance of a given address" + }, + "getLastBlockHash()": { + "notice": "Returns the block hash of the last block" + }, + "tryAggregate(bool,(address,bytes)[])": { + "notice": "Backwards-compatible with Multicall2Aggregate calls without requiring success" + }, + "tryBlockAndAggregate(bool,(address,bytes)[])": { + "notice": "Backwards-compatible with Multicall2Aggregate calls and allow failures using tryAggregate" + } + }, + "notice": "Aggregate results from multiple function calls", + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/imtbl-zkevm/solcInputs/b36a7d608ba9b8cba9935e17cb428950.json b/deployments/imtbl-zkevm/solcInputs/b36a7d608ba9b8cba9935e17cb428950.json new file mode 100644 index 00000000..d46af684 --- /dev/null +++ b/deployments/imtbl-zkevm/solcInputs/b36a7d608ba9b8cba9935e17cb428950.json @@ -0,0 +1,36 @@ +{ + "language": "Solidity", + "sources": { + "contracts/Multicall3.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.23;\n\n/// @title Multicall3\n/// @notice Aggregate results from multiple function calls\n/// @dev Multicall & Multicall2 backwards-compatible\n/// @dev Aggregate methods are marked `payable` to save 24 gas per call\n/// @author Michael Elliot \n/// @author Joshua Levine \n/// @author Nick Johnson \n/// @author Andreas Bigger \n/// @author Matt Solomon \ncontract Multicall3 {\n struct Call {\n address target;\n bytes callData;\n }\n\n struct Call3 {\n address target;\n bool allowFailure;\n bytes callData;\n }\n\n struct Call3Value {\n address target;\n bool allowFailure;\n uint value;\n bytes callData;\n }\n\n struct Result {\n bool success;\n bytes returnData;\n }\n\n /// @notice Backwards-compatible call aggregation with Multicall\n /// @param calls An array of Call structs\n /// @return blockNumber The block number where the calls were executed\n /// @return returnData An array of bytes containing the responses\n function aggregate(Call[] calldata calls) public payable returns (uint blockNumber, bytes[] memory returnData) {\n blockNumber = block.number;\n uint length = calls.length;\n returnData = new bytes[](length);\n Call calldata call;\n for (uint i = 0; i < length; ) {\n bool success;\n call = calls[i];\n (success, returnData[i]) = call.target.call(call.callData);\n require(success, \"Multicall3: call failed\");\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Backwards-compatible with Multicall2\n /// @notice Aggregate calls without requiring success\n /// @param requireSuccess If true, require all calls to succeed\n /// @param calls An array of Call structs\n /// @return returnData An array of Result structs\n function tryAggregate(bool requireSuccess, Call[] calldata calls) public payable returns (Result[] memory returnData) {\n uint length = calls.length;\n returnData = new Result[](length);\n Call calldata call;\n for (uint i = 0; i < length; ) {\n Result memory result = returnData[i];\n call = calls[i];\n (result.success, result.returnData) = call.target.call(call.callData);\n if (requireSuccess) require(result.success, \"Multicall3: call failed\");\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Backwards-compatible with Multicall2\n /// @notice Aggregate calls and allow failures using tryAggregate\n /// @param calls An array of Call structs\n /// @return blockNumber The block number where the calls were executed\n /// @return blockHash The hash of the block where the calls were executed\n /// @return returnData An array of Result structs\n function tryBlockAndAggregate(bool requireSuccess, Call[] calldata calls)\n public\n payable\n returns (\n uint blockNumber,\n bytes32 blockHash,\n Result[] memory returnData\n )\n {\n blockNumber = block.number;\n blockHash = blockhash(block.number);\n returnData = tryAggregate(requireSuccess, calls);\n }\n\n /// @notice Backwards-compatible with Multicall2\n /// @notice Aggregate calls and allow failures using tryAggregate\n /// @param calls An array of Call structs\n /// @return blockNumber The block number where the calls were executed\n /// @return blockHash The hash of the block where the calls were executed\n /// @return returnData An array of Result structs\n function blockAndAggregate(Call[] calldata calls)\n public\n payable\n returns (\n uint blockNumber,\n bytes32 blockHash,\n Result[] memory returnData\n )\n {\n (blockNumber, blockHash, returnData) = tryBlockAndAggregate(true, calls);\n }\n\n /// @notice Aggregate calls, ensuring each returns success if required\n /// @param calls An array of Call3 structs\n /// @return returnData An array of Result structs\n function aggregate3(Call3[] calldata calls) public payable returns (Result[] memory returnData) {\n uint length = calls.length;\n returnData = new Result[](length);\n Call3 calldata calli;\n for (uint i = 0; i < length; ) {\n Result memory result = returnData[i];\n calli = calls[i];\n (result.success, result.returnData) = calli.target.call(calli.callData);\n assembly {\n // Revert if the call fails and failure is not allowed\n // `allowFailure := calldataload(add(calli, 0x20))` and `success := mload(result)`\n if iszero(or(calldataload(add(calli, 0x20)), mload(result))) {\n // set \"Error(string)\" signature: bytes32(bytes4(keccak256(\"Error(string)\")))\n mstore(0x00, 0x08c379a000000000000000000000000000000000000000000000000000000000)\n // set data offset\n mstore(0x04, 0x0000000000000000000000000000000000000000000000000000000000000020)\n // set length of revert string\n mstore(0x24, 0x0000000000000000000000000000000000000000000000000000000000000017)\n // set revert string: bytes32(abi.encodePacked(\"Multicall3: call failed\"))\n mstore(0x44, 0x4d756c746963616c6c333a2063616c6c206661696c6564000000000000000000)\n revert(0x00, 0x64)\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Aggregate calls with a msg value\n /// @notice Reverts if msg.value is less than the sum of the call values\n /// @param calls An array of Call3Value structs\n /// @return returnData An array of Result structs\n function aggregate3Value(Call3Value[] calldata calls) public payable returns (Result[] memory returnData) {\n uint valAccumulator;\n uint length = calls.length;\n returnData = new Result[](length);\n Call3Value calldata calli;\n for (uint i = 0; i < length; ) {\n Result memory result = returnData[i];\n calli = calls[i];\n uint val = calli.value;\n // Humanity will be a Type V Kardashev Civilization before this overflows - andreas\n // ~ 10^25 Wei in existence << ~ 10^76 size uint fits in a uint256\n unchecked {\n valAccumulator += val;\n }\n (result.success, result.returnData) = calli.target.call{value: val}(calli.callData);\n assembly {\n // Revert if the call fails and failure is not allowed\n // `allowFailure := calldataload(add(calli, 0x20))` and `success := mload(result)`\n if iszero(or(calldataload(add(calli, 0x20)), mload(result))) {\n // set \"Error(string)\" signature: bytes32(bytes4(keccak256(\"Error(string)\")))\n mstore(0x00, 0x08c379a000000000000000000000000000000000000000000000000000000000)\n // set data offset\n mstore(0x04, 0x0000000000000000000000000000000000000000000000000000000000000020)\n // set length of revert string\n mstore(0x24, 0x0000000000000000000000000000000000000000000000000000000000000017)\n // set revert string: bytes32(abi.encodePacked(\"Multicall3: call failed\"))\n mstore(0x44, 0x4d756c746963616c6c333a2063616c6c206661696c6564000000000000000000)\n revert(0x00, 0x84)\n }\n }\n unchecked {\n ++i;\n }\n }\n // Finally, make sure the msg.value = SUM(call[0...i].value)\n require(msg.value == valAccumulator, \"Multicall3: value mismatch\");\n }\n\n /// @notice Returns the block hash for the given block number\n /// @param blockNumber The block number\n function getBlockHash(uint blockNumber) public view returns (bytes32 blockHash) {\n blockHash = blockhash(blockNumber);\n }\n\n /// @notice Returns the block number\n function getBlockNumber() public view returns (uint blockNumber) {\n blockNumber = block.number;\n }\n\n /// @notice Returns the block coinbase\n function getCurrentBlockCoinbase() public view returns (address coinbase) {\n coinbase = block.coinbase;\n }\n\n /// @notice Returns the block difficulty\n function getCurrentBlockDifficulty() public view returns (uint difficulty) {\n difficulty = block.difficulty;\n }\n\n /// @notice Returns the block gas limit\n function getCurrentBlockGasLimit() public view returns (uint gaslimit) {\n gaslimit = block.gaslimit;\n }\n\n /// @notice Returns the block timestamp\n function getCurrentBlockTimestamp() public view returns (uint timestamp) {\n timestamp = block.timestamp;\n }\n\n /// @notice Returns the (ETH) balance of a given address\n function getEthBalance(address addr) public view returns (uint balance) {\n balance = addr.balance;\n }\n\n /// @notice Returns the block hash of the last block\n function getLastBlockHash() public view returns (bytes32 blockHash) {\n unchecked {\n blockHash = blockhash(block.number - 1);\n }\n }\n\n /// @notice Gets the base fee of the given block\n /// @notice Can revert if the BASEFEE opcode is not implemented by the given chain\n function getBasefee() public view returns (uint basefee) {\n basefee = block.basefee;\n }\n\n /// @notice Returns the chain id\n function getChainId() public view returns (uint chainid) {\n chainid = block.chainid;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 10000000 + }, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "storageLayout", + "devdoc", + "userdoc", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/hardhat.config.js b/hardhat.config.js index 957233d9..0292aeb5 100644 --- a/hardhat.config.js +++ b/hardhat.config.js @@ -273,6 +273,17 @@ module.exports = { }, }, }, + // Multicall only - remove for LZ deployments + { + version: "0.8.23", + settings: { + optimizer: { + enabled: true, + runs: 10_000_000, + }, + evmVersion: "paris", + }, + }, ], },