Cryo Explorer Ethereum Mainnet

Address Contract Verified

Address 0x614A786B1e913455972f7d8ea67efe7483D8F752
Balance 0 ETH
Nonce 1
Code Size 6851 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

6851 bytes
0x60806040526004361061017b575f3560e01c80636bcedf9c116100cd578063ba41b21011610087578063e36b0b3711610062578063e36b0b3714610472578063e985e36714610486578063f2aa8218146104a5578063f9020e33146104c4575f80fd5b8063ba41b21014610406578063c107532914610434578063c1eb5ddd14610453575f80fd5b80636bcedf9c1461032157806376ca67a51461033657806380655eef146103625780638da5cb5b146103a05780639344f5c1146103d2578063ace1741c146103f1575f80fd5b806333e364cb116101385780635413c1c8116101135780635413c1c8146102af57806354a9f102146102ce57806363b20117146102f957806368f8fc101461030e575f80fd5b806333e364cb146102675780633874e3251461027b5780633abd01361461029a575f80fd5b8063115ece4c1461017f578063204120bc146101b1578063273ba6bb146101dc57806329d429a8146102135780632c4e722e146102345780633115329e14610248575b5f80fd5b34801561018a575f80fd5b5061019e610199366004611514565b6104dd565b6040519081526020015b60405180910390f35b3480156101bc575f80fd5b5061019e6101cb36600461153c565b60056020525f908152604090205481565b3480156101e7575f80fd5b50600c546101fb906001600160a01b031681565b6040516001600160a01b0390911681526020016101a8565b34801561021e575f80fd5b5061023261022d366004611562565b6105cd565b005b34801561023f575f80fd5b5061019e5f5481565b348015610253575f80fd5b506102326102623660046116c1565b610679565b348015610272575f80fd5b506102326107bc565b348015610286575f80fd5b5061023261029536600461172f565b61084b565b3480156102a5575f80fd5b5061019e600a5481565b3480156102ba575f80fd5b506102326102c9366004611774565b610939565b3480156102d9575f80fd5b5061019e6102e836600461153c565b60096020525f908152604090205481565b348015610304575f80fd5b5061019e600b5481565b61023261031c366004611514565b610a72565b34801561032c575f80fd5b5061019e60035481565b348015610341575f80fd5b506103556103503660046117d9565b610cdb565b6040516101a891906117f9565b34801561036d575f80fd5b5061039061037c36600461153c565b60046020525f908152604090205460ff1681565b60405190151581526020016101a8565b3480156103ab575f80fd5b507f000000000000000000000000d9e1b12cccd75ca0de316c1edaa8cc5fc337b1fc6101fb565b3480156103dd575f80fd5b5061019e6103ec366004611514565b610e96565b3480156103fc575f80fd5b5061019e60025481565b348015610411575f80fd5b5061039061042036600461153c565b60086020525f908152604090205460ff1681565b34801561043f575f80fd5b5061023261044e366004611514565b610f57565b34801561045e575f80fd5b50600d546101fb906001600160a01b031681565b34801561047d575f80fd5b5061023261114d565b348015610491575f80fd5b506001546101fb906001600160a01b031681565b3480156104b0575f80fd5b506101fb6104bf366004611850565b6111dd565b3480156104cf575f80fd5b506006546103909060ff1681565b5f806001600160a01b0384161561059d576001600160a01b0384165f9081526004602052604090205460ff1615156001146105595760405162461bcd60e51b815260206004820152601760248201527614519a5b8e88151bdad95b881b9bdd08185b1b1bddd959604a1b60448201526064015b60405180910390fd5b6001600160a01b0384165f90815260056020526040902054600254819061058190600a61195e565b61058b9086611969565b6105959190611980565b9150506105c4565b5f546002546105ad90600a61195e565b6105b79085611969565b6105c19190611980565b90505b90505b92915050565b7f000000000000000000000000d9e1b12cccd75ca0de316c1edaa8cc5fc337b1fc6001600160a01b0316331461062457335b60405163118cdaa760e01b81526001600160a01b039091166004820152602401610550565b6001600160a01b0382165f9081526004602052604090205481151560ff90911615150361064f575f80fd5b6001600160a01b03919091165f908152600460205260409020805460ff1916911515919091179055565b7f000000000000000000000000d9e1b12cccd75ca0de316c1edaa8cc5fc337b1fc6001600160a01b031633146106af57336105ff565b81518351146106d05760405162461bcd60e51b81526004016105509061199f565b80156106db575f8190555b5f5b83518110156107b65760045f8583815181106106fb576106fb6119eb565b6020908102919091018101516001600160a01b031682528101919091526040015f205460ff16151560011461072e575f80fd5b828181518110610740576107406119eb565b60200260200101515f03610752575f80fd5b828181518110610764576107646119eb565b602002602001015160055f868481518110610781576107816119eb565b6020908102919091018101516001600160a01b031682528101919091526040015f20556107af6001826119ff565b90506106dd565b50505050565b7f000000000000000000000000d9e1b12cccd75ca0de316c1edaa8cc5fc337b1fc6001600160a01b031633146107f257336105ff565b60065460ff161561083c5760405162461bcd60e51b815260206004820152601460248201527314519a5b8e881a5cc81b9bdd081cdd1bdc1c195960621b6044820152606401610550565b6006805460ff19166001179055565b7f000000000000000000000000d9e1b12cccd75ca0de316c1edaa8cc5fc337b1fc6001600160a01b0316331461088157336105ff565b815f0361088c575f80fd5b5f829055600180546001600160a01b0319166001600160a01b0386169081179091556006805460ff19168315151790556040805163313ce56760e01b8152905163313ce567916004808201926020929091908290030181865afa1580156108f5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109199190611a12565b60ff1660025560038390556107b66001600160a01b038516333086611205565b7f000000000000000000000000d9e1b12cccd75ca0de316c1edaa8cc5fc337b1fc6001600160a01b0316331461096f57336105ff565b80518251146109905760405162461bcd60e51b81526004016105509061199f565b5f5b8251811015610a6d578181815181106109ad576109ad6119eb565b60200260200101515f036109bf575f80fd5b600160045f8584815181106109d6576109d66119eb565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f205f6101000a81548160ff021916908315150217905550818181518110610a2557610a256119eb565b602002602001015160055f858481518110610a4257610a426119eb565b6020908102919091018101516001600160a01b031682528101919091526040015f2055600101610992565b505050565b60065460ff161515600114610ac05760405162461bcd60e51b815260206004820152601460248201527314519a5b8e881a5cc81b9bdd08195b98589b195960621b6044820152606401610550565b5f6001600160a01b038316610ad55734610ad7565b815b90505f610ae484836104dd565b9050805f03610b295760405162461bcd60e51b815260206004820152601160248201527005146696e3a20416d6f756e74206973203607c1b6044820152606401610550565b60035481600b54610b3a91906119ff565b10610b925760405162461bcd60e51b815260206004820152602260248201527f5146696e3a204e6f7420656e6f75676820746f6b656e7320746f20626520736f6044820152611b1960f21b6064820152608401610550565b6001600160a01b03841615610bb057610bab848461126c565b610bb9565b610bb9346112d1565b600154610bd0906001600160a01b03163383611360565b80600b5f828254610be191906119ff565b9091555050335f9081526008602052604090205460ff16610c6c576007805460018181019092557fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6880180546001600160a01b031916339081179091555f908152600860205260408120805460ff191683179055600a8054909190610c669084906119ff565b90915550505b335f9081526009602052604081208054839290610c8a9084906119ff565b909155505060408051838152602081018390526001600160a01b0386169133917facf531ec465d633652ed6f0179042e0f5105d16b2eb45652517eb8f96e3d1997910160405180910390a350505050565b6060818310610d385760405162461bcd60e51b815260206004820152602360248201527f5146696e3a205f66726f6d2073686f756c64206265206c657373207468616e206044820152625f746f60e81b6064820152608401610550565b5f600a548311610d485782610d4c565b600a545b90505f600a548511610d5e5784610d62565b600a545b90505f610d6f8284611a32565b67ffffffffffffffff811115610d8757610d87611597565b604051908082528060200260200182016040528015610dcb57816020015b604080518082019091525f8082526020820152815260200190600190039081610da55790505b509050815b83811015610e8c57604051806040016040528060078381548110610df657610df66119eb565b905f5260205f20015f9054906101000a90046001600160a01b03166001600160a01b0316815260200160095f60078581548110610e3557610e356119eb565b5f9182526020808320909101546001600160a01b0316835282019290925260400190205490528251839083908110610e6f57610e6f6119eb565b6020908102919091010152610e856001826119ff565b9050610dd0565b5095945050505050565b5f806001600160a01b03841615610f3d576001600160a01b0384165f9081526004602052604090205460ff161515600114610f0d5760405162461bcd60e51b815260206004820152601760248201527614519a5b8e88151bdad95b881b9bdd08185b1b1bddd959604a1b6044820152606401610550565b6001600160a01b0384165f90815260056020526040902054600254610f3390600a61195e565b61058b8286611969565b600254610f4b90600a61195e565b5f546105b79085611969565b7f000000000000000000000000d9e1b12cccd75ca0de316c1edaa8cc5fc337b1fc6001600160a01b03163314610f8d57336105ff565b6001600160a01b03821661104f574781811015610ffc5760405162461bcd60e51b815260206004820152602760248201527f5146696e50726573616c653a20496e73756666696369656e742045746865722060448201526662616c616e636560c81b6064820152608401610550565b6040516001600160a01b037f000000000000000000000000d9e1b12cccd75ca0de316c1edaa8cc5fc337b1fc169083156108fc029084905f818181858888f193505050501580156107b6573d5f803e3d5ffd5b6040516370a0823160e01b81523060048201525f906001600160a01b038416906370a0823190602401602060405180830381865afa158015611093573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110b79190611a45565b9050818110156111195760405162461bcd60e51b815260206004820152602760248201527f5146696e50726573616c653a20496e73756666696369656e7420746f6b656e2060448201526662616c616e636560c81b6064820152608401610550565b610a6d6001600160a01b0384167f000000000000000000000000d9e1b12cccd75ca0de316c1edaa8cc5fc337b1fc84611360565b7f000000000000000000000000d9e1b12cccd75ca0de316c1edaa8cc5fc337b1fc6001600160a01b0316331461118357336105ff565b60065460ff1615156001146111d15760405162461bcd60e51b815260206004820152601460248201527314519a5b8e881a5cc81b9bdd08195b98589b195960621b6044820152606401610550565b6006805460ff19169055565b600781815481106111ec575f80fd5b5f918252602090912001546001600160a01b0316905081565b6040516001600160a01b0384811660248301528381166044830152606482018390526107b69186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050611391565b5f606461127a836005611969565b6112849190611980565b600d549091506112a3906001600160a01b038581169133911684611205565b600c54610a6d9033906001600160a01b03166112bf8486611a32565b6001600160a01b038716929190611205565b5f60646112df836005611969565b6112e99190611980565b600d546040519192506001600160a01b03169082156108fc029083905f818181858888f19350505050158015611321573d5f803e3d5ffd5b50600c546001600160a01b03166108fc61133b8385611a32565b6040518115909202915f818181858888f19350505050158015610a6d573d5f803e3d5ffd5b6040516001600160a01b03838116602483015260448201839052610a6d91859182169063a9059cbb9060640161123a565b5f6113a56001600160a01b038416836113f2565b905080515f141580156113c95750808060200190518101906113c79190611a5c565b155b15610a6d57604051635274afe760e01b81526001600160a01b0384166004820152602401610550565b60606105c483835f845f80856001600160a01b031684866040516114169190611a77565b5f6040518083038185875af1925050503d805f8114611450576040519150601f19603f3d011682016040523d82523d5f602084013e611455565b606091505b5091509150611465868383611471565b925050505b9392505050565b60608261148657611481826114cd565b61146a565b815115801561149d57506001600160a01b0384163b155b156114c657604051639996b31560e01b81526001600160a01b0385166004820152602401610550565b508061146a565b8051156114dd5780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b50565b80356001600160a01b038116811461150f575f80fd5b919050565b5f8060408385031215611525575f80fd5b61152e836114f9565b946020939093013593505050565b5f6020828403121561154c575f80fd5b6105c4826114f9565b80151581146114f6575f80fd5b5f8060408385031215611573575f80fd5b61157c836114f9565b9150602083013561158c81611555565b809150509250929050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff811182821017156115d4576115d4611597565b604052919050565b5f67ffffffffffffffff8211156115f5576115f5611597565b5060051b60200190565b5f82601f83011261160e575f80fd5b813561162161161c826115dc565b6115ab565b8082825260208201915060208360051b860101925085831115611642575f80fd5b602085015b83811015610e8c57611658816114f9565b835260209283019201611647565b5f82601f830112611675575f80fd5b813561168361161c826115dc565b8082825260208201915060208360051b8601019250858311156116a4575f80fd5b602085015b83811015610e8c5780358352602092830192016116a9565b5f805f606084860312156116d3575f80fd5b833567ffffffffffffffff8111156116e9575f80fd5b6116f5868287016115ff565b935050602084013567ffffffffffffffff811115611711575f80fd5b61171d86828701611666565b93969395505050506040919091013590565b5f805f8060808587031215611742575f80fd5b61174b856114f9565b93506020850135925060408501359150606085013561176981611555565b939692955090935050565b5f8060408385031215611785575f80fd5b823567ffffffffffffffff81111561179b575f80fd5b6117a7858286016115ff565b925050602083013567ffffffffffffffff8111156117c3575f80fd5b6117cf85828601611666565b9150509250929050565b5f80604083850312156117ea575f80fd5b50508035926020909101359150565b602080825282518282018190525f918401906040840190835b8181101561184557835180516001600160a01b031684526020908101518185015290930192604090920191600101611812565b509095945050505050565b5f60208284031215611860575f80fd5b5035919050565b634e487b7160e01b5f52601160045260245ffd5b6001815b60018411156118b65780850481111561189a5761189a611867565b60018416156118a857908102905b60019390931c92800261187f565b935093915050565b5f826118cc575060016105c7565b816118d857505f6105c7565b81600181146118ee57600281146118f857611914565b60019150506105c7565b60ff84111561190957611909611867565b50506001821b6105c7565b5060208310610133831016604e8410600b8410161715611937575081810a6105c7565b6119435f19848461187b565b805f190482111561195657611956611867565b029392505050565b5f6105c483836118be565b80820281158282048414176105c7576105c7611867565b5f8261199a57634e487b7160e01b5f52601260045260245ffd5b500490565b6020808252602c908201527f5146696e3a20746f6b656e7320262070726963657320617272617973206c656e60408201526b0cee8d040dad2e6dac2e8c6d60a31b606082015260800190565b634e487b7160e01b5f52603260045260245ffd5b808201808211156105c7576105c7611867565b5f60208284031215611a22575f80fd5b815160ff811681146105c4575f80fd5b818103818111156105c7576105c7611867565b5f60208284031215611a55575f80fd5b5051919050565b5f60208284031215611a6c575f80fd5b81516105c481611555565b5f82518060208501845e5f92019182525091905056fea2646970667358221220dce7ed7281373086e7a3aeffcc78ad1452bc2e0ab8191c5613c63466ec14522464736f6c634300081a0033

Verified Source Code Full Match

Compiler: v0.8.26+commit.8a97fa7a EVM: cancun Optimization: Yes (200 runs)
QFin-Presale.sol 788 lines
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;


//░██████╗░░░░███████╗██╗███╗░░██╗░█████╗░███╗░░██╗░█████╗░███████╗
//██╔═══██╗░░░██╔════╝██║████╗░██║██╔══██╗████╗░██║██╔══██╗██╔════╝
//██║██╗██║░░░█████╗░░██║██╔██╗██║███████║██╔██╗██║██║░░╚═╝█████╗░░
//╚██████╔╝░░░██╔══╝░░██║██║╚████║██╔══██║██║╚████║██║░░██╗██╔══╝░░
//░╚═██╔═╝░██╗██║░░░░░██║██║░╚███║██║░░██║██║░╚███║╚█████╔╝███████╗
//░░░╚═╝░░░╚═╝╚═╝░░░░░╚═╝╚═╝░░╚══╝╚═╝░░╚═╝╚═╝░░╚══╝░╚════╝░╚══════╝
//Visit https://Q.finance
//Q.finance: Seamless Token Swaps. Innovative Launchpad. True Decentralization.

//█▀█ █▄░█ █░░ █▄█   ▄█ █▀█ █▀█ █▀█ █▀█   ▀█▀ █▀█ █▄▀ █▀▀ █▄░█
//█▄█ █░▀█ █▄▄ ░█░   ░█ █▄█ █▄█ █▄█ █▄█   ░█░ █▄█ █░█ ██▄ █░▀█


/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}

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

// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)

pragma solidity ^0.8.20;

abstract contract Ownable is Context {
    address private immutable _owner;

    /**
     * @dev The caller account is not authorized to perform an operation.
     */
    error OwnableUnauthorizedAccount(address account);

    /**
     * @dev Initializes the contract setting the deployer as the owner.
     */
    constructor(address initialOwner) {
        require(initialOwner != address(0), "Ownable: Invalid owner address");
        _owner = initialOwner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        if (_owner != _msgSender()) {
            revert OwnableUnauthorizedAccount(_msgSender());
        }
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }
}

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

// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

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

    /**
     * @dev Returns the value of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

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

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

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

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

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

// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)

pragma solidity ^0.8.20;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev The ETH balance of the account is not enough to perform the operation.
     */
    error AddressInsufficientBalance(address account);

    /**
     * @dev There's no code at `target` (it is not a contract).
     */
    error AddressEmptyCode(address target);

    /**
     * @dev A call to an address target failed. The target may have reverted.
     */
    error FailedInnerCall();

    /**
     * @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://consensys.net/diligence/blog/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.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        if (address(this).balance < amount) {
            revert AddressInsufficientBalance(address(this));
        }

        (bool success, ) = recipient.call{value: amount}("");
        if (!success) {
            revert FailedInnerCall();
        }
    }

    /**
     * @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 or custom error, it is bubbled
     * up by this function (like regular Solidity function calls). However, if
     * the call reverted with no returned reason, this function reverts with a
     * {FailedInnerCall} error.
     *
     * 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.
     */
    function functionCall(
        address target,
        bytes memory data
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0);
    }

    /**
     * @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`.
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        if (address(this).balance < value) {
            revert AddressInsufficientBalance(address(this));
        }
        (bool success, bytes memory returndata) = target.call{value: value}(
            data
        );
        return verifyCallResultFromTarget(target, success, returndata);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     */
    function functionStaticCall(
        address target,
        bytes memory data
    ) internal view returns (bytes memory) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, success, returndata);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     */
    function functionDelegateCall(
        address target,
        bytes memory data
    ) internal returns (bytes memory) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
     * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an
     * unsuccessful call.
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata
    ) internal view returns (bytes memory) {
        if (!success) {
            _revert(returndata);
        } else {
            // only check if target is a contract if the call was successful and the return data is empty
            // otherwise we already know that it was a contract
            if (returndata.length == 0 && target.code.length == 0) {
                revert AddressEmptyCode(target);
            }
            return returndata;
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
     * revert reason or with a default {FailedInnerCall} error.
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata
    ) internal pure returns (bytes memory) {
        if (!success) {
            _revert(returndata);
        } else {
            return returndata;
        }
    }

    /**
     * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.
     */
    function _revert(bytes memory returndata) private pure {
        // 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
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert FailedInnerCall();
        }
    }
}

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

// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.20;

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

    /**
     * @dev An operation with an ERC20 token failed.
     */
    error SafeERC20FailedOperation(address token);

    /**
     * @dev Indicates a failed `decreaseAllowance` request.
     */
    error SafeERC20FailedDecreaseAllowance(
        address spender,
        uint256 currentAllowance,
        uint256 requestedDecrease
    );

    /**
     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
    }

    /**
     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
     */
    function safeTransferFrom(
        IERC20 token,
        address from,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(
            token,
            abi.encodeCall(token.transferFrom, (from, to, value))
        );
    }

    /**
     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeIncreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        uint256 oldAllowance = token.allowance(address(this), spender);
        forceApprove(token, spender, oldAllowance + value);
    }

    /**
     * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
     * value, non-reverting calls are assumed to be successful.
     */
    function safeDecreaseAllowance(
        IERC20 token,
        address spender,
        uint256 requestedDecrease
    ) internal {
        unchecked {
            uint256 currentAllowance = token.allowance(address(this), spender);
            if (currentAllowance < requestedDecrease) {
                revert SafeERC20FailedDecreaseAllowance(
                    spender,
                    currentAllowance,
                    requestedDecrease
                );
            }
            forceApprove(token, spender, currentAllowance - requestedDecrease);
        }
    }

    /**
     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
     * to be set to zero before setting it to a non-zero value, such as USDT.
     */
    function forceApprove(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        bytes memory approvalCall = abi.encodeCall(
            token.approve,
            (spender, value)
        );

        if (!_callOptionalReturnBool(token, approvalCall)) {
            _callOptionalReturn(
                token,
                abi.encodeCall(token.approve, (spender, 0))
            );
            _callOptionalReturn(token, approvalCall);
        }
    }

    /**
     * @dev 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);
        if (returndata.length != 0 && !abi.decode(returndata, (bool))) {
            revert SafeERC20FailedOperation(address(token));
        }
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     *
     * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
     */
    function _callOptionalReturnBool(
        IERC20 token,
        bytes memory data
    ) private returns (bool) {
        // 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 cannot use {Address-functionCall} here since this should return false
        // and not revert is the subcall reverts.

        (bool success, bytes memory returndata) = address(token).call(data);
        return
            success &&
            (returndata.length == 0 || abi.decode(returndata, (bool))) &&
            address(token).code.length > 0;
    }
}

pragma solidity ^0.8.0;

interface IERC20Metadata is IERC20 {
    function name() external view returns (string memory);

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

    function decimals() external view returns (uint8);
}

// Original license: SPDX_License_Identifier: MIT

pragma solidity ^0.8.20;

contract QFinancePresale is Ownable {
    using SafeERC20 for IERC20;
    using SafeERC20 for IERC20Metadata;

    uint256 public rate;

    address public saleToken;
    uint public saleTokenDec;

    uint256 public totalTokensforSale;

    mapping(address => bool) public payableTokens;

    mapping(address => uint256) public tokenPrices;

    bool public saleStatus;

    address[] public buyers;

    mapping(address => bool) public buyersExists;
    mapping(address => uint256) public buyersAmount;

    uint256 public totalBuyers;
    uint256 public totalTokensSold;

    address public ICO;
    address public DEV;

    struct BuyerDetails {
        address buyer;
        uint amount;
    }

    event BuyToken(
        address indexed buyer,
        address indexed token,
        uint256 paidAmount,
        uint256 purchasedAmount
    );

    constructor(
        address _ICO,
        address _DEV
    ) Ownable(msg.sender) {
        saleStatus = false;
        ICO = _ICO;
        DEV = _DEV;
    }

    modifier saleEnabled() {
        require(saleStatus == true, "QFin: is not enabled");
        _;
    }

    modifier saleStoped() {
        require(saleStatus == false, "QFin: is not stopped");
        _;
    }

    function setSaleToken(
        address _saleToken,
        uint256 _totalTokensforSale,
        uint256 _rate,
        bool _saleStatus
    ) external onlyOwner {
        require(_rate != 0);
        rate = _rate;
        saleToken = _saleToken;
        saleStatus = _saleStatus;
        saleTokenDec = IERC20Metadata(_saleToken).decimals();
        totalTokensforSale = _totalTokensforSale;

        IERC20(_saleToken).safeTransferFrom(
            msg.sender,
            address(this),
            _totalTokensforSale
        );
    }

    function stopSale() external onlyOwner saleEnabled {
        saleStatus = false;
    }

    function resumeSale() external onlyOwner saleStoped {
        saleStatus = true;
    }

    function addPayableTokens(
        address[] memory _tokens,
        uint256[] memory _prices
    ) external onlyOwner {
        require(
            _tokens.length == _prices.length,
            "QFin: tokens & prices arrays length mismatch"
        );

        for (uint256 i = 0; i < _tokens.length; i++) {
            require(_prices[i] != 0);
            payableTokens[_tokens[i]] = true;
            tokenPrices[_tokens[i]] = _prices[i];
        }
    }

    function payableTokenStatus(
        address _token,
        bool _status
    ) external onlyOwner {
        require(payableTokens[_token] != _status);

        payableTokens[_token] = _status;
    }

    function updateTokenRate(
        address[] memory _tokens,
        uint256[] memory _prices,
        uint256 _rate
    ) external onlyOwner {
        require(
            _tokens.length == _prices.length,
            "QFin: tokens & prices arrays length mismatch"
        );

        if (_rate != 0) {
            rate = _rate;
        }

        for (uint256 i = 0; i < _tokens.length; i += 1) {
            require(payableTokens[_tokens[i]] == true);
            require(_prices[i] != 0);
            tokenPrices[_tokens[i]] = _prices[i];
        }
    }

    function getTokenAmount(
        address token,
        uint256 amount
    ) public view returns (uint256) {
        uint256 amtOut;
        if (token != address(0)) {
            require(
                payableTokens[token] == true,
                "QFin: Token not allowed"
            );
            uint256 price = tokenPrices[token];
            amtOut = (amount * (10 ** saleTokenDec)) / (price);
        } else {
            amtOut = (amount * (10 ** saleTokenDec)) / (rate);
        }
        return amtOut;
    }

    function getPayAmount(
        address token,
        uint256 amount
    ) public view returns (uint256) {
        uint256 amtOut;
        if (token != address(0)) {
            require(
                payableTokens[token] == true,
                "QFin: Token not allowed"
            );
            uint256 price = tokenPrices[token];
            amtOut = (amount * (price)) / (10 ** saleTokenDec);
        } else {
            amtOut = (amount * (rate)) / (10 ** saleTokenDec);
        }
        return amtOut;
    }

    function transferETH(uint256 _amount) internal {
        uint256 DEVAmt = (_amount * 5) / 100;
        payable(DEV).transfer(DEVAmt);
        payable(ICO).transfer(_amount - DEVAmt);
    }

    function transferToken(address _token, uint256 _amount) internal {
        uint256 DEVAmt = (_amount * 5) / 100;
        IERC20(_token).safeTransferFrom(
            msg.sender,
            DEV,
            DEVAmt
        );
        IERC20(_token).safeTransferFrom(
            msg.sender,
            ICO,
            _amount - DEVAmt
        );
    }

    function buyToken(
        address _token,
        uint256 _amount
    ) external payable saleEnabled {
        uint256 amount = _token != address(0) ? _amount : msg.value;
        uint256 saleTokenAmt = getTokenAmount(_token, amount);

        require(saleTokenAmt != 0, "QFin: Amount is 0");
        require(
            (totalTokensSold + saleTokenAmt) < totalTokensforSale,
            "QFin: Not enough tokens to be sold"
        );

        if (_token != address(0)) {
            transferToken(_token, _amount);
        } else {
            transferETH(msg.value);
        }

        IERC20(saleToken).safeTransfer(msg.sender, saleTokenAmt);

        totalTokensSold += saleTokenAmt;

        if (!buyersExists[msg.sender]) {
            buyers.push(msg.sender);
            buyersExists[msg.sender] = true;
            totalBuyers += 1;
        }

        buyersAmount[msg.sender] += saleTokenAmt;

        emit BuyToken(msg.sender, _token, amount, saleTokenAmt);
    }

    function buyersDetailsList(
        uint _from,
        uint _to
    ) external view returns (BuyerDetails[] memory) {
        require(_from < _to, "QFin: _from should be less than _to");

        uint to = _to > totalBuyers ? totalBuyers : _to;
        uint from = _from > totalBuyers ? totalBuyers : _from;

        BuyerDetails[] memory buyersAmt = new BuyerDetails[](to - from);

        for (uint i = from; i < to; i += 1) {
            buyersAmt[i] = BuyerDetails(buyers[i], buyersAmount[buyers[i]]);
        }

        return buyersAmt;
    }

    function withdrawFunds(address token, uint256 amount) external onlyOwner {
        if (token == address(0)) {
            // Withdraw Ether
            uint256 balance = address(this).balance;
            require(
                balance >= amount,
                "QFinPresale: Insufficient Ether balance"
            );
            payable(owner()).transfer(amount);
        } else {
            // Withdraw ERC20 tokens
            uint256 balance = IERC20(token).balanceOf(address(this));
            require(
                balance >= amount,
                "QFinPresale: Insufficient token balance"
            );
            IERC20(token).safeTransfer(owner(), amount);
        }
    }
}

Read Contract

DEV 0xc1eb5ddd → address
ICO 0x273ba6bb → address
buyers 0xf2aa8218 → address
buyersAmount 0x54a9f102 → uint256
buyersDetailsList 0x76ca67a5 → tuple[]
buyersExists 0xba41b210 → bool
getPayAmount 0x9344f5c1 → uint256
getTokenAmount 0x115ece4c → uint256
owner 0x8da5cb5b → address
payableTokens 0x80655eef → bool
rate 0x2c4e722e → uint256
saleStatus 0xf9020e33 → bool
saleToken 0xe985e367 → address
saleTokenDec 0xace1741c → uint256
tokenPrices 0x204120bc → uint256
totalBuyers 0x3abd0136 → uint256
totalTokensSold 0x63b20117 → uint256
totalTokensforSale 0x6bcedf9c → uint256

Write Contract 8 functions

These functions modify contract state and require a wallet transaction to execute.

addPayableTokens 0x5413c1c8
address[] _tokens
uint256[] _prices
buyToken 0x68f8fc10
address _token
uint256 _amount
payableTokenStatus 0x29d429a8
address _token
bool _status
resumeSale 0x33e364cb
No parameters
setSaleToken 0x3874e325
address _saleToken
uint256 _totalTokensforSale
uint256 _rate
bool _saleStatus
stopSale 0xe36b0b37
No parameters
updateTokenRate 0x3115329e
address[] _tokens
uint256[] _prices
uint256 _rate
withdrawFunds 0xc1075329
address token
uint256 amount

Recent Transactions

No transactions found for this address