Contract 0x7031bc57e774e0d81780677f53afd79f23a81a94

 
 
Txn Hash
Method
Block
From
To
Value [Txn Fee]
0x106c69fc73ca7a3ad6b19bd6d9e9d0c411afec32cbe245fb0a53e25d9f2ba39dWithdraw368703892022-12-15 18:32:3198 days 22 hrs ago0xb1c6c013ce44790871874a0a08f887ddb95525fe IN  0x7031bc57e774e0d81780677f53afd79f23a81a940 MATIC0.009996098627 100.014994376
0x4979d7bf4d414dd35e805f659530b207a514b147579203907d4dc89b52fb1d16Withdraw351823922022-11-04 7:55:27140 days 8 hrs ago0xeb678812778b68a48001b4a9a4a04c4924c33598 IN  0x7031bc57e774e0d81780677f53afd79f23a81a940 MATIC0.007411841326 197.102471189
0xa18b93200af255b6b96ed228315c7415e0fe4d20f0c5ce6e7193f6d25ca27fc4Join333159382022-09-19 20:30:33185 days 20 hrs ago0xb1c6c013ce44790871874a0a08f887ddb95525fe IN  0x7031bc57e774e0d81780677f53afd79f23a81a940 MATIC0.004378800001 30.000000011
0x918b456f2a3b1cbbfffae1f1917097da88ec667dad7c677bebf8a0092cf9d53aJoin263029802022-03-24 10:42:11365 days 5 hrs ago0x18ae67b6435afa87a77312c804bd9f0e07fa957d IN  0x7031bc57e774e0d81780677f53afd79f23a81a940 MATIC0.004960154752 30.4192
0x48a90fedc652a39eead6930b1acf11dfc94197f41544b7a50580ddcfa7f20c9eJoin255931352022-03-05 2:41:59384 days 13 hrs ago0xb1c6c013ce44790871874a0a08f887ddb95525fe IN  0x7031bc57e774e0d81780677f53afd79f23a81a940 MATIC0.009018674909 30.554999999
0x527607ecd00acfa2ffa630e0b87174ed544b071f98dd522899c4dc78cb2ca90eJoin250900062022-02-18 18:41:07398 days 21 hrs ago0xb1c6c013ce44790871874a0a08f887ddb95525fe IN  0x7031bc57e774e0d81780677f53afd79f23a81a940 MATIC0.00618583453 34.435000004
0x0652771c6894210b37fbd7f8d019939cc3864411ef687c0226d1971001feb658Join250508912022-02-17 14:15:46400 days 2 hrs ago0xfeca604172dfb6d1b6c176915e46b8b8f1ce62e4 IN  0x7031bc57e774e0d81780677f53afd79f23a81a940 MATIC0.005882337879 32.745509746
0x9bc6f1f787f7dd9e768b6227a0ab14ffff971a1e3779475477a7f26bb03de7f6Join249898042022-02-16 0:23:03401 days 16 hrs ago0x843cce7dd9fd508a981adf5d5a511cf175d0f37a IN  0x7031bc57e774e0d81780677f53afd79f23a81a940 MATIC0.00510711746531.320479982
0x39ceaa1c0b19c764013d7e3e5e52e2ba70665c534d8e821cef98ef9875800e02Join249780412022-02-15 17:06:17401 days 23 hrs ago0x8e8cc98808d0be463e1cc5f3aebbb3773ada818a IN  0x7031bc57e774e0d81780677f53afd79f23a81a940 MATIC0.005519380423 42.832379512
0x26054749f0df15806e3f74abcbaad71a59280f5e1910b327f452364e60cfa42bJoin248936752022-02-13 13:11:53404 days 3 hrs ago0x5fb07fd884f5f755c27173df25f2013ecf5ac2b5 IN  0x7031bc57e774e0d81780677f53afd79f23a81a940 MATIC0.0089683 55
0x05f62fabcf5e11d0b2683cf12131e3b5ecf611284cb629ab29b0511105dc9274Join244669742022-02-02 16:06:29415 days 31 mins ago0xba966690326f93bb2353afb327afba021605209a IN  0x7031bc57e774e0d81780677f53afd79f23a81a940 MATIC0.005410374832 30.118209022
0xab2233491059cf11606623868bf62b5bc3568c5e8645da283ee6bb194f2403f6Join243885122022-01-31 16:55:11416 days 23 hrs ago0x8e8cc98808d0be463e1cc5f3aebbb3773ada818a IN  0x7031bc57e774e0d81780677f53afd79f23a81a940 MATIC0.00029929525 2.322638914
0xcd03556f7f53b3b1dd7dd3498c0bc461afa1905564f0c52dc00987ba36357ee4Join243329592022-01-30 6:39:16418 days 9 hrs ago0x877f3bcb3c0ad49b64c404970d5671e00231b59c IN  0x7031bc57e774e0d81780677f53afd79f23a81a940 MATIC0.000338042809 1.88180012
0xbd1033381fcc175116255b222b586b508f77c080be43b7e7d1e8a53431371bebJoin243021472022-01-29 11:37:30419 days 5 hrs ago0x89ae80c788368bcc9b492af7dd38b811119aaffc IN  0x7031bc57e774e0d81780677f53afd79f23a81a940 MATIC0.006294235005 29.506624
0xa0865af99a19f405dd60bee8d52d421c2960aeda71c1a3d708557edcbc29c1faWithdraw241966002022-01-26 19:15:52421 days 21 hrs ago0xfaad617b7a7b76b8c9ba3878493b919ee2e107af IN  0x7031bc57e774e0d81780677f53afd79f23a81a940 MATIC0.043274474708 447.707118997
0x8ac72c59b49b6d97f89cae2783747192290f0642a2f1443ea726c4b45f087c0fJoin240508892022-01-23 3:39:14425 days 12 hrs ago0x9fcb72d67a4fe972fbeae178647f61a9ec3ff8f3 IN  0x7031bc57e774e0d81780677f53afd79f23a81a940 MATIC0.005316625782 32.605334126
0xe7be67f70ecac8e3c4c1239791cb927f8edd1f4249c9fb9fd2a343d72d930b1fJoin239487312022-01-20 14:05:44428 days 2 hrs ago0x00ef256c967703ec84acdbee0b9690d3bbcbd6dc IN  0x7031bc57e774e0d81780677f53afd79f23a81a940 MATIC0.020345027341 139.887975232
0xfc3a3813f69f6cfbf604e8f1f612aa4626834ee94e487185f2133b01563407e5Join239253352022-01-19 23:56:36428 days 16 hrs ago0x00ef256c967703ec84acdbee0b9690d3bbcbd6dc IN  0x7031bc57e774e0d81780677f53afd79f23a81a940 MATIC0.030765520476 110.228803666
0x3109e52038431fe68bb75c167aedaa9f458a222f6d727bf78f98d70d8ee02446Join236440592022-01-12 19:57:32435 days 20 hrs ago0x5e5c817e9264b46cbbb980198684ad9d14f3e0b4 IN  0x7031bc57e774e0d81780677f53afd79f23a81a940 MATIC0.0059338230.000000001
0x9d0570eb55f8519c5e3d00e73c06dd824f888de57ee4693056534a75590bfd3bJoin235731722022-01-10 23:16:38437 days 17 hrs ago0xa792f5eb01c3f856502e2e56368c900c8882b2f9 IN  0x7031bc57e774e0d81780677f53afd79f23a81a940 MATIC0.00487630253830.001
0xca95a38e60a3523389d70d52b349b90c4684e44eaa124b003821e533dbf56c45Join230723782021-12-28 18:03:14450 days 22 hrs ago0x8108c8061428a1cedbde50b213f3b7b1c43565eb IN  0x7031bc57e774e0d81780677f53afd79f23a81a940 MATIC0.0093678630
0xee9a015adcab620999f3a71467bbd9fb7be2a7734a6a0e7ab2323719b4451b05Join221909602021-12-06 5:46:34473 days 10 hrs ago0x2a85b4860c8f0ad23b68c22fe0d359c3d991b30f IN  0x7031bc57e774e0d81780677f53afd79f23a81a940 MATIC0.0050550230631.001
0x74f386b5ebf49cbe37639c23a9b9bb6ae0eaa3ba1475015cc0e63edf828126d7Join220149332021-12-01 13:56:06478 days 2 hrs ago0xfcd51ce91d05ffef2a678b6b15579cef0c28680a IN  0x7031bc57e774e0d81780677f53afd79f23a81a940 MATIC0.0043631430
0xe2648d821d65b5cadf4cc7fc84a20c6f58d44c3ee6062370360c8201ccdcd343Join217181142021-11-23 19:41:05485 days 20 hrs ago0x667e13efa1a4ecdad657128241045c1c26fe4645 IN  0x7031bc57e774e0d81780677f53afd79f23a81a940 MATIC0.036790006187
0x69999dc14e4ce436f9527aacd7fe92b0426aeab495e61ef41aee987acd3a2ad8Withdraw214555502021-11-16 23:41:52492 days 16 hrs ago0xfaad617b7a7b76b8c9ba3878493b919ee2e107af IN  0x7031bc57e774e0d81780677f53afd79f23a81a940 MATIC0.005177950
[ Download CSV Export 
Latest 1 internal transaction
Parent Txn Hash Block From To Value
0xffa0e536246d37aa271d8e35106482b8e9e298668d69452ae58434c6d5436d1d212358322021-11-11 6:07:08498 days 10 hrs ago 0xc25384d940e27b4ecdb86b56977ba37994ab1b6d  Contract Creation0 MATIC
[ Download CSV Export 
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
Decompile ByteCode

Contract Source Code (Solidity)

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 Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.