Address Details
contract
0x68a2948DFbD993017c9cB6BC5116Ed843b705e12
- Contract Name
- SquidMulticall
- Creator
- 0x98b292ā77919e at 0xae863dā6592d3
- Balance
- 0 CELO ( )
- Tokens
-
Fetching tokens...
- Transactions
- 0 Transactions
- Transfers
- 34 Transfers
- Gas Used
- Fetching gas used...
- Last Balance Update
- 17383153
This contract has been verified via Sourcify.
View contract in Sourcify repository
- Contract name:
- SquidMulticall
- Optimization enabled
- true
- Compiler version
- v0.8.17+commit.8df45f5f
- Optimization runs
- 99999
- EVM Version
- london
- Verified at
- 2022-12-21T08:04:39.317223Z
contracts/SquidMulticall.sol
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {ISquidMulticall} from "./interfaces/ISquidMulticall.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; contract SquidMulticall is ISquidMulticall { bool private isRunning; error TransferFailed(); function run(Call[] calldata calls) external payable { // Prevents reentrancy if (isRunning) revert AlreadyRunning(); isRunning = true; for (uint256 i = 0; i < calls.length; i++) { Call memory call = calls[i]; if (call.callType == CallType.FullTokenBalance) { (address token, uint256 amountParameterPosition) = abi.decode(call.payload, (address, uint256)); uint256 amount = IERC20(token).balanceOf(address(this)); _setCallDataParameter(call.callData, amountParameterPosition, amount); } else if (call.callType == CallType.FullNativeBalance) { call.value = address(this).balance; } else if (call.callType == CallType.CollectTokenBalance) { address token = abi.decode(call.payload, (address)); _safeTransferFrom(token, msg.sender, IERC20(token).balanceOf(msg.sender)); continue; } (bool success, bytes memory data) = call.target.call{value: call.value}(call.callData); if (!success) revert CallFailed(i, data); } isRunning = false; } function _safeTransferFrom(address token, address from, uint256 amount) private { (bool success, bytes memory returnData) = token.call( abi.encodeWithSelector(IERC20.transferFrom.selector, from, address(this), amount) ); bool transferred = success && (returnData.length == uint256(0) || abi.decode(returnData, (bool))); if (!transferred || token.code.length == 0) revert TransferFailed(); } function _setCallDataParameter(bytes memory callData, uint256 parameterPosition, uint256 value) private pure { assembly { // 36 bytes shift because 32 for prefix + 4 for selector mstore(add(callData, add(36, mul(parameterPosition, 32))), value) } } // Required to enable ETH reception with .transfer or .send receive() external payable {} }
/_openzeppelin/contracts/token/ERC20/IERC20.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
/contracts/interfaces/ISquidMulticall.sol
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; interface ISquidMulticall { enum CallType { Default, FullTokenBalance, FullNativeBalance, CollectTokenBalance } struct Call { CallType callType; address target; uint256 value; bytes callData; bytes payload; } error AlreadyRunning(); error CallFailed(uint256 callPosition, bytes reason); function run(Call[] calldata calls) external payable; }
Contract ABI
[{"type":"error","name":"AlreadyRunning","inputs":[]},{"type":"error","name":"CallFailed","inputs":[{"type":"uint256","name":"callPosition","internalType":"uint256"},{"type":"bytes","name":"reason","internalType":"bytes"}]},{"type":"error","name":"TransferFailed","inputs":[]},{"type":"function","stateMutability":"payable","outputs":[],"name":"run","inputs":[{"type":"tuple[]","name":"calls","internalType":"struct ISquidMulticall.Call[]","components":[{"type":"uint8","name":"callType","internalType":"enum ISquidMulticall.CallType"},{"type":"address","name":"target","internalType":"address"},{"type":"uint256","name":"value","internalType":"uint256"},{"type":"bytes","name":"callData","internalType":"bytes"},{"type":"bytes","name":"payload","internalType":"bytes"}]}]},{"type":"receive","stateMutability":"payable"}]
Deployed ByteCode
0x6080604081815260049081361015610022575b505050361561002057600080fd5b005b600091823560e01c63f87ef8001461003a5750610012565b602091827ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103f95781359267ffffffffffffffff958685116103f557366023860112156103f557848401359687116103f5576024850194602436918960051b0101116103f557855460ff166103ce576100dd60017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff006000541617600055565b855b87811061011757866101147fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0060005416600055565b80f35b868061012c610127848c8b610459565b610622565b60018151610139816106aa565b610142816106aa565b036102ae576101f173ffffffffffffffffffffffffffffffffffffffff6101cc8861017889860151828082518301019101610717565b92908d8d519586809481937f70a082310000000000000000000000000000000000000000000000000000000083523090830191909173ffffffffffffffffffffffffffffffffffffffff6020820193169052565b0392165afa9182156102a1575b8592610272575b50606084015160249160051b010152565b8086015173ffffffffffffffffffffffffffffffffffffffff16606088830151920151918783519301915af1610225610736565b901561023a5750610235906103fd565b6100df565b61026e869186519384937f5c0dee5d0000000000000000000000000000000000000000000000000000000085528401610766565b0390fd5b610293919250893d8b1161029a575b61028b8183610526565b8101906106fb565b90386101e0565b503d610281565b6102a961070a565b6101d9565b600281516102bb816106aa565b6102c4816106aa565b036102d35747878201526101f1565b905083600382516102e3816106aa565b6102ec816106aa565b146102f9575081906101f1565b61023593925061031a6103339161039d9301518780825183010191016106e3565b73ffffffffffffffffffffffffffffffffffffffff1690565b86517f70a0823100000000000000000000000000000000000000000000000000000000815233898201908152909190879083908190602001038173ffffffffffffffffffffffffffffffffffffffff85165afa9182156103c1575b8b926103a2575b5033906107ec565b6103fd565b6103ba919250873d891161029a5761028b8183610526565b9038610395565b6103c961070a565b61038e565b807fe4455ead00000000000000000000000000000000000000000000000000000000859252fd5b8580fd5b8380fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811461042a5760010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b919081101561049e5760051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6181360301821215610499570190565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60a0810190811067ffffffffffffffff82111761051957604052565b6105216104cd565b604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761051957604052565b73ffffffffffffffffffffffffffffffffffffffff81160361049957565b359061059082610567565b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f60209267ffffffffffffffff81116105ce575b01160190565b6105d66104cd565b6105c8565b81601f82011215610499578035906105f282610592565b926106006040519485610526565b8284526020838301011161049957816000926020809301838601378301015290565b60a0813603126104995760405190610639826104fd565b8035600481101561049957825261065260208201610585565b60208301526040810135604083015260608101359067ffffffffffffffff918281116104995761068590369083016105db565b60608401526080810135918211610499576106a2913691016105db565b608082015290565b600411156106b457565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9081602091031261049957516106f881610567565b90565b90816020910312610499575190565b506040513d6000823e3d90fd5b9190826040910312610499576020825161073081610567565b92015190565b3d15610761573d9061074782610592565b916107556040519384610526565b82523d6000602084013e565b606090565b909291928152602060408183015283519384604084015260005b8581106107c0575050507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8460006060809697860101520116010190565b818101830151848201606001528201610780565b90816020910312610499575180151581036104995790565b9160009182916040519073ffffffffffffffffffffffffffffffffffffffff60208301937f23b872dd000000000000000000000000000000000000000000000000000000008552166024830152306044830152606482015260648152610851816104fd565b519082855af161085f610736565b816108aa575b50159081156108a0575b5061087657565b60046040517f90b8ec18000000000000000000000000000000000000000000000000000000008152fd5b90503b153861086f565b80518015925082156108bf575b505038610865565b6108d292506020809183010191016107d4565b38806108b756fea264697066735822122057b447d7063c7d7d5758ad98eea66f484b9b8f4af581ada19cab550cb1194a2864736f6c63430008110033