ETH Price: $3,592.74 (+3.75%)
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Transaction Hash
Method
Block
From
To
Claim176601672023-07-10 2:01:23544 days ago1688954483IN
0x209DF5E7...C9760a596
0 ETH0.0012868942.2211199
Claim172323302023-05-10 20:21:11604 days ago1683750071IN
0x209DF5E7...C9760a596
0 ETH0.00948942131.70432711
Claim171555782023-04-30 1:24:23615 days ago1682817863IN
0x209DF5E7...C9760a596
0 ETH0.0015796328.74831894
Claim171377102023-04-27 13:07:59617 days ago1682600879IN
0x209DF5E7...C9760a596
0 ETH0.0027712538.43994322
Claim171207762023-04-25 4:02:47620 days ago1682395367IN
0x209DF5E7...C9760a596
0 ETH0.0023646932.79965506
Claim171186112023-04-24 20:46:47620 days ago1682369207IN
0x209DF5E7...C9760a596
0 ETH0.0023398342.5618611
Claim170676712023-04-17 16:27:11627 days ago1681748831IN
0x209DF5E7...C9760a596
0 ETH0.0019066434.70358375
Claim170479052023-04-14 21:02:47630 days ago1681506167IN
0x209DF5E7...C9760a596
0 ETH0.0018178425.22303098
Claim170064462023-04-08 21:53:35636 days ago1680990815IN
0x209DF5E7...C9760a596
0 ETH0.0013196818.52892788
Claim169928712023-04-06 23:43:23638 days ago1680824603IN
0x209DF5E7...C9760a596
0 ETH0.0014752720.45441474
Claim169807862023-04-05 6:21:59640 days ago1680675719IN
0x209DF5E7...C9760a596
0 ETH0.0015675628.95344174
Claim169562692023-04-01 19:06:47643 days ago1680376007IN
0x209DF5E7...C9760a596
0 ETH0.0013830319.19892973
Claim168867542023-03-23 0:41:23653 days ago1679532083IN
0x209DF5E7...C9760a596
0 ETH0.0007854614.28551336
Claim168695702023-03-20 14:46:23655 days ago1679323583IN
0x209DF5E7...C9760a596
0 ETH0.0017499824.27797505
Claim168692582023-03-20 13:43:35655 days ago1679319815IN
0x209DF5E7...C9760a596
0 ETH0.0018354725.48813645
Claim168062432023-03-11 17:12:35664 days ago1678554755IN
0x209DF5E7...C9760a596
0 ETH0.0038487554.03959098
Claim167952842023-03-10 4:09:11666 days ago1678421351IN
0x209DF5E7...C9760a596
0 ETH0.0013657424.83841901
Claim167843672023-03-08 15:15:59667 days ago1678288559IN
0x209DF5E7...C9760a596
0 ETH0.002595736
Claim167733212023-03-07 1:59:59669 days ago1678154399IN
0x209DF5E7...C9760a596
0 ETH0.0015340927.92453529
Claim167690732023-03-06 11:40:23670 days ago1678102823IN
0x209DF5E7...C9760a596
0 ETH0.00160922.32276531
Claim167610502023-03-05 8:35:47671 days ago1678005347IN
0x209DF5E7...C9760a596
0 ETH0.0012167922.1336117
Claim167174582023-02-27 5:29:47677 days ago1677475787IN
0x209DF5E7...C9760a596
0 ETH0.0008811716.04038556
Claim167049402023-02-25 11:15:23679 days ago1677323723IN
0x209DF5E7...C9760a596
0 ETH0.0010442219
Claim166199182023-02-13 12:44:23690 days ago1676292263IN
0x209DF5E7...C9760a596
0 ETH0.0014126719.60169835
Claim166183282023-02-13 7:24:59691 days ago1676273099IN
0x209DF5E7...C9760a596
0 ETH0.0011032915.2994658
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
MerkleDistributorSimple

Compiler Version
v0.7.3+commit.9bfce1f6

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, Unlicense license
File 1 of 4 : MerkleDistributorSimple.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.7.0;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/cryptography/MerkleProof.sol";
import "./interfaces/IMerkleDistributor.sol";

contract MerkleDistributorSimple is IMerkleDistributor {
    address public immutable override token;
    bytes32 public immutable override merkleRoot;

    // This is a packed array of booleans.
    mapping(uint256 => uint256) private claimedBitMap;

    constructor(address token_, bytes32 merkleRoot_) public {
        token = token_;
        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, address account, uint256 amount, bytes32[] calldata merkleProof) external override {
        require(!isClaimed(index), 'MerkleDistributor: Drop already claimed.');

        // Verify the merkle proof.
        bytes32 node = keccak256(abi.encodePacked(index, account, amount));
        require(MerkleProof.verify(merkleProof, merkleRoot, node), 'MerkleDistributor: Invalid proof.');

        // Mark it claimed and send the token.
        _setClaimed(index);
        require(IERC20(token).transfer(account, amount), 'MerkleDistributor: Transfer failed.');

        emit Claimed(index, account, amount);
    }
}

File 2 of 4 : MerkleProof.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev These functions deal with verification of Merkle trees (hash trees),
 */
library MerkleProof {
    /**
     * @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 3 of 4 : IERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

File 4 of 4 : IMerkleDistributor.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;

// Allows anyone to claim a token if they exist in a merkle root.
interface IMerkleDistributor {
  // Returns the address of the token distributed by this contract.
  function token() external view returns (address);

  // 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,
    address account,
    uint256 amount,
    bytes32[] calldata merkleProof
  ) external;

  // This event is triggered whenever a call to #claim succeeds.
  event Claimed(uint256 index, address account, uint256 amount);
}

Settings
{
  "evmVersion": "istanbul",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs",
    "useLiteralContent": true
  },
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "remappings": [],
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"token_","type":"address"},{"internalType":"bytes32","name":"merkleRoot_","type":"bytes32"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"},{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Claimed","type":"event"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"address","name":"account","type":"address"},{"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"}],"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":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

60c060405234801561001057600080fd5b506040516106123803806106128339818101604052604081101561003357600080fd5b508051602090910151606082901b6001600160601b03191660805260a08190526001600160a01b039091169061058c6100866000398061020f52806103ae52508061028052806103f8525061058c6000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c80632e7ba6ef146100515780632eb4a7ab146100df5780639e34070f146100f9578063fc0c546a1461012a575b600080fd5b6100dd6004803603608081101561006757600080fd5b8135916001600160a01b03602082013516916040820135919081019060808101606082013564010000000081111561009e57600080fd5b8201836020820111156100b057600080fd5b803590602001918460208302840111640100000000831117156100d257600080fd5b50909250905061014e565b005b6100e76103ac565b60408051918252519081900360200190f35b6101166004803603602081101561010f57600080fd5b50356103d0565b604080519115158252519081900360200190f35b6101326103f6565b604080516001600160a01b039092168252519081900360200190f35b610157856103d0565b156101935760405162461bcd60e51b81526004018080602001828103825260288152602001806104eb6028913960400191505060405180910390fd5b600085858560405160200180848152602001836001600160a01b031660601b8152601401828152602001935050505060405160208183030381529060405280519060200120905061023a8383808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152507f0000000000000000000000000000000000000000000000000000000000000000925085915061041a9050565b6102755760405162461bcd60e51b81526004018080602001828103825260218152602001806105136021913960400191505060405180910390fd5b61027e866104c3565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb86866040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156102f557600080fd5b505af1158015610309573d6000803e3d6000fd5b505050506040513d602081101561031f57600080fd5b505161035c5760405162461bcd60e51b81526004018080602001828103825260238152602001806105346023913960400191505060405180910390fd5b604080518781526001600160a01b038716602082015280820186905290517f4ec90e965519d92681267467f775ada5bd214aa92c0dc93d90a5e880ce9ed0269181900360600190a1505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6101008104600090815260208190526040902054600160ff9092169190911b9081161490565b7f000000000000000000000000000000000000000000000000000000000000000081565b600081815b85518110156104b857600086828151811061043657fe5b6020026020010151905080831161047d57828160405160200180838152602001828152602001925050506040516020818303038152906040528051906020012092506104af565b808360405160200180838152602001828152602001925050506040516020818303038152906040528051906020012092505b5060010161041f565b509092149392505050565b610100810460009081526020819052604090208054600160ff9093169290921b909117905556fe4d65726b6c654469737472696275746f723a2044726f7020616c726561647920636c61696d65642e4d65726b6c654469737472696275746f723a20496e76616c69642070726f6f662e4d65726b6c654469737472696275746f723a205472616e73666572206661696c65642ea2646970667358221220b3fcfa8d4f7d2e68a79188f248337b59c1f9265bb8921b91ce48d6e7416cbd6a64736f6c634300070300330000000000000000000000000391d2021f89dc339f60fff84546ea23e337750fb974440d5d7609bc35f45ecab90854c234bbc8532f2f54c7e8dc0da411581cf9

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80632e7ba6ef146100515780632eb4a7ab146100df5780639e34070f146100f9578063fc0c546a1461012a575b600080fd5b6100dd6004803603608081101561006757600080fd5b8135916001600160a01b03602082013516916040820135919081019060808101606082013564010000000081111561009e57600080fd5b8201836020820111156100b057600080fd5b803590602001918460208302840111640100000000831117156100d257600080fd5b50909250905061014e565b005b6100e76103ac565b60408051918252519081900360200190f35b6101166004803603602081101561010f57600080fd5b50356103d0565b604080519115158252519081900360200190f35b6101326103f6565b604080516001600160a01b039092168252519081900360200190f35b610157856103d0565b156101935760405162461bcd60e51b81526004018080602001828103825260288152602001806104eb6028913960400191505060405180910390fd5b600085858560405160200180848152602001836001600160a01b031660601b8152601401828152602001935050505060405160208183030381529060405280519060200120905061023a8383808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152507fb974440d5d7609bc35f45ecab90854c234bbc8532f2f54c7e8dc0da411581cf9925085915061041a9050565b6102755760405162461bcd60e51b81526004018080602001828103825260218152602001806105136021913960400191505060405180910390fd5b61027e866104c3565b7f0000000000000000000000000391d2021f89dc339f60fff84546ea23e337750f6001600160a01b031663a9059cbb86866040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156102f557600080fd5b505af1158015610309573d6000803e3d6000fd5b505050506040513d602081101561031f57600080fd5b505161035c5760405162461bcd60e51b81526004018080602001828103825260238152602001806105346023913960400191505060405180910390fd5b604080518781526001600160a01b038716602082015280820186905290517f4ec90e965519d92681267467f775ada5bd214aa92c0dc93d90a5e880ce9ed0269181900360600190a1505050505050565b7fb974440d5d7609bc35f45ecab90854c234bbc8532f2f54c7e8dc0da411581cf981565b6101008104600090815260208190526040902054600160ff9092169190911b9081161490565b7f0000000000000000000000000391d2021f89dc339f60fff84546ea23e337750f81565b600081815b85518110156104b857600086828151811061043657fe5b6020026020010151905080831161047d57828160405160200180838152602001828152602001925050506040516020818303038152906040528051906020012092506104af565b808360405160200180838152602001828152602001925050506040516020818303038152906040528051906020012092505b5060010161041f565b509092149392505050565b610100810460009081526020819052604090208054600160ff9093169290921b909117905556fe4d65726b6c654469737472696275746f723a2044726f7020616c726561647920636c61696d65642e4d65726b6c654469737472696275746f723a20496e76616c69642070726f6f662e4d65726b6c654469737472696275746f723a205472616e73666572206661696c65642ea2646970667358221220b3fcfa8d4f7d2e68a79188f248337b59c1f9265bb8921b91ce48d6e7416cbd6a64736f6c63430007030033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000000391d2021f89dc339f60fff84546ea23e337750fb974440d5d7609bc35f45ecab90854c234bbc8532f2f54c7e8dc0da411581cf9

-----Decoded View---------------
Arg [0] : token_ (address): 0x0391D2021f89DC339F60Fff84546EA23E337750f
Arg [1] : merkleRoot_ (bytes32): 0xb974440d5d7609bc35f45ecab90854c234bbc8532f2f54c7e8dc0da411581cf9

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000000391d2021f89dc339f60fff84546ea23e337750f
Arg [1] : b974440d5d7609bc35f45ecab90854c234bbc8532f2f54c7e8dc0da411581cf9


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
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.