Contract 0x2787cc20e5ecb4bf1bfb79eae284201027683179 10

 

Contract Overview

Balance:
0 ETH

EtherValue:
$0.00

Token:
Txn Hash Method
Block
From
To
Value
0x18369a1d49e0321eed358b8030a331d9de63ed630c7f6a28e0af2d71efd3bab9Claim1101234262023-09-27 20:13:4917 hrs 18 mins ago0x246100ec9dfcf22194316a187b38905906539b41 IN  0x2787cc20e5ecb4bf1bfb79eae2842010276831790 ETH0.0000452284730.051603466
0x4440f90cfa3ed8ae38beb58b4cbe0acf71d2f423dd95ee1889c9c06db577e2d6Set Merkle Root ...1101233752023-09-27 20:12:0717 hrs 19 mins ago0x246100ec9dfcf22194316a187b38905906539b41 IN  0x2787cc20e5ecb4bf1bfb79eae2842010276831790 ETH0.0000305262680.046018728
0x7c952a60fd4a2ccd8f281c7c5c983b2c5a05a1073d9855a340bcaf164e3d1356Set Merkle Root ...1100872452023-09-27 0:07:471 day 13 hrs ago0x246100ec9dfcf22194316a187b38905906539b41 IN  0x2787cc20e5ecb4bf1bfb79eae2842010276831790 ETH0.000016434980.052555194
0x4294b9295446e4bdc52741a2193b42e4bf24b7a5b099f6484acfe67d05e842caSet Merkle Root ...1100870532023-09-27 0:01:231 day 13 hrs ago0x246100ec9dfcf22194316a187b38905906539b41 IN  0x2787cc20e5ecb4bf1bfb79eae2842010276831790 ETH0.0000894790241.55962788
0xf5d26e59b8d04ac508c7d8e164fc1572ff68c9d9637394830d35e75f5f1f88f7Set Merkle Root ...1097848872023-09-20 0:09:118 days 13 hrs ago0x246100ec9dfcf22194316a187b38905906539b41 IN  0x2787cc20e5ecb4bf1bfb79eae2842010276831790 ETH0.000091243561.54533802
0xb4d06b9e6432534a0a555c0e2e3688d94a1f776a84f72374f8c62925e8f55d0eSet Merkle Root ...1094822442023-09-13 0:01:0515 days 13 hrs ago0x246100ec9dfcf22194316a187b38905906539b41 IN  0x2787cc20e5ecb4bf1bfb79eae2842010276831790 ETH0.0000856259811.500000058
0x904a931c7a0e55f0baa7061b11c8909825db6d88509a5475ddac2a9395cfbed8Set Merkle Root ...1091816942023-09-06 1:02:4522 days 12 hrs ago0x246100ec9dfcf22194316a187b38905906539b41 IN  0x2787cc20e5ecb4bf1bfb79eae2842010276831790 ETH0.0001246722271.500000054
0xe75039741d4525bb8f4908789aa6fdced874607f3d8c6da37e7c77a810ad381bSet Merkle Root ...1088774492023-08-30 0:01:1529 days 13 hrs ago0x246100ec9dfcf22194316a187b38905906539b41 IN  0x2787cc20e5ecb4bf1bfb79eae2842010276831790 ETH0.0001031603571.500000058
0xcd89188fa9ec5db390b4a9214a8ac1a3b4a04d98ec9f7189093ef27d52a9ede3Set Merkle Root ...1085750512023-08-23 0:01:1936 days 13 hrs ago0x246100ec9dfcf22194316a187b38905906539b41 IN  0x2787cc20e5ecb4bf1bfb79eae2842010276831790 ETH0.0001039149081.500000052
0x389a41b5b8279d66668c0ce3d758e2da6a75c1f96bede310d487a2b7a46a8cc9Set Merkle Root ...1082741782023-08-16 0:52:1343 days 12 hrs ago0x246100ec9dfcf22194316a187b38905906539b41 IN  0x2787cc20e5ecb4bf1bfb79eae2842010276831790 ETH0.0001026699121.500000067
0xba83c3831d0041bf9dce24e83c82047c4e80488bfba8a8ae9247f307068bf5c5Set Merkle Root ...1079702512023-08-09 0:01:1950 days 13 hrs ago0x246100ec9dfcf22194316a187b38905906539b41 IN  0x2787cc20e5ecb4bf1bfb79eae2842010276831790 ETH0.0001067486651.500000057
0x91bac0ff17d32b7d755c863e6cee2cf04490335d3dd9c75b20bf6b78871628c0Set Merkle Root ...1076678512023-08-02 0:01:1957 days 13 hrs ago0x246100ec9dfcf22194316a187b38905906539b41 IN  0x2787cc20e5ecb4bf1bfb79eae2842010276831790 ETH0.0001090975521.500008525
0xc88c08b91a6578aef8ae47a28b39cba55faec4546056306196da0b012ffa456bSet Merkle Root ...1073654502023-07-26 0:01:1764 days 13 hrs ago0x246100ec9dfcf22194316a187b38905906539b41 IN  0x2787cc20e5ecb4bf1bfb79eae2842010276831790 ETH0.0001133577221.500000056
0xbe5a5d10f942ad68951c71d4b4f756aeda3719bda8578e0a639af0f8d352a793Set Merkle Root ...1070630452023-07-19 0:01:0771 days 13 hrs ago0x246100ec9dfcf22194316a187b38905906539b41 IN  0x2787cc20e5ecb4bf1bfb79eae2842010276831790 ETH0.0001060065931.500000058
0x36a626c79a1c3e6eb13e747debc8ea2a91f06cd1f6ddc400d554fdf98be9d994Set Merkle Root ...1067606462023-07-12 0:01:0978 days 13 hrs ago0x246100ec9dfcf22194316a187b38905906539b41 IN  0x2787cc20e5ecb4bf1bfb79eae2842010276831790 ETH0.0000958758111.500000056
0xa10af6b5b952763187fd1b34c7c3506b5d242f2d123cb07e3feecb5f1db19567Set Merkle Root ...1064582462023-07-05 0:01:0985 days 13 hrs ago0x246100ec9dfcf22194316a187b38905906539b41 IN  0x2787cc20e5ecb4bf1bfb79eae2842010276831790 ETH0.0001473244921.500000051
0x73495c4f95691a94bd0c6063f8b164cb1db87e2c9afb292a21acf3122f93ac30Set Merkle Root ...1061558462023-06-28 0:01:0992 days 13 hrs ago0x246100ec9dfcf22194316a187b38905906539b41 IN  0x2787cc20e5ecb4bf1bfb79eae2842010276831790 ETH0.000092360841.500000068
0xe6067a2577a5b305d87b67c5b4e9e5bd22eceab0336958607efd9d98aba5509aSet Merkle Root ...1058539092023-06-21 0:16:3599 days 13 hrs ago0x246100ec9dfcf22194316a187b38905906539b41 IN  0x2787cc20e5ecb4bf1bfb79eae2842010276831790 ETH0.000097808941.500000122
0x07e3851395663a8de59e0f3184c5ea8def6573024abf6c9b90ca1d07d3f628eeSet Merkle Root ...1055510502023-06-14 0:01:17106 days 13 hrs ago0x246100ec9dfcf22194316a187b38905906539b41 IN  0x2787cc20e5ecb4bf1bfb79eae2842010276831790 ETH0.0000969869931.50000008
0x2997214ebcd828ce493b00adf1f5c065bf10347afa0257cafcab0f87c896ffe7Set Merkle Root ...1052486492023-06-07 0:01:15113 days 13 hrs ago0x246100ec9dfcf22194316a187b38905906539b41 IN  0x2787cc20e5ecb4bf1bfb79eae2842010276831790 ETH0.0001040554961.500000061
0x84159219b5762b52be5bf323e4a73b53f9d6516fd3f7244834a72f1b10bc83eeSet Merkle Root ...1030613752023-05-31 0:01:14120 days 13 hrs ago0x246100ec9dfcf22194316a187b38905906539b41 IN  0x2787cc20e5ecb4bf1bfb79eae2842010276831790 ETH0.0001594647040.001
0xaedccca0af059406fd3c12c220aed8548ba4b8fa8d7c17adfe5b8c4625088290Set Merkle Root ...1008845712023-05-24 0:01:02127 days 13 hrs ago0x246100ec9dfcf22194316a187b38905906539b41 IN  0x2787cc20e5ecb4bf1bfb79eae2842010276831790 ETH0.0001645474740.001
0x891813098936e549abe3a06c6c307a1420920671f661273aad1732e6a330ec1eSet Merkle Root ...988982792023-05-17 0:16:39134 days 13 hrs ago0x246100ec9dfcf22194316a187b38905906539b41 IN  0x2787cc20e5ecb4bf1bfb79eae2842010276831790 ETH0.0001801674790.001048154
0x6b866585b1f7009abbd8a163d75ade3c00a1df6f658fe178ac5cb3bc9ba12833Set Merkle Root ...971476772023-05-10 0:01:13141 days 13 hrs ago0x246100ec9dfcf22194316a187b38905906539b41 IN  0x2787cc20e5ecb4bf1bfb79eae2842010276831790 ETH0.0004389877110.001
0x7bf057b251080e485e369157f7d0ee676d7e6832c4e780b733566f9758046c72Set Merkle Root ...959345132023-05-03 0:01:15148 days 13 hrs ago0x246100ec9dfcf22194316a187b38905906539b41 IN  0x2787cc20e5ecb4bf1bfb79eae2842010276831790 ETH0.0003929889120.001
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0xcb5ca4b9f520c4fda8cb9045aa9d5fb2a05a8545e2b607ba2f20644fcdf2bcbc1075264842023-07-29 17:29:0560 days 20 hrs ago 0x6fd879830d9b1ee5d4f9ef12f8d5dee916bebd0b 0x2787cc20e5ecb4bf1bfb79eae2842010276831790 ETH
0x22fd5438204e789dadbec95a8b9eac10a23e64f1b2dee9c263fd8506ba626e181074726322023-07-28 11:34:0162 days 1 hr ago 0x6fd879830d9b1ee5d4f9ef12f8d5dee916bebd0b 0x2787cc20e5ecb4bf1bfb79eae2842010276831790 ETH
0x778a33f6fc5f9be54101375ac5d9ca9955ebfd663415220e20af0251a17bfeeb1074510492023-07-27 23:34:3562 days 13 hrs ago 0x2787cc20e5ecb4bf1bfb79eae284201027683179 0x1066a8eb3d90af0ad3f89839b974658577e75be20 ETH
0x778a33f6fc5f9be54101375ac5d9ca9955ebfd663415220e20af0251a17bfeeb1074510492023-07-27 23:34:3562 days 13 hrs ago 0x2787cc20e5ecb4bf1bfb79eae284201027683179 Kwenta: KWENTA Token0 ETH
0x778a33f6fc5f9be54101375ac5d9ca9955ebfd663415220e20af0251a17bfeeb1074510492023-07-27 23:34:3562 days 13 hrs ago 0x6fd879830d9b1ee5d4f9ef12f8d5dee916bebd0b 0x2787cc20e5ecb4bf1bfb79eae2842010276831790 ETH
0x90ffae7202137891fb76d755f0f60c55e5beffe4e4439738046424c7a882e1be1074423332023-07-27 18:44:0362 days 18 hrs ago 0x2787cc20e5ecb4bf1bfb79eae284201027683179 0x1066a8eb3d90af0ad3f89839b974658577e75be20 ETH
0x90ffae7202137891fb76d755f0f60c55e5beffe4e4439738046424c7a882e1be1074423332023-07-27 18:44:0362 days 18 hrs ago 0x2787cc20e5ecb4bf1bfb79eae284201027683179 Kwenta: KWENTA Token0 ETH
0x90ffae7202137891fb76d755f0f60c55e5beffe4e4439738046424c7a882e1be1074423332023-07-27 18:44:0362 days 18 hrs ago 0x2787cc20e5ecb4bf1bfb79eae284201027683179 0x1066a8eb3d90af0ad3f89839b974658577e75be20 ETH
0x90ffae7202137891fb76d755f0f60c55e5beffe4e4439738046424c7a882e1be1074423332023-07-27 18:44:0362 days 18 hrs ago 0x2787cc20e5ecb4bf1bfb79eae284201027683179 Kwenta: KWENTA Token0 ETH
0x90ffae7202137891fb76d755f0f60c55e5beffe4e4439738046424c7a882e1be1074423332023-07-27 18:44:0362 days 18 hrs ago 0x6fd879830d9b1ee5d4f9ef12f8d5dee916bebd0b 0x2787cc20e5ecb4bf1bfb79eae2842010276831790 ETH
0xe52ef4bbdfdb17ee044b8c176cf6fb134fb9b0d08c01a8f739cbc142c26035911074347422023-07-27 14:31:0162 days 23 hrs ago 0x2787cc20e5ecb4bf1bfb79eae284201027683179 0x1066a8eb3d90af0ad3f89839b974658577e75be20 ETH
0xe52ef4bbdfdb17ee044b8c176cf6fb134fb9b0d08c01a8f739cbc142c26035911074347422023-07-27 14:31:0162 days 23 hrs ago 0x2787cc20e5ecb4bf1bfb79eae284201027683179 Kwenta: KWENTA Token0 ETH
0xe52ef4bbdfdb17ee044b8c176cf6fb134fb9b0d08c01a8f739cbc142c26035911074347422023-07-27 14:31:0162 days 23 hrs ago 0x6fd879830d9b1ee5d4f9ef12f8d5dee916bebd0b 0x2787cc20e5ecb4bf1bfb79eae2842010276831790 ETH
0x6d251b4855698f34719309e66a37b95e10763cf1652e80d338436f338666e0431074256382023-07-27 9:27:3363 days 4 hrs ago 0x6fd879830d9b1ee5d4f9ef12f8d5dee916bebd0b 0x2787cc20e5ecb4bf1bfb79eae2842010276831790 ETH
0xc3734f776d28bb094ac130aaa997af17e04f0e59b8847ecf11cbabec007080bd1074248002023-07-27 8:59:3763 days 4 hrs ago 0x2787cc20e5ecb4bf1bfb79eae284201027683179 0x1066a8eb3d90af0ad3f89839b974658577e75be20 ETH
0xc3734f776d28bb094ac130aaa997af17e04f0e59b8847ecf11cbabec007080bd1074248002023-07-27 8:59:3763 days 4 hrs ago 0x2787cc20e5ecb4bf1bfb79eae284201027683179 Kwenta: KWENTA Token0 ETH
0xc3734f776d28bb094ac130aaa997af17e04f0e59b8847ecf11cbabec007080bd1074248002023-07-27 8:59:3763 days 4 hrs ago 0x6fd879830d9b1ee5d4f9ef12f8d5dee916bebd0b 0x2787cc20e5ecb4bf1bfb79eae2842010276831790 ETH
0x2a682262051b233efc6e3fcf6a715dd16b7f2c44dfb4c407e338092cc190713d1074225082023-07-27 7:43:1363 days 5 hrs ago 0x2787cc20e5ecb4bf1bfb79eae284201027683179 0x1066a8eb3d90af0ad3f89839b974658577e75be20 ETH
0x2a682262051b233efc6e3fcf6a715dd16b7f2c44dfb4c407e338092cc190713d1074225082023-07-27 7:43:1363 days 5 hrs ago 0x2787cc20e5ecb4bf1bfb79eae284201027683179 Kwenta: KWENTA Token0 ETH
0x2a682262051b233efc6e3fcf6a715dd16b7f2c44dfb4c407e338092cc190713d1074225082023-07-27 7:43:1363 days 5 hrs ago 0x6fd879830d9b1ee5d4f9ef12f8d5dee916bebd0b 0x2787cc20e5ecb4bf1bfb79eae2842010276831790 ETH
0x751f86c28b6a97c4d4b3834c1377f65d329a33af539522d8dc3394f349d8da8c1074212872023-07-27 7:02:3163 days 6 hrs ago 0x2787cc20e5ecb4bf1bfb79eae284201027683179 0x1066a8eb3d90af0ad3f89839b974658577e75be20 ETH
0x751f86c28b6a97c4d4b3834c1377f65d329a33af539522d8dc3394f349d8da8c1074212872023-07-27 7:02:3163 days 6 hrs ago 0x2787cc20e5ecb4bf1bfb79eae284201027683179 Kwenta: KWENTA Token0 ETH
0x751f86c28b6a97c4d4b3834c1377f65d329a33af539522d8dc3394f349d8da8c1074212872023-07-27 7:02:3163 days 6 hrs ago 0x2787cc20e5ecb4bf1bfb79eae284201027683179 0x1066a8eb3d90af0ad3f89839b974658577e75be20 ETH
0x751f86c28b6a97c4d4b3834c1377f65d329a33af539522d8dc3394f349d8da8c1074212872023-07-27 7:02:3163 days 6 hrs ago 0x2787cc20e5ecb4bf1bfb79eae284201027683179 Kwenta: KWENTA Token0 ETH
0x751f86c28b6a97c4d4b3834c1377f65d329a33af539522d8dc3394f349d8da8c1074212872023-07-27 7:02:3163 days 6 hrs ago 0x2787cc20e5ecb4bf1bfb79eae284201027683179 0x1066a8eb3d90af0ad3f89839b974658577e75be20 ETH
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
MultipleMerkleDistributor

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 1000 runs

Other Settings:
default evmVersion
File 1 of 10 : IERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity ^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 2 of 10 : MerkleProof.sol
// SPDX-License-Identifier: MIT

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 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 10 : IMultipleMerkleDistributor.sol
// SPDX-License-Identifier: UNLICENSED

pragma solidity >=0.6.0;

import "../../contracts/interfaces/IMultipleMerkleDistributor.sol";

abstract contract $IMultipleMerkleDistributor is IMultipleMerkleDistributor {
    constructor() {}
}

File 4 of 10 : IRewardEscrow.sol
// SPDX-License-Identifier: UNLICENSED

pragma solidity >=0.6.0;

import "../../contracts/interfaces/IRewardEscrow.sol";

contract $VestingEntries {
    constructor() {}
}

abstract contract $IRewardEscrow is IRewardEscrow {
    constructor() {}
}

File 5 of 10 : MultipleMerkleDistributor.sol
// SPDX-License-Identifier: UNLICENSED

pragma solidity >=0.6.0;

import "../contracts/MultipleMerkleDistributor.sol";

contract $MultipleMerkleDistributor is MultipleMerkleDistributor {
    constructor(address _owner, address _token, address _rewardEscrow) MultipleMerkleDistributor(_owner, _token, _rewardEscrow) {}
}

File 6 of 10 : Owned.sol
// SPDX-License-Identifier: UNLICENSED

pragma solidity >=0.6.0;

import "../../contracts/utils/Owned.sol";

contract $Owned is Owned {
    constructor(address _owner) Owned(_owner) {}
}

File 7 of 10 : IMultipleMerkleDistributor.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.8.0;

// Allows anyone to claim a token if they exist in a merkle root.
interface IMultipleMerkleDistributor {
    /// @notice data structure for aggregating multiple claims
    struct Claims {
        uint256 index;
        address account;
        uint256 amount;
        bytes32[] merkleProof;
        uint256 epoch;
    }

    /// @notice event is triggered whenever a call to `claim` succeeds
    event Claimed(
        uint256 index,
        address account,
        uint256 amount,
        uint256 epoch
    );

    /// @notice event is triggered whenever a merkle root is set
    event MerkleRootModified(uint256 epoch);

    /// @return escrow for tokens claimed
    function rewardEscrow() external view returns (address);

    /// @return token to be distributed (KWENTA)
    function token() external view returns (address);

    // @return the merkle root of the merkle tree containing account balances available to claim
    function merkleRoots(uint256) external view returns (bytes32);

    /// @notice determine if indexed claim has been claimed
    /// @param index: used for claim managment
    /// @param epoch: distribution index number
    /// @return true if indexed claim has been claimed
    function isClaimed(uint256 index, uint256 epoch)
        external
        view
        returns (bool);

    /// @notice attempt to claim as `account` and escrow KWENTA for `account`
    /// @param index: used for merkle tree managment and verification
    /// @param account: address used for escrow entry
    /// @param amount: $KWENTA amount to be escrowed
    /// @param merkleProof: off-chain generated proof of merkle tree inclusion
    /// @param epoch: distribution index number
    function claim(
        uint256 index,
        address account,
        uint256 amount,
        bytes32[] calldata merkleProof,
        uint256 epoch
    ) external;

    /// @notice function that aggregates multiple claims
    /// @param claims: array of valid claims
    function claimMultiple(Claims[] calldata claims) external;
}

File 8 of 10 : IRewardEscrow.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

library VestingEntries {
    struct VestingEntry {
        uint64 endTime;
        uint256 escrowAmount;
        uint256 duration;
    }
    struct VestingEntryWithID {
        uint64 endTime;
        uint256 escrowAmount;
        uint256 entryID;
    }
}

interface IRewardEscrow {
    // Views
    function getKwentaAddress() external view returns (address);

    function balanceOf(address account) external view returns (uint256);

    function numVestingEntries(address account) external view returns (uint256);

    function totalEscrowedAccountBalance(address account)
        external
        view
        returns (uint256);

    function totalVestedAccountBalance(address account)
        external
        view
        returns (uint256);

    function getVestingQuantity(address account, uint256[] calldata entryIDs)
        external
        view
        returns (uint256, uint256);

    function getVestingSchedules(
        address account,
        uint256 index,
        uint256 pageSize
    ) external view returns (VestingEntries.VestingEntryWithID[] memory);

    function getAccountVestingEntryIDs(
        address account,
        uint256 index,
        uint256 pageSize
    ) external view returns (uint256[] memory);

    function getVestingEntryClaimable(address account, uint256 entryID)
        external
        view
        returns (uint256, uint256);

    function getVestingEntry(address account, uint256 entryID)
        external
        view
        returns (
            uint64,
            uint256,
            uint256
        );

    // Mutative functions
    function vest(uint256[] calldata entryIDs) external;

    function createEscrowEntry(
        address beneficiary,
        uint256 deposit,
        uint256 duration
    ) external;

    function appendVestingEntry(
        address account,
        uint256 quantity,
        uint256 duration
    ) external;

    function stakeEscrow(uint256 _amount) external;

    function unstakeEscrow(uint256 _amount) external;
}

File 9 of 10 : MultipleMerkleDistributor.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import "./utils/Owned.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
import "./interfaces/IRewardEscrow.sol";
import "./interfaces/IMultipleMerkleDistributor.sol";

/// @title Kwenta MultipleMerkleDistributor
/// @author JaredBorders and JChiaramonte7
/// @notice Facilitates trading incentives distribution over multiple periods.
contract MultipleMerkleDistributor is IMultipleMerkleDistributor, Owned {
    /// @notice escrow for tokens claimed
    address public immutable override rewardEscrow;

    /// @notice token to be distributed (KWENTA)
    address public immutable override token;

    /// @notice an epoch to merkle root mapping
    /// of a merkle tree containing account balances available to claim
    mapping(uint256 => bytes32) public override merkleRoots;

    /// @notice an epoch to packed array of claimed booleans mapping
    mapping(uint256 => mapping(uint256 => uint256)) private claimedBitMaps;

    /// @notice set addresses for deployed rewardEscrow and KWENTA.
    /// Establish merkle root for verification
    /// @param _owner: designated owner of this contract
    /// @param _token: address of erc20 token to be distributed
    /// @param _rewardEscrow: address of kwenta escrow for tokens claimed
    constructor(
        address _owner,
        address _token,
        address _rewardEscrow
    ) Owned(_owner) {
        token = _token;
        rewardEscrow = _rewardEscrow;
    }

    /// @notice modify merkle root for existing distribution epoch
    function setMerkleRootForEpoch(bytes32 merkleRoot, uint256 epoch)
        external
        onlyOwner
    {
        merkleRoots[epoch] = merkleRoot;
        emit MerkleRootModified(epoch);
    }

    /// @notice determine if indexed claim has been claimed
    /// @param index: used for claim managment
    /// @param epoch: distribution index to check
    /// @return true if indexed claim has been claimed
    function isClaimed(uint256 index, uint256 epoch)
        public
        view
        override
        returns (bool)
    {
        uint256 claimedWordIndex = index / 256;
        uint256 claimedBitIndex = index % 256;
        uint256 claimedWord = claimedBitMaps[epoch][claimedWordIndex];
        uint256 mask = (1 << claimedBitIndex);
        return claimedWord & mask == mask;
    }

    /// @notice set claimed status for indexed claim to true
    /// @param index: used for claim managment
    /// @param epoch: distribution index to check
    function _setClaimed(uint256 index, uint256 epoch) private {
        uint256 claimedWordIndex = index / 256;
        uint256 claimedBitIndex = index % 256;
        claimedBitMaps[epoch][claimedWordIndex] =
            claimedBitMaps[epoch][claimedWordIndex] |
            (1 << claimedBitIndex);
    }

    /// @notice attempt to claim as `account` and escrow KWENTA for `account`
    /// @param index: used for merkle tree managment and verification
    /// @param account: address used for escrow entry
    /// @param amount: $KWENTA amount to be escrowed
    /// @param merkleProof: off-chain generated proof of merkle tree inclusion
    /// @param epoch: distribution index to check
    function claim(
        uint256 index,
        address account,
        uint256 amount,
        bytes32[] calldata merkleProof,
        uint256 epoch
    ) public override {
        require(
            !isClaimed(index, epoch),
            "MultipleMerkleDistributor: Drop already claimed."
        );

        // verify the merkle proof
        bytes32 node = keccak256(abi.encodePacked(index, account, amount));
        require(
            MerkleProof.verify(merkleProof, merkleRoots[epoch], node),
            "MultipleMerkleDistributor: Invalid proof."
        );

        // mark it claimed and send the token to RewardEscrow
        _setClaimed(index, epoch);
        IERC20(token).approve(rewardEscrow, amount);
        IRewardEscrow(rewardEscrow).createEscrowEntry(
            account,
            amount,
            52 weeks
        );

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

    /// @notice function that aggregates multiple claims
    /// @param claims: array of valid claims
    function claimMultiple(Claims[] calldata claims) external override {
        uint256 cacheLength = claims.length;
        for (uint256 i = 0; i < cacheLength; ) {
            claim(
                claims[i].index,
                claims[i].account,
                claims[i].amount,
                claims[i].merkleProof,
                claims[i].epoch
            );
            unchecked {
                i++;
            }
        }
    }
}

File 10 of 10 : Owned.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// https://docs.synthetix.io/contracts/source/contracts/owned
contract Owned {
    address public owner;
    address public nominatedOwner;

    constructor(address _owner) {
        require(_owner != address(0), "Owner address cannot be 0");
        owner = _owner;
        emit OwnerChanged(address(0), _owner);
    }

    function nominateNewOwner(address _owner) external onlyOwner {
        nominatedOwner = _owner;
        emit OwnerNominated(_owner);
    }

    function acceptOwnership() external {
        require(msg.sender == nominatedOwner, "You must be nominated before you can accept ownership");
        emit OwnerChanged(owner, nominatedOwner);
        owner = nominatedOwner;
        nominatedOwner = address(0);
    }

    modifier onlyOwner {
        _onlyOwner();
        _;
    }

    function _onlyOwner() private view {
        require(msg.sender == owner, "Only the contract owner may perform this action");
    }

    event OwnerNominated(address newOwner);
    event OwnerChanged(address oldOwner, address newOwner);
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 1000
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "metadata": {
    "useLiteralContent": true
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_rewardEscrow","type":"address"}],"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"},{"indexed":false,"internalType":"uint256","name":"epoch","type":"uint256"}],"name":"Claimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"epoch","type":"uint256"}],"name":"MerkleRootModified","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerNominated","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"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[]"},{"internalType":"uint256","name":"epoch","type":"uint256"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"},{"internalType":"uint256","name":"epoch","type":"uint256"}],"internalType":"struct IMultipleMerkleDistributor.Claims[]","name":"claims","type":"tuple[]"}],"name":"claimMultiple","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint256","name":"epoch","type":"uint256"}],"name":"isClaimed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"merkleRoots","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"nominateNewOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nominatedOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardEscrow","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"},{"internalType":"uint256","name":"epoch","type":"uint256"}],"name":"setMerkleRootForEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

60c060405234801561001057600080fd5b50604051610e4d380380610e4d83398101604081905261002f9161011d565b826001600160a01b03811661008a5760405162461bcd60e51b815260206004820152601960248201527f4f776e657220616464726573732063616e6e6f74206265203000000000000000604482015260640160405180910390fd5b600080546001600160a01b0319166001600160a01b03831690811782556040805192835260208301919091527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a1506001600160601b0319606092831b811660a052911b1660805250610160565b80516001600160a01b038116811461011857600080fd5b919050565b60008060006060848603121561013257600080fd5b61013b84610101565b925061014960208501610101565b915061015760408501610101565b90509250925092565b60805160601c60a05160601c610cad6101a0600039600081816101e4015261065f0152600081816101610152818161063001526107250152610cad6000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c8063a430be6c11610081578063d0b55e8c1161005b578063d0b55e8c146101a9578063f364c90c146101bc578063fc0c546a146101df57600080fd5b8063a430be6c1461015c578063ab5943db14610183578063c02bb7ba1461019657600080fd5b806371c5ecb1116100b257806371c5ecb11461011357806379ba5097146101415780638da5cb5b1461014957600080fd5b80631627540c146100ce57806353a47bb7146100e3575b600080fd5b6100e16100dc366004610a5f565b610206565b005b6001546100f6906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b610133610121366004610b07565b60026020526000908152604090205481565b60405190815260200161010a565b6100e161026f565b6000546100f6906001600160a01b031681565b6100f67f000000000000000000000000000000000000000000000000000000000000000081565b6100e1610191366004610a81565b610373565b6100e16101a4366004610b20565b610471565b6100e16101b7366004610ae5565b6107db565b6101cf6101ca366004610ae5565b610832565b604051901515815260200161010a565b6100f67f000000000000000000000000000000000000000000000000000000000000000081565b61020e61087d565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce229060200160405180910390a150565b6001546001600160a01b031633146102f45760405162461bcd60e51b815260206004820152603560248201527f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7560448201527f2063616e20616363657074206f776e657273686970000000000000000000000060648201526084015b60405180910390fd5b600054600154604080516001600160a01b0393841681529290911660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a1600180546000805473ffffffffffffffffffffffffffffffffffffffff199081166001600160a01b03841617909155169055565b8060005b8181101561046b5761046384848381811061039457610394610c61565b90506020028101906103a69190610bda565b358585848181106103b9576103b9610c61565b90506020028101906103cb9190610bda565b6103dc906040810190602001610a5f565b8686858181106103ee576103ee610c61565b90506020028101906104009190610bda565b6040013587878681811061041657610416610c61565b90506020028101906104289190610bda565b610436906060810190610b90565b89898881811061044857610448610c61565b905060200281019061045a9190610bda565b60800135610471565b600101610377565b50505050565b61047b8682610832565b156104ee5760405162461bcd60e51b815260206004820152603060248201527f4d756c7469706c654d65726b6c654469737472696275746f723a2044726f702060448201527f616c726561647920636c61696d65642e0000000000000000000000000000000060648201526084016102eb565b60408051602081018890526bffffffffffffffffffffffff19606088901b16918101919091526054810185905260009060740160405160208183030381529060405280519060200120905061058484848080602002602001604051908101604052809392919081815260200183836020028082843760009201829052508781526002602052604090205492508591506108ff9050565b6105f65760405162461bcd60e51b815260206004820152602960248201527f4d756c7469706c654d65726b6c654469737472696275746f723a20496e76616c60448201527f69642070726f6f662e000000000000000000000000000000000000000000000060648201526084016102eb565b61060087836109ae565b6040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152602482018790527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b390604401602060405180830381600087803b1580156106a357600080fd5b505af11580156106b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106db9190610ac3565b506040517fa0416ed30000000000000000000000000000000000000000000000000000000081526001600160a01b038781166004830152602482018790526301dfe20060448301527f0000000000000000000000000000000000000000000000000000000000000000169063a0416ed390606401600060405180830381600087803b15801561076957600080fd5b505af115801561077d573d6000803e3d6000fd5b5050604080518a81526001600160a01b038a166020820152908101889052606081018590527fd9cb1e2714d65a111c0f20f060176ad657496bd47a3de04ec7c3d4ca232112ac9250608001905060405180910390a150505050505050565b6107e361087d565b60008181526002602052604090819020839055517f7835b531ba83151bc18466c9b0ab4b168056cb422098530a34952b03f87ba519906108269083815260200190565b60405180910390a15050565b60008061084161010085610bfa565b9050600061085161010086610c37565b60009485526003602090815260408087209487529390529190932054600190911b908116149392505050565b6000546001600160a01b031633146108fd5760405162461bcd60e51b815260206004820152602f60248201527f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726660448201527f6f726d207468697320616374696f6e000000000000000000000000000000000060648201526084016102eb565b565b600081815b85518110156109a357600086828151811061092157610921610c61565b60200260200101519050808311610963576040805160208101859052908101829052606001604051602081830303815290604052805190602001209250610990565b60408051602081018390529081018490526060016040516020818303038152906040528051906020012092505b508061099b81610c0e565b915050610904565b509092149392505050565b60006109bc61010084610bfa565b905060006109cc61010085610c37565b6000938452600360209081526040808620948652939052919092208054600190921b90911790555050565b80356001600160a01b0381168114610a0e57600080fd5b919050565b60008083601f840112610a2557600080fd5b50813567ffffffffffffffff811115610a3d57600080fd5b6020830191508360208260051b8501011115610a5857600080fd5b9250929050565b600060208284031215610a7157600080fd5b610a7a826109f7565b9392505050565b60008060208385031215610a9457600080fd5b823567ffffffffffffffff811115610aab57600080fd5b610ab785828601610a13565b90969095509350505050565b600060208284031215610ad557600080fd5b81518015158114610a7a57600080fd5b60008060408385031215610af857600080fd5b50508035926020909101359150565b600060208284031215610b1957600080fd5b5035919050565b60008060008060008060a08789031215610b3957600080fd5b86359550610b49602088016109f7565b945060408701359350606087013567ffffffffffffffff811115610b6c57600080fd5b610b7889828a01610a13565b979a9699509497949695608090950135949350505050565b6000808335601e19843603018112610ba757600080fd5b83018035915067ffffffffffffffff821115610bc257600080fd5b6020019150600581901b3603821315610a5857600080fd5b60008235609e19833603018112610bf057600080fd5b9190910192915050565b600082610c0957610c09610c4b565b500490565b6000600019821415610c3057634e487b7160e01b600052601160045260246000fd5b5060010190565b600082610c4657610c46610c4b565b500690565b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fdfea2646970667358221220ee9c5e8a65d2752478613b7515ae8466d3313fcb7f267efebb8c6b351b316f9464736f6c63430008070033000000000000000000000000e029c32d412972c5f3d107da6d6ecf8f1c1e788c000000000000000000000000920cf626a271321c151d027030d5d08af699456b0000000000000000000000001066a8eb3d90af0ad3f89839b974658577e75be2

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

000000000000000000000000e029c32d412972c5f3d107da6d6ecf8f1c1e788c000000000000000000000000920cf626a271321c151d027030d5d08af699456b0000000000000000000000001066a8eb3d90af0ad3f89839b974658577e75be2

-----Decoded View---------------
Arg [0] : _owner (address): 0xe029c32d412972C5F3D107DA6d6eCF8F1C1E788C
Arg [1] : _token (address): 0x920Cf626a271321C151D027030D5d08aF699456b
Arg [2] : _rewardEscrow (address): 0x1066A8eB3d90Af0Ad3F89839b974658577e75BE2

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000e029c32d412972c5f3d107da6d6ecf8f1c1e788c
Arg [1] : 000000000000000000000000920cf626a271321c151d027030d5d08af699456b
Arg [2] : 0000000000000000000000001066a8eb3d90af0ad3f89839b974658577e75be2


Block Transaction Difficulty Gas Used Reward
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.