Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 20 internal transactions
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
21045629 | 13 days ago | Contract Creation | 0 ETH | |||
20587224 | 77 days ago | Contract Creation | 0 ETH | |||
20581594 | 78 days ago | Contract Creation | 0 ETH | |||
19620311 | 212 days ago | Contract Creation | 0 ETH | |||
18273963 | 401 days ago | Contract Creation | 0 ETH | |||
18273729 | 401 days ago | Contract Creation | 0 ETH | |||
18191964 | 412 days ago | Contract Creation | 0 ETH | |||
18103318 | 425 days ago | Contract Creation | 0 ETH | |||
17880745 | 456 days ago | Contract Creation | 0 ETH | |||
17841588 | 461 days ago | Contract Creation | 0 ETH | |||
17628001 | 491 days ago | Contract Creation | 0 ETH | |||
17608172 | 494 days ago | Contract Creation | 0 ETH | |||
17522973 | 506 days ago | Contract Creation | 0 ETH | |||
17498794 | 509 days ago | Contract Creation | 0 ETH | |||
17498117 | 510 days ago | Contract Creation | 0 ETH | |||
17450248 | 516 days ago | Contract Creation | 0 ETH | |||
17447753 | 517 days ago | Contract Creation | 0 ETH | |||
17430896 | 519 days ago | Contract Creation | 0 ETH | |||
17396007 | 524 days ago | Contract Creation | 0 ETH | |||
17396007 | 524 days ago | Contract Creation | 0 ETH |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
PassThroughWalletFactory
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 1000000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.17; import {LibClone} from "splits-utils/LibClone.sol"; import {PassThroughWalletImpl} from "./PassThroughWalletImpl.sol"; /// @title Pass-Through Wallet Factory /// @author 0xSplits /// @notice Factory for creating pass-through wallets. /// @dev This contract uses token = address(0) to refer to ETH. contract PassThroughWalletFactory { using LibClone for address; event CreatePassThroughWallet( PassThroughWalletImpl indexed passThroughWallet, PassThroughWalletImpl.InitParams params ); PassThroughWalletImpl public immutable passThroughWalletImpl; constructor() { passThroughWalletImpl = new PassThroughWalletImpl(); } function createPassThroughWallet(PassThroughWalletImpl.InitParams calldata params_) external returns (PassThroughWalletImpl passThroughWallet) { passThroughWallet = PassThroughWalletImpl(payable(address(passThroughWalletImpl).clone())); passThroughWallet.initializer(params_); emit CreatePassThroughWallet({passThroughWallet: passThroughWallet, params: params_}); } }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.17; /// @title Modified minimal proxy /// @author 0xSplits /// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibClone.sol) /// @dev Modified minimal proxy includes a `receive()` method that emits the /// `ReceiveETH(uint256)` event to skip `DELEGATECALL` when there is no calldata. /// Enables us to accept hard gas-capped `sends` & `transfers` for maximum backwards /// composability. library LibClone { error DeploymentFailed(); uint256 private constant FREE_PTR = 0x40; uint256 private constant ZERO_PTR = 0x60; /// @dev Deploys a modified minimal proxy of `implementation` function clone(address implementation) internal returns (address instance) { assembly ("memory-safe") { /** * --------------------------------------------------------------------------+ * CREATION (9 bytes - 0x09) | * --------------------------------------------------------------------------| * Opcode | Mnemonic | Stack | Memory | * --------------------------------------------------------------------------| * 60 runSize | PUSH1 runSize | r | | * 3d | RETURNDATASIZE | 0 r | | * 81 | DUP2 | r 0 r | | * 60 offset | PUSH1 offset | o r 0 r | | * 3d | RETURNDATASIZE | 0 o r 0 r | | * 39 | CODECOPY | 0 r | [0..runSize): runtime code | * f3 | RETURN | | [0..runSize): runtime code | * --------------------------------------------------------------------------| * RUNTIME (89 bytes - 0x59) | * --------------------------------------------------------------------------| * Opcode | Mnemonic | Stack | Memory | * --------------------------------------------------------------------------| * | * 36 | CALLDATASIZE | cds | | * 60 0x2c | PUSH1 0x2c | 0x2c cds | | * 57 | JUMPI | | | * 34 | CALLVALUE | cv | | * 3d | RETURNDATASIZE | 0 cv | | * 52 | MSTORE | | [0..0x20): callvalue | * 7f sig | PUSH32 0x9e.. | sig | [0..0x20): callvalue | * 59 | MSIZE | 0x20 sig | [0..0x20): callvalue | * 3d | RETURNDATASIZE | 0 0x20 sig | [0..0x20): callvalue | * a1 | LOG1 | | [0..0x20): callvalue | * 00 | STOP | | [0..0x20): callvalue | * 5b | JUMPDEST | | | * | * ::: keep some values in stack ::::::::::::::::::::::::::::::::::::::::::: | * 3d | RETURNDATASIZE | 0 | | * 3d | RETURNDATASIZE | 0 0 | | * 3d | RETURNDATASIZE | 0 0 0 | | * 3d | RETURNDATASIZE | 0 0 0 0 | | * | * ::: copy calldata to memory ::::::::::::::::::::::::::::::::::::::::::::: | * 36 | CALLDATASIZE | cds 0 0 0 0 | | * 3d | RETURNDATASIZE | 0 cds 0 0 0 0 | | * 3d | RETURNDATASIZE | 0 0 cds 0 0 0 0 | | * 37 | CALLDATACOPY | 0 0 0 0 | [0..cds): calldata | * | * ::: delegate call to the implementation contract :::::::::::::::::::::::: | * 36 | CALLDATASIZE | cds 0 0 0 0 | [0..cds): calldata | * 3d | RETURNDATASIZE | 0 cds 0 0 0 0 | [0..cds): calldata | * 73 addr | PUSH20 addr | addr 0 cds 0 0 0 0 | [0..cds): calldata | * 5a | GAS | gas addr 0 cds 0 0 0 0 | [0..cds): calldata | * f4 | DELEGATECALL | success 0 0 | [0..cds): calldata | * | * ::: copy return data to memory :::::::::::::::::::::::::::::::::::::::::: | * 3d | RETURNDATASIZE | rds success 0 0 | [0..cds): calldata | * 3d | RETURNDATASIZE | rds rds success 0 0 | [0..cds): calldata | * 93 | SWAP4 | 0 rds success 0 rds | [0..cds): calldata | * 80 | DUP1 | 0 0 rds success 0 rds | [0..cds): calldata | * 3e | RETURNDATACOPY | success 0 rds | [0..rds): returndata | * | * 60 0x57 | PUSH1 0x57 | 0x57 success 0 rds | [0..rds): returndata | * 57 | JUMPI | 0 rds | [0..rds): returndata | * | * ::: revert :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: | * fd | REVERT | | [0..rds): returndata | * | * ::: return :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: | * 5b | JUMPDEST | 0 rds | [0..rds): returndata | * f3 | RETURN | | [0..rds): returndata | * --------------------------------------------------------------------------+ * TOTAL INIT (98 bytes - 0x62) | * --------------------------------------------------------------------------| */ // save free pointer let fp := mload(FREE_PTR) mstore(0x51, 0x5af43d3d93803e605757fd5bf3) // 13 bytes mstore(0x44, implementation) // 20 bytes mstore(0x30, 0x593da1005b3d3d3d3d363d3d37363d73) // 16 bytes // `keccak256("ReceiveETH(uint256)")` mstore(0x20, 0x9e4ac34f21c619cefc926c8bd93b54bf5a39c7ab2127a895af1cc0691d7e3dff) // 32 bytes mstore(0x00, 0x60593d8160093d39f336602c57343d527f) // 17 bytes // total: 113 bytes = 0x71 // offset: 15 bytes = 0x0f // data: 98 bytes = 0x62 instance := create(0, 0x0f, 0x71) // restore free pointer, zero slot mstore(FREE_PTR, fp) mstore(ZERO_PTR, 0) // If `instance` is zero, revert. if iszero(instance) { // Store the function selector of `DeploymentFailed()`. mstore(0x00, 0x30116425) // Revert with (offset, size). revert(0x1c, 0x04) } } } }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.17; import {PausableImpl} from "splits-utils/PausableImpl.sol"; import {TokenUtils} from "splits-utils/TokenUtils.sol"; import {WalletImpl} from "splits-utils/WalletImpl.sol"; /// @title Pass-Through Wallet Implementation /// @author 0xSplits /// @notice A clone-implementation of a pass-through wallet. /// Please be aware, owner has _FULL CONTROL_ of the deployment. /// @dev This contract uses token = address(0) to refer to ETH. contract PassThroughWalletImpl is WalletImpl, PausableImpl { /// ----------------------------------------------------------------------- /// libraries /// ----------------------------------------------------------------------- using TokenUtils for address; /// ----------------------------------------------------------------------- /// structs /// ----------------------------------------------------------------------- struct InitParams { address owner; bool paused; address passThrough; } /// ----------------------------------------------------------------------- /// events /// ----------------------------------------------------------------------- event SetPassThrough(address passThrough); event PassThrough(address indexed passThrough, address[] tokens, uint256[] amounts); // emitted in clone bytecode event ReceiveETH(uint256 amount); /// ----------------------------------------------------------------------- /// storage /// ----------------------------------------------------------------------- /// ----------------------------------------------------------------------- /// storage - constants & immutables /// ----------------------------------------------------------------------- address public immutable passThroughWalletFactory; /// ----------------------------------------------------------------------- /// storage - mutables /// ----------------------------------------------------------------------- /// slot 0 - 11 bytes free /// OwnableImpl storage /// address internal $owner; /// 20 bytes /// PausableImpl storage /// bool internal $paused; /// 1 byte /// slot 1 - 12 bytes free /// address to pass-through funds to address internal $passThrough; /// 20 bytes /// ----------------------------------------------------------------------- /// constructor & initializer /// ----------------------------------------------------------------------- constructor() { passThroughWalletFactory = msg.sender; } function initializer(InitParams calldata params_) external { // only passThroughWalletFactory may call `initializer` if (msg.sender != passThroughWalletFactory) revert Unauthorized(); // don't need to init wallet separately __initPausable({owner_: params_.owner, paused_: params_.paused}); $passThrough = params_.passThrough; } /// ----------------------------------------------------------------------- /// functions /// ----------------------------------------------------------------------- /// ----------------------------------------------------------------------- /// functions - public & external - onlyOwner /// ----------------------------------------------------------------------- /// set passThrough function setPassThrough(address passThrough_) external onlyOwner { $passThrough = passThrough_; emit SetPassThrough(passThrough_); } /// ----------------------------------------------------------------------- /// functions - public & external - view /// ----------------------------------------------------------------------- function passThrough() external view returns (address) { return $passThrough; } /// ----------------------------------------------------------------------- /// functions - public & external - permissionless /// ----------------------------------------------------------------------- /// emit event when receiving ETH /// @dev implemented w/i clone bytecode /* receive() external payable { */ /* emit ReceiveETH(msg.value); */ /* } */ /// send `tokens_` to `$passThrough` function passThroughTokens(address[] calldata tokens_) external pausable returns (uint256[] memory amounts) { address _passThrough = $passThrough; uint256 length = tokens_.length; amounts = new uint256[](length); for (uint256 i; i < length;) { address token = tokens_[i]; uint256 amount = token._balanceOf(address(this)); amounts[i] = amount; token._safeTransfer(_passThrough, amount); unchecked { ++i; } } emit PassThrough(_passThrough, tokens_, amounts); } }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.17; import {OwnableImpl} from "./OwnableImpl.sol"; /// @title Pausable Implementation /// @author 0xSplits /// @notice Pausable clone-implementation abstract contract PausableImpl is OwnableImpl { error Paused(); event SetPaused(bool paused); /// ----------------------------------------------------------------------- /// storage - mutables /// ----------------------------------------------------------------------- /// slot 0 - 11 bytes free /// OwnableImpl storage /// address internal $owner; /// 20 bytes bool internal $paused; /// 1 byte /// ----------------------------------------------------------------------- /// constructor & initializer /// ----------------------------------------------------------------------- constructor() {} function __initPausable(address owner_, bool paused_) internal virtual { OwnableImpl.__initOwnable(owner_); $paused = paused_; } /// ----------------------------------------------------------------------- /// modifiers /// ----------------------------------------------------------------------- modifier pausable() virtual { if (paused()) revert Paused(); _; } /// ----------------------------------------------------------------------- /// functions - public & external - onlyOwner /// ----------------------------------------------------------------------- function setPaused(bool paused_) public virtual onlyOwner { $paused = paused_; emit SetPaused(paused_); } /// ----------------------------------------------------------------------- /// functions - public & external - view /// ----------------------------------------------------------------------- function paused() public view virtual returns (bool) { return $paused; } }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.17; import {SafeTransferLib} from "solady/utils/SafeTransferLib.sol"; /// Library to handle basic token functions for ERC20s & ETH (represented by 0x0) library TokenUtils { using SafeTransferLib for address; address internal constant ETH_ADDRESS = address(0); function _isETH(address token) internal pure returns (bool) { return (token == ETH_ADDRESS); } function _decimals(address token) internal view returns (uint8) { return _isETH(token) ? 18 : ERC20(token).decimals(); } function _balanceOf(address token, address addr) internal view returns (uint256) { return _isETH(token) ? addr.balance : ERC20(token).balanceOf(addr); } function _safeTransfer(address token, address addr, uint256 amount) internal { if (_isETH(token)) addr.safeTransferETH(amount); else token.safeTransfer(addr, amount); } } interface ERC20 { function decimals() external view returns (uint8); function balanceOf(address addr) external view returns (uint256); }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.17; import {ERC1155TokenReceiver} from "solmate/tokens/ERC1155.sol"; import {ERC721TokenReceiver} from "solmate/tokens/ERC721.sol"; import {OwnableImpl} from "./OwnableImpl.sol"; /// @title Wallet Implementation /// @author 0xSplits /// @notice Minimal smart wallet clone-implementation abstract contract WalletImpl is OwnableImpl, ERC721TokenReceiver, ERC1155TokenReceiver { struct Call { address to; uint256 value; bytes data; } event ExecCalls(Call[] calls); /// ----------------------------------------------------------------------- /// storage - mutables /// ----------------------------------------------------------------------- /// slot 0 - 12 bytes free /// OwnableImpl storage /// address internal $owner; /// 20 bytes /// ----------------------------------------------------------------------- /// constructor & initializer /// ----------------------------------------------------------------------- constructor() {} function __initWallet(address owner_) internal { OwnableImpl.__initOwnable(owner_); } /// ----------------------------------------------------------------------- /// functions - external & public - onlyOwner /// ----------------------------------------------------------------------- /// allow owner to execute arbitrary calls function execCalls(Call[] calldata calls_) external payable onlyOwner returns (uint256 blockNumber, bytes[] memory returnData) { blockNumber = block.number; uint256 length = calls_.length; returnData = new bytes[](length); bool success; for (uint256 i; i < length;) { Call calldata calli = calls_[i]; (success, returnData[i]) = calli.to.call{value: calli.value}(calli.data); require(success, string(returnData[i])); unchecked { ++i; } } emit ExecCalls(calls_); } }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.17; /// @title Ownable Implementation /// @author 0xSplits /// @notice Ownable clone-implementation abstract contract OwnableImpl { error Unauthorized(); event OwnershipTransferred(address indexed oldOwner, address indexed newOwner); /// ----------------------------------------------------------------------- /// storage - mutables /// ----------------------------------------------------------------------- /// slot 0 - 12 bytes free address internal $owner; /// 20 bytes /// ----------------------------------------------------------------------- /// constructor & initializer /// ----------------------------------------------------------------------- constructor() {} function __initOwnable(address owner_) internal virtual { emit OwnershipTransferred(address(0), owner_); $owner = owner_; } /// ----------------------------------------------------------------------- /// modifiers /// ----------------------------------------------------------------------- modifier onlyOwner() virtual { if (msg.sender != owner()) revert Unauthorized(); _; } /// ----------------------------------------------------------------------- /// functions - public & external - onlyOwner /// ----------------------------------------------------------------------- function transferOwnership(address owner_) public virtual onlyOwner { $owner = owner_; emit OwnershipTransferred(msg.sender, owner_); } /// ----------------------------------------------------------------------- /// functions - public & external - view /// ----------------------------------------------------------------------- function owner() public view virtual returns (address) { return $owner; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values. /// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/SafeTransferLib.sol) /// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol) /// @dev Caution! This library won't check that a token has code, responsibility is delegated to the caller. library SafeTransferLib { /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CUSTOM ERRORS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev The ETH transfer has failed. error ETHTransferFailed(); /// @dev The ERC20 `transferFrom` has failed. error TransferFromFailed(); /// @dev The ERC20 `transfer` has failed. error TransferFailed(); /// @dev The ERC20 `approve` has failed. error ApproveFailed(); /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CONSTANTS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Suggested gas stipend for contract receiving ETH /// that disallows any storage writes. uint256 internal constant _GAS_STIPEND_NO_STORAGE_WRITES = 2300; /// @dev Suggested gas stipend for contract receiving ETH to perform a few /// storage reads and writes, but low enough to prevent griefing. /// Multiply by a small constant (e.g. 2), if needed. uint256 internal constant _GAS_STIPEND_NO_GRIEF = 100000; /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* ETH OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Sends `amount` (in wei) ETH to `to`. /// Reverts upon failure. function safeTransferETH(address to, uint256 amount) internal { /// @solidity memory-safe-assembly assembly { // Transfer the ETH and check if it succeeded or not. if iszero(call(gas(), to, amount, 0, 0, 0, 0)) { // Store the function selector of `ETHTransferFailed()`. mstore(0x00, 0xb12d13eb) // Revert with (offset, size). revert(0x1c, 0x04) } } } /// @dev Force sends `amount` (in wei) ETH to `to`, with a `gasStipend`. /// The `gasStipend` can be set to a low enough value to prevent /// storage writes or gas griefing. /// /// If sending via the normal procedure fails, force sends the ETH by /// creating a temporary contract which uses `SELFDESTRUCT` to force send the ETH. /// /// Reverts if the current contract has insufficient balance. function forceSafeTransferETH(address to, uint256 amount, uint256 gasStipend) internal { /// @solidity memory-safe-assembly assembly { // If insufficient balance, revert. if lt(selfbalance(), amount) { // Store the function selector of `ETHTransferFailed()`. mstore(0x00, 0xb12d13eb) // Revert with (offset, size). revert(0x1c, 0x04) } // Transfer the ETH and check if it succeeded or not. if iszero(call(gasStipend, to, amount, 0, 0, 0, 0)) { mstore(0x00, to) // Store the address in scratch space. mstore8(0x0b, 0x73) // Opcode `PUSH20`. mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`. // We can directly use `SELFDESTRUCT` in the contract creation. // Compatible with `SENDALL`: https://eips.ethereum.org/EIPS/eip-4758 if iszero(create(amount, 0x0b, 0x16)) { revert(0, 0) } // For better gas estimation. } } } /// @dev Force sends `amount` (in wei) ETH to `to`, with a gas stipend /// equal to `_GAS_STIPEND_NO_GRIEF`. This gas stipend is a reasonable default /// for 99% of cases and can be overriden with the three-argument version of this /// function if necessary. /// /// If sending via the normal procedure fails, force sends the ETH by /// creating a temporary contract which uses `SELFDESTRUCT` to force send the ETH. /// /// Reverts if the current contract has insufficient balance. function forceSafeTransferETH(address to, uint256 amount) internal { // Manually inlined because the compiler doesn't inline functions with branches. /// @solidity memory-safe-assembly assembly { // If insufficient balance, revert. if lt(selfbalance(), amount) { // Store the function selector of `ETHTransferFailed()`. mstore(0x00, 0xb12d13eb) // Revert with (offset, size). revert(0x1c, 0x04) } // Transfer the ETH and check if it succeeded or not. if iszero(call(_GAS_STIPEND_NO_GRIEF, to, amount, 0, 0, 0, 0)) { mstore(0x00, to) // Store the address in scratch space. mstore8(0x0b, 0x73) // Opcode `PUSH20`. mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`. // We can directly use `SELFDESTRUCT` in the contract creation. // Compatible with `SENDALL`: https://eips.ethereum.org/EIPS/eip-4758 if iszero(create(amount, 0x0b, 0x16)) { revert(0, 0) } // For better gas estimation. } } } /// @dev Sends `amount` (in wei) ETH to `to`, with a `gasStipend`. /// The `gasStipend` can be set to a low enough value to prevent /// storage writes or gas griefing. /// /// Simply use `gasleft()` for `gasStipend` if you don't need a gas stipend. /// /// Note: Does NOT revert upon failure. /// Returns whether the transfer of ETH is successful instead. function trySafeTransferETH(address to, uint256 amount, uint256 gasStipend) internal returns (bool success) { /// @solidity memory-safe-assembly assembly { // Transfer the ETH and check if it succeeded or not. success := call(gasStipend, to, amount, 0, 0, 0, 0) } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* ERC20 OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Sends `amount` of ERC20 `token` from `from` to `to`. /// Reverts upon failure. /// /// The `from` account must have at least `amount` approved for /// the current contract to manage. function safeTransferFrom(address token, address from, address to, uint256 amount) internal { /// @solidity memory-safe-assembly assembly { let m := mload(0x40) // Cache the free memory pointer. // Store the function selector of `transferFrom(address,address,uint256)`. mstore(0x00, 0x23b872dd) mstore(0x20, from) // Store the `from` argument. mstore(0x40, to) // Store the `to` argument. mstore(0x60, amount) // Store the `amount` argument. if iszero( and( // The arguments of `and` are evaluated from right to left. // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(eq(mload(0x00), 1), iszero(returndatasize())), call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20) ) ) { // Store the function selector of `TransferFromFailed()`. mstore(0x00, 0x7939f424) // Revert with (offset, size). revert(0x1c, 0x04) } mstore(0x60, 0) // Restore the zero slot to zero. mstore(0x40, m) // Restore the free memory pointer. } } /// @dev Sends all of ERC20 `token` from `from` to `to`. /// Reverts upon failure. /// /// The `from` account must have at least `amount` approved for /// the current contract to manage. function safeTransferAllFrom(address token, address from, address to) internal returns (uint256 amount) { /// @solidity memory-safe-assembly assembly { let m := mload(0x40) // Cache the free memory pointer. mstore(0x00, 0x70a08231) // Store the function selector of `balanceOf(address)`. mstore(0x20, from) // Store the `from` argument. if iszero( and( // The arguments of `and` are evaluated from right to left. gt(returndatasize(), 0x1f), // At least 32 bytes returned. staticcall(gas(), token, 0x1c, 0x24, 0x60, 0x20) ) ) { // Store the function selector of `TransferFromFailed()`. mstore(0x00, 0x7939f424) // Revert with (offset, size). revert(0x1c, 0x04) } // Store the function selector of `transferFrom(address,address,uint256)`. mstore(0x00, 0x23b872dd) mstore(0x40, to) // Store the `to` argument. // The `amount` argument is already written to the memory word at 0x6a. amount := mload(0x60) if iszero( and( // The arguments of `and` are evaluated from right to left. // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(eq(mload(0x00), 1), iszero(returndatasize())), call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20) ) ) { // Store the function selector of `TransferFromFailed()`. mstore(0x00, 0x7939f424) // Revert with (offset, size). revert(0x1c, 0x04) } mstore(0x60, 0) // Restore the zero slot to zero. mstore(0x40, m) // Restore the free memory pointer. } } /// @dev Sends `amount` of ERC20 `token` from the current contract to `to`. /// Reverts upon failure. function safeTransfer(address token, address to, uint256 amount) internal { /// @solidity memory-safe-assembly assembly { mstore(0x1a, to) // Store the `to` argument. mstore(0x3a, amount) // Store the `amount` argument. // Store the function selector of `transfer(address,uint256)`, // left by 6 bytes (enough for 8tb of memory represented by the free memory pointer). // We waste 6-3 = 3 bytes to save on 6 runtime gas (PUSH1 0x224 SHL). mstore(0x00, 0xa9059cbb000000000000) if iszero( and( // The arguments of `and` are evaluated from right to left. // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(eq(mload(0x00), 1), iszero(returndatasize())), call(gas(), token, 0, 0x16, 0x44, 0x00, 0x20) ) ) { // Store the function selector of `TransferFailed()`. mstore(0x00, 0x90b8ec18) // Revert with (offset, size). revert(0x1c, 0x04) } // Restore the part of the free memory pointer that was overwritten, // which is guaranteed to be zero, if less than 8tb of memory is used. mstore(0x3a, 0) } } /// @dev Sends all of ERC20 `token` from the current contract to `to`. /// Reverts upon failure. function safeTransferAll(address token, address to) internal returns (uint256 amount) { /// @solidity memory-safe-assembly assembly { mstore(0x00, 0x70a08231) // Store the function selector of `balanceOf(address)`. mstore(0x20, address()) // Store the address of the current contract. if iszero( and( // The arguments of `and` are evaluated from right to left. gt(returndatasize(), 0x1f), // At least 32 bytes returned. staticcall(gas(), token, 0x1c, 0x24, 0x3a, 0x20) ) ) { // Store the function selector of `TransferFailed()`. mstore(0x00, 0x90b8ec18) // Revert with (offset, size). revert(0x1c, 0x04) } mstore(0x1a, to) // Store the `to` argument. // The `amount` argument is already written to the memory word at 0x3a. amount := mload(0x3a) // Store the function selector of `transfer(address,uint256)`, // left by 6 bytes (enough for 8tb of memory represented by the free memory pointer). // We waste 6-3 = 3 bytes to save on 6 runtime gas (PUSH1 0x224 SHL). mstore(0x00, 0xa9059cbb000000000000) if iszero( and( // The arguments of `and` are evaluated from right to left. // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(eq(mload(0x00), 1), iszero(returndatasize())), call(gas(), token, 0, 0x16, 0x44, 0x00, 0x20) ) ) { // Store the function selector of `TransferFailed()`. mstore(0x00, 0x90b8ec18) // Revert with (offset, size). revert(0x1c, 0x04) } // Restore the part of the free memory pointer that was overwritten, // which is guaranteed to be zero, if less than 8tb of memory is used. mstore(0x3a, 0) } } /// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract. /// Reverts upon failure. function safeApprove(address token, address to, uint256 amount) internal { /// @solidity memory-safe-assembly assembly { mstore(0x1a, to) // Store the `to` argument. mstore(0x3a, amount) // Store the `amount` argument. // Store the function selector of `approve(address,uint256)`, // left by 6 bytes (enough for 8tb of memory represented by the free memory pointer). // We waste 6-3 = 3 bytes to save on 6 runtime gas (PUSH1 0x224 SHL). mstore(0x00, 0x095ea7b3000000000000) if iszero( and( // The arguments of `and` are evaluated from right to left. // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(eq(mload(0x00), 1), iszero(returndatasize())), call(gas(), token, 0, 0x16, 0x44, 0x00, 0x20) ) ) { // Store the function selector of `ApproveFailed()`. mstore(0x00, 0x3e3f8f73) // Revert with (offset, size). revert(0x1c, 0x04) } // Restore the part of the free memory pointer that was overwritten, // which is guaranteed to be zero, if less than 8tb of memory is used. mstore(0x3a, 0) } } /// @dev Returns the amount of ERC20 `token` owned by `account`. /// Returns zero if the `token` does not exist. function balanceOf(address token, address account) internal view returns (uint256 amount) { /// @solidity memory-safe-assembly assembly { mstore(0x00, 0x70a08231) // Store the function selector of `balanceOf(address)`. mstore(0x20, account) // Store the `account` argument. amount := mul( mload(0x20), and( // The arguments of `and` are evaluated from right to left. gt(returndatasize(), 0x1f), // At least 32 bytes returned. staticcall(gas(), token, 0x1c, 0x24, 0x20, 0x20) ) ) } } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Minimalist and gas efficient standard ERC1155 implementation. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC1155.sol) abstract contract ERC1155 { /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event TransferSingle( address indexed operator, address indexed from, address indexed to, uint256 id, uint256 amount ); event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] amounts ); event ApprovalForAll(address indexed owner, address indexed operator, bool approved); event URI(string value, uint256 indexed id); /*////////////////////////////////////////////////////////////// ERC1155 STORAGE //////////////////////////////////////////////////////////////*/ mapping(address => mapping(uint256 => uint256)) public balanceOf; mapping(address => mapping(address => bool)) public isApprovedForAll; /*////////////////////////////////////////////////////////////// METADATA LOGIC //////////////////////////////////////////////////////////////*/ function uri(uint256 id) public view virtual returns (string memory); /*////////////////////////////////////////////////////////////// ERC1155 LOGIC //////////////////////////////////////////////////////////////*/ function setApprovalForAll(address operator, bool approved) public virtual { isApprovedForAll[msg.sender][operator] = approved; emit ApprovalForAll(msg.sender, operator, approved); } function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes calldata data ) public virtual { require(msg.sender == from || isApprovedForAll[from][msg.sender], "NOT_AUTHORIZED"); balanceOf[from][id] -= amount; balanceOf[to][id] += amount; emit TransferSingle(msg.sender, from, to, id, amount); require( to.code.length == 0 ? to != address(0) : ERC1155TokenReceiver(to).onERC1155Received(msg.sender, from, id, amount, data) == ERC1155TokenReceiver.onERC1155Received.selector, "UNSAFE_RECIPIENT" ); } function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) public virtual { require(ids.length == amounts.length, "LENGTH_MISMATCH"); require(msg.sender == from || isApprovedForAll[from][msg.sender], "NOT_AUTHORIZED"); // Storing these outside the loop saves ~15 gas per iteration. uint256 id; uint256 amount; for (uint256 i = 0; i < ids.length; ) { id = ids[i]; amount = amounts[i]; balanceOf[from][id] -= amount; balanceOf[to][id] += amount; // An array can't have a total length // larger than the max uint256 value. unchecked { ++i; } } emit TransferBatch(msg.sender, from, to, ids, amounts); require( to.code.length == 0 ? to != address(0) : ERC1155TokenReceiver(to).onERC1155BatchReceived(msg.sender, from, ids, amounts, data) == ERC1155TokenReceiver.onERC1155BatchReceived.selector, "UNSAFE_RECIPIENT" ); } function balanceOfBatch(address[] calldata owners, uint256[] calldata ids) public view virtual returns (uint256[] memory balances) { require(owners.length == ids.length, "LENGTH_MISMATCH"); balances = new uint256[](owners.length); // Unchecked because the only math done is incrementing // the array index counter which cannot possibly overflow. unchecked { for (uint256 i = 0; i < owners.length; ++i) { balances[i] = balanceOf[owners[i]][ids[i]]; } } } /*////////////////////////////////////////////////////////////// ERC165 LOGIC //////////////////////////////////////////////////////////////*/ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165 interfaceId == 0xd9b67a26 || // ERC165 Interface ID for ERC1155 interfaceId == 0x0e89341c; // ERC165 Interface ID for ERC1155MetadataURI } /*////////////////////////////////////////////////////////////// INTERNAL MINT/BURN LOGIC //////////////////////////////////////////////////////////////*/ function _mint( address to, uint256 id, uint256 amount, bytes memory data ) internal virtual { balanceOf[to][id] += amount; emit TransferSingle(msg.sender, address(0), to, id, amount); require( to.code.length == 0 ? to != address(0) : ERC1155TokenReceiver(to).onERC1155Received(msg.sender, address(0), id, amount, data) == ERC1155TokenReceiver.onERC1155Received.selector, "UNSAFE_RECIPIENT" ); } function _batchMint( address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual { uint256 idsLength = ids.length; // Saves MLOADs. require(idsLength == amounts.length, "LENGTH_MISMATCH"); for (uint256 i = 0; i < idsLength; ) { balanceOf[to][ids[i]] += amounts[i]; // An array can't have a total length // larger than the max uint256 value. unchecked { ++i; } } emit TransferBatch(msg.sender, address(0), to, ids, amounts); require( to.code.length == 0 ? to != address(0) : ERC1155TokenReceiver(to).onERC1155BatchReceived(msg.sender, address(0), ids, amounts, data) == ERC1155TokenReceiver.onERC1155BatchReceived.selector, "UNSAFE_RECIPIENT" ); } function _batchBurn( address from, uint256[] memory ids, uint256[] memory amounts ) internal virtual { uint256 idsLength = ids.length; // Saves MLOADs. require(idsLength == amounts.length, "LENGTH_MISMATCH"); for (uint256 i = 0; i < idsLength; ) { balanceOf[from][ids[i]] -= amounts[i]; // An array can't have a total length // larger than the max uint256 value. unchecked { ++i; } } emit TransferBatch(msg.sender, from, address(0), ids, amounts); } function _burn( address from, uint256 id, uint256 amount ) internal virtual { balanceOf[from][id] -= amount; emit TransferSingle(msg.sender, from, address(0), id, amount); } } /// @notice A generic interface for a contract which properly accepts ERC1155 tokens. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC1155.sol) abstract contract ERC1155TokenReceiver { function onERC1155Received( address, address, uint256, uint256, bytes calldata ) external virtual returns (bytes4) { return ERC1155TokenReceiver.onERC1155Received.selector; } function onERC1155BatchReceived( address, address, uint256[] calldata, uint256[] calldata, bytes calldata ) external virtual returns (bytes4) { return ERC1155TokenReceiver.onERC1155BatchReceived.selector; } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Modern, minimalist, and gas efficient ERC-721 implementation. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol) abstract contract ERC721 { /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event Transfer(address indexed from, address indexed to, uint256 indexed id); event Approval(address indexed owner, address indexed spender, uint256 indexed id); event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /*////////////////////////////////////////////////////////////// METADATA STORAGE/LOGIC //////////////////////////////////////////////////////////////*/ string public name; string public symbol; function tokenURI(uint256 id) public view virtual returns (string memory); /*////////////////////////////////////////////////////////////// ERC721 BALANCE/OWNER STORAGE //////////////////////////////////////////////////////////////*/ mapping(uint256 => address) internal _ownerOf; mapping(address => uint256) internal _balanceOf; function ownerOf(uint256 id) public view virtual returns (address owner) { require((owner = _ownerOf[id]) != address(0), "NOT_MINTED"); } function balanceOf(address owner) public view virtual returns (uint256) { require(owner != address(0), "ZERO_ADDRESS"); return _balanceOf[owner]; } /*////////////////////////////////////////////////////////////// ERC721 APPROVAL STORAGE //////////////////////////////////////////////////////////////*/ mapping(uint256 => address) public getApproved; mapping(address => mapping(address => bool)) public isApprovedForAll; /*////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor(string memory _name, string memory _symbol) { name = _name; symbol = _symbol; } /*////////////////////////////////////////////////////////////// ERC721 LOGIC //////////////////////////////////////////////////////////////*/ function approve(address spender, uint256 id) public virtual { address owner = _ownerOf[id]; require(msg.sender == owner || isApprovedForAll[owner][msg.sender], "NOT_AUTHORIZED"); getApproved[id] = spender; emit Approval(owner, spender, id); } function setApprovalForAll(address operator, bool approved) public virtual { isApprovedForAll[msg.sender][operator] = approved; emit ApprovalForAll(msg.sender, operator, approved); } function transferFrom( address from, address to, uint256 id ) public virtual { require(from == _ownerOf[id], "WRONG_FROM"); require(to != address(0), "INVALID_RECIPIENT"); require( msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id], "NOT_AUTHORIZED" ); // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. unchecked { _balanceOf[from]--; _balanceOf[to]++; } _ownerOf[id] = to; delete getApproved[id]; emit Transfer(from, to, id); } function safeTransferFrom( address from, address to, uint256 id ) public virtual { transferFrom(from, to, id); require( to.code.length == 0 || ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, "") == ERC721TokenReceiver.onERC721Received.selector, "UNSAFE_RECIPIENT" ); } function safeTransferFrom( address from, address to, uint256 id, bytes calldata data ) public virtual { transferFrom(from, to, id); require( to.code.length == 0 || ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) == ERC721TokenReceiver.onERC721Received.selector, "UNSAFE_RECIPIENT" ); } /*////////////////////////////////////////////////////////////// ERC165 LOGIC //////////////////////////////////////////////////////////////*/ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165 interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721 interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata } /*////////////////////////////////////////////////////////////// INTERNAL MINT/BURN LOGIC //////////////////////////////////////////////////////////////*/ function _mint(address to, uint256 id) internal virtual { require(to != address(0), "INVALID_RECIPIENT"); require(_ownerOf[id] == address(0), "ALREADY_MINTED"); // Counter overflow is incredibly unrealistic. unchecked { _balanceOf[to]++; } _ownerOf[id] = to; emit Transfer(address(0), to, id); } function _burn(uint256 id) internal virtual { address owner = _ownerOf[id]; require(owner != address(0), "NOT_MINTED"); // Ownership check above ensures no underflow. unchecked { _balanceOf[owner]--; } delete _ownerOf[id]; delete getApproved[id]; emit Transfer(owner, address(0), id); } /*////////////////////////////////////////////////////////////// INTERNAL SAFE MINT LOGIC //////////////////////////////////////////////////////////////*/ function _safeMint(address to, uint256 id) internal virtual { _mint(to, id); require( to.code.length == 0 || ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, "") == ERC721TokenReceiver.onERC721Received.selector, "UNSAFE_RECIPIENT" ); } function _safeMint( address to, uint256 id, bytes memory data ) internal virtual { _mint(to, id); require( to.code.length == 0 || ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) == ERC721TokenReceiver.onERC721Received.selector, "UNSAFE_RECIPIENT" ); } } /// @notice A generic interface for a contract which properly accepts ERC721 tokens. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol) abstract contract ERC721TokenReceiver { function onERC721Received( address, address, uint256, bytes calldata ) external virtual returns (bytes4) { return ERC721TokenReceiver.onERC721Received.selector; } }
{ "remappings": [ "ds-test/=lib/forge-std/lib/ds-test/src/", "forge-std/=lib/forge-std/src/", "solady/=lib/splits-utils/lib/solady/src/", "solmate/=lib/splits-utils/lib/solmate/src/", "splits-tests/=lib/splits-utils/test/", "splits-utils/=lib/splits-utils/src/" ], "optimizer": { "enabled": true, "runs": 1000000 }, "metadata": { "bytecodeHash": "ipfs" }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "london", "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract PassThroughWalletImpl","name":"passThroughWallet","type":"address"},{"components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"address","name":"passThrough","type":"address"}],"indexed":false,"internalType":"struct PassThroughWalletImpl.InitParams","name":"params","type":"tuple"}],"name":"CreatePassThroughWallet","type":"event"},{"inputs":[{"components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"address","name":"passThrough","type":"address"}],"internalType":"struct PassThroughWalletImpl.InitParams","name":"params_","type":"tuple"}],"name":"createPassThroughWallet","outputs":[{"internalType":"contract PassThroughWalletImpl","name":"passThroughWallet","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"passThroughWalletImpl","outputs":[{"internalType":"contract PassThroughWalletImpl","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60a060405234801561001057600080fd5b5060405161001d9061004b565b604051809103906000f080158015610039573d6000803e3d6000fd5b506001600160a01b0316608052610058565b61151e8061038a83390190565b608051610312610078600039600081816040015260a001526103126000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806386b2162e1461003b578063f28613d91461008b575b600080fd5b6100627f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b610062610099366004610246565b60006100da7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166101b4565b6040517f132e9b7100000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff82169063132e9b719061012f908590600401610282565b600060405180830381600087803b15801561014957600080fd5b505af115801561015d573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff167f7c19a2785f0fdff7e3b0a72613aacd7c4b9e612f8c57d686fd360e161804e22a836040516101a79190610282565b60405180910390a2919050565b60006040516c5af43d3d93803e605757fd5bf3605152826044526f593da1005b3d3d3d3d363d3d37363d736030527f9e4ac34f21c619cefc926c8bd93b54bf5a39c7ab2127a895af1cc0691d7e3dff6020527060593d8160093d39f336602c57343d527f6000526071600f6000f0915080604052506000606052806102415763301164256000526004601cfd5b919050565b60006060828403121561025857600080fd5b50919050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461024157600080fd5b6060810173ffffffffffffffffffffffffffffffffffffffff806102a58561025e565b16835260208401358015158082146102bc57600080fd5b602085015250806102cf6040860161025e565b166040840152509291505056fea2646970667358221220f49ed6348b24682784af1f5529dc72d65e054d4638b337bdb0771d80a1f97aa764736f6c6343000811003360a060405234801561001057600080fd5b50336080526080516114e76100376000396000818161020101526103b201526114e76000f3fe6080604052600436106100d25760003560e01c806381b82d8b1161007f578063bc197c8111610059578063bc197c81146102cb578063f23a6e6114610313578063f2fde38b14610359578063f69e64b21461037957600080fd5b806381b82d8b146102485780638da5cb5b14610273578063b47942511461029e57600080fd5b806316c38b3c116100b057806316c38b3c146101945780635c975abb146101b45780636348a0ba146101ef57600080fd5b8063132e9b71146100d7578063150b7a02146100f9578063161c547714610174575b600080fd5b3480156100e357600080fd5b506100f76100f2366004610d69565b61039a565b005b34801561010557600080fd5b5061013e610114366004610df3565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b34801561018057600080fd5b506100f761018f366004610e62565b610486565b3480156101a057600080fd5b506100f76101af366004610e7d565b610551565b3480156101c057600080fd5b5060005474010000000000000000000000000000000000000000900460ff16604051901515815260200161016b565b3480156101fb57600080fd5b506102237f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161016b565b34801561025457600080fd5b5060015473ffffffffffffffffffffffffffffffffffffffff16610223565b34801561027f57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610223565b3480156102aa57600080fd5b506102be6102b9366004610ee4565b61061b565b60405161016b9190610f61565b3480156102d757600080fd5b5061013e6102e6366004610f74565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b34801561031f57600080fd5b5061013e61032e36600461102f565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b34801561036557600080fd5b506100f7610374366004610e62565b6107d0565b61038c610387366004610ee4565b610891565b60405161016b92919061110b565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610409576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61042e6104196020830183610e62565b6104296040840160208501610e7d565b610aee565b61043e6060820160408301610e62565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b60005473ffffffffffffffffffffffffffffffffffffffff1633146104d7576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527ffe91f3077e7cf3c193f6d72f02aa58eeae9296420b00358c01db607adfd0bacc906020015b60405180910390a150565b60005473ffffffffffffffffffffffffffffffffffffffff1633146105a2576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805482151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9091161790556040517f3c70af01296aef045b2f5c9d3c30b05d4428fd257145b9c7fcd76418e65b59809061054690831515815260200190565b60005460609074010000000000000000000000000000000000000000900460ff1615610673576040517f9e87fac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60015473ffffffffffffffffffffffffffffffffffffffff16828067ffffffffffffffff8111156106a6576106a6611193565b6040519080825280602002602001820160405280156106cf578160200160208202803683370190505b50925060005b818110156107755760008686838181106106f1576106f16111c2565b90506020020160208101906107069190610e62565b9050600061072a73ffffffffffffffffffffffffffffffffffffffff831630610b42565b90508086848151811061073f5761073f6111c2565b602090810291909101015261076b73ffffffffffffffffffffffffffffffffffffffff83168683610c15565b50506001016106d5565b508173ffffffffffffffffffffffffffffffffffffffff167f4b26ffa020d84239c742767d9b9f63bceaddb9d3cb16389a3c75ce2f29b8a80e8686866040516107c0939291906111f1565b60405180910390a2505092915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610821576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081178255604051909133917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a350565b600060606108b460005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610918576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b439150828067ffffffffffffffff81111561093557610935611193565b60405190808252806020026020018201604052801561096857816020015b60608152602001906001900390816109535790505b5091506000805b82811015610aab573687878381811061098a5761098a6111c2565b905060200281019061099c919061125d565b90506109ab6020820182610e62565b73ffffffffffffffffffffffffffffffffffffffff1660208201356109d3604084018461129b565b6040516109e1929190611300565b60006040518083038185875af1925050503d8060008114610a1e576040519150601f19603f3d011682016040523d82523d6000602084013e610a23565b606091505b50868481518110610a3657610a366111c2565b60200260200101819052819450505082858381518110610a5857610a586111c2565b602002602001015190610aa1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a989190611310565b60405180910390fd5b505060010161096f565b507f79dfcb184c75a8c53199ae76930d72ffcdac408a45ea4b710dfe3f2d35a45a268686604051610add929190611323565b60405180910390a150509250929050565b610af782610c76565b6000805491151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90921691909117905550565b600073ffffffffffffffffffffffffffffffffffffffff831615610bf5576040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301528416906370a0823190602401602060405180830381865afa158015610bcc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf09190611498565b610c0e565b8173ffffffffffffffffffffffffffffffffffffffff16315b9392505050565b73ffffffffffffffffffffffffffffffffffffffff8316610c5557610c5073ffffffffffffffffffffffffffffffffffffffff831682610d00565b505050565b610c5073ffffffffffffffffffffffffffffffffffffffff84168383610d20565b60405173ffffffffffffffffffffffffffffffffffffffff8216906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60008060008084865af1610d1c5763b12d13eb6000526004601cfd5b5050565b81601a5280603a5269a9059cbb00000000000060005260206000604460166000875af13d156001600051141716610d5f576390b8ec186000526004601cfd5b6000603a52505050565b600060608284031215610d7b57600080fd5b50919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610da557600080fd5b919050565b60008083601f840112610dbc57600080fd5b50813567ffffffffffffffff811115610dd457600080fd5b602083019150836020828501011115610dec57600080fd5b9250929050565b600080600080600060808688031215610e0b57600080fd5b610e1486610d81565b9450610e2260208701610d81565b935060408601359250606086013567ffffffffffffffff811115610e4557600080fd5b610e5188828901610daa565b969995985093965092949392505050565b600060208284031215610e7457600080fd5b610c0e82610d81565b600060208284031215610e8f57600080fd5b81358015158114610c0e57600080fd5b60008083601f840112610eb157600080fd5b50813567ffffffffffffffff811115610ec957600080fd5b6020830191508360208260051b8501011115610dec57600080fd5b60008060208385031215610ef757600080fd5b823567ffffffffffffffff811115610f0e57600080fd5b610f1a85828601610e9f565b90969095509350505050565b600081518084526020808501945080840160005b83811015610f5657815187529582019590820190600101610f3a565b509495945050505050565b602081526000610c0e6020830184610f26565b60008060008060008060008060a0898b031215610f9057600080fd5b610f9989610d81565b9750610fa760208a01610d81565b9650604089013567ffffffffffffffff80821115610fc457600080fd5b610fd08c838d01610e9f565b909850965060608b0135915080821115610fe957600080fd5b610ff58c838d01610e9f565b909650945060808b013591508082111561100e57600080fd5b5061101b8b828c01610daa565b999c989b5096995094979396929594505050565b60008060008060008060a0878903121561104857600080fd5b61105187610d81565b955061105f60208801610d81565b94506040870135935060608701359250608087013567ffffffffffffffff81111561108957600080fd5b61109589828a01610daa565b979a9699509497509295939492505050565b6000815180845260005b818110156110cd576020818501810151868301820152016110b1565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b600060408201848352602060408185015281855180845260608601915060608160051b870101935082870160005b82811015611185577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa08887030184526111738683516110a7565b95509284019290840190600101611139565b509398975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040808252810183905260008460608301825b8681101561123f5773ffffffffffffffffffffffffffffffffffffffff61122a84610d81565b16825260209283019290910190600101611204565b5083810360208501526112528186610f26565b979650505050505050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa183360301811261129157600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126112d057600080fd5b83018035915067ffffffffffffffff8211156112eb57600080fd5b602001915036819003821315610dec57600080fd5b8183823760009101908152919050565b602081526000610c0e60208301846110a7565b60208082528181018390526000906040808401600586901b8501820187855b8881101561148a577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088840301845281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18b36030181126113a357600080fd5b8a01606073ffffffffffffffffffffffffffffffffffffffff6113c583610d81565b1685528782013588860152868201357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe183360301811261140457600080fd5b90910187810191903567ffffffffffffffff81111561142257600080fd5b80360383131561143157600080fd5b8188870152808287015260809150808383880137600086820183015295880195601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909401909301925090850190600101611342565b509098975050505050505050565b6000602082840312156114aa57600080fd5b505191905056fea2646970667358221220f4eb0f63e71c6d853cce8cdd833d5896512733e9c5642b5c584544c3b1647ca964736f6c63430008110033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100365760003560e01c806386b2162e1461003b578063f28613d91461008b575b600080fd5b6100627f000000000000000000000000fe87400c401c0cb61ec3a923a5d9873090e8dafc81565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b610062610099366004610246565b60006100da7f000000000000000000000000fe87400c401c0cb61ec3a923a5d9873090e8dafc73ffffffffffffffffffffffffffffffffffffffff166101b4565b6040517f132e9b7100000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff82169063132e9b719061012f908590600401610282565b600060405180830381600087803b15801561014957600080fd5b505af115801561015d573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff167f7c19a2785f0fdff7e3b0a72613aacd7c4b9e612f8c57d686fd360e161804e22a836040516101a79190610282565b60405180910390a2919050565b60006040516c5af43d3d93803e605757fd5bf3605152826044526f593da1005b3d3d3d3d363d3d37363d736030527f9e4ac34f21c619cefc926c8bd93b54bf5a39c7ab2127a895af1cc0691d7e3dff6020527060593d8160093d39f336602c57343d527f6000526071600f6000f0915080604052506000606052806102415763301164256000526004601cfd5b919050565b60006060828403121561025857600080fd5b50919050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461024157600080fd5b6060810173ffffffffffffffffffffffffffffffffffffffff806102a58561025e565b16835260208401358015158082146102bc57600080fd5b602085015250806102cf6040860161025e565b166040840152509291505056fea2646970667358221220f49ed6348b24682784af1f5529dc72d65e054d4638b337bdb0771d80a1f97aa764736f6c63430008110033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.