More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
329084428 | 14 hrs ago | 0.000005 ETH | ||||
328826173 | 32 hrs ago | 0.00000005 ETH | ||||
328703209 | 41 hrs ago | 0.00000344 ETH | ||||
328390184 | 2 days ago | 0.0000025 ETH | ||||
327361064 | 5 days ago | 0.00000102 ETH | ||||
326941437 | 6 days ago | 0.00000324 ETH | ||||
326852683 | 7 days ago | 0.00000188 ETH | ||||
326795465 | 7 days ago | 0.00000003 ETH | ||||
326429578 | 8 days ago | 0.00000006 ETH | ||||
326296919 | 8 days ago | 0.00000002 ETH | ||||
326085309 | 9 days ago | 0.00200497 ETH | ||||
326066178 | 9 days ago | 0.00001262 ETH | ||||
325590613 | 10 days ago | 0.00001195 ETH | ||||
323545752 | 16 days ago | 0.00000001 ETH | ||||
323218572 | 17 days ago | 0.00000167 ETH | ||||
322571420 | 19 days ago | 0.0000025 ETH | ||||
322192711 | 20 days ago | 0.00000391 ETH | ||||
320989254 | 24 days ago | 0.00000465 ETH | ||||
320099634 | 26 days ago | 0.0000025 ETH | ||||
319412432 | 28 days ago | 0.00000413 ETH | ||||
318966698 | 29 days ago | 0.00000147 ETH | ||||
318402604 | 31 days ago | 0.00000145 ETH | ||||
316016253 | 38 days ago | 0.00012089 ETH | ||||
315424666 | 40 days ago | 0.00000169 ETH | ||||
315382792 | 40 days ago | 0.00000244 ETH |
Loading...
Loading
Minimal Proxy Contract for 0xd94c0ce4f8eefa4ebf44bf6665688edeef213b33
Contract Name:
SplitWallet
Compiler Version
v0.8.4+commit.c7e474f2
Optimization Enabled:
Yes with 200 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.4; import {ISplitMain} from './interfaces/ISplitMain.sol'; import {ERC20} from '@rari-capital/solmate/src/tokens/ERC20.sol'; import {SafeTransferLib} from '@rari-capital/solmate/src/utils/SafeTransferLib.sol'; /** * ERRORS */ /// @notice Unauthorized sender error Unauthorized(); /** * @title SplitWallet * @author 0xSplits <[email protected]> * @notice The implementation logic for `SplitProxy`. * @dev `SplitProxy` handles `receive()` itself to avoid the gas cost with `DELEGATECALL`. */ contract SplitWallet { using SafeTransferLib for address; using SafeTransferLib for ERC20; /** * EVENTS */ /** @notice emitted after each successful ETH transfer to proxy * @param split Address of the split that received ETH * @param amount Amount of ETH received */ event ReceiveETH(address indexed split, uint256 amount); /** * STORAGE */ /** * STORAGE - CONSTANTS & IMMUTABLES */ /// @notice address of SplitMain for split distributions & EOA/SC withdrawals ISplitMain public immutable splitMain; /** * MODIFIERS */ /// @notice Reverts if the sender isn't SplitMain modifier onlySplitMain() { if (msg.sender != address(splitMain)) revert Unauthorized(); _; } /** * CONSTRUCTOR */ constructor() { splitMain = ISplitMain(msg.sender); } /** * FUNCTIONS - PUBLIC & EXTERNAL */ /** @notice Sends amount `amount` of ETH in proxy to SplitMain * @dev payable reduces gas cost; no vulnerability to accidentally lock * ETH introduced since fn call is restricted to SplitMain * @param amount Amount to send */ function sendETHToMain(uint256 amount) external payable onlySplitMain { address(splitMain).safeTransferETH(amount); } /** @notice Sends amount `amount` of ERC20 `token` in proxy to SplitMain * @dev payable reduces gas cost; no vulnerability to accidentally lock * ETH introduced since fn call is restricted to SplitMain * @param token Token to send * @param amount Amount to send */ function sendERC20ToMain(ERC20 token, uint256 amount) external payable onlySplitMain { token.safeTransfer(address(splitMain), amount); } }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity 0.8.4; import {ERC20} from '@rari-capital/solmate/src/tokens/ERC20.sol'; /** * @title ISplitMain * @author 0xSplits <[email protected]> */ interface ISplitMain { /** * FUNCTIONS */ function walletImplementation() external returns (address); function createSplit( address[] calldata accounts, uint32[] calldata percentAllocations, uint32 distributorFee, address controller ) external returns (address); function predictImmutableSplitAddress( address[] calldata accounts, uint32[] calldata percentAllocations, uint32 distributorFee ) external view returns (address); function updateSplit( address split, address[] calldata accounts, uint32[] calldata percentAllocations, uint32 distributorFee ) external; function transferControl(address split, address newController) external; function cancelControlTransfer(address split) external; function acceptControl(address split) external; function makeSplitImmutable(address split) external; function distributeETH( address split, address[] calldata accounts, uint32[] calldata percentAllocations, uint32 distributorFee, address distributorAddress ) external; function updateAndDistributeETH( address split, address[] calldata accounts, uint32[] calldata percentAllocations, uint32 distributorFee, address distributorAddress ) external; function distributeERC20( address split, ERC20 token, address[] calldata accounts, uint32[] calldata percentAllocations, uint32 distributorFee, address distributorAddress ) external; function updateAndDistributeERC20( address split, ERC20 token, address[] calldata accounts, uint32[] calldata percentAllocations, uint32 distributorFee, address distributorAddress ) external; function withdraw( address account, uint256 withdrawETH, ERC20[] calldata tokens ) external; /** * EVENTS */ /** @notice emitted after each successful split creation * @param split Address of the created split * @param accounts Ordered, unique list of addresses with ownership in the split * @param percentAllocations Percent allocations associated with each address * @param distributorFee Keeper fee paid by split to cover gas costs of distribution * @param controller Controlling address (0x0 if immutable) */ event CreateSplit( address indexed split, address[] accounts, uint32[] percentAllocations, uint32 distributorFee, address controller ); /** @notice emitted after each successful split update * @param split Address of the updated split * @param accounts Ordered, unique list of addresses with ownership in the split * @param percentAllocations Percent allocations associated with each address * @param distributorFee Keeper fee paid by split to cover gas costs of distribution */ event UpdateSplit( address indexed split, address[] accounts, uint32[] percentAllocations, uint32 distributorFee ); /** @notice emitted after each initiated split control transfer * @param split Address of the split control transfer was initiated for * @param newPotentialController Address of the split's new potential controller */ event InitiateControlTransfer( address indexed split, address indexed newPotentialController ); /** @notice emitted after each canceled split control transfer * @param split Address of the split control transfer was canceled for */ event CancelControlTransfer(address indexed split); /** @notice emitted after each successful split control transfer * @param split Address of the split control was transferred for * @param previousController Address of the split's previous controller * @param newController Address of the split's new controller */ event ControlTransfer( address indexed split, address indexed previousController, address indexed newController ); /** @notice emitted after each successful ETH balance split * @param split Address of the split that distributed its balance * @param amount Amount of ETH distributed * @param distributorAddress Address to credit distributor fee to */ event DistributeETH( address indexed split, uint256 amount, address indexed distributorAddress ); /** @notice emitted after each successful ERC20 balance split * @param split Address of the split that distributed its balance * @param token Address of ERC20 distributed * @param amount Amount of ERC20 distributed * @param distributorAddress Address to credit distributor fee to */ event DistributeERC20( address indexed split, ERC20 indexed token, uint256 amount, address indexed distributorAddress ); /** @notice emitted after each successful withdrawal * @param account Address that funds were withdrawn to * @param ethAmount Amount of ETH withdrawn * @param tokens Addresses of ERC20s withdrawn * @param tokenAmounts Amounts of corresponding ERC20s withdrawn */ event Withdrawal( address indexed account, uint256 ethAmount, ERC20[] tokens, uint256[] tokenAmounts ); }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Modern and gas efficient ERC20 + EIP-2612 implementation. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol) /// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol) /// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it. abstract contract ERC20 { /*/////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event Transfer(address indexed from, address indexed to, uint256 amount); event Approval(address indexed owner, address indexed spender, uint256 amount); /*/////////////////////////////////////////////////////////////// METADATA STORAGE //////////////////////////////////////////////////////////////*/ string public name; string public symbol; uint8 public immutable decimals; /*/////////////////////////////////////////////////////////////// ERC20 STORAGE //////////////////////////////////////////////////////////////*/ uint256 public totalSupply; mapping(address => uint256) public balanceOf; mapping(address => mapping(address => uint256)) public allowance; /*/////////////////////////////////////////////////////////////// EIP-2612 STORAGE //////////////////////////////////////////////////////////////*/ bytes32 public constant PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); uint256 internal immutable INITIAL_CHAIN_ID; bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR; mapping(address => uint256) public nonces; /*/////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor( string memory _name, string memory _symbol, uint8 _decimals ) { name = _name; symbol = _symbol; decimals = _decimals; INITIAL_CHAIN_ID = block.chainid; INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator(); } /*/////////////////////////////////////////////////////////////// ERC20 LOGIC //////////////////////////////////////////////////////////////*/ function approve(address spender, uint256 amount) public virtual returns (bool) { allowance[msg.sender][spender] = amount; emit Approval(msg.sender, spender, amount); return true; } function transfer(address to, uint256 amount) public virtual returns (bool) { balanceOf[msg.sender] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(msg.sender, to, amount); return true; } function transferFrom( address from, address to, uint256 amount ) public virtual returns (bool) { uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals. if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount; balanceOf[from] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(from, to, amount); return true; } /*/////////////////////////////////////////////////////////////// EIP-2612 LOGIC //////////////////////////////////////////////////////////////*/ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public virtual { require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED"); // Unchecked because the only math done is incrementing // the owner's nonce which cannot realistically overflow. unchecked { bytes32 digest = keccak256( abi.encodePacked( "\x19\x01", DOMAIN_SEPARATOR(), keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline)) ) ); address recoveredAddress = ecrecover(digest, v, r, s); require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER"); allowance[recoveredAddress][spender] = value; } emit Approval(owner, spender, value); } function DOMAIN_SEPARATOR() public view virtual returns (bytes32) { return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator(); } function computeDomainSeparator() internal view virtual returns (bytes32) { return keccak256( abi.encode( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256(bytes(name)), keccak256("1"), block.chainid, address(this) ) ); } /*/////////////////////////////////////////////////////////////// INTERNAL MINT/BURN LOGIC //////////////////////////////////////////////////////////////*/ function _mint(address to, uint256 amount) internal virtual { totalSupply += amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(address(0), to, amount); } function _burn(address from, uint256 amount) internal virtual { balanceOf[from] -= amount; // Cannot underflow because a user's balance // will never be larger than the total supply. unchecked { totalSupply -= amount; } emit Transfer(from, address(0), amount); } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; import {ERC20} from "../tokens/ERC20.sol"; /// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/SafeTransferLib.sol) /// @author Modified from Gnosis (https://github.com/gnosis/gp-v2-contracts/blob/main/src/contracts/libraries/GPv2SafeERC20.sol) /// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer. library SafeTransferLib { /*/////////////////////////////////////////////////////////////// ETH OPERATIONS //////////////////////////////////////////////////////////////*/ function safeTransferETH(address to, uint256 amount) internal { bool callStatus; assembly { // Transfer the ETH and store if it succeeded or not. callStatus := call(gas(), to, amount, 0, 0, 0, 0) } require(callStatus, "ETH_TRANSFER_FAILED"); } /*/////////////////////////////////////////////////////////////// ERC20 OPERATIONS //////////////////////////////////////////////////////////////*/ function safeTransferFrom( ERC20 token, address from, address to, uint256 amount ) internal { bool callStatus; assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata to memory piece by piece: mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000) // Begin with the function selector. mstore(add(freeMemoryPointer, 4), and(from, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the "from" argument. mstore(add(freeMemoryPointer, 36), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the "to" argument. mstore(add(freeMemoryPointer, 68), amount) // Finally append the "amount" argument. No mask as it's a full 32 byte value. // Call the token and store if it succeeded or not. // We use 100 because the calldata length is 4 + 32 * 3. callStatus := call(gas(), token, 0, freeMemoryPointer, 100, 0, 0) } require(didLastOptionalReturnCallSucceed(callStatus), "TRANSFER_FROM_FAILED"); } function safeTransfer( ERC20 token, address to, uint256 amount ) internal { bool callStatus; assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata to memory piece by piece: mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000) // Begin with the function selector. mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the "to" argument. mstore(add(freeMemoryPointer, 36), amount) // Finally append the "amount" argument. No mask as it's a full 32 byte value. // Call the token and store if it succeeded or not. // We use 68 because the calldata length is 4 + 32 * 2. callStatus := call(gas(), token, 0, freeMemoryPointer, 68, 0, 0) } require(didLastOptionalReturnCallSucceed(callStatus), "TRANSFER_FAILED"); } function safeApprove( ERC20 token, address to, uint256 amount ) internal { bool callStatus; assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata to memory piece by piece: mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000) // Begin with the function selector. mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the "to" argument. mstore(add(freeMemoryPointer, 36), amount) // Finally append the "amount" argument. No mask as it's a full 32 byte value. // Call the token and store if it succeeded or not. // We use 68 because the calldata length is 4 + 32 * 2. callStatus := call(gas(), token, 0, freeMemoryPointer, 68, 0, 0) } require(didLastOptionalReturnCallSucceed(callStatus), "APPROVE_FAILED"); } /*/////////////////////////////////////////////////////////////// INTERNAL HELPER LOGIC //////////////////////////////////////////////////////////////*/ function didLastOptionalReturnCallSucceed(bool callStatus) private pure returns (bool success) { assembly { // Get how many bytes the call returned. let returnDataSize := returndatasize() // If the call reverted: if iszero(callStatus) { // Copy the revert message into memory. returndatacopy(0, 0, returnDataSize) // Revert with the same message. revert(0, returnDataSize) } switch returnDataSize case 32 { // Copy the return data into memory. returndatacopy(0, 0, returnDataSize) // Set success to whether it returned true. success := iszero(iszero(mload(0))) } case 0 { // There was no return data. success := 1 } default { // It returned some malformed input. success := 0 } } } }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"split","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ReceiveETH","type":"event"},{"inputs":[{"internalType":"contract ERC20","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"sendERC20ToMain","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"sendETHToMain","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"splitMain","outputs":[{"internalType":"contract ISplitMain","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ARB | 62.01% | $0.999895 | 1,124.0206 | $1,123.9 | |
ARB | 28.00% | $1,787.52 | 0.2839 | $507.51 | |
ARB | 3.96% | $1 | 71.7774 | $71.78 | |
ARB | 1.42% | $0.999895 | 25.7151 | $25.71 | |
ARB | 0.66% | $0.328352 | 36.495 | $11.98 | |
ARB | 0.53% | $15.02 | 0.6434 | $9.66 | |
ARB | 0.39% | $2.72 | 2.6013 | $7.08 | |
ARB | 0.37% | $0.219287 | 30.9925 | $6.8 | |
ARB | 0.35% | $1,797.96 | 0.00351564 | $6.32 | |
ARB | 0.32% | $5.95 | 0.9688 | $5.76 | |
ARB | 0.27% | $1,875.04 | 0.00260906 | $4.89 | |
ARB | 0.12% | $0.999989 | 2.2512 | $2.25 | |
ARB | 0.12% | $6.93 | 0.3213 | $2.23 | |
ARB | 0.12% | $1,793.91 | 0.00116251 | $2.09 | |
ARB | 0.11% | $3.51 | 0.5903 | $2.07 | |
ARB | 0.10% | $0.999601 | 1.868 | $1.87 | |
ARB | 0.09% | $0.091193 | 18.6329 | $1.7 | |
ARB | 0.09% | $0.000024 | 66,747.7886 | $1.58 | |
ARB | 0.08% | $163.44 | 0.00848453 | $1.39 | |
ARB | 0.08% | $0.000009 | 152,114.7355 | $1.38 | |
ARB | 0.08% | $1 | 1.375 | $1.38 | |
ARB | 0.07% | $0.999853 | 1.25 | $1.25 | |
ARB | 0.06% | $0.007063 | 146.7963 | $1.04 | |
ARB | 0.05% | $1,965.59 | 0.00050576 | $0.9941 | |
ARB | 0.04% | $2,015.04 | 0.00033821 | $0.6815 | |
ARB | 0.04% | $14.63 | 0.0461 | $0.674 | |
ARB | 0.03% | $0.033104 | 18.9937 | $0.6287 | |
ARB | 0.03% | $0.000865 | 713.5836 | $0.6169 | |
ARB | 0.03% | $0.012909 | 46.8788 | $0.6051 | |
ARB | 0.03% | $383.71 | 0.00149235 | $0.5726 | |
ARB | 0.03% | $0.029449 | 17.5635 | $0.5172 | |
ARB | 0.02% | $1 | 0.4401 | $0.4405 | |
ARB | 0.02% | $0.564741 | 0.7089 | $0.4003 | |
ARB | 0.02% | $0.999589 | 0.4 | $0.3998 | |
ARB | 0.02% | $1 | 0.3985 | $0.3985 | |
ARB | 0.02% | $0.204359 | 1.8509 | $0.3782 | |
ARB | 0.02% | $0.003082 | 109.9706 | $0.3389 | |
ARB | 0.02% | <$0.000001 | 8,748,077.2441 | $0.3368 | |
ARB | 0.02% | $93,737 | 0.00000303 | $0.284 | |
ARB | 0.02% | $0.017929 | 15.628 | $0.2801 | |
ARB | 0.01% | $0.058948 | 4.4303 | $0.2611 | |
ARB | 0.01% | $0.112344 | 1.8689 | $0.2099 | |
ARB | <0.01% | $0.115561 | 1.375 | $0.1588 | |
ARB | <0.01% | <$0.000001 | 1,007,500 | $0.1296 | |
ARB | <0.01% | $0.99827 | 0.125 | $0.1247 | |
ARB | <0.01% | $1 | 0.117 | $0.1171 | |
ARB | <0.01% | $1.79 | 0.0651 | $0.1165 | |
ARB | <0.01% | $0.061399 | 1.897 | $0.1164 | |
ARB | <0.01% | $1.91 | 0.0605 | $0.1155 | |
ARB | <0.01% | $93,792 | 0.00000123 | $0.1153 | |
ARB | <0.01% | $0.202388 | 0.5455 | $0.1104 | |
ARB | <0.01% | $2,153.45 | 0.00005049 | $0.1087 | |
ARB | <0.01% | $286.93 | 0.00037528 | $0.1076 | |
ARB | <0.01% | $0.203714 | 0.5 | $0.1018 | |
BASE | 0.02% | $0.003845 | 100 | $0.3845 |
Loading...
Loading
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.