Description:
Smart contract deployed on Ethereum with Factory features.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
{{
"language": "Solidity",
"sources": {
"contracts/contracts/Multicall.sol": {
"content": "// SPDX-License-Identifier: MIT\r
pragma solidity 0.8.12;\r
\r
/// @title Multicall3\r
/// @notice Aggregate results from multiple function calls\r
/// @dev Multicall & Multicall2 backwards-compatible\r
/// @dev Aggregate methods are marked `payable` to save 24 gas per call\r
/// @author Michael Elliot <mike@makerdao.com>\r
/// @author Joshua Levine <joshua@makerdao.com>\r
/// @author Nick Johnson <arachnid@notdot.net>\r
/// @author Andreas Bigger <andreas@nascent.xyz>\r
/// @author Matt Solomon <matt@mattsolomon.dev>\r
contract Multicall3 {\r
struct Call {\r
address target;\r
bytes callData;\r
}\r
\r
struct Call3 {\r
address target;\r
bool allowFailure;\r
bytes callData;\r
}\r
\r
struct Call3Value {\r
address target;\r
bool allowFailure;\r
uint256 value;\r
bytes callData;\r
}\r
\r
struct Result {\r
bool success;\r
bytes returnData;\r
}\r
\r
/// @notice Backwards-compatible call aggregation with Multicall\r
/// @param calls An array of Call structs\r
/// @return blockNumber The block number where the calls were executed\r
/// @return returnData An array of bytes containing the responses\r
function aggregate(Call[] calldata calls) public payable returns (uint256 blockNumber, bytes[] memory returnData) {\r
blockNumber = block.number;\r
uint256 length = calls.length;\r
returnData = new bytes[](length);\r
Call calldata call;\r
for (uint256 i = 0; i < length;) {\r
bool success;\r
call = calls[i];\r
(success, returnData[i]) = call.target.call(call.callData);\r
require(success, "Multicall3: call failed");\r
unchecked { ++i; }\r
}\r
}\r
\r
/// @notice Backwards-compatible with Multicall2\r
/// @notice Aggregate calls without requiring success\r
/// @param requireSuccess If true, require all calls to succeed\r
/// @param calls An array of Call structs\r
/// @return returnData An array of Result structs\r
function tryAggregate(bool requireSuccess, Call[] calldata calls) public payable returns (Result[] memory returnData) {\r
uint256 length = calls.length;\r
returnData = new Result[](length);\r
Call calldata call;\r
for (uint256 i = 0; i < length;) {\r
Result memory result = returnData[i];\r
call = calls[i];\r
(result.success, result.returnData) = call.target.call(call.callData);\r
if (requireSuccess) require(result.success, "Multicall3: call failed");\r
unchecked { ++i; }\r
}\r
}\r
\r
/// @notice Backwards-compatible with Multicall2\r
/// @notice Aggregate calls and allow failures using tryAggregate\r
/// @param calls An array of Call structs\r
/// @return blockNumber The block number where the calls were executed\r
/// @return blockHash The hash of the block where the calls were executed\r
/// @return returnData An array of Result structs\r
function tryBlockAndAggregate(bool requireSuccess, Call[] calldata calls) public payable returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData) {\r
blockNumber = block.number;\r
blockHash = blockhash(block.number);\r
returnData = tryAggregate(requireSuccess, calls);\r
}\r
\r
/// @notice Backwards-compatible with Multicall2\r
/// @notice Aggregate calls and allow failures using tryAggregate\r
/// @param calls An array of Call structs\r
/// @return blockNumber The block number where the calls were executed\r
/// @return blockHash The hash of the block where the calls were executed\r
/// @return returnData An array of Result structs\r
function blockAndAggregate(Call[] calldata calls) public payable returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData) {\r
(blockNumber, blockHash, returnData) = tryBlockAndAggregate(true, calls);\r
}\r
\r
/// @notice Aggregate calls, ensuring each returns success if required\r
/// @param calls An array of Call3 structs\r
/// @return returnData An array of Result structs\r
function aggregate3(Call3[] calldata calls) public payable returns (Result[] memory returnData) {\r
uint256 length = calls.length;\r
returnData = new Result[](length);\r
Call3 calldata calli;\r
for (uint256 i = 0; i < length;) {\r
Result memory result = returnData[i];\r
calli = calls[i];\r
(result.success, result.returnData) = calli.target.call(calli.callData);\r
assembly {\r
// Revert if the call fails and failure is not allowed\r
// `allowFailure := calldataload(add(calli, 0x20))` and `success := mload(result)`\r
if iszero(or(calldataload(add(calli, 0x20)), mload(result))) {\r
// set "Error(string)" signature: bytes32(bytes4(keccak256("Error(string)")))\r
mstore(0x00, 0x08c379a000000000000000000000000000000000000000000000000000000000)\r
// set data offset\r
mstore(0x04, 0x0000000000000000000000000000000000000000000000000000000000000020)\r
// set length of revert string\r
mstore(0x24, 0x0000000000000000000000000000000000000000000000000000000000000017)\r
// set revert string: bytes32(abi.encodePacked("Multicall3: call failed"))\r
mstore(0x44, 0x4d756c746963616c6c333a2063616c6c206661696c6564000000000000000000)\r
revert(0x00, 0x64)\r
}\r
}\r
unchecked { ++i; }\r
}\r
}\r
\r
/// @notice Aggregate calls with a msg value\r
/// @notice Reverts if msg.value is less than the sum of the call values\r
/// @param calls An array of Call3Value structs\r
/// @return returnData An array of Result structs\r
function aggregate3Value(Call3Value[] calldata calls) public payable returns (Result[] memory returnData) {\r
uint256 valAccumulator;\r
uint256 length = calls.length;\r
returnData = new Result[](length);\r
Call3Value calldata calli;\r
for (uint256 i = 0; i < length;) {\r
Result memory result = returnData[i];\r
calli = calls[i];\r
uint256 val = calli.value;\r
// Humanity will be a Type V Kardashev Civilization before this overflows - andreas\r
// ~ 10^25 Wei in existence << ~ 10^76 size uint fits in a uint256\r
unchecked { valAccumulator += val; }\r
(result.success, result.returnData) = calli.target.call{value: val}(calli.callData);\r
assembly {\r
// Revert if the call fails and failure is not allowed\r
// `allowFailure := calldataload(add(calli, 0x20))` and `success := mload(result)`\r
if iszero(or(calldataload(add(calli, 0x20)), mload(result))) {\r
// set "Error(string)" signature: bytes32(bytes4(keccak256("Error(string)")))\r
mstore(0x00, 0x08c379a000000000000000000000000000000000000000000000000000000000)\r
// set data offset\r
mstore(0x04, 0x0000000000000000000000000000000000000000000000000000000000000020)\r
// set length of revert string\r
mstore(0x24, 0x0000000000000000000000000000000000000000000000000000000000000017)\r
// set revert string: bytes32(abi.encodePacked("Multicall3: call failed"))\r
mstore(0x44, 0x4d756c746963616c6c333a2063616c6c206661696c6564000000000000000000)\r
revert(0x00, 0x84)\r
}\r
}\r
unchecked { ++i; }\r
}\r
// Finally, make sure the msg.value = SUM(call[0...i].value)\r
require(msg.value == valAccumulator, "Multicall3: value mismatch");\r
}\r
\r
/// @notice Returns the block hash for the given block number\r
/// @param blockNumber The block number\r
function getBlockHash(uint256 blockNumber) public view returns (bytes32 blockHash) {\r
blockHash = blockhash(blockNumber);\r
}\r
\r
/// @notice Returns the block number\r
function getBlockNumber() public view returns (uint256 blockNumber) {\r
blockNumber = block.number;\r
}\r
\r
/// @notice Returns the block coinbase\r
function getCurrentBlockCoinbase() public view returns (address coinbase) {\r
coinbase = block.coinbase;\r
}\r
\r
/// @notice Returns the block difficulty\r
function getCurrentBlockDifficulty() public view returns (uint256 difficulty) {\r
difficulty = block.difficulty;\r
}\r
\r
/// @notice Returns the block gas limit\r
function getCurrentBlockGasLimit() public view returns (uint256 gaslimit) {\r
gaslimit = block.gaslimit;\r
}\r
\r
/// @notice Returns the block timestamp\r
function getCurrentBlockTimestamp() public view returns (uint256 timestamp) {\r
timestamp = block.timestamp;\r
}\r
\r
/// @notice Returns the (ETH) balance of a given address\r
function getEthBalance(address addr) public view returns (uint256 balance) {\r
balance = addr.balance;\r
}\r
\r
/// @notice Returns the block hash of the last block\r
function getLastBlockHash() public view returns (bytes32 blockHash) {\r
unchecked {\r
blockHash = blockhash(block.number - 1);\r
}\r
}\r
\r
/// @notice Gets the base fee of the given block\r
/// @notice Can revert if the BASEFEE opcode is not implemented by the given chain\r
function getBasefee() public view returns (uint256 basefee) {\r
basefee = block.basefee;\r
}\r
\r
/// @notice Returns the chain id\r
function getChainId() public view returns (uint256 chainid) {\r
chainid = block.chainid;\r
}\r
}"
}
},
"settings": {
"optimizer": {
"enabled": true,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"remappings": []
}
}}
Submitted on: 2025-11-07 20:00:07
Comments
Log in to comment.
No comments yet.