ETH Price: $2,007.47 (+1.18%)

Contract

0xcDbe12611F18B43098202d45928c905b34736C06
 

Overview

ETH Balance

0.645193555493650368 ETH

ETH Value

$1,295.21 (@ $2,007.47/ETH)

Token Holdings

Multichain Info

Transaction Hash
Method
Block
From
To
Approve169483162025-03-23 5:07:279 hrs ago1742706447IN
0xcDbe1261...b34736C06
0 ETH0.000000050.00228709
Transfer169470712025-03-23 4:25:5710 hrs ago1742703957IN
0xcDbe1261...b34736C06
0 ETH0.000000060.00139704
Approve168865802025-03-21 18:49:3543 hrs ago1742582975IN
0xcDbe1261...b34736C06
0 ETH00.00011295
Transfer168294092025-03-20 11:03:533 days ago1742468633IN
0xcDbe1261...b34736C06
0 ETH0.000000040.00100123
Transfer168071312025-03-19 22:41:173 days ago1742424077IN
0xcDbe1261...b34736C06
0 ETH0.000000050.00110113
Approve168042382025-03-19 21:04:513 days ago1742418291IN
0xcDbe1261...b34736C06
0 ETH0.000000060.00150167
Approve167833752025-03-19 9:29:254 days ago1742376565IN
0xcDbe1261...b34736C06
0 ETH00.00000132
Approve167743032025-03-19 4:27:014 days ago1742358421IN
0xcDbe1261...b34736C06
0 ETH0.000000020.00110117
Approve167704792025-03-19 2:19:334 days ago1742350773IN
0xcDbe1261...b34736C06
0 ETH00.00000216
Approve167380982025-03-18 8:20:115 days ago1742286011IN
0xcDbe1261...b34736C06
0 ETH0.000000050.00119917
Approve167371152025-03-18 7:47:255 days ago1742284045IN
0xcDbe1261...b34736C06
0 ETH0.000000050.00122834
Approve166123762025-03-15 10:29:278 days ago1742034567IN
0xcDbe1261...b34736C06
0 ETH00.00019232
Approve166068412025-03-15 7:24:578 days ago1742023497IN
0xcDbe1261...b34736C06
0 ETH0.000000050.00119645
Approve166002412025-03-15 3:44:578 days ago1742010297IN
0xcDbe1261...b34736C06
0 ETH0.000000030.00139315
Approve166002382025-03-15 3:44:518 days ago1742010291IN
0xcDbe1261...b34736C06
0 ETH0.000000030.00139395
Approve165283872025-03-13 11:49:4910 days ago1741866589IN
0xcDbe1261...b34736C06
0 ETH0.000000050.00120792
Transfer165206552025-03-13 7:32:0510 days ago1741851125IN
0xcDbe1261...b34736C06
0 ETH0.000000050.00162192
Transfer165206382025-03-13 7:31:3110 days ago1741851091IN
0xcDbe1261...b34736C06
0 ETH0.000000050.00162257
Transfer165205562025-03-13 7:28:4710 days ago1741850927IN
0xcDbe1261...b34736C06
0 ETH0.000000050.00162388
Approve164971952025-03-12 18:30:0510 days ago1741804205IN
0xcDbe1261...b34736C06
0 ETH00.00011595
Transfer164730932025-03-12 5:06:4111 days ago1741756001IN
0xcDbe1261...b34736C06
0 ETH0.000000030.00118807
Approve164486552025-03-11 15:32:0511 days ago1741707125IN
0xcDbe1261...b34736C06
0 ETH0.000000020.0011698
Approve163941072025-03-10 9:13:4913 days ago1741598029IN
0xcDbe1261...b34736C06
0 ETH00.00019995
Approve163599182025-03-09 14:14:1114 days ago1741529651IN
0xcDbe1261...b34736C06
0 ETH0.000000020.00123375
Approve163583052025-03-09 13:20:2514 days ago1741526425IN
0xcDbe1261...b34736C06
0 ETH0.000000030.00124529
View all transactions

Latest 25 internal transactions (View All)

Parent Transaction Hash Block From To
66034862024-07-26 17:59:47239 days ago1722016787
0xcDbe1261...b34736C06
0.09376813 ETH
66034162024-07-26 17:57:27239 days ago1722016647
0xcDbe1261...b34736C06
0.11957587 ETH
66033642024-07-26 17:55:43239 days ago1722016543
0xcDbe1261...b34736C06
0.11957587 ETH
65410772024-07-25 7:19:29241 days ago1721891969
0xcDbe1261...b34736C06
0.24087226 ETH
50300352024-06-20 7:51:25276 days ago1718869885
0xcDbe1261...b34736C06
0.0430129 ETH
49369962024-06-18 4:10:07278 days ago1718683807
0xcDbe1261...b34736C06
0.0430129 ETH
48992192024-06-17 7:10:53279 days ago1718608253
0xcDbe1261...b34736C06
0.23226967 ETH
48547462024-06-16 6:28:27280 days ago1718519307
0xcDbe1261...b34736C06
0.05161548 ETH
48256672024-06-15 14:19:09281 days ago1718461149
0xcDbe1261...b34736C06
0.0430129 ETH
48231452024-06-15 12:55:05281 days ago1718456105
0xcDbe1261...b34736C06
0.17205161 ETH
48225502024-06-15 12:35:15281 days ago1718454915
0xcDbe1261...b34736C06
0.0430129 ETH
48194182024-06-15 10:50:51281 days ago1718448651
0xcDbe1261...b34736C06
0.04344303 ETH
48054162024-06-15 3:04:07281 days ago1718420647
0xcDbe1261...b34736C06
0.06882064 ETH
48024302024-06-15 1:24:35281 days ago1718414675
0xcDbe1261...b34736C06
0.0430129 ETH
47778922024-06-14 11:46:39282 days ago1718365599
0xcDbe1261...b34736C06
0.0430129 ETH
47680162024-06-14 6:17:27282 days ago1718345847
0xcDbe1261...b34736C06
0.11226367 ETH
47654302024-06-14 4:51:15282 days ago1718340675
0xcDbe1261...b34736C06
0.04731419 ETH
47622762024-06-14 3:06:07282 days ago1718334367
0xcDbe1261...b34736C06
0.0860258 ETH
47432692024-06-13 16:32:33282 days ago1718296353
0xcDbe1261...b34736C06
0.84219265 ETH
47429942024-06-13 16:23:23282 days ago1718295803
0xcDbe1261...b34736C06
0.12903871 ETH
47417402024-06-13 15:41:35282 days ago1718293295
0xcDbe1261...b34736C06
0.38281484 ETH
47406332024-06-13 15:04:41282 days ago1718291081
0xcDbe1261...b34736C06
0.34410322 ETH
47378002024-06-13 13:30:15283 days ago1718285415
0xcDbe1261...b34736C06
0.0430129 ETH
47360852024-06-13 12:33:05283 days ago1718281985
0xcDbe1261...b34736C06
0.05161548 ETH
47353942024-06-13 12:10:03283 days ago1718280603
0xcDbe1261...b34736C06
0.06882064 ETH
View All Internal Transactions

Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
NoGold

Compiler Version
v0.8.20+commit.a1b79de6

Optimization Enabled:
Yes with 200 runs

Other Settings:
paris EvmVersion
File 1 of 11 : NoGold.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {MerkleProof} from "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {INoGold} from "./interfaces/INoGold.sol";
import {IThrusterRouter02} from "./interfaces/IThrusterRouter02.sol";

contract NoGold is ERC20, Ownable, INoGold {
    uint16 private constant TREASURY_RATE_BPS = 5_000;

    //<=========================>//
    //<========DURATIONS========>//
    //<=========================>//

    /**
     * @notice Duration of airdrop phase
     */
    uint40 private constant DURATION__AIRDROP = 2 days;

    /**
     * @notice Duration of presale phase
     */
    uint40 private constant DURATION__PRESALE = 1 days;

    //<===========================>//
    //<========ALLOCATIONS========>//
    //<===========================>//

    // TOTAL SUPPLY: 100_000_000

    /**
     * @notice Amount of tokens allocated to soft pool
     */
    uint256 public immutable AMOUNT_ALLOCATED__SOFT_POOL;

    /**
     * @notice Amount of tokens allocated to hard pool
     */
    uint256 public immutable AMOUNT_ALLOCATED__HARD_POOL;

    /**
     * @notice Amount allocated to provide liquidity on dexes
     */
    uint256 public immutable AMOUNT_ALLOCATED__LIQUIDITY;

    /**
     * @notice Amount allocated for KOLs
     */
    uint256 public immutable AMOUNT_ALLOCATED__KOLS;

    /**
     * @notice Amount allocated to free claimers
     */
    uint256 public immutable AMOUNT_ALLOCATED__AIRDROP;

    /**
     * @notice Amount allocated to community
     */
    uint256 public immutable AMOUNT_ALLOCATED__COMMUNITY;

    /**
     * @notice Amount allocated to referals
     */
    uint256 public immutable AMOUNT_ALLOCATED__REFS;

    //<==========================>//
    //<========RECIPIENTS========>//
    //<==========================>//

    /**
     * @notice Recepient of community funds
     */
    address public immutable RECIPIENT__COMMUNITY;

    /**
     * @notice Recepient of kols funds
     */
    address public immutable RECIPIENT__KOLS;

    /**
     * @notice Recepient of treasury funds
     */
    address public immutable RECIPIENT__TREASURY;

    //<==============================>//
    //<========DEPOSIT PARAMS========>//
    //<==============================>//

    /**
     * @notice Minimal user deposit
     */
    uint256 public immutable USER_DEPOSIT__MIN;

    /**
     * @notice Maximal user deposit
     */
    uint256 public immutable USER_DEPOSIT__MAX;

    //<=========================>//
    //<========POOL CAPS========>//
    //<=========================>//

    /**
     * @notice Cap of soft pool
     */
    uint256 public immutable CAP__SOFT;

    /**
     * @notice Cap of hard pool
     */
    uint256 public immutable CAP__HARD;

    /**
     * @notice Address of dex router
     */
    address public immutable ROUTER;

    /**
     * @notice Flag identifying if liquidity and treasury were withdrawn
     */
    bool private areFundsDistributed;

    /**
     * @notice Timestamp of start
     */
    uint40 public startTime;

    /**
     * @notice Root of merkle tree for airdrop claimers
     */
    bytes32 private merkleRootAirdrop;

    /**
     * @notice Roof of merkle tree for ref accruals claimers
     */
    bytes32 private merkleRootRefs;

    /**
     * @notice Total amount of deposits made
     */
    uint256 public depositedInTotal;

    /**
     * @notice Total amount of tokens already claimed by airdrop claimers
     */
    uint256 public amountMintedToAirdropClaimers;

    /**
     * @notice Total amount of tokens already claimed as ref accruals
     */
    uint256 private amountMintedToRefClaimers;

    /**
     * @notice Mapping from user to his deposits
     */
    mapping(address => Deposit) public deposits;

    /**
     * @notice Map identifying if presale tokens and refunds were claimed by user
     */
    mapping(address => bool) public isClaimedPresale;

    /**
     * @notice Map identifying if airdrop tokens were claimed by user
     */
    MapWrapper private isClaimedAirdrop;

    /**
     * @notice Map identifying if refs tokens were claimed by user
     */
    MapWrapper private isClaimedRefs;

    constructor(ConstructorCalldata memory data) ERC20("NOGOLD", "NOGOLD") Ownable(data.owner) {
        AMOUNT_ALLOCATED__SOFT_POOL = data.amountAllocatedSoftPool;
        AMOUNT_ALLOCATED__HARD_POOL = data.amountAllocatedHardPool;
        AMOUNT_ALLOCATED__LIQUIDITY = data.amountAllocatedLiquidity;
        AMOUNT_ALLOCATED__KOLS = data.amountAllocatedKOLs;
        AMOUNT_ALLOCATED__AIRDROP = data.amountAllocatedAirdrop;
        AMOUNT_ALLOCATED__COMMUNITY = data.amountAllocatedCommunity;
        AMOUNT_ALLOCATED__REFS = data.amountAllocatedRefs;
        RECIPIENT__KOLS = data.recipientOfKOLsFunds;
        RECIPIENT__COMMUNITY = data.recipientOfCommunityFunds;
        RECIPIENT__TREASURY = data.recipientOfTreasuryFunds;
        CAP__SOFT = data.capSoft;
        CAP__HARD = data.capHard;
        USER_DEPOSIT__MIN = data.userDepositMin;
        USER_DEPOSIT__MAX = data.userDepositMax;
        ROUTER = data.router;
    }

    receive() external payable {
        deposit();
    }

    modifier onlyBeforeStart() {
        if (startTime > 0) {
            revert UnexecutableNow();
        }
        _;
    }

    modifier onlyDuringAirdrop() {
        if (block.timestamp < startTime || block.timestamp > startTime + DURATION__AIRDROP) {
            revert UnexecutableNow();
        }
        _;
    }

    modifier onlyDuringPresale() {
        uint40 airdropEndTime = startTime + DURATION__AIRDROP;
        if (block.timestamp < airdropEndTime || block.timestamp > airdropEndTime + DURATION__PRESALE) {
            revert UnexecutableNow();
        }
        _;
    }

    modifier onlyAfterPresale() {
        if (startTime == 0 || startTime + DURATION__PRESALE + DURATION__AIRDROP > block.timestamp) {
            revert UnexecutableNow();
        }
        _;
    }

    //<===============================>//
    //<======CORE LOGIC EXTERNAL======>//
    //<===============================>//

    /**
     * @inheritdoc INoGold
     */
    function claimAirdrop(uint256 amount, bytes32[] memory merkleProof) external override onlyDuringAirdrop {
        if (amountMintedToAirdropClaimers >= AMOUNT_ALLOCATED__AIRDROP) {
            revert AllocationExceeded();
        }
        uint256 amountClaimable = (amount + amountMintedToAirdropClaimers < AMOUNT_ALLOCATED__AIRDROP)
            ? amount
            : AMOUNT_ALLOCATED__AIRDROP - amountMintedToAirdropClaimers;
        amountMintedToAirdropClaimers += amountClaimable;
        _claimWithMerkleProof(amountClaimable, amount, merkleProof, isClaimedAirdrop, merkleRootAirdrop);
        emit Claimed(msg.sender, amountClaimable, 0, ClaimerType.Airdrop);
    }

    /**
     * @inheritdoc INoGold
     */
    function deposit() public payable override onlyDuringPresale {
        Deposit storage userDeposit = deposits[msg.sender];
        uint256 amount = msg.value;
        if (
            amount < USER_DEPOSIT__MIN ||
            amount + userDeposit.amountDepositedToHard + userDeposit.amountDepositedToSoft > USER_DEPOSIT__MAX
        ) {
            revert DepositOutsideRange();
        }
        uint256 amountDepositedToSoft = (depositedInTotal < CAP__SOFT)
            ? ((depositedInTotal + amount > CAP__SOFT) ? CAP__SOFT - depositedInTotal : amount)
            : 0;
        userDeposit.amountDepositedToSoft += amountDepositedToSoft;
        userDeposit.amountDepositedToHard += amount - amountDepositedToSoft;
        depositedInTotal += amount;
        emit Deposited(msg.sender, amount);
    }

    /**
     * @inheritdoc INoGold
     */
    function claimPresale() external override onlyAfterPresale {
        Deposit storage userDeposit = deposits[msg.sender];
        if (userDeposit.amountDepositedToHard == 0 && userDeposit.amountDepositedToSoft == 0) {
            revert NoDeposits();
        }

        if (isClaimedPresale[msg.sender]) {
            revert AlreadyClaimed();
        }

        isClaimedPresale[msg.sender] = true;

        (uint256 allocation, uint256 refund) = _computeAllocationAndRefund(userDeposit);
        if (refund > 0) {
            payable(msg.sender).transfer(refund);
        }
        if (allocation > 0) {
            _mint(msg.sender, allocation);
        }
        emit Claimed(msg.sender, allocation, refund, ClaimerType.Presale);
    }

    /**
     * @inheritdoc INoGold
     */
    function claimRefs(uint256 amount, bytes32[] memory merkleProof) external override onlyAfterPresale {
        if (amountMintedToRefClaimers + amount > AMOUNT_ALLOCATED__REFS) {
            revert AllocationExceeded();
        }
        amountMintedToRefClaimers += amount;
        _claimWithMerkleProof(amount, amount, merkleProof, isClaimedRefs, merkleRootRefs);
        emit Claimed(msg.sender, amount, 0, ClaimerType.Refs);
    }

    /**
     * @inheritdoc INoGold
     */
    function computeAllocationAndRefund(
        address user
    ) external view override returns (uint256 allocation, uint256 refund) {
        Deposit storage userDeposit = deposits[user];
        return _computeAllocationAndRefund(userDeposit);
    }

    /**
     * @inheritdoc INoGold
     */
    function getIsClaimedAirdrop(address user) external view override returns (bool) {
        return isClaimedAirdrop.data[user];
    }

    /**
     * @inheritdoc INoGold
     */
    function getIsClaimedRefs(address user) external view override returns (bool) {
        return isClaimedRefs.data[user];
    }

    /**
     * @inheritdoc INoGold
     */
    function getTotalUserDeposit(address user) external view override returns (uint256) {
        Deposit storage userDeposit = deposits[user];
        return userDeposit.amountDepositedToSoft + userDeposit.amountDepositedToHard;
    }

    //<=============================================>//
    //<======ADMINISTRATIVE FUNCTIONS EXTERNAL======>//
    //<=============================================>//

    /**
     * @inheritdoc INoGold
     */
    function setMerkleRootAirdrop(bytes32 merkleRoot) external override onlyOwner {
        merkleRootAirdrop = merkleRoot;
    }

    /**
     * @inheritdoc INoGold
     */
    function start() external override onlyOwner onlyBeforeStart {
        startTime = uint40(block.timestamp);
        emit Started();
    }

    /**
     * @inheritdoc INoGold
     */
    function distributeFunds() external override onlyOwner onlyAfterPresale {
        if (depositedInTotal < CAP__SOFT) {
            revert SoftCapNotReached();
        }
        if (areFundsDistributed) {
            revert AllocationExceeded();
        }

        areFundsDistributed = true;
        uint256 amountETHWithdrawable = (CAP__HARD > depositedInTotal) ? depositedInTotal : CAP__HARD;
        uint256 amountETHLiquidity = (amountETHWithdrawable * TREASURY_RATE_BPS) / 10_000;
        uint256 amountUnclaimedAirdrop = AMOUNT_ALLOCATED__AIRDROP - amountMintedToAirdropClaimers;
        _deployLiquidity(amountETHLiquidity);
        _mint(RECIPIENT__KOLS, AMOUNT_ALLOCATED__KOLS);
        _mint(RECIPIENT__COMMUNITY, AMOUNT_ALLOCATED__COMMUNITY + amountUnclaimedAirdrop);
        payable(RECIPIENT__TREASURY).transfer(amountETHWithdrawable - amountETHLiquidity);
    }

    /**
     * @inheritdoc INoGold
     */
    function setMerkleRootRefs(bytes32 merkleRoot) external override onlyOwner {
        merkleRootRefs = merkleRoot;
    }

    //<===========================>//
    //<======ERC20 OVERRIDES======>//
    //<===========================>//

    function _update(address from, address to, uint256 value) internal override {
        if (!areFundsDistributed && from != address(this) && from != address(0) && from != ROUTER) {
            revert TradingDisabled();
        }
        super._update(from, to, value);
    }

    //<==============================>//
    //<======CORE LOGIC PRIVATE======>//
    //<==============================>//

    function _claimWithMerkleProof(
        uint256 amount,
        uint256 amountInLeaf,
        bytes32[] memory merkleProof,
        MapWrapper storage map,
        bytes32 merkleRoot
    ) private {
        if (map.data[msg.sender]) {
            revert AlreadyClaimed();
        }
        bytes32 leaf = keccak256(abi.encode(msg.sender, amountInLeaf));
        if (!MerkleProof.verify(merkleProof, merkleRoot, leaf)) {
            revert InvalidMerkleProof();
        }
        map.data[msg.sender] = true;
        _mint(msg.sender, amount);
    }

    function _deployLiquidity(uint256 amountETH) private {
        _mint(address(this), AMOUNT_ALLOCATED__LIQUIDITY);
        _approve(address(this), ROUTER, AMOUNT_ALLOCATED__LIQUIDITY);
        try
            IThrusterRouter02(ROUTER).addLiquidityETH{value: amountETH}(
                address(this),
                AMOUNT_ALLOCATED__LIQUIDITY,
                0,
                0,
                owner(),
                block.timestamp
            )
        {} catch {
            transfer(owner(), AMOUNT_ALLOCATED__LIQUIDITY);
            payable(owner()).transfer(amountETH);
        }
    }

    function _computeAllocationAndRefund(
        Deposit storage userDeposit
    ) private view returns (uint256 allocation, uint256 refund) {
        if (depositedInTotal < CAP__SOFT) {
            allocation = 0;
            refund = userDeposit.amountDepositedToSoft;
        } else if (depositedInTotal < CAP__HARD) {
            allocation =
                ((userDeposit.amountDepositedToSoft + userDeposit.amountDepositedToHard) *
                    (AMOUNT_ALLOCATED__SOFT_POOL + AMOUNT_ALLOCATED__HARD_POOL)) /
                (depositedInTotal);
            refund = 0;
        } else {
            allocation = (userDeposit.amountDepositedToSoft * AMOUNT_ALLOCATED__SOFT_POOL) / CAP__SOFT;
            allocation +=
                (userDeposit.amountDepositedToHard * AMOUNT_ALLOCATED__HARD_POOL) /
                (depositedInTotal - CAP__SOFT);
            refund = (userDeposit.amountDepositedToHard > 0)
                ? userDeposit.amountDepositedToHard -
                    ((userDeposit.amountDepositedToHard * (CAP__HARD - CAP__SOFT)) / (depositedInTotal - CAP__SOFT)) -
                    1
                : 0;
        }
    }
}

File 2 of 11 : Ownable.sol
// 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);
    }
}

File 3 of 11 : draft-IERC6093.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol)
pragma solidity ^0.8.20;

/**
 * @dev Standard ERC20 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens.
 */
interface IERC20Errors {
    /**
     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param balance Current balance for the interacting account.
     * @param needed Minimum amount required to perform a transfer.
     */
    error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC20InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC20InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.
     * @param spender Address that may be allowed to operate on tokens without being their owner.
     * @param allowance Amount of tokens a `spender` is allowed to operate with.
     * @param needed Minimum amount required to perform a transfer.
     */
    error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC20InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `spender` to be approved. Used in approvals.
     * @param spender Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC20InvalidSpender(address spender);
}

/**
 * @dev Standard ERC721 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens.
 */
interface IERC721Errors {
    /**
     * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20.
     * Used in balance queries.
     * @param owner Address of the current owner of a token.
     */
    error ERC721InvalidOwner(address owner);

    /**
     * @dev Indicates a `tokenId` whose `owner` is the zero address.
     * @param tokenId Identifier number of a token.
     */
    error ERC721NonexistentToken(uint256 tokenId);

    /**
     * @dev Indicates an error related to the ownership over a particular token. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param tokenId Identifier number of a token.
     * @param owner Address of the current owner of a token.
     */
    error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC721InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC721InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     * @param tokenId Identifier number of a token.
     */
    error ERC721InsufficientApproval(address operator, uint256 tokenId);

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC721InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC721InvalidOperator(address operator);
}

/**
 * @dev Standard ERC1155 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens.
 */
interface IERC1155Errors {
    /**
     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param balance Current balance for the interacting account.
     * @param needed Minimum amount required to perform a transfer.
     * @param tokenId Identifier number of a token.
     */
    error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC1155InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC1155InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     * @param owner Address of the current owner of a token.
     */
    error ERC1155MissingApprovalForAll(address operator, address owner);

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC1155InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC1155InvalidOperator(address operator);

    /**
     * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.
     * Used in batch transfers.
     * @param idsLength Length of the array of token identifiers
     * @param valuesLength Length of the array of token amounts
     */
    error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
}

File 4 of 11 : ERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol)

pragma solidity ^0.8.20;

import {IERC20} from "./IERC20.sol";
import {IERC20Metadata} from "./extensions/IERC20Metadata.sol";
import {Context} from "../../utils/Context.sol";
import {IERC20Errors} from "../../interfaces/draft-IERC6093.sol";

/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * The default value of {decimals} is 18. To change this, you should override
 * this function so it returns a different value.
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC20
 * applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 */
abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {
    mapping(address account => uint256) private _balances;

    mapping(address account => mapping(address spender => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5.05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the default value returned by this function, unless
     * it's overridden.
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual returns (uint8) {
        return 18;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - the caller must have a balance of at least `value`.
     */
    function transfer(address to, uint256 value) public virtual returns (bool) {
        address owner = _msgSender();
        _transfer(owner, to, value);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on
     * `transferFrom`. This is semantically equivalent to an infinite approval.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 value) public virtual returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, value);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * NOTE: Does not update the allowance if the current allowance
     * is the maximum `uint256`.
     *
     * Requirements:
     *
     * - `from` and `to` cannot be the zero address.
     * - `from` must have a balance of at least `value`.
     * - the caller must have allowance for ``from``'s tokens of at least
     * `value`.
     */
    function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, value);
        _transfer(from, to, value);
        return true;
    }

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * NOTE: This function is not virtual, {_update} should be overridden instead.
     */
    function _transfer(address from, address to, uint256 value) internal {
        if (from == address(0)) {
            revert ERC20InvalidSender(address(0));
        }
        if (to == address(0)) {
            revert ERC20InvalidReceiver(address(0));
        }
        _update(from, to, value);
    }

    /**
     * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`
     * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding
     * this function.
     *
     * Emits a {Transfer} event.
     */
    function _update(address from, address to, uint256 value) internal virtual {
        if (from == address(0)) {
            // Overflow check required: The rest of the code assumes that totalSupply never overflows
            _totalSupply += value;
        } else {
            uint256 fromBalance = _balances[from];
            if (fromBalance < value) {
                revert ERC20InsufficientBalance(from, fromBalance, value);
            }
            unchecked {
                // Overflow not possible: value <= fromBalance <= totalSupply.
                _balances[from] = fromBalance - value;
            }
        }

        if (to == address(0)) {
            unchecked {
                // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.
                _totalSupply -= value;
            }
        } else {
            unchecked {
                // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.
                _balances[to] += value;
            }
        }

        emit Transfer(from, to, value);
    }

    /**
     * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).
     * Relies on the `_update` mechanism
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * NOTE: This function is not virtual, {_update} should be overridden instead.
     */
    function _mint(address account, uint256 value) internal {
        if (account == address(0)) {
            revert ERC20InvalidReceiver(address(0));
        }
        _update(address(0), account, value);
    }

    /**
     * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.
     * Relies on the `_update` mechanism.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * NOTE: This function is not virtual, {_update} should be overridden instead
     */
    function _burn(address account, uint256 value) internal {
        if (account == address(0)) {
            revert ERC20InvalidSender(address(0));
        }
        _update(account, address(0), value);
    }

    /**
     * @dev Sets `value` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     *
     * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.
     */
    function _approve(address owner, address spender, uint256 value) internal {
        _approve(owner, spender, value, true);
    }

    /**
     * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.
     *
     * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by
     * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any
     * `Approval` event during `transferFrom` operations.
     *
     * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to
     * true using the following override:
     * ```
     * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {
     *     super._approve(owner, spender, value, true);
     * }
     * ```
     *
     * Requirements are the same as {_approve}.
     */
    function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {
        if (owner == address(0)) {
            revert ERC20InvalidApprover(address(0));
        }
        if (spender == address(0)) {
            revert ERC20InvalidSpender(address(0));
        }
        _allowances[owner][spender] = value;
        if (emitEvent) {
            emit Approval(owner, spender, value);
        }
    }

    /**
     * @dev Updates `owner` s allowance for `spender` based on spent `value`.
     *
     * Does not update the allowance value in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Does not emit an {Approval} event.
     */
    function _spendAllowance(address owner, address spender, uint256 value) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            if (currentAllowance < value) {
                revert ERC20InsufficientAllowance(spender, currentAllowance, value);
            }
            unchecked {
                _approve(owner, spender, currentAllowance - value, false);
            }
        }
    }
}

File 5 of 11 : IERC20Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.20;

import {IERC20} from "../IERC20.sol";

/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}

File 6 of 11 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
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);
}

File 7 of 11 : Context.sol
// 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;
    }
}

File 8 of 11 : MerkleProof.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/MerkleProof.sol)

pragma solidity ^0.8.20;

/**
 * @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 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.
     */
    function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {
        return processProof(proof, leaf) == root;
    }

    /**
     * @dev Calldata version of {verify}
     */
    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.
     */
    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}
     */
    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.
     */
    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.
     */
    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).
     */
    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 proofLen = proof.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        if (leavesLen + proofLen != totalHashes + 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[](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) {
            if (proofPos != proofLen) {
                revert MerkleProofInvalidMultiproof();
            }
            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.
     */
    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 proofLen = proof.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        if (leavesLen + proofLen != totalHashes + 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[](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) {
            if (proofPos != proofLen) {
                revert MerkleProofInvalidMultiproof();
            }
            unchecked {
                return hashes[totalHashes - 1];
            }
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    /**
     * @dev Sorts the pair (a, b) and hashes the result.
     */
    function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {
        return a < b ? _efficientHash(a, b) : _efficientHash(b, a);
    }

    /**
     * @dev Implementation of keccak256(abi.encode(a, b)) that doesn't allocate or expand memory.
     */
    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)
        }
    }
}

File 9 of 11 : INoGold.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

interface INoGold {
    enum ClaimerType {
        Airdrop,
        Presale,
        Refs
    }

    event Deposited(address depositor, uint256 depositAmount);
    event Claimed(address claimer, uint256 claimedTokens, uint256 amountRefunded, ClaimerType claimerType);
    event Started();

    error UnexecutableNow();
    error InvalidMerkleProof();
    error DepositOutsideRange();
    error AlreadyClaimed();
    error NoDeposits();
    error SoftCapNotReached();
    error AllocationExceeded();
    error TradingDisabled();

    struct Deposit {
        uint256 amountDepositedToSoft;
        uint256 amountDepositedToHard;
    }

    struct MapWrapper {
        mapping(address => bool) data;
    }

    struct ConstructorCalldata {
        address owner;
        address router;
        address recipientOfKOLsFunds;
        address recipientOfCommunityFunds;
        address recipientOfTreasuryFunds;
        uint256 amountAllocatedSoftPool;
        uint256 amountAllocatedHardPool;
        uint256 amountAllocatedLiquidity;
        uint256 amountAllocatedKOLs;
        uint256 amountAllocatedAirdrop;
        uint256 amountAllocatedCommunity;
        uint256 amountAllocatedRefs;
        uint256 capSoft;
        uint256 capHard;
        uint256 userDepositMin;
        uint256 userDepositMax;
    }

    /**
     * @notice Set merkle root for airdrop claimers. Only callable for owner
     * @param merkleRoot New merkle root
     */
    function setMerkleRootAirdrop(bytes32 merkleRoot) external;

    /**
     * @notice Set merkle root for ref accruals claimers. Only callable for owner
     * @param merkleRoot New merkle root
     */
    function setMerkleRootRefs(bytes32 merkleRoot) external;

    /**
     * @notice Start events. Only callable for owner
     */
    function start() external;

    /**
     * @notice Distribute funds among KOLs, community and treasury, deploy liquidity pool
     */
    function distributeFunds() external;

    /**
     * @notice Deposit eth into presale
     */
    function deposit() external payable;

    /**
     * @notice Claim airdrop allocated to user
     * @param amount Amount of allocated tokens
     * @param merkleProof Merkle proof
     */
    function claimAirdrop(uint256 amount, bytes32[] memory merkleProof) external;

    /**
     * @notice Claim refunds and allocated tokens after presale
     */
    function claimPresale() external;

    /**
     * @notice Claim airdrop allocated to user
     * @param amount Amount of allocated tokens
     * @param merkleProof Merkle proof
     */
    function claimRefs(uint256 amount, bytes32[] memory merkleProof) external;

    /**
     * @notice Get allocation and refund for specific user
     * @param user User's address to get allocation and refund associated with
     * @return allocation Amount of tokens that user will receive on claim
     * @return refund Amount of eth that user receive
     */
    function computeAllocationAndRefund(address user) external view returns (uint256 allocation, uint256 refund);

    /**
     * @notice Retrieve flag identifying if user claimed airdrop
     * @param user User's address
     * @return flag
     */
    function getIsClaimedAirdrop(address user) external view returns (bool);

    /**
     * @notice Retrieve flag identifying if user claimed refs accruals
     * @param user User's address
     * @return Flag
     */
    function getIsClaimedRefs(address user) external view returns (bool);

    /**
     * @notice Get user deposit
     * @param user User's address
     * @return Total amount deposited by user
     */
    function getTotalUserDeposit(address user) external view returns (uint256);
}

File 10 of 11 : IThrusterRouter01.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.6.2;

interface IThrusterRouter01 {
    function factory() external pure returns (address);

    function WETH() external pure returns (address);

    function addLiquidity(
        address tokenA,
        address tokenB,
        uint256 amountADesired,
        uint256 amountBDesired,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountA, uint256 amountB, uint256 liquidity);

    function addLiquidityETH(
        address token,
        uint256 amountTokenDesired,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    ) external payable returns (uint256 amountToken, uint256 amountETH, uint256 liquidity);

    function removeLiquidity(
        address tokenA,
        address tokenB,
        uint256 liquidity,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountA, uint256 amountB);

    function removeLiquidityETH(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountToken, uint256 amountETH);

    function removeLiquidityWithPermit(
        address tokenA,
        address tokenB,
        uint256 liquidity,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint256 amountA, uint256 amountB);

    function removeLiquidityETHWithPermit(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint256 amountToken, uint256 amountETH);

    function swapExactTokensForTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function swapTokensForExactTokens(
        uint256 amountOut,
        uint256 amountInMax,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function swapExactETHForTokens(
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable returns (uint256[] memory amounts);

    function swapTokensForExactETH(
        uint256 amountOut,
        uint256 amountInMax,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function swapExactTokensForETH(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function swapETHForExactTokens(
        uint256 amountOut,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable returns (uint256[] memory amounts);

    function quote(uint256 amountA, uint256 reserveA, uint256 reserveB) external pure returns (uint256 amountB);

    function getAmountOut(
        uint256 amountIn,
        uint256 reserveIn,
        uint256 reserveOut
    ) external pure returns (uint256 amountOut);

    function getAmountIn(
        uint256 amountOut,
        uint256 reserveIn,
        uint256 reserveOut
    ) external pure returns (uint256 amountIn);

    function getAmountsOut(uint256 amountIn, address[] calldata path) external view returns (uint256[] memory amounts);

    function getAmountsIn(uint256 amountOut, address[] calldata path) external view returns (uint256[] memory amounts);
}

File 11 of 11 : IThrusterRouter02.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.6.2;

import "./IThrusterRouter01.sol";

interface IThrusterRouter02 is IThrusterRouter01 {
    function removeLiquidityETHSupportingFeeOnTransferTokens(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountETH);

    function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint256 amountETH);

    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external;

    function swapExactETHForTokensSupportingFeeOnTransferTokens(
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable;

    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external;
}

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

Contract Security Audit

Contract ABI

API
[{"inputs":[{"components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"router","type":"address"},{"internalType":"address","name":"recipientOfKOLsFunds","type":"address"},{"internalType":"address","name":"recipientOfCommunityFunds","type":"address"},{"internalType":"address","name":"recipientOfTreasuryFunds","type":"address"},{"internalType":"uint256","name":"amountAllocatedSoftPool","type":"uint256"},{"internalType":"uint256","name":"amountAllocatedHardPool","type":"uint256"},{"internalType":"uint256","name":"amountAllocatedLiquidity","type":"uint256"},{"internalType":"uint256","name":"amountAllocatedKOLs","type":"uint256"},{"internalType":"uint256","name":"amountAllocatedAirdrop","type":"uint256"},{"internalType":"uint256","name":"amountAllocatedCommunity","type":"uint256"},{"internalType":"uint256","name":"amountAllocatedRefs","type":"uint256"},{"internalType":"uint256","name":"capSoft","type":"uint256"},{"internalType":"uint256","name":"capHard","type":"uint256"},{"internalType":"uint256","name":"userDepositMin","type":"uint256"},{"internalType":"uint256","name":"userDepositMax","type":"uint256"}],"internalType":"struct INoGold.ConstructorCalldata","name":"data","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AllocationExceeded","type":"error"},{"inputs":[],"name":"AlreadyClaimed","type":"error"},{"inputs":[],"name":"DepositOutsideRange","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC20InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC20InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC20InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"ERC20InvalidSpender","type":"error"},{"inputs":[],"name":"InvalidMerkleProof","type":"error"},{"inputs":[],"name":"NoDeposits","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"SoftCapNotReached","type":"error"},{"inputs":[],"name":"TradingDisabled","type":"error"},{"inputs":[],"name":"UnexecutableNow","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"claimer","type":"address"},{"indexed":false,"internalType":"uint256","name":"claimedTokens","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountRefunded","type":"uint256"},{"indexed":false,"internalType":"enum INoGold.ClaimerType","name":"claimerType","type":"uint8"}],"name":"Claimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"depositor","type":"address"},{"indexed":false,"internalType":"uint256","name":"depositAmount","type":"uint256"}],"name":"Deposited","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"},{"anonymous":false,"inputs":[],"name":"Started","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"AMOUNT_ALLOCATED__AIRDROP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"AMOUNT_ALLOCATED__COMMUNITY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"AMOUNT_ALLOCATED__HARD_POOL","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"AMOUNT_ALLOCATED__KOLS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"AMOUNT_ALLOCATED__LIQUIDITY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"AMOUNT_ALLOCATED__REFS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"AMOUNT_ALLOCATED__SOFT_POOL","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CAP__HARD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CAP__SOFT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RECIPIENT__COMMUNITY","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RECIPIENT__KOLS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RECIPIENT__TREASURY","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ROUTER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"USER_DEPOSIT__MAX","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"USER_DEPOSIT__MIN","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"amountMintedToAirdropClaimers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"claimAirdrop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimPresale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"claimRefs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"computeAllocationAndRefund","outputs":[{"internalType":"uint256","name":"allocation","type":"uint256"},{"internalType":"uint256","name":"refund","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"depositedInTotal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"deposits","outputs":[{"internalType":"uint256","name":"amountDepositedToSoft","type":"uint256"},{"internalType":"uint256","name":"amountDepositedToHard","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"distributeFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getIsClaimedAirdrop","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getIsClaimedRefs","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getTotalUserDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isClaimedPresale","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"bytes32","name":"merkleRoot","type":"bytes32"}],"name":"setMerkleRootAirdrop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"}],"name":"setMerkleRootRefs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"start","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startTime","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

3462000680576200265b38819003610260601f8201601f19168101906001600160401b0382119082101762000580576102009282916040526102603912620006805760405161020081016001600160401b0381118282101762000580576040526200006c61026062000685565b8082526200007c61028062000685565b60208301526200008e6102a062000685565b6040830152620000a06102c062000685565b6060830152620000b26102e062000685565b60808301526103005160a08301526103205160c08301526103405160e083015261036051610100830152610380516101208301526103a0516101408301526103c0516101608301526103e051610180830152610400516101a0830152610420516101c0830152610440516101e08301526200012c6200069a565b91620001376200069a565b83519092906001600160401b0381116200058057600354600181811c9116801562000675575b60208210146200055f57601f81116200060f575b50602094601f8211600114620005a25794819293949560009262000596575b50508160011b916000199060031b1c1916176003555b82516001600160401b0381116200058057600454600181811c9116801562000575575b60208210146200055f57601f8111620004f9575b506020601f82116001146200048a57819293946000926200047e575b50508160011b916000199060031b1c1916176004555b6001600160a01b038116156200046557600580546001600160a01b039283166001600160a01b03198216811790925560405192167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a360a082015160805260c082015160a05260e082015160c05261010082015160e05261012082015161010052610140820151610120526101608201516101405260018060a01b036040830151166101805260018060a01b036060830151166101605260018060a01b036080830151166101a052610180820151610200526101a0820151916102209283526101c08101516101c0526101e08101516101e052602060018060a01b0391015116610240908152611f8d9283620006ce8439608051838181610b0f01528181611e5b0152611ea0015260a051838181610c7d01528181611e3a0152611ed1015260c0518381816104ed0152610e4d015260e051838181610cf60152610f38015261010051838181610c4201528181610e2601526114a401526101205183818161096a0152610f7f015261014051838181610c0701526112db0152610160518381816109010152610fa5015261018051838181610f59015261175401526101a0518381816105600152610fda01526101c05183818160550152818161060f015261067701526101e05183818161018001528181610528015261078401526102005183818160a9015281816106cc01528181610d970152818161179b0152611dbb0152518281816107e401528181610dd90152611df0015251818181610e79015281816110f301528181611b5e0152611d470152f35b604051631e4fbdf760e01b815260006004820152602490fd5b015190503880620001f9565b600460005260206000209060005b601f1984168110620004e05750600193949583601f19811610620004c6575b505050811b016004556200020f565b015160001960f88460031b161c19169055388080620004b7565b9091602060018192858a01518155019301910162000498565b60046000527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b601f830160051c81016020841062000557575b601f830160051c820181106200054a575050620001dd565b6000815560010162000532565b508062000532565b634e487b7160e01b600052602260045260246000fd5b90607f1690620001c9565b634e487b7160e01b600052604160045260246000fd5b01519050388062000190565b601f19821695600360005260206000209160005b888110620005f657508360019596979810620005dc575b505050811b01600355620001a6565b015160001960f88460031b161c19169055388080620005cd565b91926020600181928685015181550194019201620005b6565b60036000527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b601f830160051c8101602084106200066d575b601f830160051c820181106200066057505062000171565b6000815560010162000648565b508062000648565b90607f16906200015d565b600080fd5b51906001600160a01b03821682036200068057565b60408051919082016001600160401b03811183821017620005805760405260068252651393d1d3d31160d21b602083015256fe604060808152600490813610156101c7575b361561001c57600080fd5b64ffffffffff6100328160055460a81c16611c8e565b9080821642109182156101b2575b50506101a55733600052600b602052806000207f000000000000000000000000000000000000000000000000000000000000000034108015610164575b610156576008547f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c493507f00000000000000000000000000000000000000000000000000000000000000006000818310156101445750806100de3484611ca6565b1115610134576101096100f661011393600193611cb3565b610101818654611ca6565b855534611cb3565b9201918254611ca6565b905561012134600854611ca6565b60085551338152346020820152604090a1005b50506101136001610109346100f6565b610113925060019150610109906100f6565b505163dfd1b5a360e01b8152fd5b5061017e610176600183015434611ca6565b825490611ca6565b7f00000000000000000000000000000000000000000000000000000000000000001061007d565b516303e3ba1760e41b8152fd5b6101bd919250611c60565b1642113880610040565b6000803560e01c8063046ef9a5146117be57806305ffde6c14611783578063062144a61461173f57806306fdde031461164a578063095ea7b3146116205780630bcae1ac1461146a578063137600fe1461129957806318160ddd1461127a578063211034f11461123257806323b872dd1461113e578063313ce5671461112257806332fe7b26146110de5780633a6a4d2e14610d5757806345344f8214610d195780634bcf682a14610cde5780634fc19ec814610ca05780635aacb63a14610c6557806367166d6a14610c2a5780636c4f211d14610bef57806370a0823114610bb8578063715018a614610b5b57806378e9792514610b325780637b096f3714610af75780638da5cb5b14610ace5780639541bf8a14610a9057806395d89b411461098d5780639f7fb25814610952578063a6eef45b14610930578063a8e293cd146108ec578063a9059cbb146108bb578063b21699341461089c578063be9a655514610829578063c17b09ce14610807578063c7c9e4d7146107cc578063d0e30db014610632578063d52078f3146105f7578063dd62ed3e146105ae578063e0dce2dd1461058f578063e32e389d1461054b578063ed66da2914610510578063eec89745146104d5578063f2fde38b14610441578063fa75ce48146103fc5763fc7e286d146103b75750610011565b90346103f85760203660031901126103f8579081906001600160a01b036103dc611959565b168152600b602052206001815491015482519182526020820152f35b5080fd5b503461043e57602036600319011261043e576104329082906001600160a01b03610424611959565b168152600b60205220611db5565b82519182526020820152f35b80fd5b5091346104d15760203660031901126104d15761045c611959565b90610465611a4a565b6001600160a01b039182169283156104bb575050600554826bffffffffffffffffffffffff60a01b821617600555167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b51631e4fbdf760e01b8152908101849052602490fd5b8280fd5b5090346103f857816003193601126103f857602090517f00000000000000000000000000000000000000000000000000000000000000008152f35b5090346103f857816003193601126103f857602090517f00000000000000000000000000000000000000000000000000000000000000008152f35b5090346103f857816003193601126103f857517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b5090346103f857816003193601126103f8576020906009549051908152f35b5090346103f857806003193601126103f857806020926105cc611959565b6105d4611974565b6001600160a01b0391821683526001865283832091168252845220549051908152f35b5090346103f857816003193601126103f857602090517f00000000000000000000000000000000000000000000000000000000000000008152f35b5091826003193601126104d15764ffffffffff6106558160055460a81c16611c8e565b9080821642109182156107b7575b50506107a957338352600b602052818320907f000000000000000000000000000000000000000000000000000000000000000034108015610768575b61075a5750907f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c4916008547f000000000000000000000000000000000000000000000000000000000000000080821060001461074a57806107003484611ca6565b111561073a576101096100f661071893600193611cb3565b905561072634600854611ca6565b60085551338152346020820152604090a180f35b50506107186001610109346100f6565b50506107186001610109866100f6565b825163dfd1b5a360e01b8152fd5b5061078261077a600184015434611ca6565b835490611ca6565b7f00000000000000000000000000000000000000000000000000000000000000001061069f565b90516303e3ba1760e41b8152fd5b6107c2919250611c60565b1642113880610663565b5090346103f857816003193601126103f857602090517f00000000000000000000000000000000000000000000000000000000000000008152f35b5082346103f85760203660031901126103f857610822611a4a565b3560065580f35b5091346104d157826003193601126104d157610843611a4a565b6005549164ffffffffff8360a81c166101a557505064ffffffffff60a81b19164260a81b64ffffffffff60a81b16176005557fd8cea0ecd56872ff072e771658b5682ffe4de16d752947f79597d600ea56f7a98180a180f35b5090346103f857816003193601126103f8576020906008549051908152f35b5090346103f857806003193601126103f8576020906108e56108db611959565b6024359033611a76565b5160018152f35b5090346103f857816003193601126103f857517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b5082346103f85760203660031901126103f85761094b611a4a565b3560075580f35b5090346103f857816003193601126103f857602090517f00000000000000000000000000000000000000000000000000000000000000008152f35b5090346103f857816003193601126103f857805191809380549160019083821c92828516948515610a86575b6020958686108114610a7357858952908115610a4f57506001146109f7575b6109f387876109e9828c038361198a565b5191829182611910565b0390f35b81529295507f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b5b828410610a3c57505050826109f3946109e9928201019438806109d8565b8054868501880152928601928101610a1e565b60ff19168887015250505050151560051b83010192506109e9826109f338806109d8565b634e487b7160e01b845260228352602484fd5b93607f16936109b9565b5090346103f85760203660031901126103f85760209160ff9082906001600160a01b03610abb611959565b168152600e855220541690519015158152f35b5090346103f857816003193601126103f85760055490516001600160a01b039091168152602090f35b5090346103f857816003193601126103f857602090517f00000000000000000000000000000000000000000000000000000000000000008152f35b5090346103f857816003193601126103f85760209064ffffffffff60055460a81c169051908152f35b503461043e578060031936011261043e57610b74611a4a565b600580546001600160a01b0319811690915581906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b5090346103f85760203660031901126103f85760209181906001600160a01b03610be0611959565b16815280845220549051908152f35b5090346103f857816003193601126103f857602090517f00000000000000000000000000000000000000000000000000000000000000008152f35b5090346103f857816003193601126103f857602090517f00000000000000000000000000000000000000000000000000000000000000008152f35b5090346103f857816003193601126103f857602090517f00000000000000000000000000000000000000000000000000000000000000008152f35b5090346103f85760203660031901126103f85760209160ff9082906001600160a01b03610ccb611959565b168152600c855220541690519015158152f35b5090346103f857816003193601126103f857602090517f00000000000000000000000000000000000000000000000000000000000000008152f35b5090346103f85760203660031901126103f85760209160ff9082906001600160a01b03610d44611959565b168152600d855220541690519015158152f35b5091346104d157826003193601126104d157610d71611a4a565b60055464ffffffffff808260a81c169081159182156110bf575b50506110b057600854907f000000000000000000000000000000000000000000000000000000000000000082106110a05760ff8160a01c166110905760ff60a01b1916600160a01b176005557f00000000000000000000000000000000000000000000000000000000000000008181111561108957505b61138880820290828204148215171561107657906127108593920490610e4a6009547f0000000000000000000000000000000000000000000000000000000000000000611cb3565b927f0000000000000000000000000000000000000000000000000000000000000000610e768130611cc0565b857f0000000000000000000000000000000000000000000000000000000000000000610ea3838230611bcd565b60608960c460018060a01b0396898880600554169451968795869463f305d71960e01b865230908601528a602486015289604486015289606486015260848501524260a4850152165af19081611043575b5061102c5750610f0990826005541633611a76565b84808080868560055416828215611023575bf11561101957610fce859493859493610fc9610fa387965b610f7d7f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000611cc0565b7f0000000000000000000000000000000000000000000000000000000000000000611ca6565b7f0000000000000000000000000000000000000000000000000000000000000000611cc0565b611cb3565b908290821561100f575b7f00000000000000000000000000000000000000000000000000000000000000001690f115611005575080f35b51903d90823e3d90fd5b6108fc9150610fd8565b85513d86823e3d90fd5b506108fc610f1b565b94610fce915093859493610fc9610fa38796610f33565b6060809293503d811161106f575b61105b818361198a565b8101031261106b57869038610ef4565b8680fd5b503d611051565b634e487b7160e01b855260118352602485fd5b9050610e02565b83516374a5d1f560e01b81528390fd5b8351632bdc91ad60e01b81528390fd5b5090516303e3ba1760e41b8152fd5b6110d39192506110ce90611c60565b611c8e565b429116113880610d8b565b5090346103f857816003193601126103f857517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b5090346103f857816003193601126103f8576020905160128152f35b5082903461043e57606036600319011261043e5761115a611959565b611162611974565b916044359360018060a01b03831680835260016020528683203384526020528683205491600019830361119e575b6020886108e5898989611a76565b8683106112065781156111ef5733156111d8575082526001602090815286832033845281529186902090859003905582906108e587611190565b8751634a1406b160e11b8152908101849052602490fd5b875163e602df0560e01b8152908101849052602490fd5b8751637dc7a0d960e11b8152339181019182526020820193909352604081018790528291506060010390fd5b5090346103f85760203660031901126103f8576020916112739082906001600160a01b0361125e611959565b168152600b8552206001815491015490611ca6565b9051908152f35b5090346103f857816003193601126103f8576020906002549051908152f35b5082346103f8576112a9366119c2565b939064ffffffffff60059080825460a81c16908115918215611450575b505061144157600a546112d98382611ca6565b7f000000000000000000000000000000000000000000000000000000000000000010611431578261130991611ca6565b600a5560075495338652602091600e835260ff858820541661142157845133848201908152602081018690529061134d81604084015b03601f19810183528261198a565b5190209387945b83518610156113a95785831b8401850151908181101561139c57895284528588205b9460001981146113895760010194611354565b634e487b7160e01b895260118852602489fd5b9089528452858820611376565b868992898c889403611413575091836080927ffba955b7124801955d5218289768d39688a6c2af7c54181f5bf3b0b0e7a4aa8994338352600e8452818320600160ff198254161790556113fc8133611cc0565b81519333855284015282015260026060820152a180f35b825163582f497d60e11b8152fd5b8451630c8d9eab60e31b81528690fd5b505050516374a5d1f560e01b8152fd5b5050516303e3ba1760e41b8152fd5b61145f9192506110ce90611c60565b4291161187806112c6565b5082346103f85761147a366119c2565b64ffffffffff949160059580875460a81c169081421091821561160b575b505061144157600954917f0000000000000000000000000000000000000000000000000000000000000000808410156115fb578084916114d88386611ca6565b10156115e75750506114eb828094611ca6565b60095560065496338752602092600d845260ff86892054166115d7578551338582019081526020810192909252611525816040840161133f565b5190209387945b835186101561156e5785831b8401850151908181101561156157895284528588205b946000198114611389576001019461152c565b908952845285882061154e565b868992898c889403611413575091836080927ffba955b7124801955d5218289768d39688a6c2af7c54181f5bf3b0b0e7a4aa8994338352600d8452818320600160ff198254161790556115c18133611cc0565b815193338552840152820152836060820152a180f35b8551630c8d9eab60e31b81528790fd5b6114eb916115f491611cb3565b8094611ca6565b84516374a5d1f560e01b81528690fd5b611616919250611c8e565b1642118780611498565b5090346103f857806003193601126103f8576020906108e5611640611959565b6024359033611bcd565b509190346104d157826003193601126104d157805191836003549060019082821c928281168015611735575b6020958686108214611722575084885290811561170057506001146116a7575b6109f386866109e9828b038361198a565b929550600383527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b5b8284106116ed57505050826109f3946109e9928201019438611696565b80548685018801529286019281016116d0565b60ff191687860152505050151560051b83010192506109e9826109f338611696565b634e487b7160e01b845260229052602483fd5b93607f1693611676565b5090346103f857816003193601126103f857517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b5090346103f857816003193601126103f857602090517f00000000000000000000000000000000000000000000000000000000000000008152f35b5091346104d157826003193601126104d15764ffffffffff8060055460a81c169081159182156118f6575b50506107a957338352600b60205281832090600182015415806118ed575b6118df57338452600c60205260ff83852054166118d15750338352600c602052818320805460ff1916600117905561183e90611db5565b838115801561189e575b5050906080917ffba955b7124801955d5218289768d39688a6c2af7c54181f5bf3b0b0e7a4aa89938261188f575b805192338452602084015282015260016060820152a180f35b6118998333611cc0565b611876565b8282916118c7575b8280929181923390f1156118bb578338611848565b505051903d90823e3d90fd5b6108fc91506118a6565b8251630c8d9eab60e31b8152fd5b8251630558800760e21b8152fd5b50815415611807565b6119059192506110ce90611c60565b4291161138806117e9565b6020808252825181830181905290939260005b82811061194557505060409293506000838284010152601f8019910116010190565b818101860151848201604001528501611923565b600435906001600160a01b038216820361196f57565b600080fd5b602435906001600160a01b038216820361196f57565b90601f8019910116810190811067ffffffffffffffff8211176119ac57604052565b634e487b7160e01b600052604160045260246000fd5b90604060031983011261196f57600435916024359067ffffffffffffffff9081831161196f578060238401121561196f5782600401359182116119ac578160051b60405193602093611a168584018761198a565b855260248486019282010192831161196f57602401905b828210611a3b575050505090565b81358152908301908301611a2d565b6005546001600160a01b03163303611a5e57565b60405163118cdaa760e01b8152336004820152602490fd5b6001600160a01b0392838216929091908315611bb4578416938415611b9b5760ff60055460a01c16159081611b90575b81611b87575b81611b5a575b50611b485760009083825281602052604082205490838210611b16575091604082827fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef958760209652828652038282205586815220818154019055604051908152a3565b60405163391434e360e21b81526001600160a01b03919091166004820152602481019190915260448101839052606490fd5b60405163bcb8b8fb60e01b8152600490fd5b90507f00000000000000000000000000000000000000000000000000000000000000001683141538611ab2565b60019150611aac565b308514159150611aa6565b60405163ec442f0560e01b815260006004820152602490fd5b604051634b637e8f60e11b815260006004820152602490fd5b6001600160a01b03908116918215611c475716918215611c2e5760207f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925918360005260018252604060002085600052825280604060002055604051908152a3565b604051634a1406b160e11b815260006004820152602490fd5b60405163e602df0560e01b815260006004820152602490fd5b906201518064ffffffffff80931601918211611c7857565b634e487b7160e01b600052601160045260246000fd5b906202a30064ffffffffff80931601918211611c7857565b91908201809211611c7857565b91908203918211611c7857565b6001600160a01b0390811691908215611b9b5760ff60055460a01c16159081611d78575b81611d6f575b81611d43575b50611b48577fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef602082611d27600094600254611ca6565b60025584845283825260408420818154019055604051908152a3565b90507f000000000000000000000000000000000000000000000000000000000000000016151538611cf0565b60009150611cea565b3015159150611ce4565b81810292918115918404141715611c7857565b8115611d9f570490565b634e487b7160e01b600052601260045260246000fd5b906008547f000000000000000000000000000000000000000000000000000000000000000090818110600014611dee5750506000915490565b7f000000000000000000000000000000000000000000000000000000000000000093909184831015611e905750611e8a929350611e35816001611e85935491015490611ca6565b611e7f7f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000611ca6565b90611d82565b611d95565b90600090565b611f0c6001611ec583611e8586547f000000000000000000000000000000000000000000000000000000000000000090611d82565b93015492611f06611ef67f000000000000000000000000000000000000000000000000000000000000000086611d82565b611f008588611cb3565b90611d95565b90611ca6565b9460008315611f4f575092611f0082611f34611f2e611f3a95611f4098611cb3565b86611d82565b92611cb3565b90611cb3565b6000198101908111611c785790565b93505050509056fea2646970667358221220d9dffda07c0d37419e8f00eac4e21094f2a0c079dcb45a498b91c76c41b772fe64736f6c63430008140033000000000000000000000000ed1fc8dbd91b888982b0326ef2b54cb9782039e800000000000000000000000098994a9a7a2570367554589189dc9772241650f60000000000000000000000003918707d56b06049b25a2307b4cb3021fe85d8d300000000000000000000000096069d26f70ffd2a0bcc239303a00939991be11e0000000000000000000000007b76eaf764f75a4dfe4d8a6496064bfdf0d01e6a0000000000000000000000000000000000000000000dc94dc6363300b66800000000000000000000000000000000000000000000001b929ba82dd368bb980000000000000000000000000000000000000000000000108b2a2c280290940000000000000000000000000000000000000000000000000422ca8b0a00a4250000000000000000000000000000000000000000000000000771d2fa45345aa9000000000000000000000000000000000000000000000000084595161401484a00000000000000000000000000000000000000000000000004f68ca6d8cd91c6000000000000000000000000000000000000000000000000000002b5e3af16b188000000000000000000000000000000000000000000000000000821ab0d441498000000000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000022b1c8c1227a0000

Deployed Bytecode

0x604060808152600490813610156101c7575b361561001c57600080fd5b64ffffffffff6100328160055460a81c16611c8e565b9080821642109182156101b2575b50506101a55733600052600b602052806000207f00000000000000000000000000000000000000000000000000b1a2bc2ec5000034108015610164575b610156576008547f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c493507f000000000000000000000000000000000000000000000002b5e3af16b18800006000818310156101445750806100de3484611ca6565b1115610134576101096100f661011393600193611cb3565b610101818654611ca6565b855534611cb3565b9201918254611ca6565b905561012134600854611ca6565b60085551338152346020820152604090a1005b50506101136001610109346100f6565b610113925060019150610109906100f6565b505163dfd1b5a360e01b8152fd5b5061017e610176600183015434611ca6565b825490611ca6565b7f00000000000000000000000000000000000000000000000022b1c8c1227a00001061007d565b516303e3ba1760e41b8152fd5b6101bd919250611c60565b1642113880610040565b6000803560e01c8063046ef9a5146117be57806305ffde6c14611783578063062144a61461173f57806306fdde031461164a578063095ea7b3146116205780630bcae1ac1461146a578063137600fe1461129957806318160ddd1461127a578063211034f11461123257806323b872dd1461113e578063313ce5671461112257806332fe7b26146110de5780633a6a4d2e14610d5757806345344f8214610d195780634bcf682a14610cde5780634fc19ec814610ca05780635aacb63a14610c6557806367166d6a14610c2a5780636c4f211d14610bef57806370a0823114610bb8578063715018a614610b5b57806378e9792514610b325780637b096f3714610af75780638da5cb5b14610ace5780639541bf8a14610a9057806395d89b411461098d5780639f7fb25814610952578063a6eef45b14610930578063a8e293cd146108ec578063a9059cbb146108bb578063b21699341461089c578063be9a655514610829578063c17b09ce14610807578063c7c9e4d7146107cc578063d0e30db014610632578063d52078f3146105f7578063dd62ed3e146105ae578063e0dce2dd1461058f578063e32e389d1461054b578063ed66da2914610510578063eec89745146104d5578063f2fde38b14610441578063fa75ce48146103fc5763fc7e286d146103b75750610011565b90346103f85760203660031901126103f8579081906001600160a01b036103dc611959565b168152600b602052206001815491015482519182526020820152f35b5080fd5b503461043e57602036600319011261043e576104329082906001600160a01b03610424611959565b168152600b60205220611db5565b82519182526020820152f35b80fd5b5091346104d15760203660031901126104d15761045c611959565b90610465611a4a565b6001600160a01b039182169283156104bb575050600554826bffffffffffffffffffffffff60a01b821617600555167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b51631e4fbdf760e01b8152908101849052602490fd5b8280fd5b5090346103f857816003193601126103f857602090517f000000000000000000000000000000000000000000108b2a2c280290940000008152f35b5090346103f857816003193601126103f857602090517f00000000000000000000000000000000000000000000000022b1c8c1227a00008152f35b5090346103f857816003193601126103f857517f0000000000000000000000007b76eaf764f75a4dfe4d8a6496064bfdf0d01e6a6001600160a01b03168152602090f35b5090346103f857816003193601126103f8576020906009549051908152f35b5090346103f857806003193601126103f857806020926105cc611959565b6105d4611974565b6001600160a01b0391821683526001865283832091168252845220549051908152f35b5090346103f857816003193601126103f857602090517f00000000000000000000000000000000000000000000000000b1a2bc2ec500008152f35b5091826003193601126104d15764ffffffffff6106558160055460a81c16611c8e565b9080821642109182156107b7575b50506107a957338352600b602052818320907f00000000000000000000000000000000000000000000000000b1a2bc2ec5000034108015610768575b61075a5750907f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c4916008547f000000000000000000000000000000000000000000000002b5e3af16b188000080821060001461074a57806107003484611ca6565b111561073a576101096100f661071893600193611cb3565b905561072634600854611ca6565b60085551338152346020820152604090a180f35b50506107186001610109346100f6565b50506107186001610109866100f6565b825163dfd1b5a360e01b8152fd5b5061078261077a600184015434611ca6565b835490611ca6565b7f00000000000000000000000000000000000000000000000022b1c8c1227a00001061069f565b90516303e3ba1760e41b8152fd5b6107c2919250611c60565b1642113880610663565b5090346103f857816003193601126103f857602090517f00000000000000000000000000000000000000000000000821ab0d44149800008152f35b5082346103f85760203660031901126103f857610822611a4a565b3560065580f35b5091346104d157826003193601126104d157610843611a4a565b6005549164ffffffffff8360a81c166101a557505064ffffffffff60a81b19164260a81b64ffffffffff60a81b16176005557fd8cea0ecd56872ff072e771658b5682ffe4de16d752947f79597d600ea56f7a98180a180f35b5090346103f857816003193601126103f8576020906008549051908152f35b5090346103f857806003193601126103f8576020906108e56108db611959565b6024359033611a76565b5160018152f35b5090346103f857816003193601126103f857517f00000000000000000000000096069d26f70ffd2a0bcc239303a00939991be11e6001600160a01b03168152602090f35b5082346103f85760203660031901126103f85761094b611a4a565b3560075580f35b5090346103f857816003193601126103f857602090517f000000000000000000000000000000000000000000084595161401484a0000008152f35b5090346103f857816003193601126103f857805191809380549160019083821c92828516948515610a86575b6020958686108114610a7357858952908115610a4f57506001146109f7575b6109f387876109e9828c038361198a565b5191829182611910565b0390f35b81529295507f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b5b828410610a3c57505050826109f3946109e9928201019438806109d8565b8054868501880152928601928101610a1e565b60ff19168887015250505050151560051b83010192506109e9826109f338806109d8565b634e487b7160e01b845260228352602484fd5b93607f16936109b9565b5090346103f85760203660031901126103f85760209160ff9082906001600160a01b03610abb611959565b168152600e855220541690519015158152f35b5090346103f857816003193601126103f85760055490516001600160a01b039091168152602090f35b5090346103f857816003193601126103f857602090517f0000000000000000000000000000000000000000000dc94dc6363300b66800008152f35b5090346103f857816003193601126103f85760209064ffffffffff60055460a81c169051908152f35b503461043e578060031936011261043e57610b74611a4a565b600580546001600160a01b0319811690915581906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b5090346103f85760203660031901126103f85760209181906001600160a01b03610be0611959565b16815280845220549051908152f35b5090346103f857816003193601126103f857602090517f00000000000000000000000000000000000000000004f68ca6d8cd91c60000008152f35b5090346103f857816003193601126103f857602090517f0000000000000000000000000000000000000000000771d2fa45345aa90000008152f35b5090346103f857816003193601126103f857602090517f0000000000000000000000000000000000000000001b929ba82dd368bb9800008152f35b5090346103f85760203660031901126103f85760209160ff9082906001600160a01b03610ccb611959565b168152600c855220541690519015158152f35b5090346103f857816003193601126103f857602090517f0000000000000000000000000000000000000000000422ca8b0a00a4250000008152f35b5090346103f85760203660031901126103f85760209160ff9082906001600160a01b03610d44611959565b168152600d855220541690519015158152f35b5091346104d157826003193601126104d157610d71611a4a565b60055464ffffffffff808260a81c169081159182156110bf575b50506110b057600854907f000000000000000000000000000000000000000000000002b5e3af16b188000082106110a05760ff8160a01c166110905760ff60a01b1916600160a01b176005557f00000000000000000000000000000000000000000000000821ab0d44149800008181111561108957505b61138880820290828204148215171561107657906127108593920490610e4a6009547f0000000000000000000000000000000000000000000771d2fa45345aa9000000611cb3565b927f000000000000000000000000000000000000000000108b2a2c28029094000000610e768130611cc0565b857f00000000000000000000000098994a9a7a2570367554589189dc9772241650f6610ea3838230611bcd565b60608960c460018060a01b0396898880600554169451968795869463f305d71960e01b865230908601528a602486015289604486015289606486015260848501524260a4850152165af19081611043575b5061102c5750610f0990826005541633611a76565b84808080868560055416828215611023575bf11561101957610fce859493859493610fc9610fa387965b610f7d7f0000000000000000000000000000000000000000000422ca8b0a00a4250000007f0000000000000000000000003918707d56b06049b25a2307b4cb3021fe85d8d3611cc0565b7f000000000000000000000000000000000000000000084595161401484a000000611ca6565b7f00000000000000000000000096069d26f70ffd2a0bcc239303a00939991be11e611cc0565b611cb3565b908290821561100f575b7f0000000000000000000000007b76eaf764f75a4dfe4d8a6496064bfdf0d01e6a1690f115611005575080f35b51903d90823e3d90fd5b6108fc9150610fd8565b85513d86823e3d90fd5b506108fc610f1b565b94610fce915093859493610fc9610fa38796610f33565b6060809293503d811161106f575b61105b818361198a565b8101031261106b57869038610ef4565b8680fd5b503d611051565b634e487b7160e01b855260118352602485fd5b9050610e02565b83516374a5d1f560e01b81528390fd5b8351632bdc91ad60e01b81528390fd5b5090516303e3ba1760e41b8152fd5b6110d39192506110ce90611c60565b611c8e565b429116113880610d8b565b5090346103f857816003193601126103f857517f00000000000000000000000098994a9a7a2570367554589189dc9772241650f66001600160a01b03168152602090f35b5090346103f857816003193601126103f8576020905160128152f35b5082903461043e57606036600319011261043e5761115a611959565b611162611974565b916044359360018060a01b03831680835260016020528683203384526020528683205491600019830361119e575b6020886108e5898989611a76565b8683106112065781156111ef5733156111d8575082526001602090815286832033845281529186902090859003905582906108e587611190565b8751634a1406b160e11b8152908101849052602490fd5b875163e602df0560e01b8152908101849052602490fd5b8751637dc7a0d960e11b8152339181019182526020820193909352604081018790528291506060010390fd5b5090346103f85760203660031901126103f8576020916112739082906001600160a01b0361125e611959565b168152600b8552206001815491015490611ca6565b9051908152f35b5090346103f857816003193601126103f8576020906002549051908152f35b5082346103f8576112a9366119c2565b939064ffffffffff60059080825460a81c16908115918215611450575b505061144157600a546112d98382611ca6565b7f00000000000000000000000000000000000000000004f68ca6d8cd91c600000010611431578261130991611ca6565b600a5560075495338652602091600e835260ff858820541661142157845133848201908152602081018690529061134d81604084015b03601f19810183528261198a565b5190209387945b83518610156113a95785831b8401850151908181101561139c57895284528588205b9460001981146113895760010194611354565b634e487b7160e01b895260118852602489fd5b9089528452858820611376565b868992898c889403611413575091836080927ffba955b7124801955d5218289768d39688a6c2af7c54181f5bf3b0b0e7a4aa8994338352600e8452818320600160ff198254161790556113fc8133611cc0565b81519333855284015282015260026060820152a180f35b825163582f497d60e11b8152fd5b8451630c8d9eab60e31b81528690fd5b505050516374a5d1f560e01b8152fd5b5050516303e3ba1760e41b8152fd5b61145f9192506110ce90611c60565b4291161187806112c6565b5082346103f85761147a366119c2565b64ffffffffff949160059580875460a81c169081421091821561160b575b505061144157600954917f0000000000000000000000000000000000000000000771d2fa45345aa9000000808410156115fb578084916114d88386611ca6565b10156115e75750506114eb828094611ca6565b60095560065496338752602092600d845260ff86892054166115d7578551338582019081526020810192909252611525816040840161133f565b5190209387945b835186101561156e5785831b8401850151908181101561156157895284528588205b946000198114611389576001019461152c565b908952845285882061154e565b868992898c889403611413575091836080927ffba955b7124801955d5218289768d39688a6c2af7c54181f5bf3b0b0e7a4aa8994338352600d8452818320600160ff198254161790556115c18133611cc0565b815193338552840152820152836060820152a180f35b8551630c8d9eab60e31b81528790fd5b6114eb916115f491611cb3565b8094611ca6565b84516374a5d1f560e01b81528690fd5b611616919250611c8e565b1642118780611498565b5090346103f857806003193601126103f8576020906108e5611640611959565b6024359033611bcd565b509190346104d157826003193601126104d157805191836003549060019082821c928281168015611735575b6020958686108214611722575084885290811561170057506001146116a7575b6109f386866109e9828b038361198a565b929550600383527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b5b8284106116ed57505050826109f3946109e9928201019438611696565b80548685018801529286019281016116d0565b60ff191687860152505050151560051b83010192506109e9826109f338611696565b634e487b7160e01b845260229052602483fd5b93607f1693611676565b5090346103f857816003193601126103f857517f0000000000000000000000003918707d56b06049b25a2307b4cb3021fe85d8d36001600160a01b03168152602090f35b5090346103f857816003193601126103f857602090517f000000000000000000000000000000000000000000000002b5e3af16b18800008152f35b5091346104d157826003193601126104d15764ffffffffff8060055460a81c169081159182156118f6575b50506107a957338352600b60205281832090600182015415806118ed575b6118df57338452600c60205260ff83852054166118d15750338352600c602052818320805460ff1916600117905561183e90611db5565b838115801561189e575b5050906080917ffba955b7124801955d5218289768d39688a6c2af7c54181f5bf3b0b0e7a4aa89938261188f575b805192338452602084015282015260016060820152a180f35b6118998333611cc0565b611876565b8282916118c7575b8280929181923390f1156118bb578338611848565b505051903d90823e3d90fd5b6108fc91506118a6565b8251630c8d9eab60e31b8152fd5b8251630558800760e21b8152fd5b50815415611807565b6119059192506110ce90611c60565b4291161138806117e9565b6020808252825181830181905290939260005b82811061194557505060409293506000838284010152601f8019910116010190565b818101860151848201604001528501611923565b600435906001600160a01b038216820361196f57565b600080fd5b602435906001600160a01b038216820361196f57565b90601f8019910116810190811067ffffffffffffffff8211176119ac57604052565b634e487b7160e01b600052604160045260246000fd5b90604060031983011261196f57600435916024359067ffffffffffffffff9081831161196f578060238401121561196f5782600401359182116119ac578160051b60405193602093611a168584018761198a565b855260248486019282010192831161196f57602401905b828210611a3b575050505090565b81358152908301908301611a2d565b6005546001600160a01b03163303611a5e57565b60405163118cdaa760e01b8152336004820152602490fd5b6001600160a01b0392838216929091908315611bb4578416938415611b9b5760ff60055460a01c16159081611b90575b81611b87575b81611b5a575b50611b485760009083825281602052604082205490838210611b16575091604082827fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef958760209652828652038282205586815220818154019055604051908152a3565b60405163391434e360e21b81526001600160a01b03919091166004820152602481019190915260448101839052606490fd5b60405163bcb8b8fb60e01b8152600490fd5b90507f00000000000000000000000098994a9a7a2570367554589189dc9772241650f61683141538611ab2565b60019150611aac565b308514159150611aa6565b60405163ec442f0560e01b815260006004820152602490fd5b604051634b637e8f60e11b815260006004820152602490fd5b6001600160a01b03908116918215611c475716918215611c2e5760207f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925918360005260018252604060002085600052825280604060002055604051908152a3565b604051634a1406b160e11b815260006004820152602490fd5b60405163e602df0560e01b815260006004820152602490fd5b906201518064ffffffffff80931601918211611c7857565b634e487b7160e01b600052601160045260246000fd5b906202a30064ffffffffff80931601918211611c7857565b91908201809211611c7857565b91908203918211611c7857565b6001600160a01b0390811691908215611b9b5760ff60055460a01c16159081611d78575b81611d6f575b81611d43575b50611b48577fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef602082611d27600094600254611ca6565b60025584845283825260408420818154019055604051908152a3565b90507f00000000000000000000000098994a9a7a2570367554589189dc9772241650f616151538611cf0565b60009150611cea565b3015159150611ce4565b81810292918115918404141715611c7857565b8115611d9f570490565b634e487b7160e01b600052601260045260246000fd5b906008547f000000000000000000000000000000000000000000000002b5e3af16b188000090818110600014611dee5750506000915490565b7f00000000000000000000000000000000000000000000000821ab0d441498000093909184831015611e905750611e8a929350611e35816001611e85935491015490611ca6565b611e7f7f0000000000000000000000000000000000000000001b929ba82dd368bb9800007f0000000000000000000000000000000000000000000dc94dc6363300b6680000611ca6565b90611d82565b611d95565b90600090565b611f0c6001611ec583611e8586547f0000000000000000000000000000000000000000000dc94dc6363300b668000090611d82565b93015492611f06611ef67f0000000000000000000000000000000000000000001b929ba82dd368bb98000086611d82565b611f008588611cb3565b90611d95565b90611ca6565b9460008315611f4f575092611f0082611f34611f2e611f3a95611f4098611cb3565b86611d82565b92611cb3565b90611cb3565b6000198101908111611c785790565b93505050509056fea2646970667358221220d9dffda07c0d37419e8f00eac4e21094f2a0c079dcb45a498b91c76c41b772fe64736f6c63430008140033

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

000000000000000000000000ed1fc8dbd91b888982b0326ef2b54cb9782039e800000000000000000000000098994a9a7a2570367554589189dc9772241650f60000000000000000000000003918707d56b06049b25a2307b4cb3021fe85d8d300000000000000000000000096069d26f70ffd2a0bcc239303a00939991be11e0000000000000000000000007b76eaf764f75a4dfe4d8a6496064bfdf0d01e6a0000000000000000000000000000000000000000000dc94dc6363300b66800000000000000000000000000000000000000000000001b929ba82dd368bb980000000000000000000000000000000000000000000000108b2a2c280290940000000000000000000000000000000000000000000000000422ca8b0a00a4250000000000000000000000000000000000000000000000000771d2fa45345aa9000000000000000000000000000000000000000000000000084595161401484a00000000000000000000000000000000000000000000000004f68ca6d8cd91c6000000000000000000000000000000000000000000000000000002b5e3af16b188000000000000000000000000000000000000000000000000000821ab0d441498000000000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000022b1c8c1227a0000

-----Decoded View---------------
Arg [0] : data (tuple): System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput]

-----Encoded View---------------
16 Constructor Arguments found :
Arg [0] : 000000000000000000000000ed1fc8dbd91b888982b0326ef2b54cb9782039e8
Arg [1] : 00000000000000000000000098994a9a7a2570367554589189dc9772241650f6
Arg [2] : 0000000000000000000000003918707d56b06049b25a2307b4cb3021fe85d8d3
Arg [3] : 00000000000000000000000096069d26f70ffd2a0bcc239303a00939991be11e
Arg [4] : 0000000000000000000000007b76eaf764f75a4dfe4d8a6496064bfdf0d01e6a
Arg [5] : 0000000000000000000000000000000000000000000dc94dc6363300b6680000
Arg [6] : 0000000000000000000000000000000000000000001b929ba82dd368bb980000
Arg [7] : 000000000000000000000000000000000000000000108b2a2c28029094000000
Arg [8] : 0000000000000000000000000000000000000000000422ca8b0a00a425000000
Arg [9] : 0000000000000000000000000000000000000000000771d2fa45345aa9000000
Arg [10] : 000000000000000000000000000000000000000000084595161401484a000000
Arg [11] : 00000000000000000000000000000000000000000004f68ca6d8cd91c6000000
Arg [12] : 000000000000000000000000000000000000000000000002b5e3af16b1880000
Arg [13] : 00000000000000000000000000000000000000000000000821ab0d4414980000
Arg [14] : 00000000000000000000000000000000000000000000000000b1a2bc2ec50000
Arg [15] : 00000000000000000000000000000000000000000000000022b1c8c1227a0000


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

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