ETH Price: $2,034.60 (+3.89%)

Contract

0x2011F4805896Ae0BB96FD2990d3d9DB16aB2E2Bc
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Claim Tokens226903322025-06-12 18:40:35270 days ago1749753635IN
0x2011F480...16aB2E2Bc
0 ETH0.000382281.4987473
Claim Tokens226649502025-06-09 5:31:35273 days ago1749447095IN
0x2011F480...16aB2E2Bc
0 ETH0.000271370.99721861
Claim Tokens220821182025-03-19 16:30:23355 days ago1742401823IN
0x2011F480...16aB2E2Bc
0 ETH0.000357021.4
Claim Tokens219618722025-03-02 21:26:23371 days ago1740950783IN
0x2011F480...16aB2E2Bc
0 ETH0.000523532.04637175
Claim Tokens218583122025-02-16 10:18:11386 days ago1739701091IN
0x2011F480...16aB2E2Bc
0 ETH0.000306081.2
Claim Tokens218524132025-02-15 14:26:59387 days ago1739629619IN
0x2011F480...16aB2E2Bc
0 ETH0.000391981.44008826
Claim Tokens218513142025-02-15 10:44:35387 days ago1739616275IN
0x2011F480...16aB2E2Bc
0 ETH0.000197240.72475685
Claim Tokens218276942025-02-12 3:15:35390 days ago1739330135IN
0x2011F480...16aB2E2Bc
0 ETH0.000376871.38070991
Claim Tokens217547652025-02-01 22:50:47400 days ago1738450247IN
0x2011F480...16aB2E2Bc
0 ETH0.000878843.21983379
Claim Tokens217225282025-01-28 10:48:47405 days ago1738061327IN
0x2011F480...16aB2E2Bc
0 ETH0.000970213.56459103
Claim Tokens217189762025-01-27 22:54:11405 days ago1738018451IN
0x2011F480...16aB2E2Bc
0 ETH0.001429725.23856737
Claim Tokens216948242025-01-24 14:01:23409 days ago1737727283IN
0x2011F480...16aB2E2Bc
0 ETH0.0055715721.84230013
Claim Tokens216919722025-01-24 4:28:35409 days ago1737692915IN
0x2011F480...16aB2E2Bc
0 ETH0.000952563.5
Claim Tokens216193312025-01-14 1:06:11419 days ago1736816771IN
0x2011F480...16aB2E2Bc
0 ETH0.001629186.36702697
Claim Tokens216193122025-01-14 1:02:23419 days ago1736816543IN
0x2011F480...16aB2E2Bc
0 ETH0.00154246.04640155
Claim Tokens216153852025-01-13 11:52:59420 days ago1736769179IN
0x2011F480...16aB2E2Bc
0 ETH0.0042975415.7905175
Claim Tokens216000002025-01-11 8:19:11422 days ago1736583551IN
0x2011F480...16aB2E2Bc
0 ETH0.000822513.22474704
Claim Tokens215850162025-01-09 6:04:11424 days ago1736402651IN
0x2011F480...16aB2E2Bc
0 ETH0.001153494.2386318
Claim Tokens215762932025-01-08 0:52:11425 days ago1736297531IN
0x2011F480...16aB2E2Bc
0 ETH0.001658486.48328313
Claim Tokens215717912025-01-07 9:47:23426 days ago1736243243IN
0x2011F480...16aB2E2Bc
0 ETH0.001943677.12055671
Claim Tokens215530742025-01-04 19:01:59429 days ago1736017319IN
0x2011F480...16aB2E2Bc
0 ETH0.002444858.95660527
Claim Tokens215435872025-01-03 11:14:11430 days ago1735902851IN
0x2011F480...16aB2E2Bc
0 ETH0.00196867.71755082
Claim Tokens215139362024-12-30 7:55:59434 days ago1735545359IN
0x2011F480...16aB2E2Bc
0 ETH0.000889653.48801324
Claim Tokens215138152024-12-30 7:31:23434 days ago1735543883IN
0x2011F480...16aB2E2Bc
0 ETH0.000812942.98676465
Claim Tokens215078152024-12-29 11:25:47435 days ago1735471547IN
0x2011F480...16aB2E2Bc
0 ETH0.001071074.18623243
View all transactions

Latest 1 internal transaction

Advanced mode:
Parent Transaction Hash Method Block
From
To
0x3d602d80206624592024-09-02 11:02:47553 days ago1725274967  Contract Creation0 ETH
Loading...
Loading
Loading...
Loading
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

Minimal Proxy Contract for 0xf64677baf779ab1247538986b22863d8abfde9a6

Contract Name:
DCBL2E

Compiler Version
v0.8.25+commit.b61c2a91

Optimization Enabled:
Yes with 10000 runs

Other Settings:
paris EvmVersion

Contract Source Code (Solidity Standard Json-Input format)

// SPDX-License-Identifier: MIT

//** DCB Token Claim Contract */
//** Author: Aceson 2024.5 */

pragma solidity 0.8.25;

import { Initializable } from "openzeppelin-contracts/contracts/proxy/utils/Initializable.sol";
import { MerkleProof } from "openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol";

import { IDCBFactory } from "./interfaces/IDCBFactory.sol";
import { IDCBVesting } from "./interfaces/IDCBVesting.sol";
import { IDCBL2E } from "./interfaces/IDCBL2E.sol";

contract DCBL2E is Initializable, IDCBL2E {
    // Reference to the factory contract
    IDCBFactory public _factory;

    // Reference to the vesting contract
    IDCBVesting public _vesting;

    // Mapping to store the allocation per user
    mapping(address => uint256) public userAllocation;

    // Struct to store claim information
    ClaimInfo public claimInfo;

    // Array to store the participants
    address[] private participants;

    // Merkle root for verifying user claims
    bytes32 public merkleRoot;

    // Constant representing the version of the contract
    uint8 public constant VERSION = 2;

    // Modifier to ensure that only the manager can call certain functions
    modifier onlyManager() {
        if (!_factory.hasRole(keccak256("MANAGER_ROLE"), msg.sender)) revert OnlyManager();
        _;
    }

    /// @notice Initializes the L2E contract with the given parameters
    /// @param p Struct containing parameters for initialization
    function initialize(Params calldata p) external initializer {
        // Revert if the distribution amount is zero or if the end date is in the past
        if (p.distAmount == 0 || p.endDate < block.timestamp) revert InvalidParams();

        // Set the factory and vesting contract references
        _factory = IDCBFactory(msg.sender);
        _vesting = IDCBVesting(p.vestingAddr);

        // Initialize the claim information
        claimInfo.distAmount = p.distAmount;
        claimInfo.createDate = uint32(block.timestamp);
        claimInfo.endDate = p.endDate;

        // Emit an event for the creation of a new claim event
        emit CreateL2E(p);
    }

    /// @notice Sets the parameters for the claim
    /// @param p Struct containing parameters for the claim
    function setParams(Params calldata p) external {
        // Ensure that only the factory can call this function
        if (msg.sender != address(_factory)) revert OnlyFactory();

        // Revert if the distribution amount is zero or if the end date is in the past
        if (p.distAmount == 0 || p.endDate < block.timestamp) revert InvalidParams();

        // Update the claim information
        claimInfo.distAmount = p.distAmount;
        claimInfo.endDate = p.endDate;
    }

    /// @notice Sets the merkle root for the claim
    /// @param _merkleRoot The merkle root of the agreement
    function setMerkleRoot(bytes32 _merkleRoot) external onlyManager {
        // Ensure that the merkle root is not already set
        if (merkleRoot != 0x0) revert MerkleRootAlreadySet();

        // Set the merkle root
        merkleRoot = _merkleRoot;
    }

    /// @notice Allows users to claim tokens based on their allocation
    /// @param amount The amount of tokens to claim
    /// @param merkleProof The merkle proof for the user
    /// @return Returns true if the claim is successful
    function claimTokens(uint256 amount, bytes32[] calldata merkleProof) external returns (bool) {
        // Ensure that the merkle root is set
        if (merkleRoot == 0x0) revert MerkleRootNotSet();

        // Ensure that the user has not already claimed
        if (userAllocation[msg.sender] != 0) revert AlreadyClaimed();

        // Ensure that the claim period has ended
        if (block.timestamp < claimInfo.endDate) revert NotEnded();

        // Verify the merkle proof
        bytes32 leaf = keccak256(bytes.concat(keccak256(abi.encode(msg.sender, amount))));
        if (!MerkleProof.verify(merkleProof, merkleRoot, leaf)) revert InvalidMerkleProof();

        // Record the user's allocation
        userAllocation[msg.sender] = amount;

        // Add the user to the list of participants
        participants.push(msg.sender);

        // Record the user's investment in the factory and vesting contracts
        _factory.setUserInvestment(msg.sender, address(this), amount);
        _vesting.setL2EWhitelist(msg.sender, amount);

        // Emit an event for the user's claim
        emit UserClaimed(msg.sender, amount);

        return true;
    }

    /// @notice Getter function for the list of participants
    /// @return Returns the total participants of the L2E
    function getParticipants() external view returns (address[] memory) {
        return participants;
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (proxy/utils/Initializable.sol)

pragma solidity ^0.8.2;

import "../../utils/Address.sol";

/**
 * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
 * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
 * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
 * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
 *
 * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
 * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
 * case an upgrade adds a module that needs to be initialized.
 *
 * For example:
 *
 * [.hljs-theme-light.nopadding]
 * ```solidity
 * contract MyToken is ERC20Upgradeable {
 *     function initialize() initializer public {
 *         __ERC20_init("MyToken", "MTK");
 *     }
 * }
 *
 * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
 *     function initializeV2() reinitializer(2) public {
 *         __ERC20Permit_init("MyToken");
 *     }
 * }
 * ```
 *
 * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
 * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
 *
 * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
 * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
 *
 * [CAUTION]
 * ====
 * Avoid leaving a contract uninitialized.
 *
 * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
 * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
 * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
 *
 * [.hljs-theme-light.nopadding]
 * ```
 * /// @custom:oz-upgrades-unsafe-allow constructor
 * constructor() {
 *     _disableInitializers();
 * }
 * ```
 * ====
 */
abstract contract Initializable {
    /**
     * @dev Indicates that the contract has been initialized.
     * @custom:oz-retyped-from bool
     */
    uint8 private _initialized;

    /**
     * @dev Indicates that the contract is in the process of being initialized.
     */
    bool private _initializing;

    /**
     * @dev Triggered when the contract has been initialized or reinitialized.
     */
    event Initialized(uint8 version);

    /**
     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
     * `onlyInitializing` functions can be used to initialize parent contracts.
     *
     * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a
     * constructor.
     *
     * Emits an {Initialized} event.
     */
    modifier initializer() {
        bool isTopLevelCall = !_initializing;
        require(
            (isTopLevelCall && _initialized < 1) || (!Address.isContract(address(this)) && _initialized == 1),
            "Initializable: contract is already initialized"
        );
        _initialized = 1;
        if (isTopLevelCall) {
            _initializing = true;
        }
        _;
        if (isTopLevelCall) {
            _initializing = false;
            emit Initialized(1);
        }
    }

    /**
     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
     * used to initialize parent contracts.
     *
     * A reinitializer may be used after the original initialization step. This is essential to configure modules that
     * are added through upgrades and that require initialization.
     *
     * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
     * cannot be nested. If one is invoked in the context of another, execution will revert.
     *
     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
     * a contract, executing them in the right order is up to the developer or operator.
     *
     * WARNING: setting the version to 255 will prevent any future reinitialization.
     *
     * Emits an {Initialized} event.
     */
    modifier reinitializer(uint8 version) {
        require(!_initializing && _initialized < version, "Initializable: contract is already initialized");
        _initialized = version;
        _initializing = true;
        _;
        _initializing = false;
        emit Initialized(version);
    }

    /**
     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
     * {initializer} and {reinitializer} modifiers, directly or indirectly.
     */
    modifier onlyInitializing() {
        require(_initializing, "Initializable: contract is not initializing");
        _;
    }

    /**
     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called
     * through proxies.
     *
     * Emits an {Initialized} event the first time it is successfully executed.
     */
    function _disableInitializers() internal virtual {
        require(!_initializing, "Initializable: contract is initializing");
        if (_initialized != type(uint8).max) {
            _initialized = type(uint8).max;
            emit Initialized(type(uint8).max);
        }
    }

    /**
     * @dev Returns the highest version that has been initialized. See {reinitializer}.
     */
    function _getInitializedVersion() internal view returns (uint8) {
        return _initialized;
    }

    /**
     * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
     */
    function _isInitializing() internal view returns (bool) {
        return _initializing;
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     *
     * Furthermore, `isContract` will also return true if the target contract within
     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
     * which only has an effect at the end of a transaction.
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // Look for revert reason and bubble it up if present
        if (returndata.length > 0) {
            // The easiest way to bubble the revert reason is using memory via assembly
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/MerkleProof.sol)

pragma solidity ^0.8.0;

/**
 * @dev These functions deal with verification of Merkle Tree proofs.
 *
 * The tree and the proofs can be generated using our
 * https://github.com/OpenZeppelin/merkle-tree[JavaScript library].
 * You will find a quickstart guide in the readme.
 *
 * WARNING: You should avoid using leaf values that are 64 bytes long prior to
 * hashing, or use a hash function other than keccak256 for hashing leaves.
 * This is because the concatenation of a sorted pair of internal nodes in
 * the merkle tree could be reinterpreted as a leaf value.
 * OpenZeppelin's JavaScript library generates merkle trees that are safe
 * against this attack out of the box.
 */
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 Calldata version of {verify}
     *
     * _Available since v4.7._
     */
    function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {
        return processProofCalldata(proof, leaf) == root;
    }

    /**
     * @dev Returns the rebuilt hash obtained by traversing a Merkle 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++) {
            computedHash = _hashPair(computedHash, proof[i]);
        }
        return computedHash;
    }

    /**
     * @dev Calldata version of {processProof}
     *
     * _Available since v4.7._
     */
    function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            computedHash = _hashPair(computedHash, proof[i]);
        }
        return computedHash;
    }

    /**
     * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a merkle tree defined by
     * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _Available since v4.7._
     */
    function multiProofVerify(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32 root,
        bytes32[] memory leaves
    ) internal pure returns (bool) {
        return processMultiProof(proof, proofFlags, leaves) == root;
    }

    /**
     * @dev Calldata version of {multiProofVerify}
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _Available since v4.7._
     */
    function multiProofVerifyCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32 root,
        bytes32[] memory leaves
    ) internal pure returns (bool) {
        return processMultiProofCalldata(proof, proofFlags, leaves) == root;
    }

    /**
     * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction
     * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another
     * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false
     * respectively.
     *
     * CAUTION: Not all merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree
     * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the
     * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer).
     *
     * _Available since v4.7._
     */
    function processMultiProof(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by
        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
        // the merkle tree.
        uint256 leavesLen = leaves.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof");

        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
        bytes32[] memory hashes = new bytes32[](totalHashes);
        uint256 leafPos = 0;
        uint256 hashPos = 0;
        uint256 proofPos = 0;
        // At each step, we compute the next hash using two values:
        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
        //   get the next hash.
        // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the
        //   `proof` array.
        for (uint256 i = 0; i < totalHashes; i++) {
            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
            bytes32 b = proofFlags[i]
                ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])
                : proof[proofPos++];
            hashes[i] = _hashPair(a, b);
        }

        if (totalHashes > 0) {
            unchecked {
                return hashes[totalHashes - 1];
            }
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    /**
     * @dev Calldata version of {processMultiProof}.
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _Available since v4.7._
     */
    function processMultiProofCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by
        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
        // the merkle tree.
        uint256 leavesLen = leaves.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof");

        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
        bytes32[] memory hashes = new bytes32[](totalHashes);
        uint256 leafPos = 0;
        uint256 hashPos = 0;
        uint256 proofPos = 0;
        // At each step, we compute the next hash using two values:
        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
        //   get the next hash.
        // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the
        //   `proof` array.
        for (uint256 i = 0; i < totalHashes; i++) {
            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
            bytes32 b = proofFlags[i]
                ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])
                : proof[proofPos++];
            hashes[i] = _hashPair(a, b);
        }

        if (totalHashes > 0) {
            unchecked {
                return hashes[totalHashes - 1];
            }
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {
        return a < b ? _efficientHash(a, b) : _efficientHash(b, a);
    }

    function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, a)
            mstore(0x20, b)
            value := keccak256(0x00, 0x40)
        }
    }
}

// SPDX-License-Identifier: UNLICENSED

//** DCB Investments Interface */
//** Author Aaron & Aceson : DCB 2023.2 */

pragma solidity 0.8.25;

interface IDCBFactory {
    function changeImplementations(address _newVesting, address _newL2E, address _newIDO) external;

    function hasRole(bytes32, address) external view returns (bool);

    function claimDistribution(address _event) external returns (bool);

    function idoImpl() external view returns (address);

    function eventsList(uint256) external view returns (address);

    function getUserInvestments(address _address) external view returns (address[] memory);

    function initialize() external;

    function numUserInvestments(address) external view returns (uint256);

    function setManagerRole(address _user, bool _status) external;

    function setUserInvestment(address _address, address _event, uint256 _amount) external returns (bool);

    function l2eImpl() external view returns (address);

    function userAmount(address, address) external view returns (uint256);

    function vestingImpl() external view returns (address);
}

// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.25;

/* solhint-disable */

interface IDCBL2E {
    struct Params {
        uint32 endDate;
        address rewardTokenAddr;
        address vestingAddr;
        uint256 distAmount;
    }

    struct ClaimInfo {
        uint32 createDate; //Created date
        uint32 endDate; //Event end date
        uint256 distAmount; //Total distributed amount
    }

    error OnlyManager();
    error InvalidParams();
    error OnlyFactory();
    error AlreadyClaimed();
    error NotEnded();
    error InvalidMerkleProof();
    error MerkleRootAlreadySet();
    error MerkleRootNotSet();

    event CreateL2E(Params p);
    event UserRegistered(address user);
    event UserNotRegistered(address user);
    event UserClaimed(address user, uint256 amount);

    function claimInfo() external view returns (uint32 createDate, uint32 endDate, uint256 distAmount);

    function claimTokens(uint256 amount, bytes32[] calldata merkleProof) external returns (bool);

    function getParticipants() external view returns (address[] memory);

    function initialize(Params memory p) external;

    function setParams(Params calldata p) external;
}

// SPDX-License-Identifier: MIT

//** DCB Vesting Interface */

pragma solidity 0.8.25;

interface IDCBVesting {
    struct VestingInfo {
        uint256 cliff;
        uint256 start;
        uint256 duration;
        uint256 initialUnlockPercent;
    }

    struct VestingPool {
        uint256 cliff;
        uint256 start;
        uint256 duration;
        uint256 initialUnlockPercent;
        WhitelistInfo[] whitelistPool;
        mapping(address => HasWhitelist) hasWhitelist;
    }

    /**
     *
     * @dev WhiteInfo is the struct type which store whitelist information
     *
     */
    struct WhitelistInfo {
        bool refunded;
        address wallet;
        uint256 amount;
        uint256 distributedAmount;
        uint256 value; // price * amount in decimals of payment token
        uint256 refundFee;
        uint256 refundDate;
    }

    struct HasWhitelist {
        uint256 arrIdx;
        bool active;
    }

    struct ContractSetup {
        address _innovator;
        address _vestedToken;
        address _paymentToken;
        uint256 _totalTokenOnSale;
        uint256 _gracePeriod;
    }

    struct VestingSetup {
        uint256 _startTime;
        uint256 _cliff;
        uint256 _duration;
        uint256 _initialUnlockPercent;
    }

    error OnlyInnovator();
    error OnlyFactory();
    error UserNotInWhitelist();
    error InvalidParams();
    error VestingAlreadyStarted();
    error AlreadyVested();
    error AlreadyRefunded();
    error AlreadyClaimed();
    error NotInGracePeriod();
    error IDOStillInProgress();
    error GracePeriodInProgress();
    error ZeroAmount();
    error AlreadyRegistered();
    error FundsNotClaimed();

    event IDOInitialized(ContractSetup c, VestingSetup p);
    event IDOSet(ContractSetup c);
    event L2EInitialized(address _token, VestingSetup p);
    event RaisedFundsClaimed(uint256 payment, uint256 remaining);
    event BuybackAndBurn(uint256 amount);
    event SetVestingParams(uint256 _cliff, uint256 _start, uint256 _duration, uint256 _initialUnlockPercent);
    event Claim(address indexed token, uint256 amount, uint256 time);
    event SetWhitelist(address indexed wallet, uint256 amount, uint256 value);
    event Refund(address indexed wallet, uint256 amount);

    function initializeIDO(ContractSetup memory c, VestingSetup memory p) external;

    function initializeL2E(address _token, VestingSetup memory p) external;

    function setIDOWhitelist(address _wallet, uint256 _amount, uint256 _value, uint256 _refundFee) external;

    function setL2EWhitelist(address _wallet, uint256 _amount) external;

    function claimDistribution(address _wallet) external returns (bool);

    function getWhitelist(address _wallet) external view returns (WhitelistInfo memory);

    function getWhitelistPool() external view returns (WhitelistInfo[] memory);

    function transferOwnership(address _newOwner) external;

    function setVestingParams(
        uint256 _cliff,
        uint256 _start,
        uint256 _duration,
        uint256 _initialUnlockPercent
    )
        external;

    function setIDOParams(ContractSetup calldata c) external;

    function setToken(address _newToken) external;

    function rescueTokens(address _receiver, uint256 _amount) external;

    /**
     *
     * inherit functions will be used in contract
     *
     */
    function getVestAmount(address _wallet) external view returns (uint256);

    function getReleasableAmount(address _wallet) external view returns (uint256);

    function getVestingInfo() external view returns (VestingInfo memory);
}

Settings
{
  "metadata": {
    "bytecodeHash": "none"
  },
  "optimizer": {
    "enabled": true,
    "runs": 10000
  },
  "evmVersion": "paris",
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract ABI

API
[{"inputs":[],"name":"AlreadyClaimed","type":"error"},{"inputs":[],"name":"InvalidMerkleProof","type":"error"},{"inputs":[],"name":"InvalidParams","type":"error"},{"inputs":[],"name":"MerkleRootAlreadySet","type":"error"},{"inputs":[],"name":"MerkleRootNotSet","type":"error"},{"inputs":[],"name":"NotEnded","type":"error"},{"inputs":[],"name":"OnlyFactory","type":"error"},{"inputs":[],"name":"OnlyManager","type":"error"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint32","name":"endDate","type":"uint32"},{"internalType":"address","name":"rewardTokenAddr","type":"address"},{"internalType":"address","name":"vestingAddr","type":"address"},{"internalType":"uint256","name":"distAmount","type":"uint256"}],"indexed":false,"internalType":"struct IDCBL2E.Params","name":"p","type":"tuple"}],"name":"CreateL2E","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"UserClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"}],"name":"UserNotRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"}],"name":"UserRegistered","type":"event"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_factory","outputs":[{"internalType":"contract IDCBFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_vesting","outputs":[{"internalType":"contract IDCBVesting","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimInfo","outputs":[{"internalType":"uint32","name":"createDate","type":"uint32"},{"internalType":"uint32","name":"endDate","type":"uint32"},{"internalType":"uint256","name":"distAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"claimTokens","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getParticipants","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"endDate","type":"uint32"},{"internalType":"address","name":"rewardTokenAddr","type":"address"},{"internalType":"address","name":"vestingAddr","type":"address"},{"internalType":"uint256","name":"distAmount","type":"uint256"}],"internalType":"struct IDCBL2E.Params","name":"p","type":"tuple"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"}],"name":"setMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"endDate","type":"uint32"},{"internalType":"address","name":"rewardTokenAddr","type":"address"},{"internalType":"address","name":"vestingAddr","type":"address"},{"internalType":"uint256","name":"distAmount","type":"uint256"}],"internalType":"struct IDCBL2E.Params","name":"p","type":"tuple"}],"name":"setParams","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userAllocation","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

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.