ETH Price: $2,253.33 (+6.63%)

Contract

0xEA4284948c461e3b9Ed6B3Af8f14F660ae90400A
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Set Duration164506652023-01-20 21:21:231150 days ago1674249683IN
0xEA428494...0ae90400A
0 ETH0.0007461825.02377919
Create Buy Order...164506652023-01-20 21:21:231150 days ago1674249683IN
0xEA428494...0ae90400A
0.005 ETH0.0020713525.52377919
Create Buy Order...164506642023-01-20 21:21:111150 days ago1674249671IN
0xEA428494...0ae90400A
0.2 ETH0.0020892125.74386553
Create Buy Order...164506622023-01-20 21:20:471150 days ago1674249647IN
0xEA428494...0ae90400A
50 ETH0.0023047828.40011943
Create Buy Order164506612023-01-20 21:20:351150 days ago1674249635IN
0xEA428494...0ae90400A
0 ETH0.0023109428.79066476
Create Buy Order...164506602023-01-20 21:20:231150 days ago1674249623IN
0xEA428494...0ae90400A
0.005 ETH0.0033375428.93306293
Create Buy Order...164506602023-01-20 21:20:231150 days ago1674249623IN
0xEA428494...0ae90400A
5 ETH0.0023886129.43306293
Create Buy Order164506582023-01-20 21:19:591150 days ago1674249599IN
0xEA428494...0ae90400A
0 ETH0.0035728729.95996608
Create Buy Order...164506572023-01-20 21:19:471150 days ago1674249587IN
0xEA428494...0ae90400A
50 ETH0.002448630.17231708
Create Buy Order164506562023-01-20 21:19:351150 days ago1674249575IN
0xEA428494...0ae90400A
0 ETH0.0036401530.52413189
Create Buy Order...164506542023-01-20 21:19:111150 days ago1674249551IN
0xEA428494...0ae90400A
0.59 ETH0.0029676425.726373
Create Buy Order...164506522023-01-20 21:18:471150 days ago1674249527IN
0xEA428494...0ae90400A
0.1496 ETH0.0023438628.88165267
Create Buy Order...164506522023-01-20 21:18:471150 days ago1674249527IN
0xEA428494...0ae90400A
0.134117 ETH0.0033892929.38165267
Create Buy Order164506492023-01-20 21:18:111150 days ago1674249491IN
0xEA428494...0ae90400A
0 ETH0.002139229.7008953
Create Buy Order164506462023-01-20 21:17:351150 days ago1674249455IN
0xEA428494...0ae90400A
0 ETH0.0020195928.0448769
Create Buy Order164506452023-01-20 21:17:231150 days ago1674249443IN
0xEA428494...0ae90400A
0 ETH0.0033505928.09325191
Create Buy Order164506422023-01-20 21:16:471150 days ago1674249407IN
0xEA428494...0ae90400A
0 ETH0.0059633550
Create Buy Order164506412023-01-20 21:16:351150 days ago1674249395IN
0xEA428494...0ae90400A
0 ETH0.002143129.7549699
Create Buy Order164506342023-01-20 21:15:111150 days ago1674249311IN
0xEA428494...0ae90400A
0 ETH0.0034165530.77613552
Create Buy Order...164506292023-01-20 21:14:111150 days ago1674249251IN
0xEA428494...0ae90400A
5 ETH0.0025381231.27536747
Create Buy Order164506232023-01-20 21:12:591150 days ago1674249179IN
0xEA428494...0ae90400A
0 ETH0.0022710231.53627657
Create Buy Order164506182023-01-20 21:11:591150 days ago1674249119IN
0xEA428494...0ae90400A
0 ETH0.0032890930.96348915
Create Buy Order164506162023-01-20 21:11:351150 days ago1674249095IN
0xEA428494...0ae90400A
0 ETH0.0036461131.85298047
Create Buy Order164506142023-01-20 21:11:111150 days ago1674249071IN
0xEA428494...0ae90400A
0 ETH0.003865632.41136234
Create Buy Order...164506082023-01-20 21:09:591150 days ago1674248999IN
0xEA428494...0ae90400A
50 ETH0.0040757935.3329487
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Method Block
From
To
Transfer164506652023-01-20 21:21:231150 days ago1674249683
0xEA428494...0ae90400A
0.005 ETH
Transfer164506642023-01-20 21:21:111150 days ago1674249671
0xEA428494...0ae90400A
0.2 ETH
Transfer164506622023-01-20 21:20:471150 days ago1674249647
0xEA428494...0ae90400A
50 ETH
Transfer164506602023-01-20 21:20:231150 days ago1674249623
0xEA428494...0ae90400A
0.005 ETH
Transfer164506602023-01-20 21:20:231150 days ago1674249623
0xEA428494...0ae90400A
5 ETH
Transfer164506572023-01-20 21:19:471150 days ago1674249587
0xEA428494...0ae90400A
50 ETH
Transfer164506542023-01-20 21:19:111150 days ago1674249551
0xEA428494...0ae90400A
0.59 ETH
Transfer164506522023-01-20 21:18:471150 days ago1674249527
0xEA428494...0ae90400A
0.1496 ETH
Transfer164506522023-01-20 21:18:471150 days ago1674249527
0xEA428494...0ae90400A
0.134117 ETH
Transfer164506292023-01-20 21:14:111150 days ago1674249251
0xEA428494...0ae90400A
5 ETH
Transfer164506082023-01-20 21:09:591150 days ago1674248999
0xEA428494...0ae90400A
50 ETH
Transfer164505902023-01-20 21:06:111150 days ago1674248771
0xEA428494...0ae90400A
0.3655 ETH
Transfer164505872023-01-20 21:05:351150 days ago1674248735
0xEA428494...0ae90400A
0.2 ETH
Transfer164505872023-01-20 21:05:351150 days ago1674248735
0xEA428494...0ae90400A
0.19 ETH
Transfer164505842023-01-20 21:04:591150 days ago1674248699
0xEA428494...0ae90400A
0.012 ETH
Transfer164505762023-01-20 21:03:231150 days ago1674248603
0xEA428494...0ae90400A
0.12 ETH
Transfer164505562023-01-20 20:59:231150 days ago1674248363
0xEA428494...0ae90400A
0.01 ETH
Transfer164505502023-01-20 20:58:111150 days ago1674248291
0xEA428494...0ae90400A
0.123 ETH
Transfer164505152023-01-20 20:51:111150 days ago1674247871
0xEA428494...0ae90400A
0.124791 ETH
Transfer164504742023-01-20 20:42:591150 days ago1674247379
0xEA428494...0ae90400A
0.143381 ETH
Transfer164504742023-01-20 20:42:591150 days ago1674247379
0xEA428494...0ae90400A
1.2 ETH
Transfer164504542023-01-20 20:38:591150 days ago1674247139
0xEA428494...0ae90400A
2.1 ETH
Transfer164504302023-01-20 20:34:111150 days ago1674246851
0xEA428494...0ae90400A
1.9 ETH
Transfer164504272023-01-20 20:33:351150 days ago1674246815
0xEA428494...0ae90400A
2.5 ETH
Transfer164504242023-01-20 20:32:591150 days ago1674246779
0xEA428494...0ae90400A
4.9 ETH
View All Internal Transactions
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

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

Contract Source Code Verified (Exact Match)

Contract Name:
Presale

Compiler Version
v0.8.15+commit.e14f2714

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
// SPDX-License-Identifier: BSD-3-Clause
pragma solidity ^0.8.13;

import {MerkleProof} from "lib/openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol";
import {Ownable} from "lib/openzeppelin-contracts/contracts/access/Ownable.sol";
import {IAggregatorV3} from "./interfaces/IAggregatorV3.sol";

/*//////////////////////////////////////////////////////////////
                          ERRORS
//////////////////////////////////////////////////////////////*/

error SaleOngoing(uint256 current, uint256 ends);
error SaleNotStarted(uint256 current, uint256 start);
error SaleEnded(uint256 current, uint256 ends);
error InvalidProof();
error AlreadyInitialised();
error NotInitialised();
error AlreadyClaimed();
error ClaimsNotOpen();
error PaymentCalcUnderflow();
error NotPaymentToken();
error ModularError(uint120 by, uint120 remainder);
error ZeroAddress();
error ZeroAmount();
error MoreThanBalance();
error NoAccess();

/*//////////////////////////////////////////////////////////////
                          INTERFACES
//////////////////////////////////////////////////////////////*/

interface IERC20 {
    function balanceOf(address) external returns (uint256);
    function transfer(address, uint256) external;
    function transferFrom(address, address, uint256) external;
}

interface IPresale {
    event PresaleInit(address indexed token, address indexed priceFeed, address indexed admin, address treasury);
    event Initialised(uint40 start, uint40 duration, uint256 price);
    event ClaimRootSet(bytes32 indexed root);
    event BuyOrder(address indexed buyer, address indexed paymentToken, uint256 payment, uint256 tokens);
    event Claim(
        address indexed buyer,
        uint256 filledTokens,
        uint256 unusedUsdc,
        uint256 unusedUsdt,
        uint256 unusedDai,
        uint256 unusedEth
    );
    event PriceFeedUpdate(address indexed priceFeed);
    event BuyOrderEth(address indexed buyer, int256 priceOfEth, uint256 amountOfEth, uint256 tokens);
    event AdminUpdate(address indexed admin);
    event TreasuryUpdate(address indexed treasury);
    event ClaimStatus(bool claimStatus);
    event DurationUpdate(uint40 duration);
    event PriceUpdate(uint256 price);
}

/// @title Presale
/// @author DeGatchi (https://github.com/DeGatchi)
/// @author 0xHessian (https://github.com/0xHessian)
/// @author 7811 (https://github.com/cranium7811)
contract Presale is IPresale, Ownable {
    /*//////////////////////////////////////////////////////////////
                                STATE
    //////////////////////////////////////////////////////////////*/

    /// Whether the contract's variables have been set.
    bool public initialised;
    // check the status of claim
    // 0 - false - not ready
    // 1 - true - ready
    bool public claimStatus;
    // address of the admin
    address public admin;
    // address of the treasury
    address public immutable treasury;

    /// Tokens being used as payment
    address public immutable dai;
    address public immutable usdt;
    address public immutable usdc;
    /// Token being sold
    IERC20 public immutable token;
    // Chainlink Aggregator interface
    IAggregatorV3 public priceFeed;

    /// When the sale begins.
    uint40 public start;
    /// How long the sale goes for.
    uint40 public duration;
    /// Total amount of tokens ordered.
    uint120 public supplyOrdered;
    /// Price per token
    uint256 public price;

    /// Root used to set the claim statistics.
    bytes32 public claimRoot;

    struct Receipt {
        uint120 dai; // Total DAI used as payment (18 decimals).
        uint120 usdt; // Total USDT used as payment (6 decimals).
        uint120 usdc; // Total USDC used as payment (6 decimals).
        uint120 eth; // Total ETH used as payment (18 decimals).
        uint120 tokens; // Total presale tokens ordered.
        bool claimed; // Whether the order has been claimed.
    }

    /// A record of EOAs and their corresponding order receipts.
    mapping(address => Receipt) public receipt;

    /*//////////////////////////////////////////////////////////////
                                MODIFIERS
    //////////////////////////////////////////////////////////////*/

    /// Enable use when contract has initialised.
    modifier onlyInit() {
        if (!initialised) revert NotInitialised();
        _;
    }

    /// Enable use when the sale has finished.
    modifier onlyEnd() {
        if (block.timestamp < start + duration) {
            revert SaleOngoing(block.timestamp, start + duration);
        }
        _;
    }

    /*//////////////////////////////////////////////////////////////
                               INITIALIZE
    //////////////////////////////////////////////////////////////*/

    /// @notice Sets up the contract addresses as immutable for gas saving.
    /// @param _dai ERC20 USDC token being used as payment (has 18 decimals).
    /// @param _usdt ERC20 USDC token being used as payment (has 6 decimals).
    /// @param _usdc ERC20 USDC token being used as payment (has 6 decimals).
    /// @param _token ERC20 token being sold for `_usdc`.
    /// @param _admin address of the admin
    /// @param _treasury address of the treasury
    constructor(
        address _dai,
        address _usdt,
        address _usdc,
        address _token,
        address _priceFeed,
        address _admin,
        address _treasury
    ) {
        dai = _dai;
        usdt = _usdt;
        usdc = _usdc;
        token = IERC20(_token);
        priceFeed = IAggregatorV3(_priceFeed);
        admin = _admin;
        treasury = _treasury;

        emit PresaleInit(_token, _priceFeed, _admin, _treasury);
    }

    /// @notice Sets up the sale.
    /// @dev Requires the initialiser to send `_supply` of `_token` to this address.
    /// @param _start Timestamp of when the sale begins.
    /// @param _duration How long the sale goes for.
    /// @param _price The `_usdc` payment value of each `_token`.
    function initialise(uint40 _start, uint40 _duration, uint256 _price) external onlyOwner {
        if (initialised) revert AlreadyInitialised();

        initialised = true;
        start = _start;
        duration = _duration;
        price = _price;

        emit Initialised(_start, _duration, _price);
    }

    /*//////////////////////////////////////////////////////////////
                                SETTERS
    //////////////////////////////////////////////////////////////*/

    /// @notice Allows owner to update the claim root to enable `claim()`.
    /// @dev Used to update the `claimRoot` to enable claiming.
    /// @param _newRoot Merkle root used after sale has ended to allow buyers to claim their tokens.
    function setClaimRoot(bytes32 _newRoot) public onlyOwner onlyEnd {
        if (block.timestamp < start) {
            revert SaleNotStarted(block.timestamp, start);
        }
        claimRoot = _newRoot;
        emit ClaimRootSet(_newRoot);
    }

    /// @notice allows the owner to set the priceFeed contract's address
    /// @param _priceFeed address of the new priceFeed contract
    function setPriceFeed(address _priceFeed) external {
        if (msg.sender != admin) revert NoAccess();
        if (_priceFeed == address(0)) revert ZeroAddress();
        priceFeed = IAggregatorV3(_priceFeed);
        emit PriceFeedUpdate(_priceFeed);
    }

    /// @notice allows the owner to set the address of `admin`
    /// @param _admin address of the `admin`
    function setAdmin(address _admin) external onlyOwner {
        if (_admin == address(0)) revert ZeroAddress();
        admin = _admin;
        emit AdminUpdate(_admin);
    }

    /// @notice allows the admin to set the claim status
    /// @param _claimStatus status of the claim, 0 - not ready, 1 - ready
    function setClaimStatus(bool _claimStatus) external {
        if (msg.sender != admin) revert NoAccess();
        claimStatus = _claimStatus;
        emit ClaimStatus(_claimStatus);
    }

    /// @notice allows the admin to set the duration of the sale
    /// @param _duration duration of the ongoing sale
    function setDuration(uint40 _duration) external {
        if (msg.sender != admin) revert NoAccess();
        duration = _duration;
        emit DurationUpdate(_duration);
    }

    /*//////////////////////////////////////////////////////////////
                            CREATE BUY ORDERS
    //////////////////////////////////////////////////////////////*/

    /// @notice Allows users to create an order to purchase presale tokens usdc, usdt or dai.
    /// @dev The buy event is used for the backend bot to determine the orders.
    /// @param _purchaseAmount Amount of usd value in the ERC20 token's decimal units
    /// @param _paymentToken Token paying with.
    function createBuyOrder(uint256 _purchaseAmount, address _paymentToken) external onlyInit {
        // Add a revert if purchaseAmount is less than 1
        if (_purchaseAmount < 1) revert ZeroAmount();

        uint40 _start = start;
        if (block.timestamp < _start) {
            revert SaleNotStarted(block.timestamp, _start);
        }
        if (block.timestamp >= _start + duration) {
            revert SaleEnded(block.timestamp, _start + duration);
        }

        Receipt storage _receipt = receipt[msg.sender];
        uint256 _tokens;
        if (_paymentToken == dai) {
            _tokens = (_purchaseAmount * 1e6) / price;
            _receipt.dai += uint120(_purchaseAmount);
        } else {
            _tokens = (_purchaseAmount * 1e18) / price;
            if (_paymentToken == usdc) _receipt.usdc += uint120(_purchaseAmount);
            else if (_paymentToken == usdt) _receipt.usdt += uint120(_purchaseAmount);
            else revert NotPaymentToken();
        }

        _receipt.tokens += uint120(_tokens);
        supplyOrdered += uint120(_tokens);
        IERC20(_paymentToken).transferFrom(msg.sender, treasury, _purchaseAmount);

        emit BuyOrder(msg.sender, _paymentToken, _purchaseAmount, _tokens);
    }

    /// @notice Allows users to create an order to purchase presale tokens w/ ETH.
    /// @dev The buy event is used for the backend bot to determine the orders.
    function createBuyOrderEth() external payable onlyInit {
        if (msg.value < 1) revert ZeroAmount();

        // Make sure the sale is ongoing.
        uint40 _start = start;
        if (block.timestamp < _start) revert SaleNotStarted(block.timestamp, _start);
        if (block.timestamp >= _start + duration) revert SaleEnded(block.timestamp, _start + duration);

        int256 _ethPrice = _getLatestPrice();
        uint256 _tokens = (uint256(_ethPrice) * msg.value) / (price * 1e2);
        Receipt storage _receipt = receipt[msg.sender];

        _receipt.eth += uint120(msg.value);
        _receipt.tokens += uint120(_tokens);
        supplyOrdered += uint120(_tokens);

        (bool success, ) = treasury.call{value :msg.value}("");
        require(success, "Transfer failed.");

        emit BuyOrderEth(msg.sender, _ethPrice, msg.value, _tokens);
    }

    /*//////////////////////////////////////////////////////////////
                            CLAIM AND TRANSFER
    //////////////////////////////////////////////////////////////*/

    /// @notice When sale ends, users can redeem their allocation w/ the filler bot's output.
    /// @dev Set owner as the treasury claimer to receive all used USDC + unsold tokens.
    ///      E.g, 90/100 tokens sold for 45 usdc paid; owner claims 10 tokens + 45 USDC.
    /// @param _claimer The EOA claiming on behalf for by the caller.
    /// @param _filledTokens Total presale tokens being sent to `_claimer`.
    /// @param _unusedUsdc Total USDC amount, that weren't used to buy `token`, being sent to `_claimer`.
    /// @param _unusedUsdt Total USDT amount, that weren't used to buy `token`, being sent to `_claimer`.
    /// @param _unusedDai Total DAI amount, that weren't used to buy `token`, being sent to `_claimer`.
    /// @param _unusedDai Total ETH amount, that weren't used to buy `token`, being sent to `_claimer`.
    /// @param _proof Merkle tree verification path.
    function claim(
        address _claimer,
        uint120 _filledTokens,
        uint120 _unusedUsdc,
        uint120 _unusedUsdt,
        uint120 _unusedDai,
        uint120 _unusedEth,
        bytes32[] memory _proof
    ) external onlyInit onlyEnd {
        if (claimRoot == bytes32(0)) revert ClaimsNotOpen();
        if (!claimStatus) revert ClaimsNotOpen();

        Receipt storage _receipt = receipt[_claimer];
        if (_receipt.claimed) revert AlreadyClaimed();

        bytes32 leaf = keccak256(
            bytes.concat(
                keccak256(abi.encode(_claimer, _filledTokens, _unusedUsdc, _unusedUsdt, _unusedDai, _unusedEth))
            )
        );
        if (!MerkleProof.verify(_proof, claimRoot, leaf)) revert InvalidProof();

        _receipt.claimed = true;

        if (_filledTokens > 0) token.transfer(_claimer, _filledTokens);
        if (_unusedUsdc > 0) IERC20(usdc).transfer(_claimer, _unusedUsdc);
        if (_unusedUsdt > 0) IERC20(usdt).transfer(_claimer, _unusedUsdt);
        if (_unusedDai > 0) IERC20(dai).transfer(_claimer, _unusedDai);
        if (_unusedEth > 0) payable(_claimer).transfer(_unusedEth);

        emit Claim(_claimer, _filledTokens, _unusedUsdc, _unusedUsdt, _unusedDai, _unusedEth);
    }

    /// @notice transfers the tokens and the remaining stablecoin/ETH tokens after filling the order
    /// @dev can be only called by the `admin`
    /// @param _buyer addresses of all the buyers
    /// @param _filledTokens amount of all the allocated tokens per address
    /// @param _unusedUsdc total remaining usdc which was not used when filling the order
    /// @param _unusedUsdt total remaining usdt which was not used when filling the order
    /// @param _unusedDai total remaining dai which was not used when filling the order
    /// @param _unusedEth total remaining eth which was not used when filling the order
    function transferTokens(
        address[] calldata _buyer,
        uint120[] calldata _filledTokens,
        uint120[] calldata _unusedUsdc,
        uint120[] calldata _unusedUsdt,
        uint120[] calldata _unusedDai,
        uint120[] calldata _unusedEth
    ) external {
        if (msg.sender != admin) revert NoAccess();
        if (!claimStatus) revert ClaimsNotOpen();

        uint256 length = _buyer.length;
        if (
            (_filledTokens.length != length) || (_unusedUsdc.length != length) || (_unusedUsdt.length != length)
                || (_unusedDai.length != length) || (_unusedEth.length != length)
        ) revert NoAccess();

        for (uint256 i; i < _buyer.length;) {
            transferTokensWithoutProof(
                _buyer[i], _filledTokens[i], _unusedUsdc[i], _unusedUsdt[i], _unusedDai[i], _unusedEth[i]
            );
            unchecked {
                ++i;
            }
        }
    }

    /// @notice transfers the tokens and the remaining stablecoin/ETH tokens after filling the order
    /// @dev can be only called by the `admin`
    /// @param _buyer address of the buyer/claimer
    /// @param _filledTokens amount of tokens which we transfer when filling the order per buyer
    /// @param _unusedUsdc total remaining usdc which was not used when filling the order per buyer
    /// @param _unusedUsdt total remaining usdt which was not used when filling the order per buyer
    /// @param _unusedDai total remaining dai which was not used when filling the order per buyer
    /// @param _unusedEth total remaining eth which was not used when filling the order per buyer
    function transferTokensWithoutProof(
        address _buyer,
        uint120 _filledTokens,
        uint120 _unusedUsdc,
        uint120 _unusedUsdt,
        uint120 _unusedDai,
        uint120 _unusedEth
    ) public {
        if (msg.sender != admin) revert NoAccess();
        if (!claimStatus) revert ClaimsNotOpen();

        Receipt storage _receipt = receipt[_buyer];
        if (_receipt.claimed) revert AlreadyClaimed();
        _receipt.claimed = true;

        if (_filledTokens > 0) token.transfer(_buyer, _filledTokens);
        if (_unusedUsdc > 0) IERC20(usdc).transfer(_buyer, _unusedUsdc);
        if (_unusedUsdt > 0) IERC20(usdt).transfer(_buyer, _unusedUsdt);
        if (_unusedDai > 0) IERC20(dai).transfer(_buyer, _unusedDai);
        if (_unusedEth > 0) payable(_buyer).transfer(_unusedEth);
    }

    /*//////////////////////////////////////////////////////////////
                          WITHDRAW FUNCTIONS
    //////////////////////////////////////////////////////////////*/

    /// @notice Withdraw any amount(less than the balance) of an ERC20 token from this contract to a receiver
    /// @dev can only be called by the owner
    /// @param _token address of the ERC20 token to be withdrawn
    /// @param _amount the amount of tokens to be withdrawn
    function withdraw(address _token, uint120 _amount) external onlyOwner {
        // check if the balance is more than the amount
        uint256 _balance = IERC20(_token).balanceOf(address(this));
        if (uint256(_amount) > _balance) revert MoreThanBalance();

        // transfer the `ERC20` token
        IERC20(_token).transfer(treasury, _amount);
    }

    /// @notice withdraw any amount (less than the balance) of ETH from this contract to a receiver
    /// @dev can only be called by the owner
    /// @param _amount the amount of ETH to be withdrawn
    function withdrawEth(uint120 _amount) external onlyOwner {
        // check if the balance is more than the amount
        uint256 _balance = address(this).balance;
        if (uint256(_amount) > _balance) revert MoreThanBalance();

        // transfer the eth
        (bool success, ) = treasury.call{value : _amount}("");
        require(success, "Transfer failed.");
    }

    /*//////////////////////////////////////////////////////////////
                        INTERNAL FUNCTIONS
    //////////////////////////////////////////////////////////////*/

    /// @notice get the latest price for eth from Chainlink's Aggregator PriceFeed
    function _getLatestPrice() internal view returns (int256) {
        (, int256 _price,,,) = priceFeed.latestRoundData();
        return _price;
    }

    /*//////////////////////////////////////////////////////////////
                            FALLBACK
    //////////////////////////////////////////////////////////////*/

    receive() external payable {}
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;

import "../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.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev 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 {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

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

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

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

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

pragma solidity ^0.8.0;

/**
 * @dev These functions deal with verification of Merkle Tree proofs.
 *
 * The proofs can be generated using the JavaScript library
 * https://github.com/miguelmota/merkletreejs[merkletreejs].
 * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.
 *
 * See `test/utils/cryptography/MerkleProof.test.js` for some examples.
 *
 * 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.
 */
library MerkleProof {
    /**
     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
     * defined by `root`. For this, a `proof` must be provided, containing
     * sibling hashes on the branch from the leaf to the root of the tree. Each
     * pair of leaves and each pair of pre-images are assumed to be sorted.
     */
    function verify(
        bytes32[] memory proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProof(proof, leaf) == root;
    }

    /**
     * @dev Calldata version of {verify}
     *
     * _Available since v4.7._
     */
    function verifyCalldata(
        bytes32[] calldata proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProofCalldata(proof, leaf) == root;
    }

    /**
     * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
     * hash matches the root of the tree. When processing the proof, the pairs
     * of leafs & pre-images are assumed to be sorted.
     *
     * _Available since v4.4._
     */
    function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            computedHash = _hashPair(computedHash, proof[i]);
        }
        return computedHash;
    }

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

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

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

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

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

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

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

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

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

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

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

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IAggregatorV3 {
    function decimals() external view returns (uint8);

    function description() external view returns (string memory);

    function version() external view returns (uint256);

    function getRoundData(uint80 _roundId)
        external
        view
        returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);

    function latestRoundData()
        external
        view
        returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);
}

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

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"_dai","type":"address"},{"internalType":"address","name":"_usdt","type":"address"},{"internalType":"address","name":"_usdc","type":"address"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_priceFeed","type":"address"},{"internalType":"address","name":"_admin","type":"address"},{"internalType":"address","name":"_treasury","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyClaimed","type":"error"},{"inputs":[],"name":"AlreadyInitialised","type":"error"},{"inputs":[],"name":"ClaimsNotOpen","type":"error"},{"inputs":[],"name":"InvalidProof","type":"error"},{"inputs":[],"name":"MoreThanBalance","type":"error"},{"inputs":[],"name":"NoAccess","type":"error"},{"inputs":[],"name":"NotInitialised","type":"error"},{"inputs":[],"name":"NotPaymentToken","type":"error"},{"inputs":[{"internalType":"uint256","name":"current","type":"uint256"},{"internalType":"uint256","name":"ends","type":"uint256"}],"name":"SaleEnded","type":"error"},{"inputs":[{"internalType":"uint256","name":"current","type":"uint256"},{"internalType":"uint256","name":"start","type":"uint256"}],"name":"SaleNotStarted","type":"error"},{"inputs":[{"internalType":"uint256","name":"current","type":"uint256"},{"internalType":"uint256","name":"ends","type":"uint256"}],"name":"SaleOngoing","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"inputs":[],"name":"ZeroAmount","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"admin","type":"address"}],"name":"AdminUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"buyer","type":"address"},{"indexed":true,"internalType":"address","name":"paymentToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"payment","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokens","type":"uint256"}],"name":"BuyOrder","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"int256","name":"priceOfEth","type":"int256"},{"indexed":false,"internalType":"uint256","name":"amountOfEth","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokens","type":"uint256"}],"name":"BuyOrderEth","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"uint256","name":"filledTokens","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"unusedUsdc","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"unusedUsdt","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"unusedDai","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"unusedEth","type":"uint256"}],"name":"Claim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"root","type":"bytes32"}],"name":"ClaimRootSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"claimStatus","type":"bool"}],"name":"ClaimStatus","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint40","name":"duration","type":"uint40"}],"name":"DurationUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint40","name":"start","type":"uint40"},{"indexed":false,"internalType":"uint40","name":"duration","type":"uint40"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"}],"name":"Initialised","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":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"priceFeed","type":"address"},{"indexed":true,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"address","name":"treasury","type":"address"}],"name":"PresaleInit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"priceFeed","type":"address"}],"name":"PriceFeedUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"}],"name":"PriceUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"treasury","type":"address"}],"name":"TreasuryUpdate","type":"event"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_claimer","type":"address"},{"internalType":"uint120","name":"_filledTokens","type":"uint120"},{"internalType":"uint120","name":"_unusedUsdc","type":"uint120"},{"internalType":"uint120","name":"_unusedUsdt","type":"uint120"},{"internalType":"uint120","name":"_unusedDai","type":"uint120"},{"internalType":"uint120","name":"_unusedEth","type":"uint120"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimStatus","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_purchaseAmount","type":"uint256"},{"internalType":"address","name":"_paymentToken","type":"address"}],"name":"createBuyOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"createBuyOrderEth","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"dai","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"duration","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint40","name":"_start","type":"uint40"},{"internalType":"uint40","name":"_duration","type":"uint40"},{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"initialise","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initialised","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"priceFeed","outputs":[{"internalType":"contract IAggregatorV3","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"receipt","outputs":[{"internalType":"uint120","name":"dai","type":"uint120"},{"internalType":"uint120","name":"usdt","type":"uint120"},{"internalType":"uint120","name":"usdc","type":"uint120"},{"internalType":"uint120","name":"eth","type":"uint120"},{"internalType":"uint120","name":"tokens","type":"uint120"},{"internalType":"bool","name":"claimed","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_admin","type":"address"}],"name":"setAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_newRoot","type":"bytes32"}],"name":"setClaimRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_claimStatus","type":"bool"}],"name":"setClaimStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint40","name":"_duration","type":"uint40"}],"name":"setDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_priceFeed","type":"address"}],"name":"setPriceFeed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"start","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"supplyOrdered","outputs":[{"internalType":"uint120","name":"","type":"uint120"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_buyer","type":"address[]"},{"internalType":"uint120[]","name":"_filledTokens","type":"uint120[]"},{"internalType":"uint120[]","name":"_unusedUsdc","type":"uint120[]"},{"internalType":"uint120[]","name":"_unusedUsdt","type":"uint120[]"},{"internalType":"uint120[]","name":"_unusedDai","type":"uint120[]"},{"internalType":"uint120[]","name":"_unusedEth","type":"uint120[]"}],"name":"transferTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_buyer","type":"address"},{"internalType":"uint120","name":"_filledTokens","type":"uint120"},{"internalType":"uint120","name":"_unusedUsdc","type":"uint120"},{"internalType":"uint120","name":"_unusedUsdt","type":"uint120"},{"internalType":"uint120","name":"_unusedDai","type":"uint120"},{"internalType":"uint120","name":"_unusedEth","type":"uint120"}],"name":"transferTokensWithoutProof","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"usdc","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"usdt","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint120","name":"_amount","type":"uint120"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint120","name":"_amount","type":"uint120"}],"name":"withdrawEth","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

6101206040523480156200001257600080fd5b50604051620028d3380380620028d3833981016040819052620000359162000140565b6200004033620000d3565b6001600160a01b0387811660a05286811660c05285811660e052848116610100819052600280548684166001600160a01b031991821681179092556001805487861692168217905592841660808190526040519081529091907fd4decd75c1b81806e68890dff94855825d24afe0200fff3d1dc75e6dafdd4e309060200160405180910390a450505050505050620001d5565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b03811681146200013b57600080fd5b919050565b600080600080600080600060e0888a0312156200015c57600080fd5b620001678862000123565b9650620001776020890162000123565b9550620001876040890162000123565b9450620001976060890162000123565b9350620001a76080890162000123565b9250620001b760a0890162000123565b9150620001c760c0890162000123565b905092959891949750929550565b60805160a05160c05160e0516101005161265062000283600039600081816106ce015281816115af0152611a1601526000818161035d01528181610e180152818161163f0152611aa60152600081816102d101528181610e71015281816116cf0152611b3601526000818161067a01528181610d690152818161175f0152611bc60152600081816103d101528181610948015281816109e001528181610f8501526113df01526126506000f3fe6080604052600436106101dc5760003560e01c8063724e78da11610102578063c147c8a511610095578063f2fde38b11610064578063f2fde38b14610648578063f4b9fa7514610668578063f851a4401461069c578063fc0c546a146106bc57600080fd5b8063c147c8a51461052a578063ddd25be81461054a578063e35e56631461056a578063e53ed6161461061057600080fd5b8063a035b1fe116100d1578063a035b1fe146104ae578063a5b58676146104c4578063ae87fc4b146104e4578063be9a65551461050557600080fd5b8063724e78da14610448578063741bef1a146104685780638da5cb5b1461048857806397466cab146104a657600080fd5b80633998081a1161017a57806361d027b31161014957806361d027b3146103bf578063654f97a3146103f3578063704b6c0214610413578063715018a61461043357600080fd5b80633998081a1461032b5780633e413bee1461034b5780634d675b881461037f5780636113e5521461039f57600080fd5b806314ea35e7116101b657806314ea35e71461027b57806321b97f201461029f5780632f48ab7d146102bf5780633730099a1461030b57600080fd5b806307003bb4146101e85780630740c9ef1461021e5780630fb5a6b41461024057600080fd5b366101e357005b600080fd5b3480156101f457600080fd5b5060005461020990600160a01b900460ff1681565b60405190151581526020015b60405180910390f35b34801561022a57600080fd5b5061023e61023936600461201b565b6106f0565b005b34801561024c57600080fd5b5060025461026590600160c81b900464ffffffffff1681565b60405164ffffffffff9091168152602001610215565b34801561028757600080fd5b5061029160055481565b604051908152602001610215565b3480156102ab57600080fd5b5061023e6102ba366004612036565b610778565b3480156102cb57600080fd5b506102f37f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610215565b34801561031757600080fd5b5061023e61032636600461207d565b610883565b34801561033757600080fd5b5061023e6103463660046120b0565b6109a9565b34801561035757600080fd5b506102f37f000000000000000000000000000000000000000000000000000000000000000081565b34801561038b57600080fd5b5061023e61039a366004612117565b610aa0565b3480156103ab57600080fd5b5061023e6103ba36600461225a565b610c54565b3480156103cb57600080fd5b506102f37f000000000000000000000000000000000000000000000000000000000000000081565b3480156103ff57600080fd5b5061023e61040e36600461227d565b611046565b34801561041f57600080fd5b5061023e61042e36600461229f565b6110be565b34801561043f57600080fd5b5061023e611137565b34801561045457600080fd5b5061023e61046336600461229f565b61114b565b34801561047457600080fd5b506002546102f3906001600160a01b031681565b34801561049457600080fd5b506000546001600160a01b03166102f3565b61023e6111e7565b3480156104ba57600080fd5b5061029160045481565b3480156104d057600080fd5b5061023e6104df3660046122ba565b6114da565b3480156104f057600080fd5b5060005461020990600160a81b900460ff1681565b34801561051157600080fd5b5060025461026590600160a01b900464ffffffffff1681565b34801561053657600080fd5b5061023e610545366004612344565b611820565b34801561055657600080fd5b5061023e610565366004612468565b611cf1565b34801561057657600080fd5b506105cd61058536600461229f565b6006602052600090815260409020805460018201546002909201546001600160781b0380831693600160781b9384900482169382821693918190048316928216910460ff1686565b604080516001600160781b0397881681529587166020870152938616938501939093529084166060840152909216608082015290151560a082015260c001610215565b34801561061c57600080fd5b50600354610630906001600160781b031681565b6040516001600160781b039091168152602001610215565b34801561065457600080fd5b5061023e61066336600461229f565b611dc4565b34801561067457600080fd5b506102f37f000000000000000000000000000000000000000000000000000000000000000081565b3480156106a857600080fd5b506001546102f3906001600160a01b031681565b3480156106c857600080fd5b506102f37f000000000000000000000000000000000000000000000000000000000000000081565b6001546001600160a01b0316331461071b5760405163160d3af160e11b815260040160405180910390fd5b6002805464ffffffffff60c81b1916600160c81b64ffffffffff8416908102919091179091556040519081527f88119d9c2527a3bbdd001f5a8c4ae3bfbff5c4d2ec8663f0d78322a0dcbb1725906020015b60405180910390a150565b610780611e3d565b6002546107a49064ffffffffff600160c81b8204811691600160a01b9004166124ba565b64ffffffffff164210156108065760025442906107d89064ffffffffff600160c81b8204811691600160a01b9004166124ba565b60405163e275812560e01b8152600481019290925264ffffffffff1660248201526044015b60405180910390fd5b600254600160a01b900464ffffffffff164210156108505760025460405163457f873160e01b8152426004820152600160a01b90910464ffffffffff1660248201526044016107fd565b600581905560405181907f6b3b0a9ab98c361bbd6e7c0fa7c102fb7a4e7712191bf556a461a9e5aa70948f90600090a250565b61088b611e3d565b6040516370a0823160e01b81523060048201526000906001600160a01b038416906370a08231906024016020604051808303816000875af11580156108d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f891906124e3565b905080826001600160781b0316111561092457604051631b4266e760e21b815260040160405180910390fd5b60405163a9059cbb60e01b81526001600160a01b0384169063a9059cbb90610972907f00000000000000000000000000000000000000000000000000000000000000009086906004016124fc565b600060405180830381600087803b15801561098c57600080fd5b505af11580156109a0573d6000803e3d6000fd5b50505050505050565b6109b1611e3d565b476001600160781b0382168110156109dc57604051631b4266e760e21b815260040160405180910390fd5b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160781b031660405160006040518083038185875af1925050503d8060008114610a52576040519150601f19603f3d011682016040523d82523d6000602084013e610a57565b606091505b5050905080610a9b5760405162461bcd60e51b815260206004820152601060248201526f2a3930b739b332b9103330b4b632b21760811b60448201526064016107fd565b505050565b6001546001600160a01b03163314610acb5760405163160d3af160e11b815260040160405180910390fd5b600054600160a81b900460ff16610af557604051633b03644960e01b815260040160405180910390fd5b8a8981141580610b055750878114155b80610b105750858114155b80610b1b5750838114155b80610b265750818114155b15610b445760405163160d3af160e11b815260040160405180910390fd5b60005b8c811015610c4457610c3c8e8e83818110610b6457610b6461251e565b9050602002016020810190610b79919061229f565b8d8d84818110610b8b57610b8b61251e565b9050602002016020810190610ba091906120b0565b8c8c85818110610bb257610bb261251e565b9050602002016020810190610bc791906120b0565b8b8b86818110610bd957610bd961251e565b9050602002016020810190610bee91906120b0565b8a8a87818110610c0057610c0061251e565b9050602002016020810190610c1591906120b0565b898988818110610c2757610c2761251e565b90506020020160208101906104df91906120b0565b600101610b47565b5050505050505050505050505050565b600054600160a01b900460ff16610c7e5760405163421972d160e11b815260040160405180910390fd5b6001821015610ca057604051631f2a200560e01b815260040160405180910390fd5b600254600160a01b900464ffffffffff1642811115610ce15760405163457f873160e01b815242600482015264ffffffffff821660248201526044016107fd565b600254610cfc90600160c81b900464ffffffffff16826124ba565b64ffffffffff164210610d4f576002544290610d2690600160c81b900464ffffffffff16836124ba565b60405163ce40104160e01b8152600481019290925264ffffffffff1660248201526044016107fd565b336000908152600660205260408120906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811690851603610df557600454610da286620f4240612534565b610dac9190612553565b825490915085908390600090610dcc9084906001600160781b0316612575565b92506101000a8154816001600160781b0302191690836001600160781b03160217905550610ee5565b600454610e0a86670de0b6b3a7640000612534565b610e149190612553565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316846001600160a01b031603610e6f57600182018054869190600090610dcc9084906001600160781b0316612575565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316846001600160a01b031603610ecc57815485908390600f90610dcc908490600160781b90046001600160781b0316612575565b604051632c83944560e01b815260040160405180910390fd5b600282018054829190600090610f059084906001600160781b0316612575565b92506101000a8154816001600160781b0302191690836001600160781b0316021790555080600360008282829054906101000a90046001600160781b0316610f4d9190612575565b82546001600160781b039182166101009390930a9283029190920219909116179055506040516323b872dd60e01b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b039081166024830152604482018790528516906323b872dd90606401600060405180830381600087803b158015610fe157600080fd5b505af1158015610ff5573d6000803e3d6000fd5b505060408051888152602081018590526001600160a01b03881693503392507f3b73bff6407bf93966c8d7a35e634896ff57226eb26f367b06b2b7a3d513fdcb910160405180910390a35050505050565b6001546001600160a01b031633146110715760405163160d3af160e11b815260040160405180910390fd5b60008054821515600160a81b0260ff60a81b199091161790556040517fa6c41a0df1bf3653d829a71569e419f707fe0129924b2b9dfc22493d0b81d9f99061076d90831515815260200190565b6110c6611e3d565b6001600160a01b0381166110ed5760405163d92e233d60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0383169081179091556040517f0c2515f25186df02132ad46f01e062c3b8982c8de57fa2b1b0a280d8e810f39b90600090a250565b61113f611e3d565b6111496000611e97565b565b6001546001600160a01b031633146111765760405163160d3af160e11b815260040160405180910390fd5b6001600160a01b03811661119d5760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040517fddcc21be684c966209b6f56a96e50f3034f7f931ff5fc9cdf79ad684e32f890390600090a250565b600054600160a01b900460ff166112115760405163421972d160e11b815260040160405180910390fd5b600134101561123357604051631f2a200560e01b815260040160405180910390fd5b600254600160a01b900464ffffffffff16428111156112745760405163457f873160e01b815242600482015264ffffffffff821660248201526044016107fd565b60025461128f90600160c81b900464ffffffffff16826124ba565b64ffffffffff1642106112b9576002544290610d2690600160c81b900464ffffffffff16836124ba565b60006112c3611ee7565b9050600060045460646112d69190612534565b6112e03484612534565b6112ea9190612553565b3360009081526006602052604090206001810180549293509091349190600f90611325908490600160781b90046001600160781b0316612575565b92506101000a8154816001600160781b0302191690836001600160781b03160217905550818160020160008282829054906101000a90046001600160781b031661136f9190612575565b92506101000a8154816001600160781b0302191690836001600160781b0316021790555081600360008282829054906101000a90046001600160781b03166113b79190612575565b92506101000a8154816001600160781b0302191690836001600160781b0316021790555060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163460405160006040518083038185875af1925050503d8060008114611448576040519150601f19603f3d011682016040523d82523d6000602084013e61144d565b606091505b50509050806114915760405162461bcd60e51b815260206004820152601060248201526f2a3930b739b332b9103330b4b632b21760811b60448201526064016107fd565b6040805185815234602082015290810184905233907fbabfb52ebe2322d72451b6b4e6235a7864be7d11f426e81dc6436edd6f750f339060600160405180910390a25050505050565b6001546001600160a01b031633146115055760405163160d3af160e11b815260040160405180910390fd5b600054600160a81b900460ff1661152f57604051633b03644960e01b815260040160405180910390fd5b6001600160a01b03861660009081526006602052604090206002810154600160781b900460ff161561157457604051630c8d9eab60e31b815260040160405180910390fd5b60028101805460ff60781b1916600160781b1790556001600160781b038616156116195760405163a9059cbb60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906115e6908a908a906004016124fc565b600060405180830381600087803b15801561160057600080fd5b505af1158015611614573d6000803e3d6000fd5b505050505b6001600160781b038516156116a95760405163a9059cbb60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb90611676908a9089906004016124fc565b600060405180830381600087803b15801561169057600080fd5b505af11580156116a4573d6000803e3d6000fd5b505050505b6001600160781b038416156117395760405163a9059cbb60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb90611706908a9088906004016124fc565b600060405180830381600087803b15801561172057600080fd5b505af1158015611734573d6000803e3d6000fd5b505050505b6001600160781b038316156117c95760405163a9059cbb60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb90611796908a9087906004016124fc565b600060405180830381600087803b1580156117b057600080fd5b505af11580156117c4573d6000803e3d6000fd5b505050505b6001600160781b038216156109a0576040516001600160a01b038816906001600160781b03841680156108fc02916000818181858888f19350505050158015611816573d6000803e3d6000fd5b5050505050505050565b600054600160a01b900460ff1661184a5760405163421972d160e11b815260040160405180910390fd5b60025461186e9064ffffffffff600160c81b8204811691600160a01b9004166124ba565b64ffffffffff164210156118a25760025442906107d89064ffffffffff600160c81b8204811691600160a01b9004166124ba565b6005546118c257604051633b03644960e01b815260040160405180910390fd5b600054600160a81b900460ff166118ec57604051633b03644960e01b815260040160405180910390fd5b6001600160a01b03871660009081526006602052604090206002810154600160781b900460ff161561193157604051630c8d9eab60e31b815260040160405180910390fd5b604080516001600160a01b038a1660208201526001600160781b03808a16928201929092528188166060820152818716608082015281861660a082015290841660c082015260009060e00160408051601f19818403018152828252805160209182012090830152016040516020818303038152906040528051906020012090506119be8360055483611f6c565b6119db576040516309bde33960e01b815260040160405180910390fd5b60028201805460ff60781b1916600160781b1790556001600160781b03881615611a805760405163a9059cbb60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb90611a4d908c908c906004016124fc565b600060405180830381600087803b158015611a6757600080fd5b505af1158015611a7b573d6000803e3d6000fd5b505050505b6001600160781b03871615611b105760405163a9059cbb60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb90611add908c908b906004016124fc565b600060405180830381600087803b158015611af757600080fd5b505af1158015611b0b573d6000803e3d6000fd5b505050505b6001600160781b03861615611ba05760405163a9059cbb60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb90611b6d908c908a906004016124fc565b600060405180830381600087803b158015611b8757600080fd5b505af1158015611b9b573d6000803e3d6000fd5b505050505b6001600160781b03851615611c305760405163a9059cbb60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb90611bfd908c9089906004016124fc565b600060405180830381600087803b158015611c1757600080fd5b505af1158015611c2b573d6000803e3d6000fd5b505050505b6001600160781b03841615611c7f576040516001600160a01b038a16906001600160781b03861680156108fc02916000818181858888f19350505050158015611c7d573d6000803e3d6000fd5b505b604080516001600160781b038a8116825289811660208301528881168284015287811660608301528616608082015290516001600160a01b038b16917f21280d282ce6aa29c649fd1825373d7c77892fac3f1958fd98d5ca52dd82a197919081900360a00190a2505050505050505050565b611cf9611e3d565b600054600160a01b900460ff1615611d2457604051633c3282e760e01b815260040160405180910390fd5b60008054600160a01b60ff60a01b1990911681179091556002805469ffffffffffffffffffff60a01b191664ffffffffff86811693840264ffffffffff60c81b191691909117600160c81b91861691820217909155600483905560408051928352602083019190915281018290527f112f3cbd45f910900888cf719e3bc92aeeece9327ad9db92c459ec5f49862f2e9060600160405180910390a1505050565b611dcc611e3d565b6001600160a01b038116611e315760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016107fd565b611e3a81611e97565b50565b6000546001600160a01b031633146111495760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107fd565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600080600260009054906101000a90046001600160a01b03166001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015611f3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f6191906125b1565b509195945050505050565b600082611f798584611f82565b14949350505050565b600081815b8451811015611fc757611fb382868381518110611fa657611fa661251e565b6020026020010151611fcf565b915080611fbf81612601565b915050611f87565b509392505050565b6000818310611feb576000828152602084905260409020611ffa565b60008381526020839052604090205b9392505050565b803564ffffffffff8116811461201657600080fd5b919050565b60006020828403121561202d57600080fd5b611ffa82612001565b60006020828403121561204857600080fd5b5035919050565b80356001600160a01b038116811461201657600080fd5b80356001600160781b038116811461201657600080fd5b6000806040838503121561209057600080fd5b6120998361204f565b91506120a760208401612066565b90509250929050565b6000602082840312156120c257600080fd5b611ffa82612066565b60008083601f8401126120dd57600080fd5b50813567ffffffffffffffff8111156120f557600080fd5b6020830191508360208260051b850101111561211057600080fd5b9250929050565b60008060008060008060008060008060008060c08d8f03121561213957600080fd5b67ffffffffffffffff8d35111561214f57600080fd5b61215c8e8e358f016120cb565b909c509a5067ffffffffffffffff60208e0135111561217a57600080fd5b61218a8e60208f01358f016120cb565b909a50985067ffffffffffffffff60408e013511156121a857600080fd5b6121b88e60408f01358f016120cb565b909850965067ffffffffffffffff60608e013511156121d657600080fd5b6121e68e60608f01358f016120cb565b909650945067ffffffffffffffff60808e0135111561220457600080fd5b6122148e60808f01358f016120cb565b909450925067ffffffffffffffff60a08e0135111561223257600080fd5b6122428e60a08f01358f016120cb565b81935080925050509295989b509295989b509295989b565b6000806040838503121561226d57600080fd5b823591506120a76020840161204f565b60006020828403121561228f57600080fd5b81358015158114611ffa57600080fd5b6000602082840312156122b157600080fd5b611ffa8261204f565b60008060008060008060c087890312156122d357600080fd5b6122dc8761204f565b95506122ea60208801612066565b94506122f860408801612066565b935061230660608801612066565b925061231460808801612066565b915061232260a08801612066565b90509295509295509295565b634e487b7160e01b600052604160045260246000fd5b600080600080600080600060e0888a03121561235f57600080fd5b6123688861204f565b96506020612377818a01612066565b965061238560408a01612066565b955061239360608a01612066565b94506123a160808a01612066565b93506123af60a08a01612066565b925060c089013567ffffffffffffffff808211156123cc57600080fd5b818b0191508b601f8301126123e057600080fd5b8135818111156123f2576123f261232e565b8060051b604051601f19603f830116810181811085821117156124175761241761232e565b60405291825284820192508381018501918e83111561243557600080fd5b938501935b828510156124535784358452938501939285019261243a565b80965050505050505092959891949750929550565b60008060006060848603121561247d57600080fd5b61248684612001565b925061249460208501612001565b9150604084013590509250925092565b634e487b7160e01b600052601160045260246000fd5b600064ffffffffff8083168185168083038211156124da576124da6124a4565b01949350505050565b6000602082840312156124f557600080fd5b5051919050565b6001600160a01b039290921682526001600160781b0316602082015260400190565b634e487b7160e01b600052603260045260246000fd5b600081600019048311821515161561254e5761254e6124a4565b500290565b60008261257057634e487b7160e01b600052601260045260246000fd5b500490565b60006001600160781b038083168185168083038211156124da576124da6124a4565b805169ffffffffffffffffffff8116811461201657600080fd5b600080600080600060a086880312156125c957600080fd5b6125d286612597565b94506020860151935060408601519250606086015191506125f560808701612597565b90509295509295909350565b600060018201612613576126136124a4565b506001019056fea26469706673582212205b3f503377a4d7d4ef943b5ae7ef04fa7b760f351c03a85ede1c4289b07f4e1c64736f6c634300080f00330000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000fcb5c72173a19116aab48e5cb94e0e8c0126a7b10000000000000000000000005f4ec3df9cbd43714fe2740f5e3616155c5b84190000000000000000000000009e79d6940ec90d2a53595c3785ea668da59e072f000000000000000000000000fe42009aefd23742c1f2bb08e49b33f1bff3fc1d

Deployed Bytecode

0x6080604052600436106101dc5760003560e01c8063724e78da11610102578063c147c8a511610095578063f2fde38b11610064578063f2fde38b14610648578063f4b9fa7514610668578063f851a4401461069c578063fc0c546a146106bc57600080fd5b8063c147c8a51461052a578063ddd25be81461054a578063e35e56631461056a578063e53ed6161461061057600080fd5b8063a035b1fe116100d1578063a035b1fe146104ae578063a5b58676146104c4578063ae87fc4b146104e4578063be9a65551461050557600080fd5b8063724e78da14610448578063741bef1a146104685780638da5cb5b1461048857806397466cab146104a657600080fd5b80633998081a1161017a57806361d027b31161014957806361d027b3146103bf578063654f97a3146103f3578063704b6c0214610413578063715018a61461043357600080fd5b80633998081a1461032b5780633e413bee1461034b5780634d675b881461037f5780636113e5521461039f57600080fd5b806314ea35e7116101b657806314ea35e71461027b57806321b97f201461029f5780632f48ab7d146102bf5780633730099a1461030b57600080fd5b806307003bb4146101e85780630740c9ef1461021e5780630fb5a6b41461024057600080fd5b366101e357005b600080fd5b3480156101f457600080fd5b5060005461020990600160a01b900460ff1681565b60405190151581526020015b60405180910390f35b34801561022a57600080fd5b5061023e61023936600461201b565b6106f0565b005b34801561024c57600080fd5b5060025461026590600160c81b900464ffffffffff1681565b60405164ffffffffff9091168152602001610215565b34801561028757600080fd5b5061029160055481565b604051908152602001610215565b3480156102ab57600080fd5b5061023e6102ba366004612036565b610778565b3480156102cb57600080fd5b506102f37f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec781565b6040516001600160a01b039091168152602001610215565b34801561031757600080fd5b5061023e61032636600461207d565b610883565b34801561033757600080fd5b5061023e6103463660046120b0565b6109a9565b34801561035757600080fd5b506102f37f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b34801561038b57600080fd5b5061023e61039a366004612117565b610aa0565b3480156103ab57600080fd5b5061023e6103ba36600461225a565b610c54565b3480156103cb57600080fd5b506102f37f000000000000000000000000fe42009aefd23742c1f2bb08e49b33f1bff3fc1d81565b3480156103ff57600080fd5b5061023e61040e36600461227d565b611046565b34801561041f57600080fd5b5061023e61042e36600461229f565b6110be565b34801561043f57600080fd5b5061023e611137565b34801561045457600080fd5b5061023e61046336600461229f565b61114b565b34801561047457600080fd5b506002546102f3906001600160a01b031681565b34801561049457600080fd5b506000546001600160a01b03166102f3565b61023e6111e7565b3480156104ba57600080fd5b5061029160045481565b3480156104d057600080fd5b5061023e6104df3660046122ba565b6114da565b3480156104f057600080fd5b5060005461020990600160a81b900460ff1681565b34801561051157600080fd5b5060025461026590600160a01b900464ffffffffff1681565b34801561053657600080fd5b5061023e610545366004612344565b611820565b34801561055657600080fd5b5061023e610565366004612468565b611cf1565b34801561057657600080fd5b506105cd61058536600461229f565b6006602052600090815260409020805460018201546002909201546001600160781b0380831693600160781b9384900482169382821693918190048316928216910460ff1686565b604080516001600160781b0397881681529587166020870152938616938501939093529084166060840152909216608082015290151560a082015260c001610215565b34801561061c57600080fd5b50600354610630906001600160781b031681565b6040516001600160781b039091168152602001610215565b34801561065457600080fd5b5061023e61066336600461229f565b611dc4565b34801561067457600080fd5b506102f37f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f81565b3480156106a857600080fd5b506001546102f3906001600160a01b031681565b3480156106c857600080fd5b506102f37f000000000000000000000000fcb5c72173a19116aab48e5cb94e0e8c0126a7b181565b6001546001600160a01b0316331461071b5760405163160d3af160e11b815260040160405180910390fd5b6002805464ffffffffff60c81b1916600160c81b64ffffffffff8416908102919091179091556040519081527f88119d9c2527a3bbdd001f5a8c4ae3bfbff5c4d2ec8663f0d78322a0dcbb1725906020015b60405180910390a150565b610780611e3d565b6002546107a49064ffffffffff600160c81b8204811691600160a01b9004166124ba565b64ffffffffff164210156108065760025442906107d89064ffffffffff600160c81b8204811691600160a01b9004166124ba565b60405163e275812560e01b8152600481019290925264ffffffffff1660248201526044015b60405180910390fd5b600254600160a01b900464ffffffffff164210156108505760025460405163457f873160e01b8152426004820152600160a01b90910464ffffffffff1660248201526044016107fd565b600581905560405181907f6b3b0a9ab98c361bbd6e7c0fa7c102fb7a4e7712191bf556a461a9e5aa70948f90600090a250565b61088b611e3d565b6040516370a0823160e01b81523060048201526000906001600160a01b038416906370a08231906024016020604051808303816000875af11580156108d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f891906124e3565b905080826001600160781b0316111561092457604051631b4266e760e21b815260040160405180910390fd5b60405163a9059cbb60e01b81526001600160a01b0384169063a9059cbb90610972907f000000000000000000000000fe42009aefd23742c1f2bb08e49b33f1bff3fc1d9086906004016124fc565b600060405180830381600087803b15801561098c57600080fd5b505af11580156109a0573d6000803e3d6000fd5b50505050505050565b6109b1611e3d565b476001600160781b0382168110156109dc57604051631b4266e760e21b815260040160405180910390fd5b60007f000000000000000000000000fe42009aefd23742c1f2bb08e49b33f1bff3fc1d6001600160a01b0316836001600160781b031660405160006040518083038185875af1925050503d8060008114610a52576040519150601f19603f3d011682016040523d82523d6000602084013e610a57565b606091505b5050905080610a9b5760405162461bcd60e51b815260206004820152601060248201526f2a3930b739b332b9103330b4b632b21760811b60448201526064016107fd565b505050565b6001546001600160a01b03163314610acb5760405163160d3af160e11b815260040160405180910390fd5b600054600160a81b900460ff16610af557604051633b03644960e01b815260040160405180910390fd5b8a8981141580610b055750878114155b80610b105750858114155b80610b1b5750838114155b80610b265750818114155b15610b445760405163160d3af160e11b815260040160405180910390fd5b60005b8c811015610c4457610c3c8e8e83818110610b6457610b6461251e565b9050602002016020810190610b79919061229f565b8d8d84818110610b8b57610b8b61251e565b9050602002016020810190610ba091906120b0565b8c8c85818110610bb257610bb261251e565b9050602002016020810190610bc791906120b0565b8b8b86818110610bd957610bd961251e565b9050602002016020810190610bee91906120b0565b8a8a87818110610c0057610c0061251e565b9050602002016020810190610c1591906120b0565b898988818110610c2757610c2761251e565b90506020020160208101906104df91906120b0565b600101610b47565b5050505050505050505050505050565b600054600160a01b900460ff16610c7e5760405163421972d160e11b815260040160405180910390fd5b6001821015610ca057604051631f2a200560e01b815260040160405180910390fd5b600254600160a01b900464ffffffffff1642811115610ce15760405163457f873160e01b815242600482015264ffffffffff821660248201526044016107fd565b600254610cfc90600160c81b900464ffffffffff16826124ba565b64ffffffffff164210610d4f576002544290610d2690600160c81b900464ffffffffff16836124ba565b60405163ce40104160e01b8152600481019290925264ffffffffff1660248201526044016107fd565b336000908152600660205260408120906001600160a01b037f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f811690851603610df557600454610da286620f4240612534565b610dac9190612553565b825490915085908390600090610dcc9084906001600160781b0316612575565b92506101000a8154816001600160781b0302191690836001600160781b03160217905550610ee5565b600454610e0a86670de0b6b3a7640000612534565b610e149190612553565b90507f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b0316846001600160a01b031603610e6f57600182018054869190600090610dcc9084906001600160781b0316612575565b7f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec76001600160a01b0316846001600160a01b031603610ecc57815485908390600f90610dcc908490600160781b90046001600160781b0316612575565b604051632c83944560e01b815260040160405180910390fd5b600282018054829190600090610f059084906001600160781b0316612575565b92506101000a8154816001600160781b0302191690836001600160781b0316021790555080600360008282829054906101000a90046001600160781b0316610f4d9190612575565b82546001600160781b039182166101009390930a9283029190920219909116179055506040516323b872dd60e01b81523360048201527f000000000000000000000000fe42009aefd23742c1f2bb08e49b33f1bff3fc1d6001600160a01b039081166024830152604482018790528516906323b872dd90606401600060405180830381600087803b158015610fe157600080fd5b505af1158015610ff5573d6000803e3d6000fd5b505060408051888152602081018590526001600160a01b03881693503392507f3b73bff6407bf93966c8d7a35e634896ff57226eb26f367b06b2b7a3d513fdcb910160405180910390a35050505050565b6001546001600160a01b031633146110715760405163160d3af160e11b815260040160405180910390fd5b60008054821515600160a81b0260ff60a81b199091161790556040517fa6c41a0df1bf3653d829a71569e419f707fe0129924b2b9dfc22493d0b81d9f99061076d90831515815260200190565b6110c6611e3d565b6001600160a01b0381166110ed5760405163d92e233d60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0383169081179091556040517f0c2515f25186df02132ad46f01e062c3b8982c8de57fa2b1b0a280d8e810f39b90600090a250565b61113f611e3d565b6111496000611e97565b565b6001546001600160a01b031633146111765760405163160d3af160e11b815260040160405180910390fd5b6001600160a01b03811661119d5760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040517fddcc21be684c966209b6f56a96e50f3034f7f931ff5fc9cdf79ad684e32f890390600090a250565b600054600160a01b900460ff166112115760405163421972d160e11b815260040160405180910390fd5b600134101561123357604051631f2a200560e01b815260040160405180910390fd5b600254600160a01b900464ffffffffff16428111156112745760405163457f873160e01b815242600482015264ffffffffff821660248201526044016107fd565b60025461128f90600160c81b900464ffffffffff16826124ba565b64ffffffffff1642106112b9576002544290610d2690600160c81b900464ffffffffff16836124ba565b60006112c3611ee7565b9050600060045460646112d69190612534565b6112e03484612534565b6112ea9190612553565b3360009081526006602052604090206001810180549293509091349190600f90611325908490600160781b90046001600160781b0316612575565b92506101000a8154816001600160781b0302191690836001600160781b03160217905550818160020160008282829054906101000a90046001600160781b031661136f9190612575565b92506101000a8154816001600160781b0302191690836001600160781b0316021790555081600360008282829054906101000a90046001600160781b03166113b79190612575565b92506101000a8154816001600160781b0302191690836001600160781b0316021790555060007f000000000000000000000000fe42009aefd23742c1f2bb08e49b33f1bff3fc1d6001600160a01b03163460405160006040518083038185875af1925050503d8060008114611448576040519150601f19603f3d011682016040523d82523d6000602084013e61144d565b606091505b50509050806114915760405162461bcd60e51b815260206004820152601060248201526f2a3930b739b332b9103330b4b632b21760811b60448201526064016107fd565b6040805185815234602082015290810184905233907fbabfb52ebe2322d72451b6b4e6235a7864be7d11f426e81dc6436edd6f750f339060600160405180910390a25050505050565b6001546001600160a01b031633146115055760405163160d3af160e11b815260040160405180910390fd5b600054600160a81b900460ff1661152f57604051633b03644960e01b815260040160405180910390fd5b6001600160a01b03861660009081526006602052604090206002810154600160781b900460ff161561157457604051630c8d9eab60e31b815260040160405180910390fd5b60028101805460ff60781b1916600160781b1790556001600160781b038616156116195760405163a9059cbb60e01b81526001600160a01b037f000000000000000000000000fcb5c72173a19116aab48e5cb94e0e8c0126a7b1169063a9059cbb906115e6908a908a906004016124fc565b600060405180830381600087803b15801561160057600080fd5b505af1158015611614573d6000803e3d6000fd5b505050505b6001600160781b038516156116a95760405163a9059cbb60e01b81526001600160a01b037f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48169063a9059cbb90611676908a9089906004016124fc565b600060405180830381600087803b15801561169057600080fd5b505af11580156116a4573d6000803e3d6000fd5b505050505b6001600160781b038416156117395760405163a9059cbb60e01b81526001600160a01b037f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7169063a9059cbb90611706908a9088906004016124fc565b600060405180830381600087803b15801561172057600080fd5b505af1158015611734573d6000803e3d6000fd5b505050505b6001600160781b038316156117c95760405163a9059cbb60e01b81526001600160a01b037f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f169063a9059cbb90611796908a9087906004016124fc565b600060405180830381600087803b1580156117b057600080fd5b505af11580156117c4573d6000803e3d6000fd5b505050505b6001600160781b038216156109a0576040516001600160a01b038816906001600160781b03841680156108fc02916000818181858888f19350505050158015611816573d6000803e3d6000fd5b5050505050505050565b600054600160a01b900460ff1661184a5760405163421972d160e11b815260040160405180910390fd5b60025461186e9064ffffffffff600160c81b8204811691600160a01b9004166124ba565b64ffffffffff164210156118a25760025442906107d89064ffffffffff600160c81b8204811691600160a01b9004166124ba565b6005546118c257604051633b03644960e01b815260040160405180910390fd5b600054600160a81b900460ff166118ec57604051633b03644960e01b815260040160405180910390fd5b6001600160a01b03871660009081526006602052604090206002810154600160781b900460ff161561193157604051630c8d9eab60e31b815260040160405180910390fd5b604080516001600160a01b038a1660208201526001600160781b03808a16928201929092528188166060820152818716608082015281861660a082015290841660c082015260009060e00160408051601f19818403018152828252805160209182012090830152016040516020818303038152906040528051906020012090506119be8360055483611f6c565b6119db576040516309bde33960e01b815260040160405180910390fd5b60028201805460ff60781b1916600160781b1790556001600160781b03881615611a805760405163a9059cbb60e01b81526001600160a01b037f000000000000000000000000fcb5c72173a19116aab48e5cb94e0e8c0126a7b1169063a9059cbb90611a4d908c908c906004016124fc565b600060405180830381600087803b158015611a6757600080fd5b505af1158015611a7b573d6000803e3d6000fd5b505050505b6001600160781b03871615611b105760405163a9059cbb60e01b81526001600160a01b037f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48169063a9059cbb90611add908c908b906004016124fc565b600060405180830381600087803b158015611af757600080fd5b505af1158015611b0b573d6000803e3d6000fd5b505050505b6001600160781b03861615611ba05760405163a9059cbb60e01b81526001600160a01b037f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7169063a9059cbb90611b6d908c908a906004016124fc565b600060405180830381600087803b158015611b8757600080fd5b505af1158015611b9b573d6000803e3d6000fd5b505050505b6001600160781b03851615611c305760405163a9059cbb60e01b81526001600160a01b037f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f169063a9059cbb90611bfd908c9089906004016124fc565b600060405180830381600087803b158015611c1757600080fd5b505af1158015611c2b573d6000803e3d6000fd5b505050505b6001600160781b03841615611c7f576040516001600160a01b038a16906001600160781b03861680156108fc02916000818181858888f19350505050158015611c7d573d6000803e3d6000fd5b505b604080516001600160781b038a8116825289811660208301528881168284015287811660608301528616608082015290516001600160a01b038b16917f21280d282ce6aa29c649fd1825373d7c77892fac3f1958fd98d5ca52dd82a197919081900360a00190a2505050505050505050565b611cf9611e3d565b600054600160a01b900460ff1615611d2457604051633c3282e760e01b815260040160405180910390fd5b60008054600160a01b60ff60a01b1990911681179091556002805469ffffffffffffffffffff60a01b191664ffffffffff86811693840264ffffffffff60c81b191691909117600160c81b91861691820217909155600483905560408051928352602083019190915281018290527f112f3cbd45f910900888cf719e3bc92aeeece9327ad9db92c459ec5f49862f2e9060600160405180910390a1505050565b611dcc611e3d565b6001600160a01b038116611e315760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016107fd565b611e3a81611e97565b50565b6000546001600160a01b031633146111495760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107fd565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600080600260009054906101000a90046001600160a01b03166001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015611f3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f6191906125b1565b509195945050505050565b600082611f798584611f82565b14949350505050565b600081815b8451811015611fc757611fb382868381518110611fa657611fa661251e565b6020026020010151611fcf565b915080611fbf81612601565b915050611f87565b509392505050565b6000818310611feb576000828152602084905260409020611ffa565b60008381526020839052604090205b9392505050565b803564ffffffffff8116811461201657600080fd5b919050565b60006020828403121561202d57600080fd5b611ffa82612001565b60006020828403121561204857600080fd5b5035919050565b80356001600160a01b038116811461201657600080fd5b80356001600160781b038116811461201657600080fd5b6000806040838503121561209057600080fd5b6120998361204f565b91506120a760208401612066565b90509250929050565b6000602082840312156120c257600080fd5b611ffa82612066565b60008083601f8401126120dd57600080fd5b50813567ffffffffffffffff8111156120f557600080fd5b6020830191508360208260051b850101111561211057600080fd5b9250929050565b60008060008060008060008060008060008060c08d8f03121561213957600080fd5b67ffffffffffffffff8d35111561214f57600080fd5b61215c8e8e358f016120cb565b909c509a5067ffffffffffffffff60208e0135111561217a57600080fd5b61218a8e60208f01358f016120cb565b909a50985067ffffffffffffffff60408e013511156121a857600080fd5b6121b88e60408f01358f016120cb565b909850965067ffffffffffffffff60608e013511156121d657600080fd5b6121e68e60608f01358f016120cb565b909650945067ffffffffffffffff60808e0135111561220457600080fd5b6122148e60808f01358f016120cb565b909450925067ffffffffffffffff60a08e0135111561223257600080fd5b6122428e60a08f01358f016120cb565b81935080925050509295989b509295989b509295989b565b6000806040838503121561226d57600080fd5b823591506120a76020840161204f565b60006020828403121561228f57600080fd5b81358015158114611ffa57600080fd5b6000602082840312156122b157600080fd5b611ffa8261204f565b60008060008060008060c087890312156122d357600080fd5b6122dc8761204f565b95506122ea60208801612066565b94506122f860408801612066565b935061230660608801612066565b925061231460808801612066565b915061232260a08801612066565b90509295509295509295565b634e487b7160e01b600052604160045260246000fd5b600080600080600080600060e0888a03121561235f57600080fd5b6123688861204f565b96506020612377818a01612066565b965061238560408a01612066565b955061239360608a01612066565b94506123a160808a01612066565b93506123af60a08a01612066565b925060c089013567ffffffffffffffff808211156123cc57600080fd5b818b0191508b601f8301126123e057600080fd5b8135818111156123f2576123f261232e565b8060051b604051601f19603f830116810181811085821117156124175761241761232e565b60405291825284820192508381018501918e83111561243557600080fd5b938501935b828510156124535784358452938501939285019261243a565b80965050505050505092959891949750929550565b60008060006060848603121561247d57600080fd5b61248684612001565b925061249460208501612001565b9150604084013590509250925092565b634e487b7160e01b600052601160045260246000fd5b600064ffffffffff8083168185168083038211156124da576124da6124a4565b01949350505050565b6000602082840312156124f557600080fd5b5051919050565b6001600160a01b039290921682526001600160781b0316602082015260400190565b634e487b7160e01b600052603260045260246000fd5b600081600019048311821515161561254e5761254e6124a4565b500290565b60008261257057634e487b7160e01b600052601260045260246000fd5b500490565b60006001600160781b038083168185168083038211156124da576124da6124a4565b805169ffffffffffffffffffff8116811461201657600080fd5b600080600080600060a086880312156125c957600080fd5b6125d286612597565b94506020860151935060408601519250606086015191506125f560808701612597565b90509295509295909350565b600060018201612613576126136124a4565b506001019056fea26469706673582212205b3f503377a4d7d4ef943b5ae7ef04fa7b760f351c03a85ede1c4289b07f4e1c64736f6c634300080f0033

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

0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000fcb5c72173a19116aab48e5cb94e0e8c0126a7b10000000000000000000000005f4ec3df9cbd43714fe2740f5e3616155c5b84190000000000000000000000009e79d6940ec90d2a53595c3785ea668da59e072f000000000000000000000000fe42009aefd23742c1f2bb08e49b33f1bff3fc1d

-----Decoded View---------------
Arg [0] : _dai (address): 0x6B175474E89094C44Da98b954EedeAC495271d0F
Arg [1] : _usdt (address): 0xdAC17F958D2ee523a2206206994597C13D831ec7
Arg [2] : _usdc (address): 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
Arg [3] : _token (address): 0xFCB5C72173A19116AAb48e5cb94E0E8C0126A7B1
Arg [4] : _priceFeed (address): 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419
Arg [5] : _admin (address): 0x9E79D6940eC90d2a53595c3785Ea668da59e072F
Arg [6] : _treasury (address): 0xFe42009AeFD23742c1F2bB08e49b33F1bff3fc1d

-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f
Arg [1] : 000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7
Arg [2] : 000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
Arg [3] : 000000000000000000000000fcb5c72173a19116aab48e5cb94e0e8c0126a7b1
Arg [4] : 0000000000000000000000005f4ec3df9cbd43714fe2740f5e3616155c5b8419
Arg [5] : 0000000000000000000000009e79d6940ec90d2a53595c3785ea668da59e072f
Arg [6] : 000000000000000000000000fe42009aefd23742c1f2bb08e49b33f1bff3fc1d


Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.