MATIC Price: $0.717344 (-1.81%)
Gas: 30 GWei
 
Transaction Hash
Method
Block
From
To
Value
Withdraw368703892022-12-15 18:32:31528 days ago1671129151IN
0x7031BC57...F23a81a94
0 MATIC0.00999609100.01499437
Withdraw351823922022-11-04 7:55:27569 days ago1667548527IN
0x7031BC57...F23a81a94
0 MATIC0.00741184197.10247118
Join333159382022-09-19 20:30:33615 days ago1663619433IN
0x7031BC57...F23a81a94
0 MATIC0.004378830.00000001
Join263029802022-03-24 10:42:11794 days ago1648118531IN
0x7031BC57...F23a81a94
0 MATIC0.0049601530.4192
Join255931352022-03-05 2:41:59813 days ago1646448119IN
0x7031BC57...F23a81a94
0 MATIC0.0090186730.55499999
Join250900062022-02-18 18:41:07828 days ago1645209667IN
0x7031BC57...F23a81a94
0 MATIC0.0061858334.435
Join250508912022-02-17 14:15:46829 days ago1645107346IN
0x7031BC57...F23a81a94
0 MATIC0.0058823332.74550974
Join249898042022-02-16 0:23:03831 days ago1644970983IN
0x7031BC57...F23a81a94
0 MATIC0.0051071131.32047998
Join249780412022-02-15 17:06:17831 days ago1644944777IN
0x7031BC57...F23a81a94
0 MATIC0.0055193842.83237951
Join248936752022-02-13 13:11:53833 days ago1644757913IN
0x7031BC57...F23a81a94
0 MATIC0.008968355
Join244669742022-02-02 16:06:29844 days ago1643817989IN
0x7031BC57...F23a81a94
0 MATIC0.0054103730.11820902
Join243885122022-01-31 16:55:11846 days ago1643648111IN
0x7031BC57...F23a81a94
0 MATIC0.000299292.32263891
Join243329592022-01-30 6:39:16847 days ago1643524756IN
0x7031BC57...F23a81a94
0 MATIC0.000338041.88180012
Join243021472022-01-29 11:37:30848 days ago1643456250IN
0x7031BC57...F23a81a94
0 MATIC0.0062942329.506624
Withdraw241966002022-01-26 19:15:52851 days ago1643224552IN
0x7031BC57...F23a81a94
0 MATIC0.04327447447.70711899
Join240508892022-01-23 3:39:14854 days ago1642909154IN
0x7031BC57...F23a81a94
0 MATIC0.0053166232.60533412
Join239487312022-01-20 14:05:44857 days ago1642687544IN
0x7031BC57...F23a81a94
0 MATIC0.02034502139.88797523
Join239253352022-01-19 23:56:36858 days ago1642636596IN
0x7031BC57...F23a81a94
0 MATIC0.03076552110.22880366
Join236440592022-01-12 19:57:32865 days ago1642017452IN
0x7031BC57...F23a81a94
0 MATIC0.0059338230
Join235731722022-01-10 23:16:38867 days ago1641856598IN
0x7031BC57...F23a81a94
0 MATIC0.004876330.001
Join230723782021-12-28 18:03:14880 days ago1640714594IN
0x7031BC57...F23a81a94
0 MATIC0.0093678630
Join221909602021-12-06 5:46:34902 days ago1638769594IN
0x7031BC57...F23a81a94
0 MATIC0.0050550231.001
Join220149332021-12-01 13:56:06907 days ago1638366966IN
0x7031BC57...F23a81a94
0 MATIC0.0043631430
Join217181142021-11-23 19:41:05915 days ago1637696465IN
0x7031BC57...F23a81a94
0 MATIC0.03679187
Withdraw214555502021-11-16 23:41:52922 days ago1637106112IN
0x7031BC57...F23a81a94
0 MATIC0.005177950
View all transactions

Latest 1 internal transaction

Parent Transaction Hash Block From To Value
212358322021-11-11 6:07:08927 days ago1636610828  Contract Creation0 MATIC
Loading...
Loading

Minimal Proxy Contract for 0xaa7536aaba15edc3c6bec5f2e3ad22d3314ae570

Contract Name:
IDO_NFT_FCFS

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

Decompile Bytecode Similar Contracts
/**
 *Submitted for verification at polygonscan.com on 2021-11-11
*/

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

// File @openzeppelin/contracts/token/ERC20/[email protected]
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;
/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}


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

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}


// File @openzeppelin/contracts/token/ERC721/[email protected]

/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;
}


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

/**
 * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
 * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an
 * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
 * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
 *
 * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
 * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
 *
 * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
 * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
 */
abstract contract Initializable {
    /**
     * @dev Indicates that the contract has been initialized.
     */
    bool private _initialized;

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

    /**
     * @dev Modifier to protect an initializer function from being invoked twice.
     */
    modifier initializer() {
        require(_initializing || !_initialized, "Initializable: contract is already initialized");

        bool isTopLevelCall = !_initializing;
        if (isTopLevelCall) {
            _initializing = true;
            _initialized = true;
        }

        _;

        if (isTopLevelCall) {
            _initializing = false;
        }
    }
}


// File contracts/interfaces/IIDOFactory.sol


interface IIDOFactory {
    function whitelist(address _address) external view returns (bool);
    function priceOracle() external view returns(address);
    function slippage() external view returns(uint);
    function governance() external view returns (address);
    function gfi() external view returns (address);
    function weth() external view returns (address);
    function usdc() external view returns (address);
    function tierManager() external view returns (address);
    function swapRouter() external view returns (address);
    function swapFactory() external view returns (address);
    function feeManager() external view returns (address);
    function deployFarm(address depositToken, address rewardToken, uint amount, uint blockReward, uint start, uint end, uint bonusEnd, uint bonus) external;
    function deployCompounder(address _farmAddress, address _depositToken, address _rewardToken, uint _maxCallerReward, uint _callerFee, uint _minHarvest, bool _lpFarm, address _lpA, address _lpB) external;
    function farmFactory() external view returns(address);
}


// File contracts/interfaces/IIDO_NFT_FCFS_Agreement.sol

interface IIDO_NFT_FCFS_Agreement {
    function initialize(address _owner, address _IDOImplementation) external;
    function locked() external view returns (bool);
    function owner() external view returns (address);
    function percentDecimals() external view returns(uint);
    function IDOImplementation() external view returns(address);
    function IDOToken() external view returns (address);
    function saleToken() external view returns (address);
    function price()external view returns(uint);
    function totalAmount()external view returns(uint);
    function saleStart()external view returns(uint);
    function commission()external view returns(uint);
    function GFIcommission() external view returns(address);
    function treasury() external view returns(address);
    function GFISudoUser() external view returns(address);
    function clientSudoUser() external view returns(address);
    function roundDelay(uint i) external view returns(uint);
    function maxPerRound(uint i) external view returns(uint);
    function staggeredStart() external view returns(bool);
    function nftIndex() external view returns(uint);
    function whaleStopper() external view returns(uint);
    function commissionCap() external view returns(uint);
}


// File contracts/interfaces/ITierManager.sol


interface ITierManager {
    function checkTier(address caller) external returns(uint);
    function checkTierIncludeSnapshot(address caller) external view returns(uint);
}


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

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

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

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

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

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

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

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

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

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

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

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

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    function _verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) private pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}


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


/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using Address for address;

    function safeTransfer(
        IERC20 token,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(
        IERC20 token,
        address from,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        require(
            (value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        uint256 newAllowance = token.allowance(address(this), spender) + value;
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            uint256 newAllowance = oldAllowance - value;
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
        }
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) {
            // Return data is optional
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}


// File @openzeppelin/contracts/token/ERC721/[email protected]

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
interface IERC721Receiver {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}


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

/**
 * @dev Implementation of the {IERC721Receiver} interface.
 *
 * Accepts all token transfers.
 * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.
 */
contract ERC721Holder is IERC721Receiver {
    /**
     * @dev See {IERC721Receiver-onERC721Received}.
     *
     * Always returns `IERC721Receiver.onERC721Received.selector`.
     */
    function onERC721Received(
        address,
        address,
        uint256,
        bytes memory
    ) public virtual override returns (bytes4) {
        return this.onERC721Received.selector;
    }
}


// File contracts/LaunchPad/IDO_NFT_FCFS.sol








/**
 * @title Basic IDO contract for NFTs that offers GFI Tier presale, and First Come First Serve Model
 * @author crispymangoes
 * @notice Actual IDO contract is a minimal proxy implementation deployed by the IDO Factory
 */
contract IDO_NFT_FCFS is Initializable, ERC721Holder {
    IIDOFactory private Factory;
    IERC721 private IDOToken;
    IERC20 private saleToken;
    IIDO_NFT_FCFS_Agreement private Agreement;
    address public AgreementAddress;
    mapping(address => uint) public contribution;
    uint public currentNFT;
    uint public fundsRaised;//How much of the sale token has been rasied in the sale
    uint public commissionAlreadyPaid;

    /**
     * @notice emitted when an NFT is bought
     * @param buyer the address of the person who bought the NFT
     * @param tokenId the token id of the NFT that was bought
     */
    event Sale(address buyer, uint tokenId);

    /// @notice modifier used so the privilaged functions can be called by Gravity OR 3rd party
    modifier onlySudo() {
        require(msg.sender == Agreement.GFISudoUser() || msg.sender == Agreement.clientSudoUser(), 'Gravity Finance: Forbidden');
        _;
    }

    /**
     * @notice called by the IDO factory upon creation to set global variable state
     * @dev can only be called ONCE
     * @param agreement the address of the agreement for this IDO
     */
    function initializeIDO(address agreement) external initializer {
        AgreementAddress = agreement;
        Agreement = IIDO_NFT_FCFS_Agreement(agreement);
        saleToken = IERC20(Agreement.saleToken());
        IDOToken = IERC721(Agreement.IDOToken());
        Factory = IIDOFactory(msg.sender);
        currentNFT = Agreement.nftIndex();
    }

    /****************** External Priviledged Functions ******************/
    /**
     * @notice Privelaged function that allows Gravity or 3rd party to withdraw procedes from the sale
     * @dev no time require, because this function can be called as much as needed
     */
    function withdraw() external onlySudo {
        //send commission to feeManager
        uint gravityCommission = saleToken.balanceOf(address(this)) * Agreement.commission() / Agreement.percentDecimals();
        if((gravityCommission + commissionAlreadyPaid) > Agreement.commissionCap()){
            gravityCommission = Agreement.commissionCap() - commissionAlreadyPaid;
        }
        commissionAlreadyPaid += gravityCommission;
        SafeERC20.safeTransfer(saleToken, Agreement.GFIcommission(), gravityCommission);
        
        //send remaining sale token balance to 3rd party
        SafeERC20.safeTransfer(saleToken, Agreement.treasury(), saleToken.balanceOf(address(this)));
    }

    /****************** External State Changing Functions ******************/
    /**
     * @notice How users join the IDO
     * @notice allows GFI tier holders early access to the sale
     * @dev limits Tx purchase amounts during presale, based off getMaxMint function
     * @dev if roundDelay(0) time has passed since IDO started, GFI Tiers are not looked at at all
     * and the only limit applied is the whaleStopper require check
     * @param _amount the number of NFTs you want to buy
     */
    function join(
        uint256 _amount
    ) external {
        require(_amount > 0, "_amount must be non zero");
        require(_amount <= Agreement.whaleStopper(), "Purchase amount too large");
        if(block.timestamp < (Agreement.saleStart() + Agreement.roundDelay(0))){//need to look at tiers
            uint userTier = ITierManager(Factory.tierManager()).checkTierIncludeSnapshot(msg.sender);
            if(Agreement.staggeredStart()){require( block.timestamp >= (Agreement.saleStart() + Agreement.roundDelay(userTier)), "User Tier Must Wait");}
            uint maxMint = getMaxMint(msg.sender);
            require(_amount <= maxMint, "_amount excedes users max amount");
        }
        //transfer _amount into IDO
        uint saleTokensOwed = _amount * Agreement.price();
        SafeERC20.safeTransferFrom(saleToken, msg.sender, address(this), saleTokensOwed);
        //give user their NFTs
        for(uint i=0; i<_amount; i++){
            IDOToken.safeTransferFrom(address(this), msg.sender, currentNFT);
            emit Sale(msg.sender, currentNFT);
            currentNFT+=1;
        }
        contribution[msg.sender] += _amount;//store the total number of NFTs the user has bought
        fundsRaised += saleTokensOwed;//record the total amount of sale tokens the sale has raised
    }

    /****************** Public State Reading Functions ******************/
    /**
     * @notice view function that returns how many NFTs an address can buy
     * @dev more efficient to pass in userTier to this function instead of address, but easier for front end to pass in an address
     * @dev if returned value is 1000000000 that means there is no purchase limit
    */
    function getMaxMint(address _caller) public view returns(uint maxMint) {
        if(block.timestamp < (Agreement.saleStart() + Agreement.roundDelay(0))){//need to look at tiers
            uint userTier = ITierManager(Factory.tierManager()).checkTierIncludeSnapshot(_caller);
            for(uint i=3; i>0; i--){
                if ( block.timestamp >= (Agreement.saleStart() + Agreement.roundDelay(i)) ){
                    maxMint += Agreement.maxPerRound(userTier);
                }
                else{
                    break;
                }
            }
            maxMint = maxMint - contribution[_caller];
        }
        else{
            maxMint = Agreement.whaleStopper();//user mint is only limited by whaleStopper
        }
    }

    /**
     * @notice view function that tells a user what event tier they will have for this IDO
     */
    function userEventTier(address _caller) public view returns(uint tier){
        tier = ITierManager(Factory.tierManager()).checkTierIncludeSnapshot(_caller);
    }
}

Contract ABI

[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Sale","type":"event"},{"inputs":[],"name":"AgreementAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"commissionAlreadyPaid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"contribution","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentNFT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fundsRaised","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_caller","type":"address"}],"name":"getMaxMint","outputs":[{"internalType":"uint256","name":"maxMint","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"agreement","type":"address"}],"name":"initializeIDO","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"join","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_caller","type":"address"}],"name":"userEventTier","outputs":[{"internalType":"uint256","name":"tier","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

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