diff --git a/contracts/external/Multicall3.sol b/contracts/external/Multicall3.sol new file mode 100644 index 000000000..95867b60f --- /dev/null +++ b/contracts/external/Multicall3.sol @@ -0,0 +1,252 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; // Bumped version + +/** + * This contract has been copied from the MD1/Multicall repository. + * @dev https://github.com/mds1/multicall/blob/ebd8b64457454fc10037b3a3ea858f9c08dad4d3/src/Multicall3.sol + * @dev changelog: pragma solidity ^0.8.12 -> pragma solidity ^0.8.0 + **/ + +/// @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; + uint256 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 (uint256 blockNumber, bytes[] memory returnData) { + blockNumber = block.number; + uint256 length = calls.length; + returnData = new bytes[](length); + Call calldata call; + for (uint256 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) + { + uint256 length = calls.length; + returnData = new Result[](length); + Call calldata call; + for (uint256 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 ( + uint256 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 ( + uint256 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) { + uint256 length = calls.length; + returnData = new Result[](length); + Call3 calldata calli; + for (uint256 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) { + uint256 valAccumulator; + uint256 length = calls.length; + returnData = new Result[](length); + Call3Value calldata calli; + for (uint256 i = 0; i < length; ) { + Result memory result = returnData[i]; + calli = calls[i]; + uint256 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(uint256 blockNumber) public view returns (bytes32 blockHash) { + blockHash = blockhash(blockNumber); + } + + /// @notice Returns the block number + function getBlockNumber() public view returns (uint256 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 (uint256 difficulty) { + difficulty = block.difficulty; + } + + /// @notice Returns the block gas limit + function getCurrentBlockGasLimit() public view returns (uint256 gaslimit) { + gaslimit = block.gaslimit; + } + + /// @notice Returns the block timestamp + function getCurrentBlockTimestamp() public view returns (uint256 timestamp) { + timestamp = block.timestamp; + } + + /// @notice Returns the (ETH) balance of a given address + function getEthBalance(address addr) public view returns (uint256 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 (uint256 basefee) { + basefee = block.basefee; + } + + /// @notice Returns the chain id + function getChainId() public view returns (uint256 chainid) { + chainid = block.chainid; + } +} diff --git a/deploy/055_deploy_multicall3.ts b/deploy/055_deploy_multicall3.ts new file mode 100644 index 000000000..672d850dc --- /dev/null +++ b/deploy/055_deploy_multicall3.ts @@ -0,0 +1,19 @@ +import { DeployFunction } from "hardhat-deploy/types"; +import { HardhatRuntimeEnvironment } from "hardhat/types"; + +const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + const { deployer } = await hre.getNamedAccounts(); + + // @note if deploying this contract on a chain like Linea that only supports up to + // solc 0.8.19, the hardhat.config solc version needs to be overridden and this + // contract needs to be recompiled. + await hre.deployments.deploy("Multicall3", { + contract: "Multicall3", + from: deployer, + log: true, + skipIfAlreadyDeployed: true, + args: [], + }); +}; +module.exports = func; +func.tags = ["Multicall3"]; diff --git a/deployments/alephzero/Multicall3.json b/deployments/alephzero/Multicall3.json new file mode 100644 index 000000000..9d7485e87 --- /dev/null +++ b/deployments/alephzero/Multicall3.json @@ -0,0 +1,592 @@ +{ + "address": "0x3CA11702f7c0F28e0b4e03C31F7492969862C569", + "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": "0xf23ac7d0cc8f0e06fdf9493e4895971979c5ecf5533aea4bbf149554fb710494", + "receipt": { + "to": null, + "from": "0x9A8f92a830A5cB89a3816e3D267CB7791c16b04D", + "contractAddress": "0x3CA11702f7c0F28e0b4e03C31F7492969862C569", + "transactionIndex": 1, + "gasUsed": "817235", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x65fc5028fb1ffd734d547ffda2a55e3858288df699fd1d91a72bf5f69635851c", + "transactionHash": "0xf23ac7d0cc8f0e06fdf9493e4895971979c5ecf5533aea4bbf149554fb710494", + "logs": [], + "blockNumber": 4194197, + "cumulativeGasUsed": "817235", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "7072a52b122ccd9b52398fd971741494", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"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/external/Multicall3.sol\":\"Multicall3\"},\"debug\":{\"revertStrings\":\"strip\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[],\"viaIR\":true},\"sources\":{\"contracts/external/Multicall3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.12;\\n\\n/**\\n * This contract has been copied from the MD1/Multicall repository.\\n * @dev https://github.com/mds1/multicall/blob/ebd8b64457454fc10037b3a3ea858f9c08dad4d3/src/Multicall3.sol\\n **/\\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 uint256 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 (uint256 blockNumber, bytes[] memory returnData) {\\n blockNumber = block.number;\\n uint256 length = calls.length;\\n returnData = new bytes[](length);\\n Call calldata call;\\n for (uint256 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(\\n bool requireSuccess,\\n Call[] calldata calls\\n ) public payable returns (Result[] memory returnData) {\\n uint256 length = calls.length;\\n returnData = new Result[](length);\\n Call calldata call;\\n for (uint256 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(\\n bool requireSuccess,\\n Call[] calldata calls\\n ) public payable returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData) {\\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(\\n Call[] calldata calls\\n ) public payable returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData) {\\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 uint256 length = calls.length;\\n returnData = new Result[](length);\\n Call3 calldata calli;\\n for (uint256 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 uint256 valAccumulator;\\n uint256 length = calls.length;\\n returnData = new Result[](length);\\n Call3Value calldata calli;\\n for (uint256 i = 0; i < length; ) {\\n Result memory result = returnData[i];\\n calli = calls[i];\\n uint256 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(uint256 blockNumber) public view returns (bytes32 blockHash) {\\n blockHash = blockhash(blockNumber);\\n }\\n\\n /// @notice Returns the block number\\n function getBlockNumber() public view returns (uint256 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 (uint256 difficulty) {\\n difficulty = block.difficulty;\\n }\\n\\n /// @notice Returns the block gas limit\\n function getCurrentBlockGasLimit() public view returns (uint256 gaslimit) {\\n gaslimit = block.gaslimit;\\n }\\n\\n /// @notice Returns the block timestamp\\n function getCurrentBlockTimestamp() public view returns (uint256 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 (uint256 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 (uint256 basefee) {\\n basefee = block.basefee;\\n }\\n\\n /// @notice Returns the chain id\\n function getChainId() public view returns (uint256 chainid) {\\n chainid = block.chainid;\\n }\\n}\\n\",\"keccak256\":\"0xe3c4badfb161bc7409bf1c4e8cc4b6a9168b22e6af40398b6bc6824ceb1ed013\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080806040523461001657610dcc908161001d8239f35b50600080fdfe6040608081526004361015610015575b50600080fd5b600090813560e01c80630f28c97d146102b5578063174dea711461029d578063252dba421461027857806327e86d6e1461023b5780633408e47014610221578063399542e9146102095780633e64a696146101ef57806342cbb15c146101d55780634d2301cc146101b157806372425d9d1461019757806382ad56cb1461017f57806386d516e814610165578063a8b0574e14610146578063bce38bd714610123578063c3077fa9146100fd5763ee82ac5e146100d2575061000f565b346100f9576100f591506100e536610618565b9051904081529081906020820190565b0390f35b5080fd5b506100f5915061011561010f36610363565b90610a76565b9093919251938493846105a7565b506100f5915061013b6101353661054f565b916109ca565b9051918291826104b4565b5090346101605750610157366102f5565b51418152602090f35b809150fd5b5090346101605750610176366102f5565b51458152602090f35b506100f5915061013b61019136610363565b90610b54565b50903461016057506101a8366102f5565b51448152602090f35b50346100f9576100f591506101c5366105e2565b9051903181529081906020820190565b50903461016057506101e6366102f5565b51438152602090f35b5090346101605750610200366102f5565b51488152602090f35b506100f5915061011561021b3661054f565b91610a66565b5090346101605750610232366102f5565b51468152602090f35b509034610160575061024c366102f5565b517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4301408152602090f35b506100f5915061029061028a36610363565b90610868565b92909151928392836104c8565b506100f5915061013b6102af36610363565b90610c90565b5050346102f257506102c6366102f5565b426080527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8060a0016080f35b80fd5b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc600091011261000f57565b9181601f840112156103525782359167ffffffffffffffff831161035a576020808501948460051b01011161035257565b505050600080fd5b50505050600080fd5b60207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8201126103b0576004359067ffffffffffffffff8211610352576103ac91600401610321565b9091565b5050600080fd5b91908251928382526000905b84821061040e5750601f84602094957fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09311610401575b0116010190565b60008582860101526103fa565b906020908180828501015190828601015201906103c3565b908082519081815260208091019281808460051b8301019501936000915b8483106104545750505050505090565b90919293949584806104a4837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08660019603018752828b51805115158352015190604090818582015201906103b7565b9801930193019194939290610444565b9060206104c5928181520190610426565b90565b90604082019082526020604081840152835180925260608301928160608460051b8301019501936000915b8483106105035750505050505090565b909192939495848061053f837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa086600196030187528a516103b7565b98019301930191949392906104f3565b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126103b05760043580151581141561035257916024359067ffffffffffffffff821161035a576103ac91600401610321565b6104c59392606092825260208201528160408201520190610426565b73ffffffffffffffffffffffffffffffffffffffff8116141561000f57565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc602091011261000f576004356104c5816105c3565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc602091011261000f5760043590565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f604051930116820182811067ffffffffffffffff8211176106bc57604052565b6106c4610648565b604052565b60209067ffffffffffffffff81116106e3575b60051b0190565b6106eb610648565b6106dc565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9190811015610761575b60051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc181360301821215610352570190565b6107696106f0565b61072a565b356104c5816105c3565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610352570180359067ffffffffffffffff82116103525760200191813603831361035257565b908092918237016000815290565b3d1561083a573d9067ffffffffffffffff821161082d575b61082060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f85011601610678565b9182523d6000602084013e565b610835610648565b6107ef565b606090565b6020918151811015610854575b60051b010190565b61085c6106f0565b61084c565b1561000f57565b91439261087c610877846106c9565b610678565b8381527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06108a9856106c9565b0160005b818110610927575050809360005b8181106108c85750505050565b806109216000806108dc600195878a610720565b816108f46108e98361076e565b926020810190610778565b9190610905604051809481936107c9565b03925af16109116107d7565b61091b848861083f565b52610861565b016108bb565b8060606020809386010152016108ad565b90610945610877836106c9565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe061097382946106c9565b0190600090815b8381106109875750505050565b60209060408051908082019082821067ffffffffffffffff8311176109bd575b528481528260608183015282850101520161097a565b6109c5610648565b6109a7565b9291906109d682610938565b9360005b8381106109e75750505050565b6109f1818761083f565b51826109fe838787610720565b6000808235610a0c816105c3565b81610a1c60209586810190610778565b9190826040519384928337810182815203925af190610a396107d7565b90840152159182159052610a51575b506001016109da565b610a5b5738610a48565b505050505050600080fd5b439384409390926104c5926109ca565b90610a8081610938565b9160005b828110610a95575050504340904392565b610a9f818561083f565b51610aab828585610720565b6000808235610ab9816105c3565b81610ac960209586810190610778565b9190826040519384928337810182815203925af190610ae66107d7565b90830152159081159052610afc57600101610a84565b5050505050600080fd5b9190811015610b47575b60051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa181360301821215610352570190565b610b4f6106f0565b610b10565b919091610b6083610938565b9260005b818110610b7057505050565b610b7a818661083f565b51610b86828486610b06565b600080610b928361076e565b610bb1826040610ba481880188610778565b93909151809481936107c9565b03925af191610bbe6107d7565b90610bd3602094859384840152829015159052565b519101351715610be65750600101610b64565b9450505050507f08c379a00000000000000000000000000000000000000000000000000000000060005260045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260646000fd5b9190811015610c83575b60051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8181360301821215610352570190565b610c8b6106f0565b610c4c565b919091600090610c9f84610938565b93825b818110610cb957505050610cb7903414610861565b565b610cc3818761083f565b51610ccf828486610c42565b6000806040610cf681850135809a0199610ce88661076e565b92610ba46060880188610778565b03925af191610d036107d7565b90610d18602094859384840152829015159052565b519101351715610d2b5750600101610ca2565b955050505050507f08c379a00000000000000000000000000000000000000000000000000000000060005260045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260846000fdfea3646970667358221220adae158c9151a67aac41ae0dd5f69fb3aeca55dc37e1209e0c5e26849efb62736c6578706572696d656e74616cf564736f6c634300080c0041", + "deployedBytecode": "0x6040608081526004361015610015575b50600080fd5b600090813560e01c80630f28c97d146102b5578063174dea711461029d578063252dba421461027857806327e86d6e1461023b5780633408e47014610221578063399542e9146102095780633e64a696146101ef57806342cbb15c146101d55780634d2301cc146101b157806372425d9d1461019757806382ad56cb1461017f57806386d516e814610165578063a8b0574e14610146578063bce38bd714610123578063c3077fa9146100fd5763ee82ac5e146100d2575061000f565b346100f9576100f591506100e536610618565b9051904081529081906020820190565b0390f35b5080fd5b506100f5915061011561010f36610363565b90610a76565b9093919251938493846105a7565b506100f5915061013b6101353661054f565b916109ca565b9051918291826104b4565b5090346101605750610157366102f5565b51418152602090f35b809150fd5b5090346101605750610176366102f5565b51458152602090f35b506100f5915061013b61019136610363565b90610b54565b50903461016057506101a8366102f5565b51448152602090f35b50346100f9576100f591506101c5366105e2565b9051903181529081906020820190565b50903461016057506101e6366102f5565b51438152602090f35b5090346101605750610200366102f5565b51488152602090f35b506100f5915061011561021b3661054f565b91610a66565b5090346101605750610232366102f5565b51468152602090f35b509034610160575061024c366102f5565b517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4301408152602090f35b506100f5915061029061028a36610363565b90610868565b92909151928392836104c8565b506100f5915061013b6102af36610363565b90610c90565b5050346102f257506102c6366102f5565b426080527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8060a0016080f35b80fd5b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc600091011261000f57565b9181601f840112156103525782359167ffffffffffffffff831161035a576020808501948460051b01011161035257565b505050600080fd5b50505050600080fd5b60207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8201126103b0576004359067ffffffffffffffff8211610352576103ac91600401610321565b9091565b5050600080fd5b91908251928382526000905b84821061040e5750601f84602094957fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09311610401575b0116010190565b60008582860101526103fa565b906020908180828501015190828601015201906103c3565b908082519081815260208091019281808460051b8301019501936000915b8483106104545750505050505090565b90919293949584806104a4837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08660019603018752828b51805115158352015190604090818582015201906103b7565b9801930193019194939290610444565b9060206104c5928181520190610426565b90565b90604082019082526020604081840152835180925260608301928160608460051b8301019501936000915b8483106105035750505050505090565b909192939495848061053f837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa086600196030187528a516103b7565b98019301930191949392906104f3565b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126103b05760043580151581141561035257916024359067ffffffffffffffff821161035a576103ac91600401610321565b6104c59392606092825260208201528160408201520190610426565b73ffffffffffffffffffffffffffffffffffffffff8116141561000f57565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc602091011261000f576004356104c5816105c3565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc602091011261000f5760043590565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f604051930116820182811067ffffffffffffffff8211176106bc57604052565b6106c4610648565b604052565b60209067ffffffffffffffff81116106e3575b60051b0190565b6106eb610648565b6106dc565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9190811015610761575b60051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc181360301821215610352570190565b6107696106f0565b61072a565b356104c5816105c3565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610352570180359067ffffffffffffffff82116103525760200191813603831361035257565b908092918237016000815290565b3d1561083a573d9067ffffffffffffffff821161082d575b61082060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f85011601610678565b9182523d6000602084013e565b610835610648565b6107ef565b606090565b6020918151811015610854575b60051b010190565b61085c6106f0565b61084c565b1561000f57565b91439261087c610877846106c9565b610678565b8381527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06108a9856106c9565b0160005b818110610927575050809360005b8181106108c85750505050565b806109216000806108dc600195878a610720565b816108f46108e98361076e565b926020810190610778565b9190610905604051809481936107c9565b03925af16109116107d7565b61091b848861083f565b52610861565b016108bb565b8060606020809386010152016108ad565b90610945610877836106c9565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe061097382946106c9565b0190600090815b8381106109875750505050565b60209060408051908082019082821067ffffffffffffffff8311176109bd575b528481528260608183015282850101520161097a565b6109c5610648565b6109a7565b9291906109d682610938565b9360005b8381106109e75750505050565b6109f1818761083f565b51826109fe838787610720565b6000808235610a0c816105c3565b81610a1c60209586810190610778565b9190826040519384928337810182815203925af190610a396107d7565b90840152159182159052610a51575b506001016109da565b610a5b5738610a48565b505050505050600080fd5b439384409390926104c5926109ca565b90610a8081610938565b9160005b828110610a95575050504340904392565b610a9f818561083f565b51610aab828585610720565b6000808235610ab9816105c3565b81610ac960209586810190610778565b9190826040519384928337810182815203925af190610ae66107d7565b90830152159081159052610afc57600101610a84565b5050505050600080fd5b9190811015610b47575b60051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa181360301821215610352570190565b610b4f6106f0565b610b10565b919091610b6083610938565b9260005b818110610b7057505050565b610b7a818661083f565b51610b86828486610b06565b600080610b928361076e565b610bb1826040610ba481880188610778565b93909151809481936107c9565b03925af191610bbe6107d7565b90610bd3602094859384840152829015159052565b519101351715610be65750600101610b64565b9450505050507f08c379a00000000000000000000000000000000000000000000000000000000060005260045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260646000fd5b9190811015610c83575b60051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8181360301821215610352570190565b610c8b6106f0565b610c4c565b919091600090610c9f84610938565b93825b818110610cb957505050610cb7903414610861565b565b610cc3818761083f565b51610ccf828486610c42565b6000806040610cf681850135809a0199610ce88661076e565b92610ba46060880188610778565b03925af191610d036107d7565b90610d18602094859384840152829015159052565b519101351715610d2b5750600101610ca2565b955050505050507f08c379a00000000000000000000000000000000000000000000000000000000060005260045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260846000fdfea3646970667358221220adae158c9151a67aac41ae0dd5f69fb3aeca55dc37e1209e0c5e26849efb62736c6578706572696d656e74616cf564736f6c634300080c0041", + "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 + } +} diff --git a/deployments/alephzero/solcInputs/7072a52b122ccd9b52398fd971741494.json b/deployments/alephzero/solcInputs/7072a52b122ccd9b52398fd971741494.json new file mode 100644 index 000000000..f4b8f7934 --- /dev/null +++ b/deployments/alephzero/solcInputs/7072a52b122ccd9b52398fd971741494.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "contracts/external/Multicall3.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.12;\n\n/**\n * This contract has been copied from the MD1/Multicall repository.\n * @dev https://github.com/mds1/multicall/blob/ebd8b64457454fc10037b3a3ea858f9c08dad4d3/src/Multicall3.sol\n **/\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 uint256 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 (uint256 blockNumber, bytes[] memory returnData) {\n blockNumber = block.number;\n uint256 length = calls.length;\n returnData = new bytes[](length);\n Call calldata call;\n for (uint256 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(\n bool requireSuccess,\n Call[] calldata calls\n ) public payable returns (Result[] memory returnData) {\n uint256 length = calls.length;\n returnData = new Result[](length);\n Call calldata call;\n for (uint256 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(\n bool requireSuccess,\n Call[] calldata calls\n ) public payable returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData) {\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(\n Call[] calldata calls\n ) public payable returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData) {\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 uint256 length = calls.length;\n returnData = new Result[](length);\n Call3 calldata calli;\n for (uint256 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 uint256 valAccumulator;\n uint256 length = calls.length;\n returnData = new Result[](length);\n Call3Value calldata calli;\n for (uint256 i = 0; i < length; ) {\n Result memory result = returnData[i];\n calli = calls[i];\n uint256 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(uint256 blockNumber) public view returns (bytes32 blockHash) {\n blockHash = blockhash(blockNumber);\n }\n\n /// @notice Returns the block number\n function getBlockNumber() public view returns (uint256 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 (uint256 difficulty) {\n difficulty = block.difficulty;\n }\n\n /// @notice Returns the block gas limit\n function getCurrentBlockGasLimit() public view returns (uint256 gaslimit) {\n gaslimit = block.gaslimit;\n }\n\n /// @notice Returns the block timestamp\n function getCurrentBlockTimestamp() public view returns (uint256 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 (uint256 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 (uint256 basefee) {\n basefee = block.basefee;\n }\n\n /// @notice Returns the chain id\n function getChainId() public view returns (uint256 chainid) {\n chainid = block.chainid;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 1000000 + }, + "viaIR": true, + "debug": { + "revertStrings": "strip" + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": ["ast"] + } + }, + "metadata": { + "useLiteralContent": true + } + } +}