Overview
S Balance
S Value
$0.00More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Name:
DeFiveLpClaiming
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 9999 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.20; import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; contract DeFiveLpClaiming is Ownable, ReentrancyGuard { using SafeERC20 for IERC20; // State variables for tracking claims mapping(address => uint256) private _claims; // Claiming parameters IERC20 private _token; uint256 private _totalMigrated; uint256 private _totalClaimable; uint256 private _totalClaimedAmount; uint256 private _openingTime; uint256 private _closingTime; bool private _finalized; uint256 private _totalClaimedCounter; bytes32 private _merkleRoot; // Events event Claimed(address indexed user, uint256 claimedAmount); event Finalized(address indexed owner, uint256 totalMigrated, uint256 totalBurned); event MerkleRootSet(bytes32 merkleRoot); // Modifier to ensure actions are only performed while the claiming is active modifier onlyWhileActive() { require(_isClaimingActive(), "Claiming not active"); _; } // Modifier to ensure actions are only performed after claiming closes modifier onlyWhileClosed() { require(!_isClaimingActive(), "Claiming still active"); _; } // Modifier to ensure actions are performed before the claiming starts modifier beforeClaimingStart() { require(block.timestamp < _openingTime, "Claiming has already started"); _; } // Constructor for initializing the claiming contract constructor( address initialOwner, IERC20 token, uint256 totalMigrated, uint256 totalClaimable, uint256 openingTime, uint256 closingTime, bytes32 merkleRoot ) Ownable(initialOwner) { require(address(token) != address(0), "Invalid token address"); require(openingTime >= block.timestamp, "Opening time must be in the future"); require(closingTime > openingTime, "Closing time must be after opening time"); require(totalMigrated > 0, "Total Migrated must be greater than zero"); require(totalClaimable > 0, "Total Claimable must be greater than zero"); require(merkleRoot != bytes32(0), "Merkle root cannot be zero"); _token = token; _totalMigrated = totalMigrated; _totalClaimable = totalClaimable; _openingTime = openingTime; _closingTime = closingTime; _finalized = false; _totalClaimedCounter = 0; _merkleRoot = merkleRoot; } // Function to allow claiming with Merkle proof verification function claim(uint256 amount, bytes32[] calldata merkleProof) public onlyWhileActive nonReentrant { require(_claims[msg.sender] == 0, "User has already claimed"); require(amount > 0, "Claim amount must be greater than zero"); // Verify the Merkle proof bytes32 leaf = keccak256(abi.encode(msg.sender, amount)); require(MerkleProof.verify(merkleProof, _merkleRoot, leaf), "Invalid Merkle proof"); uint256 availableBalance = _token.balanceOf(address(this)); // Calculate user's proportional share uint256 userAlloc = (amount * _totalClaimable) / _totalMigrated; uint256 claimingAmount = userAlloc > availableBalance ? availableBalance : userAlloc; _totalClaimedAmount += claimingAmount; _totalClaimedCounter++; _claims[msg.sender] = claimingAmount; _token.safeTransfer(msg.sender, claimingAmount); emit Claimed(msg.sender, claimingAmount); } // Finalize the claiming after successful completion function finalize() public onlyOwner onlyWhileClosed nonReentrant { require(!_finalized, "Claiming already finalized"); uint256 remainingTokens = _token.balanceOf(address(this)); require(remainingTokens > 0, "No remaining tokens to burn"); _token.safeTransfer(msg.sender, remainingTokens); _finalized = true; emit Finalized(msg.sender, _totalClaimedAmount, remainingTokens); } // Internal function to check if claiming is currently active function _isClaimingActive() internal view returns (bool) { return block.timestamp >= _openingTime && block.timestamp <= _closingTime; } function getTotalClaimed() public view returns (uint256) { return _totalClaimedAmount; } function getTotalMigrated() public view returns (uint256) { return _totalMigrated; } function getTotalClaimable() public view returns (uint256) { return _totalClaimable; } function getOpeningTime() public view returns (uint256) { return _openingTime; } function getClosingTime() public view returns (uint256) { return _closingTime; } function isFinalized() public view returns (bool) { return _finalized; } function getClaims(address user) public view returns (uint256) { return _claims[user]; } function isClaimingActive() public view returns (bool) { return _isClaimingActive(); } function getTotalClaimedCounter() public view returns (uint256) { return _totalClaimedCounter; } function getToken() public view returns (address) { return address(_token); } function getMerkleRoot() public view returns (bytes32) { return _merkleRoot; } function setMerkleRoot(bytes32 merkleRoot) public onlyOwner beforeClaimingStart { require(merkleRoot != bytes32(0), "Merkle root cannot be zero"); _merkleRoot = merkleRoot; emit MerkleRootSet(merkleRoot); } function setOpeningTime(uint256 openingTime) public onlyOwner beforeClaimingStart { require(openingTime >= block.timestamp, "Opening time must be in the future"); _openingTime = openingTime; } function setClosingTime(uint256 closingTime) public onlyOwner beforeClaimingStart { require(closingTime > _openingTime, "Closing time must be after opening time"); _closingTime = closingTime; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; import {Context} from "../utils/Context.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. * * The initial owner is set to the address provided by the deployer. 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; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling 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 { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _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); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (interfaces/IERC1363.sol) pragma solidity ^0.8.20; import {IERC20} from "./IERC20.sol"; import {IERC165} from "./IERC165.sol"; /** * @title IERC1363 * @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363]. * * Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract * after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction. */ interface IERC1363 is IERC20, IERC165 { /* * Note: the ERC-165 identifier for this interface is 0xb0202a11. * 0xb0202a11 === * bytes4(keccak256('transferAndCall(address,uint256)')) ^ * bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^ * bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^ * bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^ * bytes4(keccak256('approveAndCall(address,uint256)')) ^ * bytes4(keccak256('approveAndCall(address,uint256,bytes)')) */ /** * @dev Moves a `value` amount of tokens from the caller's account to `to` * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferAndCall(address to, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from the caller's account to `to` * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @param data Additional data with no specified format, sent in call to `to`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param from The address which you want to send tokens from. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferFromAndCall(address from, address to, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param from The address which you want to send tokens from. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @param data Additional data with no specified format, sent in call to `to`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`. * @param spender The address which will spend the funds. * @param value The amount of tokens to be spent. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function approveAndCall(address spender, uint256 value) external returns (bool); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`. * @param spender The address which will spend the funds. * @param value The amount of tokens to be spent. * @param data Additional data with no specified format, sent in call to `spender`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC165.sol) pragma solidity ^0.8.20; import {IERC165} from "../utils/introspection/IERC165.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "../token/ERC20/IERC20.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-20 standard as defined in the ERC. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 value) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 value) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.2.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "../IERC20.sol"; import {IERC1363} from "../../../interfaces/IERC1363.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC-20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { /** * @dev An operation with an ERC-20 token failed. */ error SafeERC20FailedOperation(address token); /** * @dev Indicates a failed `decreaseAllowance` request. */ error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease); /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value))); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value))); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. * * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client" * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); forceApprove(token, spender, oldAllowance + value); } /** * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no * value, non-reverting calls are assumed to be successful. * * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client" * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal { unchecked { uint256 currentAllowance = token.allowance(address(this), spender); if (currentAllowance < requestedDecrease) { revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease); } forceApprove(token, spender, currentAllowance - requestedDecrease); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. * * NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function * only sets the "standard" allowance. Any temporary allowance will remain active, in addition to the value being * set here. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value)); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0))); _callOptionalReturn(token, approvalCall); } } /** * @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * Reverts if the returned value is other than `true`. */ function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal { if (to.code.length == 0) { safeTransfer(token, to, value); } else if (!token.transferAndCall(to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target * has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * Reverts if the returned value is other than `true`. */ function transferFromAndCallRelaxed( IERC1363 token, address from, address to, uint256 value, bytes memory data ) internal { if (to.code.length == 0) { safeTransferFrom(token, from, to, value); } else if (!token.transferFromAndCall(from, to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}. * Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall} * once without retrying, and relies on the returned value to be true. * * Reverts if the returned value is other than `true`. */ function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal { if (to.code.length == 0) { forceApprove(token, to, value); } else if (!token.approveAndCall(to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturnBool} that reverts if call fails to meet the requirements. */ function _callOptionalReturn(IERC20 token, bytes memory data) private { uint256 returnSize; uint256 returnValue; assembly ("memory-safe") { let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20) // bubble errors if iszero(success) { let ptr := mload(0x40) returndatacopy(ptr, 0, returndatasize()) revert(ptr, returndatasize()) } returnSize := returndatasize() returnValue := mload(0) } if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silently catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { bool success; uint256 returnSize; uint256 returnValue; assembly ("memory-safe") { success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20) returnSize := returndatasize() returnValue := mload(0) } return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @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; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/cryptography/Hashes.sol) pragma solidity ^0.8.20; /** * @dev Library of standard hash functions. * * _Available since v5.1._ */ library Hashes { /** * @dev Commutative Keccak256 hash of a sorted pair of bytes32. Frequently used when working with merkle proofs. * * NOTE: Equivalent to the `standardNodeHash` in our https://github.com/OpenZeppelin/merkle-tree[JavaScript library]. */ function commutativeKeccak256(bytes32 a, bytes32 b) internal pure returns (bytes32) { return a < b ? _efficientKeccak256(a, b) : _efficientKeccak256(b, a); } /** * @dev Implementation of keccak256(abi.encode(a, b)) that doesn't allocate or expand memory. */ function _efficientKeccak256(bytes32 a, bytes32 b) private pure returns (bytes32 value) { assembly ("memory-safe") { mstore(0x00, a) mstore(0x20, b) value := keccak256(0x00, 0x40) } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/cryptography/MerkleProof.sol) // This file was procedurally generated from scripts/generate/templates/MerkleProof.js. pragma solidity ^0.8.20; import {Hashes} from "./Hashes.sol"; /** * @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. * * IMPORTANT: Consider memory side-effects when using custom hashing functions * that access memory in an unsafe way. * * NOTE: This library supports proof verification for merkle trees built using * custom _commutative_ hashing functions (i.e. `H(a, b) == H(b, a)`). Proving * leaf inclusion in trees built using non-commutative hashing functions requires * additional logic that is not supported by this library. */ library MerkleProof { /** *@dev The multiproof provided is not valid. */ error MerkleProofInvalidMultiproof(); /** * @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. * * This version handles proofs in memory with the default hashing function. */ 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 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 leaves & pre-images are assumed to be sorted. * * This version handles proofs in memory with the default hashing function. */ function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = Hashes.commutativeKeccak256(computedHash, proof[i]); } return computedHash; } /** * @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. * * This version handles proofs in memory with a custom hashing function. */ function verify( bytes32[] memory proof, bytes32 root, bytes32 leaf, function(bytes32, bytes32) view returns (bytes32) hasher ) internal view returns (bool) { return processProof(proof, leaf, hasher) == 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 leaves & pre-images are assumed to be sorted. * * This version handles proofs in memory with a custom hashing function. */ function processProof( bytes32[] memory proof, bytes32 leaf, function(bytes32, bytes32) view returns (bytes32) hasher ) internal view returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = hasher(computedHash, proof[i]); } return computedHash; } /** * @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. * * This version handles proofs in calldata with the default hashing function. */ 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 leaves & pre-images are assumed to be sorted. * * This version handles proofs in calldata with the default hashing function. */ function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = Hashes.commutativeKeccak256(computedHash, proof[i]); } return computedHash; } /** * @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. * * This version handles proofs in calldata with a custom hashing function. */ function verifyCalldata( bytes32[] calldata proof, bytes32 root, bytes32 leaf, function(bytes32, bytes32) view returns (bytes32) hasher ) internal view returns (bool) { return processProofCalldata(proof, leaf, hasher) == 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 leaves & pre-images are assumed to be sorted. * * This version handles proofs in calldata with a custom hashing function. */ function processProofCalldata( bytes32[] calldata proof, bytes32 leaf, function(bytes32, bytes32) view returns (bytes32) hasher ) internal view returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = hasher(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}. * * This version handles multiproofs in memory with the default hashing function. * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. * * NOTE: Consider the case where `root == proof[0] && leaves.length == 0` as it will return `true`. * The `leaves` must be validated independently. See {processMultiProof}. */ function multiProofVerify( bytes32[] memory proof, bool[] memory proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProof(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. * * This version handles multiproofs in memory with the default hashing function. * * 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). * * NOTE: The _empty set_ (i.e. the case where `proof.length == 1 && leaves.length == 0`) is considered a no-op, * and therefore a valid multiproof (i.e. it returns `proof[0]`). Consider disallowing this case if you're not * validating the leaves elsewhere. */ 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 proofFlagsLen = proofFlags.length; // Check proof validity. if (leavesLen + proof.length != proofFlagsLen + 1) { revert MerkleProofInvalidMultiproof(); } // 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[](proofFlagsLen); 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 < proofFlagsLen; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = Hashes.commutativeKeccak256(a, b); } if (proofFlagsLen > 0) { if (proofPos != proof.length) { revert MerkleProofInvalidMultiproof(); } unchecked { return hashes[proofFlagsLen - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @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}. * * This version handles multiproofs in memory with a custom hashing function. * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. * * NOTE: Consider the case where `root == proof[0] && leaves.length == 0` as it will return `true`. * The `leaves` must be validated independently. See {processMultiProof}. */ function multiProofVerify( bytes32[] memory proof, bool[] memory proofFlags, bytes32 root, bytes32[] memory leaves, function(bytes32, bytes32) view returns (bytes32) hasher ) internal view returns (bool) { return processMultiProof(proof, proofFlags, leaves, hasher) == 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. * * This version handles multiproofs in memory with a custom hashing function. * * 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). * * NOTE: The _empty set_ (i.e. the case where `proof.length == 1 && leaves.length == 0`) is considered a no-op, * and therefore a valid multiproof (i.e. it returns `proof[0]`). Consider disallowing this case if you're not * validating the leaves elsewhere. */ function processMultiProof( bytes32[] memory proof, bool[] memory proofFlags, bytes32[] memory leaves, function(bytes32, bytes32) view returns (bytes32) hasher ) internal view 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 proofFlagsLen = proofFlags.length; // Check proof validity. if (leavesLen + proof.length != proofFlagsLen + 1) { revert MerkleProofInvalidMultiproof(); } // 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[](proofFlagsLen); 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 < proofFlagsLen; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = hasher(a, b); } if (proofFlagsLen > 0) { if (proofPos != proof.length) { revert MerkleProofInvalidMultiproof(); } unchecked { return hashes[proofFlagsLen - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @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}. * * This version handles multiproofs in calldata with the default hashing function. * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. * * NOTE: Consider the case where `root == proof[0] && leaves.length == 0` as it will return `true`. * The `leaves` must be validated independently. See {processMultiProofCalldata}. */ 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. * * This version handles multiproofs in calldata with the default hashing function. * * 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). * * NOTE: The _empty set_ (i.e. the case where `proof.length == 1 && leaves.length == 0`) is considered a no-op, * and therefore a valid multiproof (i.e. it returns `proof[0]`). Consider disallowing this case if you're not * validating the leaves elsewhere. */ 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 proofFlagsLen = proofFlags.length; // Check proof validity. if (leavesLen + proof.length != proofFlagsLen + 1) { revert MerkleProofInvalidMultiproof(); } // 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[](proofFlagsLen); 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 < proofFlagsLen; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = Hashes.commutativeKeccak256(a, b); } if (proofFlagsLen > 0) { if (proofPos != proof.length) { revert MerkleProofInvalidMultiproof(); } unchecked { return hashes[proofFlagsLen - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @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}. * * This version handles multiproofs in calldata with a custom hashing function. * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. * * NOTE: Consider the case where `root == proof[0] && leaves.length == 0` as it will return `true`. * The `leaves` must be validated independently. See {processMultiProofCalldata}. */ function multiProofVerifyCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32 root, bytes32[] memory leaves, function(bytes32, bytes32) view returns (bytes32) hasher ) internal view returns (bool) { return processMultiProofCalldata(proof, proofFlags, leaves, hasher) == 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. * * This version handles multiproofs in calldata with a custom hashing function. * * 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). * * NOTE: The _empty set_ (i.e. the case where `proof.length == 1 && leaves.length == 0`) is considered a no-op, * and therefore a valid multiproof (i.e. it returns `proof[0]`). Consider disallowing this case if you're not * validating the leaves elsewhere. */ function processMultiProofCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32[] memory leaves, function(bytes32, bytes32) view returns (bytes32) hasher ) internal view 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 proofFlagsLen = proofFlags.length; // Check proof validity. if (leavesLen + proof.length != proofFlagsLen + 1) { revert MerkleProofInvalidMultiproof(); } // 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[](proofFlagsLen); 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 < proofFlagsLen; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = hasher(a, b); } if (proofFlagsLen > 0) { if (proofPos != proof.length) { revert MerkleProofInvalidMultiproof(); } unchecked { return hashes[proofFlagsLen - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[ERC]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuard.sol) pragma solidity ^0.8.20; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If EIP-1153 (transient storage) is available on the chain you're deploying at, * consider using {ReentrancyGuardTransient} instead. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant NOT_ENTERED = 1; uint256 private constant ENTERED = 2; uint256 private _status; /** * @dev Unauthorized reentrant call. */ error ReentrancyGuardReentrantCall(); constructor() { _status = NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be NOT_ENTERED if (_status == ENTERED) { revert ReentrancyGuardReentrantCall(); } // Any calls to nonReentrant after this point will fail _status = ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == ENTERED; } }
{ "optimizer": { "enabled": true, "runs": 9999 }, "metadata": { "bytecodeHash": "none", "useLiteralContent": true }, "evmVersion": "paris", "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"initialOwner","type":"address"},{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"uint256","name":"totalMigrated","type":"uint256"},{"internalType":"uint256","name":"totalClaimable","type":"uint256"},{"internalType":"uint256","name":"openingTime","type":"uint256"},{"internalType":"uint256","name":"closingTime","type":"uint256"},{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"claimedAmount","type":"uint256"}],"name":"Claimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"totalMigrated","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalBurned","type":"uint256"}],"name":"Finalized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"merkleRoot","type":"bytes32"}],"name":"MerkleRootSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"finalize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getClaims","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getClosingTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMerkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOpeningTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalClaimable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalClaimed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalClaimedCounter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalMigrated","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isClaimingActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isFinalized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"uint256","name":"closingTime","type":"uint256"}],"name":"setClosingTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"}],"name":"setMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"openingTime","type":"uint256"}],"name":"setOpeningTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b506040516200141d3803806200141d833981016040819052620000349162000356565b866001600160a01b0381166200006557604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b6200007081620002ed565b50600180556001600160a01b038616620000cd5760405162461bcd60e51b815260206004820152601560248201527f496e76616c696420746f6b656e2061646472657373000000000000000000000060448201526064016200005c565b428310156200012a5760405162461bcd60e51b815260206004820152602260248201527f4f70656e696e672074696d65206d75737420626520696e207468652066757475604482015261726560f01b60648201526084016200005c565b8282116200018b5760405162461bcd60e51b815260206004820152602760248201527f436c6f73696e672074696d65206d757374206265206166746572206f70656e696044820152666e672074696d6560c81b60648201526084016200005c565b60008511620001ee5760405162461bcd60e51b815260206004820152602860248201527f546f74616c204d69677261746564206d7573742062652067726561746572207460448201526768616e207a65726f60c01b60648201526084016200005c565b60008411620002525760405162461bcd60e51b815260206004820152602960248201527f546f74616c20436c61696d61626c65206d7573742062652067726561746572206044820152687468616e207a65726f60b81b60648201526084016200005c565b80620002a15760405162461bcd60e51b815260206004820152601a60248201527f4d65726b6c6520726f6f742063616e6e6f74206265207a65726f00000000000060448201526064016200005c565b600380546001600160a01b0319166001600160a01b0397909716969096179095556004939093556005919091556007556008556009805460ff191690556000600a55600b5550620003c2565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03811681146200035357600080fd5b50565b600080600080600080600060e0888a0312156200037257600080fd5b87516200037f816200033d565b602089015190975062000392816200033d565b604089015160608a015160808b015160a08c015160c0909c01519a9d939c50919a90999198509650945092505050565b61104b80620003d26000396000f3fe608060405234801561001057600080fd5b50600436106101515760003560e01c8063736a83a1116100cd57806391d76bbb11610081578063d0d46a0b11610066578063d0d46a0b14610273578063d7463573146102a9578063f2fde38b146102b157600080fd5b806391d76bbb14610258578063abdd11a81461026057600080fd5b806381c8cd55116100b257806381c8cd55146102275780638d4e40831461022f5780638da5cb5b1461023a57600080fd5b8063736a83a11461020c5780637cb647591461021457600080fd5b806349590657116101245780634bb278f3116101095780634bb278f3146101f45780636180c609146101fc578063715018a61461020457600080fd5b806349590657146101d95780634b89c41d146101e157600080fd5b806321df0da7146101565780632f52ebb71461019a5780632f9cb9aa146101af5780633732ad1c146101c1575b600080fd5b60035473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101ad6101a8366004610e5c565b6102c4565b005b6008545b604051908152602001610191565b6101c9610625565b6040519015158152602001610191565b600b546101b3565b6101ad6101ef366004610edb565b610634565b6101ad610709565b6005546101b3565b6101ad61093f565b6006546101b3565b6101ad610222366004610edb565b610951565b600a546101b3565b60095460ff166101c9565b60005473ffffffffffffffffffffffffffffffffffffffff16610170565b6004546101b3565b6101ad61026e366004610edb565b610a32565b6101b3610281366004610ef4565b73ffffffffffffffffffffffffffffffffffffffff1660009081526002602052604090205490565b6007546101b3565b6101ad6102bf366004610ef4565b610b06565b6102cc610b6a565b61031d5760405162461bcd60e51b815260206004820152601360248201527f436c61696d696e67206e6f74206163746976650000000000000000000000000060448201526064015b60405180910390fd5b610325610b83565b33600090815260026020526040902054156103825760405162461bcd60e51b815260206004820152601860248201527f557365722068617320616c726561647920636c61696d656400000000000000006044820152606401610314565b600083116103f85760405162461bcd60e51b815260206004820152602660248201527f436c61696d20616d6f756e74206d75737420626520677265617465722074686160448201527f6e207a65726f00000000000000000000000000000000000000000000000000006064820152608401610314565b6040805133602082015290810184905260009060600160405160208183030381529060405280519060200120905061046783838080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050600b549150849050610bc6565b6104b35760405162461bcd60e51b815260206004820152601460248201527f496e76616c6964204d65726b6c652070726f6f660000000000000000000000006044820152606401610314565b6003546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015610522573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105469190610f2a565b905060006004546005548761055b9190610f72565b6105659190610f89565b905060008282116105765781610578565b825b9050806006600082825461058c9190610fc4565b9091555050600a80549060006105a183610fd7565b90915550503360008181526002602052604090208290556003546105de9173ffffffffffffffffffffffffffffffffffffffff9091169083610bdc565b60405181815233907fd8138f8a3f377c5259ca548e70e4c2de94f129f5a11036a15b69513cba2b426a9060200160405180910390a25050505061062060018055565b505050565b600061062f610b6a565b905090565b61063c610c69565b600754421061068d5760405162461bcd60e51b815260206004820152601c60248201527f436c61696d696e672068617320616c72656164792073746172746564000000006044820152606401610314565b60075481116107045760405162461bcd60e51b815260206004820152602760248201527f436c6f73696e672074696d65206d757374206265206166746572206f70656e6960448201527f6e672074696d65000000000000000000000000000000000000000000000000006064820152608401610314565b600855565b610711610c69565b610719610b6a565b156107665760405162461bcd60e51b815260206004820152601560248201527f436c61696d696e67207374696c6c2061637469766500000000000000000000006044820152606401610314565b61076e610b83565b60095460ff16156107c15760405162461bcd60e51b815260206004820152601a60248201527f436c61696d696e6720616c72656164792066696e616c697a65640000000000006044820152606401610314565b6003546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015610830573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108549190610f2a565b9050600081116108a65760405162461bcd60e51b815260206004820152601b60248201527f4e6f2072656d61696e696e6720746f6b656e7320746f206275726e00000000006044820152606401610314565b6003546108ca9073ffffffffffffffffffffffffffffffffffffffff163383610bdc565b600980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055600654604080519182526020820183905233917f616c9469db50815ae0f1d0a020d9fc9060da7c57f03559afb0d4ebdaa0a3a05e910160405180910390a25061093d60018055565b565b610947610c69565b61093d6000610cbc565b610959610c69565b60075442106109aa5760405162461bcd60e51b815260206004820152601c60248201527f436c61696d696e672068617320616c72656164792073746172746564000000006044820152606401610314565b806109f75760405162461bcd60e51b815260206004820152601a60248201527f4d65726b6c6520726f6f742063616e6e6f74206265207a65726f0000000000006044820152606401610314565b600b8190556040518181527f42cbc405e4dbf1b691e85b9a34b08ecfcf7a9ad9078bf4d645ccfa1fac11c10b9060200160405180910390a150565b610a3a610c69565b6007544210610a8b5760405162461bcd60e51b815260206004820152601c60248201527f436c61696d696e672068617320616c72656164792073746172746564000000006044820152606401610314565b42811015610b015760405162461bcd60e51b815260206004820152602260248201527f4f70656e696e672074696d65206d75737420626520696e20746865206675747560448201527f72650000000000000000000000000000000000000000000000000000000000006064820152608401610314565b600755565b610b0e610c69565b73ffffffffffffffffffffffffffffffffffffffff8116610b5e576040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260006004820152602401610314565b610b6781610cbc565b50565b6000600754421015801561062f57505060085442111590565b600260015403610bbf576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002600155565b600082610bd38584610d31565b14949350505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052610620908490610d80565b60005473ffffffffffffffffffffffffffffffffffffffff16331461093d576040517f118cdaa7000000000000000000000000000000000000000000000000000000008152336004820152602401610314565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600081815b8451811015610d7657610d6282868381518110610d5557610d5561100f565b6020026020010151610e2a565b915080610d6e81610fd7565b915050610d36565b5090505b92915050565b600080602060008451602086016000885af180610da3576040513d6000823e3d81fd5b50506000513d91508115610dbb578060011415610dd5565b73ffffffffffffffffffffffffffffffffffffffff84163b155b15610e24576040517f5274afe700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85166004820152602401610314565b50505050565b6000818310610e46576000828152602084905260409020610e55565b60008381526020839052604090205b9392505050565b600080600060408486031215610e7157600080fd5b83359250602084013567ffffffffffffffff80821115610e9057600080fd5b818601915086601f830112610ea457600080fd5b813581811115610eb357600080fd5b8760208260051b8501011115610ec857600080fd5b6020830194508093505050509250925092565b600060208284031215610eed57600080fd5b5035919050565b600060208284031215610f0657600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610e5557600080fd5b600060208284031215610f3c57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417610d7a57610d7a610f43565b600082610fbf577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820180821115610d7a57610d7a610f43565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361100857611008610f43565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c6343000814000a0000000000000000000000006571c18ddea876ce67932be7115a4e2d11b5d94300000000000000000000000029b0480aaed3a90828843a5abcfbbf556655bb1200000000000000000000000000000000000000000003796274caf64c7100000000000000000000000000000000000000000000000001bcb13a657b26388000000000000000000000000000000000000000000000000000000000000067b2fbdd0000000000000000000000000000000000000000000000000000000067b303ada0965f4bc2ece8afa99a40f14d3d2d8ba5df5cde5ff5934ca1a47a73a8038ace
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101515760003560e01c8063736a83a1116100cd57806391d76bbb11610081578063d0d46a0b11610066578063d0d46a0b14610273578063d7463573146102a9578063f2fde38b146102b157600080fd5b806391d76bbb14610258578063abdd11a81461026057600080fd5b806381c8cd55116100b257806381c8cd55146102275780638d4e40831461022f5780638da5cb5b1461023a57600080fd5b8063736a83a11461020c5780637cb647591461021457600080fd5b806349590657116101245780634bb278f3116101095780634bb278f3146101f45780636180c609146101fc578063715018a61461020457600080fd5b806349590657146101d95780634b89c41d146101e157600080fd5b806321df0da7146101565780632f52ebb71461019a5780632f9cb9aa146101af5780633732ad1c146101c1575b600080fd5b60035473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101ad6101a8366004610e5c565b6102c4565b005b6008545b604051908152602001610191565b6101c9610625565b6040519015158152602001610191565b600b546101b3565b6101ad6101ef366004610edb565b610634565b6101ad610709565b6005546101b3565b6101ad61093f565b6006546101b3565b6101ad610222366004610edb565b610951565b600a546101b3565b60095460ff166101c9565b60005473ffffffffffffffffffffffffffffffffffffffff16610170565b6004546101b3565b6101ad61026e366004610edb565b610a32565b6101b3610281366004610ef4565b73ffffffffffffffffffffffffffffffffffffffff1660009081526002602052604090205490565b6007546101b3565b6101ad6102bf366004610ef4565b610b06565b6102cc610b6a565b61031d5760405162461bcd60e51b815260206004820152601360248201527f436c61696d696e67206e6f74206163746976650000000000000000000000000060448201526064015b60405180910390fd5b610325610b83565b33600090815260026020526040902054156103825760405162461bcd60e51b815260206004820152601860248201527f557365722068617320616c726561647920636c61696d656400000000000000006044820152606401610314565b600083116103f85760405162461bcd60e51b815260206004820152602660248201527f436c61696d20616d6f756e74206d75737420626520677265617465722074686160448201527f6e207a65726f00000000000000000000000000000000000000000000000000006064820152608401610314565b6040805133602082015290810184905260009060600160405160208183030381529060405280519060200120905061046783838080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050600b549150849050610bc6565b6104b35760405162461bcd60e51b815260206004820152601460248201527f496e76616c6964204d65726b6c652070726f6f660000000000000000000000006044820152606401610314565b6003546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015610522573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105469190610f2a565b905060006004546005548761055b9190610f72565b6105659190610f89565b905060008282116105765781610578565b825b9050806006600082825461058c9190610fc4565b9091555050600a80549060006105a183610fd7565b90915550503360008181526002602052604090208290556003546105de9173ffffffffffffffffffffffffffffffffffffffff9091169083610bdc565b60405181815233907fd8138f8a3f377c5259ca548e70e4c2de94f129f5a11036a15b69513cba2b426a9060200160405180910390a25050505061062060018055565b505050565b600061062f610b6a565b905090565b61063c610c69565b600754421061068d5760405162461bcd60e51b815260206004820152601c60248201527f436c61696d696e672068617320616c72656164792073746172746564000000006044820152606401610314565b60075481116107045760405162461bcd60e51b815260206004820152602760248201527f436c6f73696e672074696d65206d757374206265206166746572206f70656e6960448201527f6e672074696d65000000000000000000000000000000000000000000000000006064820152608401610314565b600855565b610711610c69565b610719610b6a565b156107665760405162461bcd60e51b815260206004820152601560248201527f436c61696d696e67207374696c6c2061637469766500000000000000000000006044820152606401610314565b61076e610b83565b60095460ff16156107c15760405162461bcd60e51b815260206004820152601a60248201527f436c61696d696e6720616c72656164792066696e616c697a65640000000000006044820152606401610314565b6003546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015610830573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108549190610f2a565b9050600081116108a65760405162461bcd60e51b815260206004820152601b60248201527f4e6f2072656d61696e696e6720746f6b656e7320746f206275726e00000000006044820152606401610314565b6003546108ca9073ffffffffffffffffffffffffffffffffffffffff163383610bdc565b600980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055600654604080519182526020820183905233917f616c9469db50815ae0f1d0a020d9fc9060da7c57f03559afb0d4ebdaa0a3a05e910160405180910390a25061093d60018055565b565b610947610c69565b61093d6000610cbc565b610959610c69565b60075442106109aa5760405162461bcd60e51b815260206004820152601c60248201527f436c61696d696e672068617320616c72656164792073746172746564000000006044820152606401610314565b806109f75760405162461bcd60e51b815260206004820152601a60248201527f4d65726b6c6520726f6f742063616e6e6f74206265207a65726f0000000000006044820152606401610314565b600b8190556040518181527f42cbc405e4dbf1b691e85b9a34b08ecfcf7a9ad9078bf4d645ccfa1fac11c10b9060200160405180910390a150565b610a3a610c69565b6007544210610a8b5760405162461bcd60e51b815260206004820152601c60248201527f436c61696d696e672068617320616c72656164792073746172746564000000006044820152606401610314565b42811015610b015760405162461bcd60e51b815260206004820152602260248201527f4f70656e696e672074696d65206d75737420626520696e20746865206675747560448201527f72650000000000000000000000000000000000000000000000000000000000006064820152608401610314565b600755565b610b0e610c69565b73ffffffffffffffffffffffffffffffffffffffff8116610b5e576040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260006004820152602401610314565b610b6781610cbc565b50565b6000600754421015801561062f57505060085442111590565b600260015403610bbf576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002600155565b600082610bd38584610d31565b14949350505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052610620908490610d80565b60005473ffffffffffffffffffffffffffffffffffffffff16331461093d576040517f118cdaa7000000000000000000000000000000000000000000000000000000008152336004820152602401610314565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600081815b8451811015610d7657610d6282868381518110610d5557610d5561100f565b6020026020010151610e2a565b915080610d6e81610fd7565b915050610d36565b5090505b92915050565b600080602060008451602086016000885af180610da3576040513d6000823e3d81fd5b50506000513d91508115610dbb578060011415610dd5565b73ffffffffffffffffffffffffffffffffffffffff84163b155b15610e24576040517f5274afe700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85166004820152602401610314565b50505050565b6000818310610e46576000828152602084905260409020610e55565b60008381526020839052604090205b9392505050565b600080600060408486031215610e7157600080fd5b83359250602084013567ffffffffffffffff80821115610e9057600080fd5b818601915086601f830112610ea457600080fd5b813581811115610eb357600080fd5b8760208260051b8501011115610ec857600080fd5b6020830194508093505050509250925092565b600060208284031215610eed57600080fd5b5035919050565b600060208284031215610f0657600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610e5557600080fd5b600060208284031215610f3c57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417610d7a57610d7a610f43565b600082610fbf577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820180821115610d7a57610d7a610f43565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361100857611008610f43565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c6343000814000a
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000006571c18ddea876ce67932be7115a4e2d11b5d94300000000000000000000000029b0480aaed3a90828843a5abcfbbf556655bb1200000000000000000000000000000000000000000003796274caf64c7100000000000000000000000000000000000000000000000001bcb13a657b26388000000000000000000000000000000000000000000000000000000000000067b2fbdd0000000000000000000000000000000000000000000000000000000067b303ada0965f4bc2ece8afa99a40f14d3d2d8ba5df5cde5ff5934ca1a47a73a8038ace
-----Decoded View---------------
Arg [0] : initialOwner (address): 0x6571c18ddEa876Ce67932bE7115A4E2d11b5D943
Arg [1] : token (address): 0x29b0480aaeD3a90828843A5abCfbBf556655bB12
Arg [2] : totalMigrated (uint256): 4200000000000000000000000
Arg [3] : totalClaimable (uint256): 2100000000000000000000000
Arg [4] : openingTime (uint256): 1739783133
Arg [5] : closingTime (uint256): 1739785133
Arg [6] : merkleRoot (bytes32): 0xa0965f4bc2ece8afa99a40f14d3d2d8ba5df5cde5ff5934ca1a47a73a8038ace
-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 0000000000000000000000006571c18ddea876ce67932be7115a4e2d11b5d943
Arg [1] : 00000000000000000000000029b0480aaed3a90828843a5abcfbbf556655bb12
Arg [2] : 00000000000000000000000000000000000000000003796274caf64c71000000
Arg [3] : 00000000000000000000000000000000000000000001bcb13a657b2638800000
Arg [4] : 0000000000000000000000000000000000000000000000000000000067b2fbdd
Arg [5] : 0000000000000000000000000000000000000000000000000000000067b303ad
Arg [6] : a0965f4bc2ece8afa99a40f14d3d2d8ba5df5cde5ff5934ca1a47a73a8038ace
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.