More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
View more zero value Internal Transactions in Advanced View mode
Loading...
Loading
Similar Match Source Code This contract matches the deployed Bytecode of the Source Code for Contract 0x930fa895...5c8225b4B The constructor portion of the code might be different and could alter the actual behaviour of the contract
Contract Name:
MerkleDistro
Compiler Version
v0.8.6+commit.11564f7e
Optimization Enabled:
Yes with 999999 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity)
/** *Submitted for verification at gnosisscan.io on 2022-08-05 */ // File: contracts/Interfaces/IDistro.sol pragma solidity =0.8.6; interface IDistro { /** * @dev Emitted when someone makes a claim of tokens */ event Claim(address indexed grantee, uint256 amount); /** * @dev Emitted when the DISTRIBUTOR allocate an amount to a grantee */ event Allocate( address indexed distributor, address indexed grantee, uint256 amount ); /** * @dev Emitted when the DEFAULT_ADMIN assign an amount to a DISTRIBUTOR */ event Assign( address indexed admin, address indexed distributor, uint256 amount ); /** * @dev Emitted when someone change their reception address */ event ChangeAddress(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when a new startTime is set */ event StartTimeChanged(uint256 newStartTime, uint256 newCliffTime); /** * @dev Returns the total amount of tokens will be streamed */ function totalTokens() external view returns (uint256); /** * Function that allows the DEFAULT_ADMIN_ROLE to assign set a new startTime if it hasn't started yet * @param newStartTime new startTime * * Emits a {StartTimeChanged} event. * */ function setStartTime(uint256 newStartTime) external; /** * Function that allows the DEFAULT_ADMIN_ROLE to assign tokens to an address who later can distribute them. * @dev It is required that the DISTRIBUTOR_ROLE is already held by the address to which an amount will be assigned * @param distributor the address, generally a smart contract, that will determine who gets how many tokens * @param amount Total amount of tokens to assign to that address for distributing */ function assign(address distributor, uint256 amount) external; /** * Function to claim tokens for a specific address. It uses the current timestamp */ function claim() external; /** * Function that allows to the distributor address to allocate some amount of tokens to a specific recipient * @dev Needs to be initialized: Nobody has the DEFAULT_ADMIN_ROLE and all available tokens have been assigned * @param recipient of token allocation * @param amount allocated amount * @param claim whether claim after allocate */ function allocate( address recipient, uint256 amount, bool claim ) external; /** * Function that allows to the distributor address to allocate some amounts of tokens to specific recipients * @dev Needs to be initialized: Nobody has the DEFAULT_ADMIN_ROLE and all available tokens have been assigned * @param recipients of token allocation * @param amounts allocated amount */ function allocateMany(address[] memory recipients, uint256[] memory amounts) external; function sendGIVbacks(address[] memory recipients, uint256[] memory amounts) external; /** * Function that allows a recipient to change its address * @dev The change can only be made to an address that has not previously received an allocation & * the distributor cannot change its address */ function changeAddress(address newAddress) external; /** * Function to get the current timestamp from the block */ function getTimestamp() external view returns (uint256); /** * Function to get the total unlocked tokes at some moment */ function globallyClaimableAt(uint256 timestamp) external view returns (uint256); /** * Function to get the unlocked tokes at some moment for a specific address */ function claimableAt(address recipient, uint256 timestamp) external view returns (uint256); /** * Function to get the unlocked tokens for a specific address. It uses the current timestamp */ function claimableNow(address recipient) external view returns (uint256); function cancelAllocation(address prevRecipient, address newRecipient) external; } // File: contracts/Interfaces/IMerkleTreeDistributor.sol pragma solidity =0.8.6; // Allows anyone to claim a token if they exist in a merkle root. interface IMerkleTreeDistributor { // Returns the merkle root of the merkle tree containing account balances available to claim. function merkleRoot() external view returns (bytes32); // Returns true if the index has been marked claimed. function isClaimed(uint256 index) external view returns (bool); // Claim the given amount of the token to the given address. Reverts if the inputs are invalid. function claim( uint256 index, uint256 amount, bytes32[] calldata merkleProof ) external; // Claim the given amount of the token to the given address to a specific recipient. Reverts if the inputs are invalid. function claimTo( uint256 index, address account, address recipient, uint256 amount, bytes32[] calldata merkleProof ) external; // This event is triggered whenever a call to #claim succeeds. event Claimed( uint256 index, address account, address recipient, uint256 amount ); } // File: openzeppelin-contracts-upgradable-v4/proxy/utils/Initializable.sol pragma solidity ^0.8.0; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { require(_initializing || !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } } // File: openzeppelin-contracts-upgradable-v4/utils/ContextUpgradeable.sol pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal initializer { __Context_init_unchained(); } function __Context_init_unchained() internal initializer { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } uint256[50] private __gap; } // File: openzeppelin-contracts-upgradable-v4/access/OwnableUpgradeable.sol pragma solidity ^0.8.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal initializer { __Context_init_unchained(); __Ownable_init_unchained(); } function __Ownable_init_unchained() internal initializer { _setOwner(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _setOwner(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _setOwner(newOwner); } function _setOwner(address newOwner) private { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } uint256[49] private __gap; } // File: openzeppelin-contracts-upgradable-v4/utils/cryptography/MerkleProofUpgradeable.sol pragma solidity ^0.8.0; /** * @dev These functions deal with verification of Merkle Trees proofs. * * The proofs can be generated using the JavaScript library * https://github.com/miguelmota/merkletreejs[merkletreejs]. * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled. * * See `test/utils/cryptography/MerkleProof.test.js` for some examples. */ library MerkleProofUpgradeable { /** * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree * defined by `root`. For this, a `proof` must be provided, containing * sibling hashes on the branch from the leaf to the root of the tree. Each * pair of leaves and each pair of pre-images are assumed to be sorted. */ function verify( bytes32[] memory proof, bytes32 root, bytes32 leaf ) internal pure returns (bool) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { bytes32 proofElement = proof[i]; if (computedHash <= proofElement) { // Hash(current computed hash + current element of the proof) computedHash = keccak256(abi.encodePacked(computedHash, proofElement)); } else { // Hash(current element of the proof + current computed hash) computedHash = keccak256(abi.encodePacked(proofElement, computedHash)); } } // Check if the computed hash (root) is equal to the provided root return computedHash == root; } } // File: contracts/Distributors/MerkleDistro.sol pragma solidity =0.8.6; // Based on: https://github.com/Uniswap/merkle-distributor/blob/master/contracts/MerkleDistributor.sol /* * Changelog: * * Added SPDX-License-Identifier * * Update to solidity ^0.8.0 * * Update openzeppelin imports * * Make it upgradable * * Add claimTo function that allows the owner to claim on behalf of someone * * Use tokenDistro.allocate instead of token transfer */ contract MerkleDistro is IMerkleTreeDistributor, Initializable, OwnableUpgradeable { IDistro public tokenDistro; bytes32 public override merkleRoot; // This is a packed array of booleans. mapping(uint256 => uint256) private claimedBitMap; function initialize(IDistro _tokenDistro, bytes32 _merkleRoot) public initializer { __Ownable_init(); tokenDistro = _tokenDistro; merkleRoot = _merkleRoot; } function isClaimed(uint256 index) public view override returns (bool) { uint256 claimedWordIndex = index / 256; uint256 claimedBitIndex = index % 256; uint256 claimedWord = claimedBitMap[claimedWordIndex]; uint256 mask = (1 << claimedBitIndex); return claimedWord & mask == mask; } function _setClaimed(uint256 index) private { uint256 claimedWordIndex = index / 256; uint256 claimedBitIndex = index % 256; claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex); } function claim( uint256 index, uint256 amount, bytes32[] calldata merkleProof ) external override { require(!isClaimed(index), "MerkleDistro::claim Drop already claimed."); // Verify the merkle proof. bytes32 node = keccak256(abi.encodePacked(index, msg.sender, amount)); require( MerkleProofUpgradeable.verify(merkleProof, merkleRoot, node), "MerkleDistro::claim Invalid proof." ); // Mark it claimed and allocate the tokens _setClaimed(index); tokenDistro.allocate(msg.sender, amount, true); emit Claimed(index, msg.sender, msg.sender, amount); } /** This function allows to the owner to claim tokens in behalf of another to a different address It is intended for those cases in which the owner knows that the recipient is no longer in possession of the account. */ function claimTo( uint256 index, address account, address recipient, uint256 amount, bytes32[] calldata merkleProof ) external override onlyOwner { require(!isClaimed(index), "MerkleDistro::claim Drop already claimed."); // Verify the merkle proof. bytes32 node = keccak256(abi.encodePacked(index, account, amount)); require( MerkleProofUpgradeable.verify(merkleProof, merkleRoot, node), "MerkleDistro::claim Invalid proof." ); // Mark it claimed and allocate the tokens _setClaimed(index); tokenDistro.allocate(recipient, amount, true); emit Claimed(index, account, recipient, amount); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"},{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Claimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"claimTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IDistro","name":"_tokenDistro","type":"address"},{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"isClaimed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tokenDistro","outputs":[{"internalType":"contract IDistro","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100a35760003560e01c80639e34070f11610076578063be13f47c1161005b578063be13f47c14610156578063ca8af4d414610169578063f2fde38b1461018957600080fd5b80639e34070f14610120578063ae0b51df1461014357600080fd5b8063054d5e2a146100a85780632eb4a7ab146100bd578063715018a6146100d95780638da5cb5b146100e1575b600080fd5b6100bb6100b6366004611030565b61019c565b005b6100c660665481565b6040519081526020015b60405180910390f35b6100bb6104e6565b60335473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100d0565b61013361012e366004611017565b610573565b60405190151581526020016100d0565b6100bb6101513660046110ac565b6105b4565b6100bb610164366004610feb565b61085c565b6065546100fb9073ffffffffffffffffffffffffffffffffffffffff1681565b6100bb610197366004610fc7565b6109c1565b60335473ffffffffffffffffffffffffffffffffffffffff163314610222576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b61022b86610573565b156102b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4d65726b6c6544697374726f3a3a636c61696d2044726f7020616c726561647960448201527f20636c61696d65642e00000000000000000000000000000000000000000000006064820152608401610219565b60408051602081018890527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606088901b169181019190915260548101849052600090607401604051602081830303815290604052805190602001209050610357838380806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506066549150849050610af1565b6103e3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4d65726b6c6544697374726f3a3a636c61696d20496e76616c69642070726f6f60448201527f662e0000000000000000000000000000000000000000000000000000000000006064820152608401610219565b6103ec87610ba0565b6065546040517f6ca163de00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8781166004830152602482018790526001604483015290911690636ca163de90606401600060405180830381600087803b15801561046757600080fd5b505af115801561047b573d6000803e3d6000fd5b5050604080518a815273ffffffffffffffffffffffffffffffffffffffff8a811660208301528916818301526060810188905290517fce3bcb6e219596cf26007ffdfaae8953bc3f76e3f36c0a79b23e28020da3222e9350908190036080019150a150505050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610567576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610219565b6105716000610bde565b565b600080610582610100846110ff565b9050600061059261010085611173565b60009283526067602052604090922054600190921b9182169091149392505050565b6105bd84610573565b1561064a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4d65726b6c6544697374726f3a3a636c61696d2044726f7020616c726561647960448201527f20636c61696d65642e00000000000000000000000000000000000000000000006064820152608401610219565b60408051602081018690527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003360601b1691810191909152605481018490526000906074016040516020818303038152906040528051906020012090506106e8838380806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506066549150849050610af1565b610774576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4d65726b6c6544697374726f3a3a636c61696d20496e76616c69642070726f6f60448201527f662e0000000000000000000000000000000000000000000000000000000000006064820152608401610219565b61077d85610ba0565b6065546040517f6ca163de000000000000000000000000000000000000000000000000000000008152336004820152602481018690526001604482015273ffffffffffffffffffffffffffffffffffffffff90911690636ca163de90606401600060405180830381600087803b1580156107f657600080fd5b505af115801561080a573d6000803e3d6000fd5b5050604080518881523360208201819052818301526060810188905290517fce3bcb6e219596cf26007ffdfaae8953bc3f76e3f36c0a79b23e28020da3222e9350908190036080019150a15050505050565b600054610100900460ff1680610875575060005460ff16155b610901576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610219565b600054610100900460ff1615801561094057600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b610948610c55565b606580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8516179055606682905580156109bc57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610a42576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610219565b73ffffffffffffffffffffffffffffffffffffffff8116610ae5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610219565b610aee81610bde565b50565b600081815b8551811015610b95576000868281518110610b1357610b136111b6565b60200260200101519050808311610b55576040805160208101859052908101829052606001604051602081830303815290604052805190602001209250610b82565b60408051602081018390529081018490526060016040516020818303038152906040528051906020012092505b5080610b8d81611113565b915050610af6565b509092149392505050565b6000610bae610100836110ff565b90506000610bbe61010084611173565b6000928352606760205260409092208054600190931b9092179091555050565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff1680610c6e575060005460ff16155b610cfa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610219565b600054610100900460ff16158015610d3957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b610d41610d7a565b610d49610e8e565b8015610aee57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905550565b600054610100900460ff1680610d93575060005460ff16155b610e1f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610219565b600054610100900460ff16158015610d4957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790558015610aee57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905550565b600054610100900460ff1680610ea7575060005460ff16155b610f33576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610219565b600054610100900460ff16158015610f7257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b610d4933610bde565b60008083601f840112610f8d57600080fd5b50813567ffffffffffffffff811115610fa557600080fd5b6020830191508360208260051b8501011115610fc057600080fd5b9250929050565b600060208284031215610fd957600080fd5b8135610fe4816111e5565b9392505050565b60008060408385031215610ffe57600080fd5b8235611009816111e5565b946020939093013593505050565b60006020828403121561102957600080fd5b5035919050565b60008060008060008060a0878903121561104957600080fd5b86359550602087013561105b816111e5565b9450604087013561106b816111e5565b935060608701359250608087013567ffffffffffffffff81111561108e57600080fd5b61109a89828a01610f7b565b979a9699509497509295939492505050565b600080600080606085870312156110c257600080fd5b8435935060208501359250604085013567ffffffffffffffff8111156110e757600080fd5b6110f387828801610f7b565b95989497509550505050565b60008261110e5761110e611187565b500490565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561116c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b60008261118257611182611187565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff81168114610aee57600080fdfea264697066735822122024ee3a6a17d1c7af4ee3ef9e43f73287262f1e5709de13a2660fe315589b469864736f6c63430008060033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 100.00% | $0.312006 | 34,679,546.5393 | $10,820,226.6 |
Loading...
Loading
Loading...
Loading
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.