ETH Price: $3,788.00 (-12.51%)
Gas: 0.93 Gwei

Contract

0xd7807E5752B368A6a64b76828Aaff0750522a76E
 

Overview

ETH Balance

11.903829326405023939 ETH

Eth Value

$45,091.66 (@ $3,788.00/ETH)

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Claim235377842025-10-09 4:26:112 days ago1759983971IN
Redacted Cartel: Rewards Distributor
0 ETH0.000015950.1222511
Claim235331162025-10-08 12:45:352 days ago1759927535IN
Redacted Cartel: Rewards Distributor
0 ETH0.000047240.2526
Claim235302992025-10-08 3:16:473 days ago1759893407IN
Redacted Cartel: Rewards Distributor
0 ETH0.000017350.13994364
Claim235133242025-10-05 18:21:235 days ago1759688483IN
Redacted Cartel: Rewards Distributor
0 ETH0.000120051.15357287
Claim235133202025-10-05 18:20:355 days ago1759688435IN
Redacted Cartel: Rewards Distributor
0 ETH0.000089361.14084675
Claim234941732025-10-03 2:09:358 days ago1759457375IN
Redacted Cartel: Rewards Distributor
0 ETH0.000197031.17974483
Claim234694532025-09-29 15:09:5911 days ago1759158599IN
Redacted Cartel: Rewards Distributor
0 ETH0.001328228.38345253
Claim234428982025-09-25 22:01:5915 days ago1758837719IN
Redacted Cartel: Rewards Distributor
0 ETH0.000158891.37277057
Claim234402352025-09-25 13:04:5915 days ago1758805499IN
Redacted Cartel: Rewards Distributor
0 ETH0.000585763.90519836
Claim234363122025-09-24 23:55:3516 days ago1758758135IN
Redacted Cartel: Rewards Distributor
0 ETH0.000209981.1225864
Claim233428362025-09-11 22:35:1129 days ago1757630111IN
Redacted Cartel: Rewards Distributor
0 ETH0.000178111.18750953
Claim233092192025-09-07 5:46:5934 days ago1757224019IN
Redacted Cartel: Rewards Distributor
0 ETH0.000024840.134
Claim232899782025-09-04 13:14:5936 days ago1756991699IN
Redacted Cartel: Rewards Distributor
0 ETH0.000131080.71806897
Claim232887582025-09-04 9:08:2336 days ago1756976903IN
Redacted Cartel: Rewards Distributor
0 ETH0.000053540.37865613
Claim232296242025-08-27 2:58:4745 days ago1756263527IN
Redacted Cartel: Rewards Distributor
0 ETH0.000084120.72641733
Claim232109792025-08-24 12:34:1147 days ago1756038851IN
Redacted Cartel: Rewards Distributor
0 ETH0.000037990.28599339
Claim231700002025-08-18 19:21:4753 days ago1755544907IN
Redacted Cartel: Rewards Distributor
0 ETH0.000486082.38097265
Claim231611112025-08-17 13:35:1154 days ago1755437711IN
Redacted Cartel: Rewards Distributor
0 ETH0.000364482.18202085
Claim231610862025-08-17 13:30:1154 days ago1755437411IN
Redacted Cartel: Rewards Distributor
0 ETH0.000291172.19239488
Claim231342672025-08-13 19:37:3558 days ago1755113855IN
Redacted Cartel: Rewards Distributor
0 ETH0.000465892.78959906
Claim231225052025-08-12 4:13:3560 days ago1754972015IN
Redacted Cartel: Rewards Distributor
0 ETH0.000057320.31125132
Claim231116142025-08-10 15:41:5961 days ago1754840519IN
Redacted Cartel: Rewards Distributor
0 ETH0.000657542.95817618
Claim230976302025-08-08 16:47:5963 days ago1754671679IN
Redacted Cartel: Rewards Distributor
0 ETH0.000563723.01455041
Claim230630452025-08-03 20:52:1168 days ago1754254331IN
Redacted Cartel: Rewards Distributor
0 ETH0.000047120.31430357
Claim230319612025-07-30 12:32:2372 days ago1753878743IN
Redacted Cartel: Rewards Distributor
0 ETH0.000461212.46643991
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Method Block
From
To
Transfer235331162025-10-08 12:45:352 days ago1759927535
Redacted Cartel: Rewards Distributor
0.00038421 ETH
Transfer235302992025-10-08 3:16:473 days ago1759893407
Redacted Cartel: Rewards Distributor
0.0016663 ETH
Transfer235133202025-10-05 18:20:355 days ago1759688435
Redacted Cartel: Rewards Distributor
0.0102051 ETH
Transfer234694532025-09-29 15:09:5911 days ago1759158599
Redacted Cartel: Rewards Distributor
0.00216318 ETH
Transfer234363122025-09-24 23:55:3516 days ago1758758135
Redacted Cartel: Rewards Distributor
0.00350054 ETH
Transfer233092192025-09-07 5:46:5934 days ago1757224019
Redacted Cartel: Rewards Distributor
0.00302831 ETH
Transfer232897172025-09-04 12:22:2336 days ago1756988543
Redacted Cartel: Rewards Distributor
0.00153007 ETH
Transfer232887582025-09-04 9:08:2336 days ago1756976903
Redacted Cartel: Rewards Distributor
0.00048132 ETH
Transfer231746542025-08-19 10:55:2352 days ago1755600923
Redacted Cartel: Rewards Distributor
0.00357994 ETH
Transfer231700002025-08-18 19:21:4753 days ago1755544907
Redacted Cartel: Rewards Distributor
0.00149956 ETH
Transfer231646612025-08-18 1:28:1154 days ago1755480491
Redacted Cartel: Rewards Distributor
0.0010781 ETH
Transfer231116142025-08-10 15:41:5961 days ago1754840519
Redacted Cartel: Rewards Distributor
0.00076498 ETH
Transfer230976302025-08-08 16:47:5963 days ago1754671679
Redacted Cartel: Rewards Distributor
0.00084024 ETH
Transfer230319612025-07-30 12:32:2372 days ago1753878743
Redacted Cartel: Rewards Distributor
0.00671479 ETH
Transfer230148182025-07-28 2:59:4775 days ago1753671587
Redacted Cartel: Rewards Distributor
0.00074415 ETH
Transfer230055902025-07-26 20:05:1176 days ago1753560311
Redacted Cartel: Rewards Distributor
0.00009247 ETH
Transfer229787032025-07-23 1:51:1180 days ago1753235471
Redacted Cartel: Rewards Distributor
0.00085985 ETH
Transfer229440752025-07-18 5:44:2385 days ago1752817463
Redacted Cartel: Rewards Distributor
0.00038879 ETH
Transfer228734912025-07-08 9:11:4794 days ago1751965907
Redacted Cartel: Rewards Distributor
0.00093848 ETH
Transfer228612022025-07-06 15:57:5996 days ago1751817479
Redacted Cartel: Rewards Distributor
0.00045851 ETH
Transfer228095782025-06-29 10:46:35103 days ago1751193995
Redacted Cartel: Rewards Distributor
0.00318822 ETH
Transfer228029012025-06-28 12:20:59104 days ago1751113259
Redacted Cartel: Rewards Distributor
0.0043316 ETH
Transfer226032872025-05-31 14:24:35132 days ago1748701475
Redacted Cartel: Rewards Distributor
0.00391674 ETH
Transfer225922492025-05-30 1:23:11134 days ago1748568191
Redacted Cartel: Rewards Distributor
0.01190634 ETH
Transfer225662092025-05-26 9:56:11137 days ago1748253371
Redacted Cartel: Rewards Distributor
0.00576738 ETH
View All Internal Transactions
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
RewardDistributor

Compiler Version
v0.8.12+commit.f00d7308

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license
/**
 *Submitted for verification at Etherscan.io on 2022-08-08
*/

/**
 *Submitted for verification at Etherscan.io on 2022-07-27
*/

// Sources flattened with hardhat v2.9.2 https://hardhat.org

// File @openzeppelin/contracts/utils/[email protected]


// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)



/**
 * @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 Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}


// File @openzeppelin/contracts/access/[email protected]


// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)



/**
 * @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 Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_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 {
        _transferOwnership(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");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}


// File @rari-capital/solmate/src/utils/[email protected]


pragma solidity >=0.8.0;

/// @notice Gas optimized reentrancy protection for smart contracts.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/ReentrancyGuard.sol)
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/security/ReentrancyGuard.sol)
abstract contract ReentrancyGuard {
    uint256 private reentrancyStatus = 1;

    modifier nonReentrant() {
        require(reentrancyStatus == 1, "REENTRANCY");

        reentrancyStatus = 2;

        _;

        reentrancyStatus = 1;
    }
}


// File @rari-capital/solmate/src/tokens/[email protected]


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);
    }
}


// File @rari-capital/solmate/src/utils/[email protected]


pragma solidity >=0.8.0;

/// @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
            }
        }
    }
}


// File @openzeppelin/contracts/utils/cryptography/[email protected]


// OpenZeppelin Contracts (last updated v4.5.0) (utils/cryptography/MerkleProof.sol)



/**
 * @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) {
        return processProof(proof, leaf) == root;
    }

    /**
     * @dev Returns the rebuilt hash obtained by traversing a Merklee tree up
     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
     * hash matches the root of the tree. When processing the proof, the pairs
     * of leafs & pre-images are assumed to be sorted.
     *
     * _Available since v4.4._
     */
    function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
        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 = _efficientHash(computedHash, proofElement);
            } else {
                // Hash(current element of the proof + current computed hash)
                computedHash = _efficientHash(proofElement, computedHash);
            }
        }
        return computedHash;
    }

    function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
        assembly {
            mstore(0x00, a)
            mstore(0x20, b)
            value := keccak256(0x00, 0x40)
        }
    }
}


// File contracts/core/RewardDistributor.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.8.12;





/// @title RewardDistributor
/// @author ████

/**
    @notice
    Adapted from Hidden-Hand's RewardDistributor
*/

contract RewardDistributor is Ownable, ReentrancyGuard {
    using SafeTransferLib for ERC20;

    struct Distribution {
        address token;
        bytes32 merkleRoot;
        bytes32 proof;
    }

    struct Reward {
        address token;
        bytes32 merkleRoot;
        bytes32 proof;
        uint256 updateCount;
    }

    struct Claim {
        address token;
        address account;
        uint256 amount;
        bytes32[] merkleProof;
    }

    // Address of the Multisig (also as the primary source of rewards)
    address public immutable MULTISIG;

    // Maps each of the token address to its reward metadata
    mapping(address => Reward) public rewards;
    // Tracks the amount of claimed reward for the specified token address + account
    mapping(address => mapping(address => uint256)) public claimed;

    event RewardClaimed(
        address indexed token,
        address indexed account,
        uint256 amount,
        uint256 updateCount
    );

    event RewardMetadataUpdated(
        address indexed token,
        bytes32 merkleRoot,
        bytes32 proof,
        uint256 indexed updateCount
    );

    constructor(address multisig) {
        require(multisig != address(0), "Invalid address");
        MULTISIG = multisig;
    }

    /**
        @notice Enables and restricts native token ingress to Multisig
     */
    receive() external payable {
        if (msg.sender != MULTISIG) revert("Not MULTISIG");
    }

    /**
        @notice Claim rewards based on the specified metadata
        @param  claims  Claim[] List of claim metadata
     */
    function claim(Claim[] calldata claims) external nonReentrant {
        require(claims.length != 0, "Invalid claims");

        for (uint256 i; i < claims.length; ++i) {
            _claim(
                claims[i].token,
                claims[i].account,
                claims[i].amount,
                claims[i].merkleProof
            );
        }
    }

    /**
        @notice Update rewards metadata
        @param  distributions  Distribution[] List of reward distribution details
     */
    function updateRewardsMetadata(Distribution[] calldata distributions)
        external
        onlyOwner
    {
        require(distributions.length != 0, "Invalid distributions");

        for (uint256 i; i < distributions.length; ++i) {
            // Update the metadata and also increment the update counter
            Distribution calldata distribution = distributions[i];
            Reward storage reward = rewards[distribution.token];
            reward.token = distribution.token;
            reward.merkleRoot = distribution.merkleRoot;
            reward.proof = distribution.proof;
            ++reward.updateCount;

            emit RewardMetadataUpdated(
                distribution.token,
                distribution.merkleRoot,
                distribution.proof,
                reward.updateCount
            );
        }
    }

    /**
        @notice Claim a reward
        @param  token        address    Token address
        @param  account      address    Eligible user account
        @param  amount       uint256    Reward amount
        @param  merkleProof  bytes32[]  Merkle proof
     */
    function _claim(
        address token,
        address account,
        uint256 amount,
        bytes32[] calldata merkleProof
    ) private {
        Reward memory reward = rewards[token];

        require(reward.merkleRoot != 0, "Distribution not enabled");

        // Verify the merkle proof
        require(
            MerkleProof.verify(
                merkleProof,
                reward.merkleRoot,
                keccak256(abi.encodePacked(account, amount))
            ),
            "Invalid proof"
        );

        // Verify the claimable amount
        require(claimed[token][account] < amount, "No claimable reward");

        // Calculate the claimable amount based off the total of reward (used in the merkle tree)
        // since the beginning for the user, minus the total claimed so far
        uint256 claimable = amount - claimed[token][account];
        // Update the claimed amount to the current total
        claimed[token][account] = amount;

        // Check whether the reward is in the form of native tokens or ERC20
        // by checking if the token address is set to the Multisig or not
        if (token != MULTISIG) {
            ERC20(token).safeTransfer(account, claimable);
        } else {
            (bool sent, ) = payable(account).call{value: claimable}("");
            require(sent, "Failed to transfer to account");
        }

        emit RewardClaimed(
            token,
            account,
            claimable,
            reward.updateCount
        );
    }
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"multisig","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"updateCount","type":"uint256"}],"name":"RewardClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"bytes32","name":"merkleRoot","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"proof","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"updateCount","type":"uint256"}],"name":"RewardMetadataUpdated","type":"event"},{"inputs":[],"name":"MULTISIG","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"internalType":"struct RewardDistributor.Claim[]","name":"claims","type":"tuple[]"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"claimed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":[{"internalType":"address","name":"","type":"address"}],"name":"rewards","outputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"},{"internalType":"bytes32","name":"proof","type":"bytes32"},{"internalType":"uint256","name":"updateCount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"},{"internalType":"bytes32","name":"proof","type":"bytes32"}],"internalType":"struct RewardDistributor.Distribution[]","name":"distributions","type":"tuple[]"}],"name":"updateRewardsMetadata","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60a06040526001805534801561001457600080fd5b50604051610f34380380610f34833981016040819052610033916100e9565b61003c33610099565b6001600160a01b0381166100885760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b604482015260640160405180910390fd5b6001600160a01b0316608052610119565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000602082840312156100fb57600080fd5b81516001600160a01b038116811461011257600080fd5b9392505050565b608051610df361014160003960008181608f015281816101cc015261088a0152610df36000f3fe60806040526004361061007f5760003560e01c8063715018a61161004e578063715018a6146102265780638da5cb5b1461023b57806396e859d814610259578063f2fde38b1461027957600080fd5b80630700037d146100f75780630c9cbf0e146101745780632530b145146101ba578063486866261461020657600080fd5b366100f257336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146100f05760405162461bcd60e51b815260206004820152600c60248201526b4e6f74204d554c544953494760a01b60448201526064015b60405180910390fd5b005b600080fd5b34801561010357600080fd5b50610145610112366004610b8c565b600260208190526000918252604090912080546001820154928201546003909201546001600160a01b0390911692919084565b604080516001600160a01b03909516855260208501939093529183015260608201526080015b60405180910390f35b34801561018057600080fd5b506101ac61018f366004610bae565b600360209081526000928352604080842090915290825290205481565b60405190815260200161016b565b3480156101c657600080fd5b506101ee7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161016b565b34801561021257600080fd5b506100f0610221366004610be1565b610299565b34801561023257600080fd5b506100f0610408565b34801561024757600080fd5b506000546001600160a01b03166101ee565b34801561026557600080fd5b506100f0610274366004610c56565b61043e565b34801561028557600080fd5b506100f0610294366004610b8c565b6105d2565b6001546001146102d85760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b60448201526064016100e7565b60026001558061031b5760405162461bcd60e51b815260206004820152600e60248201526d496e76616c696420636c61696d7360901b60448201526064016100e7565b60005b818110156103ff576103ef83838381811061033b5761033b610cb9565b905060200281019061034d9190610ccf565b61035b906020810190610b8c565b84848481811061036d5761036d610cb9565b905060200281019061037f9190610ccf565b610390906040810190602001610b8c565b8585858181106103a2576103a2610cb9565b90506020028101906103b49190610ccf565b604001358686868181106103ca576103ca610cb9565b90506020028101906103dc9190610ccf565b6103ea906060810190610cef565b61066d565b6103f881610d56565b905061031e565b50506001805550565b6000546001600160a01b031633146104325760405162461bcd60e51b81526004016100e790610d71565b61043c60006109d0565b565b6000546001600160a01b031633146104685760405162461bcd60e51b81526004016100e790610d71565b806104ad5760405162461bcd60e51b8152602060048201526015602482015274496e76616c696420646973747269627574696f6e7360581b60448201526064016100e7565b60005b818110156105cd57368383838181106104cb576104cb610cb9565b606002919091019150600090506002816104e86020850185610b8c565b6001600160a01b03168152602080820192909252604001600020915061051090830183610b8c565b81546001600160a01b0319166001600160a01b0391909116178155602082013560018201556040820135600282015560038101805460009061055190610d56565b9091555060038101546105676020840184610b8c565b6001600160a01b03167f9ca93988e299d8264919a188c320f8d8efa97e1976a234f3c6c42315fc10b4e0846020013585604001356040516105b2929190918252602082015260400190565b60405180910390a35050806105c690610d56565b90506104b0565b505050565b6000546001600160a01b031633146105fc5760405162461bcd60e51b81526004016100e790610d71565b6001600160a01b0381166106615760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016100e7565b61066a816109d0565b50565b6001600160a01b03808616600090815260026020818152604092839020835160808101855281549095168552600181015491850182905291820154928401929092526003015460608301526107045760405162461bcd60e51b815260206004820152601860248201527f446973747269627574696f6e206e6f7420656e61626c6564000000000000000060448201526064016100e7565b6107848383808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505050506020838101516040516bffffffffffffffffffffffff1960608b901b1692810192909252603482018890529060540160405160208183030381529060405280519060200120610a20565b6107c05760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b210383937b7b360991b60448201526064016100e7565b6001600160a01b03808716600090815260036020908152604080832093891683529290522054841161082a5760405162461bcd60e51b8152602060048201526013602482015272139bc818db185a5b58589b19481c995dd85c99606a1b60448201526064016100e7565b6001600160a01b03808716600090815260036020908152604080832093891683529290529081205461085c9086610da6565b6001600160a01b0380891660008181526003602090815260408083208c8616845290915290208890559192507f000000000000000000000000000000000000000000000000000000000000000016146108c8576108c36001600160a01b0388168783610a36565b61096d565b6000866001600160a01b03168260405160006040518083038185875af1925050503d8060008114610915576040519150601f19603f3d011682016040523d82523d6000602084013e61091a565b606091505b505090508061096b5760405162461bcd60e51b815260206004820152601d60248201527f4661696c656420746f207472616e7366657220746f206163636f756e7400000060448201526064016100e7565b505b856001600160a01b0316876001600160a01b03167f7a84a08b02c91f3c62d572853f966fc799bbd121e8ad7833a4494ab8dcfcb4048385606001516040516109bf929190918252602082015260400190565b60405180910390a350505050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600082610a2d8584610ab5565b14949350505050565b600060405163a9059cbb60e01b81526001600160a01b03841660048201528260248201526000806044836000895af1915050610a7181610b29565b610aaf5760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b60448201526064016100e7565b50505050565b600081815b8451811015610b21576000858281518110610ad757610ad7610cb9565b60200260200101519050808311610afd5760008381526020829052604090209250610b0e565b600081815260208490526040902092505b5080610b1981610d56565b915050610aba565b509392505050565b60003d82610b3b57806000803e806000fd5b8060208114610b53578015610b645760009250610b69565b816000803e60005115159250610b69565b600192505b5050919050565b80356001600160a01b0381168114610b8757600080fd5b919050565b600060208284031215610b9e57600080fd5b610ba782610b70565b9392505050565b60008060408385031215610bc157600080fd5b610bca83610b70565b9150610bd860208401610b70565b90509250929050565b60008060208385031215610bf457600080fd5b823567ffffffffffffffff80821115610c0c57600080fd5b818501915085601f830112610c2057600080fd5b813581811115610c2f57600080fd5b8660208260051b8501011115610c4457600080fd5b60209290920196919550909350505050565b60008060208385031215610c6957600080fd5b823567ffffffffffffffff80821115610c8157600080fd5b818501915085601f830112610c9557600080fd5b813581811115610ca457600080fd5b866020606083028501011115610c4457600080fd5b634e487b7160e01b600052603260045260246000fd5b60008235607e19833603018112610ce557600080fd5b9190910192915050565b6000808335601e19843603018112610d0657600080fd5b83018035915067ffffffffffffffff821115610d2157600080fd5b6020019150600581901b3603821315610d3957600080fd5b9250929050565b634e487b7160e01b600052601160045260246000fd5b6000600019821415610d6a57610d6a610d40565b5060010190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b600082821015610db857610db8610d40565b50039056fea2646970667358221220e686f6bcec02b95fda91dc3aabca349a2d71402ac10c33ecba0ca921213a073364736f6c634300080c0033000000000000000000000000a52fd396891e7a74b641a2cb1a6999fcf56b077e

Deployed Bytecode

0x60806040526004361061007f5760003560e01c8063715018a61161004e578063715018a6146102265780638da5cb5b1461023b57806396e859d814610259578063f2fde38b1461027957600080fd5b80630700037d146100f75780630c9cbf0e146101745780632530b145146101ba578063486866261461020657600080fd5b366100f257336001600160a01b037f000000000000000000000000a52fd396891e7a74b641a2cb1a6999fcf56b077e16146100f05760405162461bcd60e51b815260206004820152600c60248201526b4e6f74204d554c544953494760a01b60448201526064015b60405180910390fd5b005b600080fd5b34801561010357600080fd5b50610145610112366004610b8c565b600260208190526000918252604090912080546001820154928201546003909201546001600160a01b0390911692919084565b604080516001600160a01b03909516855260208501939093529183015260608201526080015b60405180910390f35b34801561018057600080fd5b506101ac61018f366004610bae565b600360209081526000928352604080842090915290825290205481565b60405190815260200161016b565b3480156101c657600080fd5b506101ee7f000000000000000000000000a52fd396891e7a74b641a2cb1a6999fcf56b077e81565b6040516001600160a01b03909116815260200161016b565b34801561021257600080fd5b506100f0610221366004610be1565b610299565b34801561023257600080fd5b506100f0610408565b34801561024757600080fd5b506000546001600160a01b03166101ee565b34801561026557600080fd5b506100f0610274366004610c56565b61043e565b34801561028557600080fd5b506100f0610294366004610b8c565b6105d2565b6001546001146102d85760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b60448201526064016100e7565b60026001558061031b5760405162461bcd60e51b815260206004820152600e60248201526d496e76616c696420636c61696d7360901b60448201526064016100e7565b60005b818110156103ff576103ef83838381811061033b5761033b610cb9565b905060200281019061034d9190610ccf565b61035b906020810190610b8c565b84848481811061036d5761036d610cb9565b905060200281019061037f9190610ccf565b610390906040810190602001610b8c565b8585858181106103a2576103a2610cb9565b90506020028101906103b49190610ccf565b604001358686868181106103ca576103ca610cb9565b90506020028101906103dc9190610ccf565b6103ea906060810190610cef565b61066d565b6103f881610d56565b905061031e565b50506001805550565b6000546001600160a01b031633146104325760405162461bcd60e51b81526004016100e790610d71565b61043c60006109d0565b565b6000546001600160a01b031633146104685760405162461bcd60e51b81526004016100e790610d71565b806104ad5760405162461bcd60e51b8152602060048201526015602482015274496e76616c696420646973747269627574696f6e7360581b60448201526064016100e7565b60005b818110156105cd57368383838181106104cb576104cb610cb9565b606002919091019150600090506002816104e86020850185610b8c565b6001600160a01b03168152602080820192909252604001600020915061051090830183610b8c565b81546001600160a01b0319166001600160a01b0391909116178155602082013560018201556040820135600282015560038101805460009061055190610d56565b9091555060038101546105676020840184610b8c565b6001600160a01b03167f9ca93988e299d8264919a188c320f8d8efa97e1976a234f3c6c42315fc10b4e0846020013585604001356040516105b2929190918252602082015260400190565b60405180910390a35050806105c690610d56565b90506104b0565b505050565b6000546001600160a01b031633146105fc5760405162461bcd60e51b81526004016100e790610d71565b6001600160a01b0381166106615760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016100e7565b61066a816109d0565b50565b6001600160a01b03808616600090815260026020818152604092839020835160808101855281549095168552600181015491850182905291820154928401929092526003015460608301526107045760405162461bcd60e51b815260206004820152601860248201527f446973747269627574696f6e206e6f7420656e61626c6564000000000000000060448201526064016100e7565b6107848383808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505050506020838101516040516bffffffffffffffffffffffff1960608b901b1692810192909252603482018890529060540160405160208183030381529060405280519060200120610a20565b6107c05760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b210383937b7b360991b60448201526064016100e7565b6001600160a01b03808716600090815260036020908152604080832093891683529290522054841161082a5760405162461bcd60e51b8152602060048201526013602482015272139bc818db185a5b58589b19481c995dd85c99606a1b60448201526064016100e7565b6001600160a01b03808716600090815260036020908152604080832093891683529290529081205461085c9086610da6565b6001600160a01b0380891660008181526003602090815260408083208c8616845290915290208890559192507f000000000000000000000000a52fd396891e7a74b641a2cb1a6999fcf56b077e16146108c8576108c36001600160a01b0388168783610a36565b61096d565b6000866001600160a01b03168260405160006040518083038185875af1925050503d8060008114610915576040519150601f19603f3d011682016040523d82523d6000602084013e61091a565b606091505b505090508061096b5760405162461bcd60e51b815260206004820152601d60248201527f4661696c656420746f207472616e7366657220746f206163636f756e7400000060448201526064016100e7565b505b856001600160a01b0316876001600160a01b03167f7a84a08b02c91f3c62d572853f966fc799bbd121e8ad7833a4494ab8dcfcb4048385606001516040516109bf929190918252602082015260400190565b60405180910390a350505050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600082610a2d8584610ab5565b14949350505050565b600060405163a9059cbb60e01b81526001600160a01b03841660048201528260248201526000806044836000895af1915050610a7181610b29565b610aaf5760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b60448201526064016100e7565b50505050565b600081815b8451811015610b21576000858281518110610ad757610ad7610cb9565b60200260200101519050808311610afd5760008381526020829052604090209250610b0e565b600081815260208490526040902092505b5080610b1981610d56565b915050610aba565b509392505050565b60003d82610b3b57806000803e806000fd5b8060208114610b53578015610b645760009250610b69565b816000803e60005115159250610b69565b600192505b5050919050565b80356001600160a01b0381168114610b8757600080fd5b919050565b600060208284031215610b9e57600080fd5b610ba782610b70565b9392505050565b60008060408385031215610bc157600080fd5b610bca83610b70565b9150610bd860208401610b70565b90509250929050565b60008060208385031215610bf457600080fd5b823567ffffffffffffffff80821115610c0c57600080fd5b818501915085601f830112610c2057600080fd5b813581811115610c2f57600080fd5b8660208260051b8501011115610c4457600080fd5b60209290920196919550909350505050565b60008060208385031215610c6957600080fd5b823567ffffffffffffffff80821115610c8157600080fd5b818501915085601f830112610c9557600080fd5b813581811115610ca457600080fd5b866020606083028501011115610c4457600080fd5b634e487b7160e01b600052603260045260246000fd5b60008235607e19833603018112610ce557600080fd5b9190910192915050565b6000808335601e19843603018112610d0657600080fd5b83018035915067ffffffffffffffff821115610d2157600080fd5b6020019150600581901b3603821315610d3957600080fd5b9250929050565b634e487b7160e01b600052601160045260246000fd5b6000600019821415610d6a57610d6a610d40565b5060010190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b600082821015610db857610db8610d40565b50039056fea2646970667358221220e686f6bcec02b95fda91dc3aabca349a2d71402ac10c33ecba0ca921213a073364736f6c634300080c0033

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

000000000000000000000000a52fd396891e7a74b641a2cb1a6999fcf56b077e

-----Decoded View---------------
Arg [0] : multisig (address): 0xA52Fd396891E7A74b641a2Cb1A6999Fcf56B077e

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000a52fd396891e7a74b641a2cb1a6999fcf56b077e


Deployed Bytecode Sourcemap

19488:4900:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20948:10;-1:-1:-1;;;;;20962:8:0;20948:22;;20944:50;;20972:22;;-1:-1:-1;;;20972:22:0;;216:2:1;20972:22:0;;;198:21:1;255:2;235:18;;;228:30;-1:-1:-1;;;274:18:1;;;267:42;326:18;;20972:22:0;;;;;;;;20944:50;19488:4900;;;;;20152:41;;;;;;;;;;-1:-1:-1;20152:41:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;20152:41:0;;;;;;;;;;;;-1:-1:-1;;;;;973:32:1;;;955:51;;1037:2;1022:18;;1015:34;;;;1065:18;;;1058:34;1123:2;1108:18;;1101:34;942:3;927:19;20152:41:0;;;;;;;;20286:62;;;;;;;;;;-1:-1:-1;20286:62:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;1557:25:1;;;1545:2;1530:18;20286:62:0;1411:177:1;20048:33:0;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1757:32:1;;;1739:51;;1727:2;1712:18;20048:33:0;1593:203:1;21147:371:0;;;;;;;;;;-1:-1:-1;21147:371:0;;;;;:::i;:::-;;:::i;2707:103::-;;;;;;;;;;;;;:::i;2056:87::-;;;;;;;;;;-1:-1:-1;2102:7:0;2129:6;-1:-1:-1;;;;;2129:6:0;2056:87;;21668:869;;;;;;;;;;-1:-1:-1;21668:869:0;;;;;:::i;:::-;;:::i;2965:201::-;;;;;;;;;;-1:-1:-1;2965:201:0;;;;;:::i;:::-;;:::i;21147:371::-;4076:16;;4096:1;4076:21;4068:44;;;;-1:-1:-1;;;4068:44:0;;3301:2:1;4068:44:0;;;3283:21:1;3340:2;3320:18;;;3313:30;-1:-1:-1;;;3359:18:1;;;3352:40;3409:18;;4068:44:0;3099:334:1;4068:44:0;4144:1;4125:16;:20;21228:18;21220:45:::1;;;::::0;-1:-1:-1;;;21220:45:0;;3640:2:1;21220:45:0::1;::::0;::::1;3622:21:1::0;3679:2;3659:18;;;3652:30;-1:-1:-1;;;3698:18:1;;;3691:44;3752:18;;21220:45:0::1;3438:338:1::0;21220:45:0::1;21283:9;21278:233;21294:17:::0;;::::1;21278:233;;;21333:166;21358:6;;21365:1;21358:9;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;:15;::::0;::::1;::::0;::::1;::::0;::::1;:::i;:::-;21392:6;;21399:1;21392:9;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;:17;::::0;;;;;::::1;;;:::i;:::-;21428:6;;21435:1;21428:9;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;:16;;;21463:6;;21470:1;21463:9;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;:21;::::0;::::1;::::0;::::1;::::0;::::1;:::i;:::-;21333:6;:166::i;:::-;21313:3;::::0;::::1;:::i;:::-;;;21278:233;;;-1:-1:-1::0;;4191:1:0;4172:20;;-1:-1:-1;21147:371:0:o;2707:103::-;2102:7;2129:6;-1:-1:-1;;;;;2129:6:0;877:10;2276:23;2268:68;;;;-1:-1:-1;;;2268:68:0;;;;;;;:::i;:::-;2772:30:::1;2799:1;2772:18;:30::i;:::-;2707:103::o:0;21668:869::-;2102:7;2129:6;-1:-1:-1;;;;;2129:6:0;877:10;2276:23;2268:68;;;;-1:-1:-1;;;2268:68:0;;;;;;;:::i;:::-;21799:25;21791:59:::1;;;::::0;-1:-1:-1;;;21791:59:0;;5625:2:1;21791:59:0::1;::::0;::::1;5607:21:1::0;5664:2;5644:18;;;5637:30;-1:-1:-1;;;5683:18:1;;;5676:51;5744:18;;21791:59:0::1;5423:345:1::0;21791:59:0::1;21868:9;21863:667;21879:24:::0;;::::1;21863:667;;;21999:34;22036:13;;22050:1;22036:16;;;;;;;:::i;:::-;;;::::0;;;::::1;::::0;-1:-1:-1;22067:21:0::1;::::0;-1:-1:-1;22091:7:0::1;22067:21:::0;22099:18:::1;;::::0;::::1;22036:16:::0;22099:18:::1;:::i;:::-;-1:-1:-1::0;;;;;22091:27:0::1;::::0;;::::1;::::0;;::::1;::::0;;;;;;-1:-1:-1;22091:27:0;;-1:-1:-1;22148:18:0::1;::::0;;::::1;:12:::0;:18:::1;:::i;:::-;22133:33:::0;;-1:-1:-1;;;;;;22133:33:0::1;-1:-1:-1::0;;;;;22133:33:0;;;::::1;;::::0;;22201:23:::1;::::0;::::1;;-1:-1:-1::0;22181:17:0;::::1;:43:::0;22254:18:::1;::::0;::::1;;22239:12;::::0;::::1;:33:::0;22289:18:::1;::::0;::::1;22287:20:::0;;-1:-1:-1;;22287:20:0::1;::::0;::::1;:::i;:::-;::::0;;;-1:-1:-1;22485:18:0::1;::::0;::::1;::::0;22369::::1;;::::0;::::1;:12:::0;:18:::1;:::i;:::-;-1:-1:-1::0;;;;;22329:189:0::1;;22406:12;:23;;;22448:12;:18;;;22329:189;;;;;;5947:25:1::0;;;6003:2;5988:18;;5981:34;5935:2;5920:18;;5773:248;22329:189:0::1;;;;;;;;21910:620;;21905:3;;;;:::i;:::-;;;21863:667;;;;21668:869:::0;;:::o;2965:201::-;2102:7;2129:6;-1:-1:-1;;;;;2129:6:0;877:10;2276:23;2268:68;;;;-1:-1:-1;;;2268:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;3054:22:0;::::1;3046:73;;;::::0;-1:-1:-1;;;3046:73:0;;6228:2:1;3046:73:0::1;::::0;::::1;6210:21:1::0;6267:2;6247:18;;;6240:30;6306:34;6286:18;;;6279:62;-1:-1:-1;;;6357:18:1;;;6350:36;6403:19;;3046:73:0::1;6026:402:1::0;3046:73:0::1;3130:28;3149:8;3130:18;:28::i;:::-;2965:201:::0;:::o;22822:1563::-;-1:-1:-1;;;;;23003:14:0;;;22980:20;23003:14;;;:7;:14;;;;;;;;;22980:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23030:59;;;;-1:-1:-1;;;23030:59:0;;6635:2:1;23030:59:0;;;6617:21:1;6674:2;6654:18;;;6647:30;6713:26;6693:18;;;6686:54;6757:18;;23030:59:0;6433:348:1;23030:59:0;23160:162;23197:11;;23160:162;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;23227:17:0;;;;;23273:33;;-1:-1:-1;;6963:2:1;6959:15;;;6955:53;23273:33:0;;;6943:66:1;;;;7025:12;;;7018:28;;;23227:17:0;7062:12:1;;23273:33:0;;;;;;;;;;;;23263:44;;;;;;23160:18;:162::i;:::-;23138:225;;;;-1:-1:-1;;;23138:225:0;;7287:2:1;23138:225:0;;;7269:21:1;7326:2;7306:18;;;7299:30;-1:-1:-1;;;7345:18:1;;;7338:43;7398:18;;23138:225:0;7085:337:1;23138:225:0;-1:-1:-1;;;;;23424:14:0;;;;;;;:7;:14;;;;;;;;:23;;;;;;;;;;:32;-1:-1:-1;23416:64:0;;;;-1:-1:-1;;;23416:64:0;;7629:2:1;23416:64:0;;;7611:21:1;7668:2;7648:18;;;7641:30;-1:-1:-1;;;7687:18:1;;;7680:49;7746:18;;23416:64:0;7427:343:1;23416:64:0;-1:-1:-1;;;;;23698:14:0;;;23669:17;23698:14;;;:7;:14;;;;;;;;:23;;;;;;;;;;;;23689:32;;:6;:32;:::i;:::-;-1:-1:-1;;;;;23791:14:0;;;;;;;:7;:14;;;;;;;;:23;;;;;;;;;;:32;;;23669:52;;-1:-1:-1;24002:8:0;23993:17;;23989:248;;24027:45;-1:-1:-1;;;;;24027:25:0;;24053:7;24062:9;24027:25;:45::i;:::-;23989:248;;;24106:9;24129:7;-1:-1:-1;;;;;24121:21:0;24150:9;24121:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24105:59;;;24187:4;24179:46;;;;-1:-1:-1;;;24179:46:0;;8317:2:1;24179:46:0;;;8299:21:1;8356:2;8336:18;;;8329:30;8395:31;8375:18;;;8368:59;8444:18;;24179:46:0;8115:353:1;24179:46:0;24090:147;23989:248;24302:7;-1:-1:-1;;;;;24254:123:0;24282:5;-1:-1:-1;;;;;24254:123:0;;24324:9;24348:6;:18;;;24254:123;;;;;;5947:25:1;;;6003:2;5988:18;;5981:34;5935:2;5920:18;;5773:248;24254:123:0;;;;;;;;22969:1416;;22822:1563;;;;;:::o;3326:191::-;3400:16;3419:6;;-1:-1:-1;;;;;3436:17:0;;;-1:-1:-1;;;;;;3436:17:0;;;;;;3469:40;;3419:6;;;;;;;3469:40;;3400:16;3469:40;3389:128;3326:191;:::o;17772:190::-;17897:4;17950;17921:25;17934:5;17941:4;17921:12;:25::i;:::-;:33;;17772:190;-1:-1:-1;;;;17772:190:0:o;13450:1065::-;13567:15;13701:4;13695:11;-1:-1:-1;;;13802:17:0;13795:93;-1:-1:-1;;;;;13977:2:0;13973:51;13969:1;13950:17;13946:25;13939:86;14112:6;14107:2;14088:17;14084:26;14077:42;14410:1;14407;14403:2;14384:17;14381:1;14374:5;14367;14362:50;14348:64;;;14443:44;14476:10;14443:32;:44::i;:::-;14435:72;;;;-1:-1:-1;;;14435:72:0;;8928:2:1;14435:72:0;;;8910:21:1;8967:2;8947:18;;;8940:30;-1:-1:-1;;;8986:18:1;;;8979:45;9041:18;;14435:72:0;8726:339:1;14435:72:0;13556:959;13450:1065;;;:::o;18324:675::-;18407:7;18450:4;18407:7;18465:497;18489:5;:12;18485:1;:16;18465:497;;;18523:20;18546:5;18552:1;18546:8;;;;;;;;:::i;:::-;;;;;;;18523:31;;18589:12;18573;:28;18569:382;;19075:13;19125:15;;;19161:4;19154:15;;;19208:4;19192:21;;18701:57;;18569:382;;;19075:13;19125:15;;;19161:4;19154:15;;;19208:4;19192:21;;18878:57;;18569:382;-1:-1:-1;18503:3:0;;;;:::i;:::-;;;;18465:497;;;-1:-1:-1;18979:12:0;18324:675;-1:-1:-1;;;18324:675:0:o;15785:1072::-;15866:12;15991:16;16071:10;16061:244;;16180:14;16177:1;16174;16159:36;16275:14;16272:1;16265:25;16061:244;16328:14;16361:2;16356:248;;;;16618:99;;;;16823:1;16812:12;;16321:518;;16356:248;16458:14;16455:1;16452;16437:36;16585:1;16579:8;16572:16;16565:24;16554:35;;16356:248;;16618:99;16701:1;16690:12;;16321:518;;;15785:1072;;;:::o;355:173:1:-;423:20;;-1:-1:-1;;;;;472:31:1;;462:42;;452:70;;518:1;515;508:12;452:70;355:173;;;:::o;533:186::-;592:6;645:2;633:9;624:7;620:23;616:32;613:52;;;661:1;658;651:12;613:52;684:29;703:9;684:29;:::i;:::-;674:39;533:186;-1:-1:-1;;;533:186:1:o;1146:260::-;1214:6;1222;1275:2;1263:9;1254:7;1250:23;1246:32;1243:52;;;1291:1;1288;1281:12;1243:52;1314:29;1333:9;1314:29;:::i;:::-;1304:39;;1362:38;1396:2;1385:9;1381:18;1362:38;:::i;:::-;1352:48;;1146:260;;;;;:::o;1801:639::-;1911:6;1919;1972:2;1960:9;1951:7;1947:23;1943:32;1940:52;;;1988:1;1985;1978:12;1940:52;2028:9;2015:23;2057:18;2098:2;2090:6;2087:14;2084:34;;;2114:1;2111;2104:12;2084:34;2152:6;2141:9;2137:22;2127:32;;2197:7;2190:4;2186:2;2182:13;2178:27;2168:55;;2219:1;2216;2209:12;2168:55;2259:2;2246:16;2285:2;2277:6;2274:14;2271:34;;;2301:1;2298;2291:12;2271:34;2354:7;2349:2;2339:6;2336:1;2332:14;2328:2;2324:23;2320:32;2317:45;2314:65;;;2375:1;2372;2365:12;2314:65;2406:2;2398:11;;;;;2428:6;;-1:-1:-1;1801:639:1;;-1:-1:-1;;;;1801:639:1:o;2445:649::-;2562:6;2570;2623:2;2611:9;2602:7;2598:23;2594:32;2591:52;;;2639:1;2636;2629:12;2591:52;2679:9;2666:23;2708:18;2749:2;2741:6;2738:14;2735:34;;;2765:1;2762;2755:12;2735:34;2803:6;2792:9;2788:22;2778:32;;2848:7;2841:4;2837:2;2833:13;2829:27;2819:55;;2870:1;2867;2860:12;2819:55;2910:2;2897:16;2936:2;2928:6;2925:14;2922:34;;;2952:1;2949;2942:12;2922:34;3008:7;3003:2;2995:4;2987:6;2983:17;2979:2;2975:26;2971:35;2968:48;2965:68;;;3029:1;3026;3019:12;3781:127;3842:10;3837:3;3833:20;3830:1;3823:31;3873:4;3870:1;3863:15;3897:4;3894:1;3887:15;3913:322;4003:4;4061:11;4048:25;4155:3;4151:8;4140;4124:14;4120:29;4116:44;4096:18;4092:69;4082:97;;4175:1;4172;4165:12;4082:97;4196:33;;;;;3913:322;-1:-1:-1;;3913:322:1:o;4240:545::-;4333:4;4339:6;4399:11;4386:25;4493:2;4489:7;4478:8;4462:14;4458:29;4454:43;4434:18;4430:68;4420:96;;4512:1;4509;4502:12;4420:96;4539:33;;4591:20;;;-1:-1:-1;4634:18:1;4623:30;;4620:50;;;4666:1;4663;4656:12;4620:50;4699:4;4687:17;;-1:-1:-1;4750:1:1;4746:14;;;4730;4726:35;4716:46;;4713:66;;;4775:1;4772;4765:12;4713:66;4240:545;;;;;:::o;4790:127::-;4851:10;4846:3;4842:20;4839:1;4832:31;4882:4;4879:1;4872:15;4906:4;4903:1;4896:15;4922:135;4961:3;-1:-1:-1;;4982:17:1;;4979:43;;;5002:18;;:::i;:::-;-1:-1:-1;5049:1:1;5038:13;;4922:135::o;5062:356::-;5264:2;5246:21;;;5283:18;;;5276:30;5342:34;5337:2;5322:18;;5315:62;5409:2;5394:18;;5062:356::o;7775:125::-;7815:4;7843:1;7840;7837:8;7834:34;;;7848:18;;:::i;:::-;-1:-1:-1;7885:9:1;;7775:125::o

Swarm Source

ipfs://e686f6bcec02b95fda91dc3aabca349a2d71402ac10c33ecba0ca921213a0733

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ 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.