S Price: $0.409272 (-0.64%)

Contract Diff Checker

Contract Name:
FairPresaleDapp

Contract Source Code:

File 1 of 1 : FairPresaleDapp

// SPDX-License-Identifier: MIT
//Dx protocol --- https://dx.app
pragma solidity ^0.8.17;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    function decimals() external view returns (uint8);

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

interface ERC20 {
    function name() external pure returns (string memory);

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

    function transfer(address to, uint256 value) external returns (bool);

    function approve(address spender, uint256 value) external returns (bool);

    function transferFrom(
        address from,
        address to,
        uint256 value
    ) external returns (bool);

    function totalSupply() external view returns (uint256);

    function balanceOf(address who) external view returns (uint256);

    function allowance(address owner, address spender)
        external
        view
        returns (uint256);

    event Transfer(address indexed from, address indexed to, uint256 value);

    event Approval(
        address indexed owner,
        address indexed spender,
        uint256 value
    );
}

/**
 * @title SafeMath
 * @dev Math operations with safety checks that throw on error
 */
library SafeMath {
    /**
     * @dev Multiplies two numbers, throws on overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256 c) {
        // Gas optimization: this is cheaper than asserting 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
        if (a == 0) {
            return 0;
        }

        c = a * b;
        assert(c / a == b);
        return c;
    }

    /**
     * @dev Integer division of two numbers, truncating the quotient.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        // assert(b > 0); // Solidity automatically throws when dividing by 0
        // uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold
        return a / b;
    }

    /**
     * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        assert(b <= a);
        return a - b;
    }

    /**
     * @dev Adds two numbers, throws on overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256 c) {
        c = a + b;
        assert(c >= a);
        return c;
    }
}

/**
 * @title Ownable
 * @dev The Ownable contract has an owner address, and provides basic authorization control
 * functions, this simplifies the implementation of "user permissions".
 */
contract Ownable {
    address public owner;
    address public voter;

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

    /**
     * @dev The Ownable constructor sets the original `owner` of the contract to the sender
     * account.
     */
    constructor() {
        owner = msg.sender;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(msg.sender == owner);
        _;
    }

    modifier onlyVoter() {
        require(msg.sender == voter);
        _;
    }

    /**
     * @dev Allows the current owner to relinquish control of the contract.
     */
    function renounceOwnership() public onlyOwner {
        emit OwnershipRenounced(owner);
        owner = address(0);
    }

    /**
     * @dev Allows the current owner to transfer control of the contract to a newOwner.
     * @param _newOwner The address to transfer ownership to.
     */
    function transferOwnership(address _newOwner) public onlyOwner {
        _transferOwnership(_newOwner);
    }

    /**
     * @dev Transfers control of the contract to a newOwner.
     * @param _newOwner The address to transfer ownership to.
     */
    function _transferOwnership(address _newOwner) internal {
        require(_newOwner != address(0));
        emit OwnershipTransferred(owner, _newOwner);
        owner = _newOwner;
    }
}

interface LPToken {
    function sync() external;
}

// pragma solidity >=0.5.0;

interface UniswapFactory {
    event PairCreated(
        address indexed token0,
        address indexed token1,
        address pair,
        uint256
    );

    function getPair(address tokenA, address tokenB)
        external
        view
        returns (address pair);

    function createPair(address tokenA, address tokenB)
        external
        returns (address pair);
}

// pragma solidity >=0.5.0;

interface IUniswapV2Pair {
    event Approval(
        address indexed owner,
        address indexed spender,
        uint256 value
    );
    event Transfer(address indexed from, address indexed to, uint256 value);

    function name() external pure returns (string memory);

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

    function decimals() external pure returns (uint8);

    function totalSupply() external view returns (uint256);

    function balanceOf(address owner) external view returns (uint256);

    function allowance(address owner, address spender)
        external
        view
        returns (uint256);

    function approve(address spender, uint256 value) external returns (bool);

    function transfer(address to, uint256 value) external returns (bool);

    function transferFrom(
        address from,
        address to,
        uint256 value
    ) external returns (bool);
}

// pragma solidity >=0.6.2;

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

    function WETH() external pure returns (address);

    function WBNB() external pure returns (address);

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

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

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

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

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

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

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

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

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

interface lpLockDeployerInterface {
    function createLPLocker(
        address _lockingToken,
        uint256 _lockerEndTimeStamp,
        string memory _logo,
        uint256 _lockingAmount
    ) external payable returns (address);
}

contract DefiFairCrowdsale is Ownable {
    event TokenPurchase(
        address indexed purchaser,
        address indexed beneficiary,
        uint256 value,
        uint256 amount
    );
    event Closed();
    event RefundsEnabled();
    event Refunded(address indexed beneficiary, uint256 weiAmount);
    event claimedBack(address indexed beneficiary, uint256 weiAmount);
    event Finalized();
    string public presaleType = "FAIRLAUNCH";
    using SafeMath for uint256;

    mapping(address => uint256) public affiliatesAmount;
    mapping(address => uint256) public affiliatesAmountForBuyer;
    mapping(address => uint256) public affiliatesAmountClaimed;
    mapping(address => uint256) public contributors;
    mapping(address => uint256) public contributorsTracker;
    mapping(address => uint256) public contributorsClaim;
    mapping(address => uint256) public contributorsRefundAnytime;
    mapping(address => uint256) public contributorsPayoutNumber;
    mapping(uint256 => address) public contributorsAddressTracker;
    mapping(address => bool) public contributed;
    mapping(address => bool) public anytimeRefunded;
    mapping(address => bool) public whitelist;

    bool public whitelistEnabled;
    uint256 public contributorCount;
    uint256 public AddWhitelistNumber;
    uint256 public RemoveWhitelistNumber;
    mapping(uint256 => address) public AddWhitelistTracker;
    //mapping(uint256 => address) public RemoveWhitelistTracker;
    address[] public AddWhitelistTrackerArray;
    //address[] public RemoveWhitelistTrackerArray;
    uint256 public presaleGoalReachedTime = 0;
    //event Initialized();
    //event TimesChanged(uint startTime, uint endTime, uint oldStartTime, uint oldEndTime);
    //bool public initialized = false;
    //bool public Preaslefinalized = false;
    uint256 public buyRate;
    uint256 teamFeePer = 2; // team fees percentage
    uint256 public nativeMultiplier = 20;
    uint256[2] __min_max_eth;
    uint256 public soft_cap;
    //uint256 public hard_cap;
    uint256 public startTime;
    uint256 public endTime;
    uint256 public weiRaised;
    uint256 public whitelistCoolOff = 60;
    uint256 public finalizeTimeout = 600; //600;  //time before finalize when anytime refund is disabled
    uint256 public tokenReturnLockTime = 604800;
    address public token;
    uint256 public disabledWhitelistTime;
    uint256 public totalAffiliateAmount;
    uint256 public totalAffiliateCount;
    bool public whitelistDisabledInitiated;
    bool public isFinalized;
    bool public finalizeValid;
    bool public vestingEnabled;
    bool public refundEnabled;
    bool public alternateFee;
    bool public affiliate;
    uint256 public MaxAllowedContribution;
    uint256 public numberOfVest;
    uint256 public finalizedTime;
    uint256 public vestingPeriod;
    uint256 public uniswapPercentage;
    uint256 public presaleAmount;
    uint256 public uniAmount;
    uint256 public totalTokenRequired;
    uint256 public affiliatePer = 10;
    uint256 public extraAmountPerVal;
    address public presaleCreator;
    address public feeContract;
    address public referrerAddr;

    constructor(
        address _token,
        uint256[2] memory _presaleUniAmount,
        uint256[2] memory start_end_time,
        address[2] memory targetWallets,
        uint256[3] memory _soft_cap_min_max_eth,
        uint256[2] memory _UniPercentage_teamFeePer,
        uint256[3] memory _extraAmountPer_lockTime_nativeMul,
        address[2] memory _lpLockDepAndRouter,
        uint256 _affiliatePer,
        uint256 _tokenReturnTime
    ) //Crowdsale(_rate, targetWallets[0], ERC20(token), _min_max_eth[1])
    //TimedCrowdsale(start_end_time[0] > now ? start_end_time[0] : now, start_end_time[1])
    //CappedCrowdsale(soft_hard_cap[1] * TOKEN_DECIMAL_MULTIPLIER)

    //RefundableCrowdsale(soft_hard_cap[0] * TOKEN_DECIMAL_MULTIPLIER, teamFees, _UniPercentage, targetWallets[1])

    {
        //  require((_govUniPercentage[0] >= 0) && (_govUniPercentage[0] <= 100), "Governance amount is outside of governance limits");
        affiliatePer = _affiliatePer;
        tokenReturnLockTime = _tokenReturnTime;
        __min_max_eth = [_soft_cap_min_max_eth[1], _soft_cap_min_max_eth[2]];
        soft_cap = _soft_cap_min_max_eth[0];
        // hard_cap = soft_hard_cap[1] * TOKEN_DECIMAL_MULTIPLIER;
        startTime = start_end_time[0];
        endTime = start_end_time[1];
        token = _token;
        MaxAllowedContribution = _soft_cap_min_max_eth[2];
        presaleCreator = targetWallets[0];
        feeContract = targetWallets[1];
        teamFeePer = _UniPercentage_teamFeePer[1];
        uniswapPercentage = _UniPercentage_teamFeePer[0];
        presaleAmount = _presaleUniAmount[0];
        uniAmount = _presaleUniAmount[1];
        totalTokenRequired =
            ((presaleAmount + uniAmount) * (teamFeePer + 100)) /
            100;
        extraAmountPerVal = _extraAmountPer_lockTime_nativeMul[0] + 100;
        locktime = _extraAmountPer_lockTime_nativeMul[1];
        nativeMultiplier = _extraAmountPer_lockTime_nativeMul[2];
        lpLockDeployer = _lpLockDepAndRouter[0];
        ROUTER_ADDRESS = _lpLockDepAndRouter[1];
    }

    /*
    function checkContributorValidity(address contributor_addr) public view returns(uint256) {

        return contributors[contributor_addr];

    }
*/

    function checkRate() public view returns (uint256) {
        return buyRate;
    }

    function minEthContribution() public view returns (uint256) {
        return __min_max_eth[0];
    }

    function maxEthContribution() public view returns (uint256) {
        return __min_max_eth[1];
    }

    function presaleStartTime() public view returns (uint256) {
        return startTime;
    }

    function presaleEndTime() public view returns (uint256) {
        return endTime;
    }

    function isContract(address _addr) private view returns (bool isContract) {
        uint32 size;
        assembly {
            size := extcodesize(_addr)
        }
        return (size > 0);
    }

    /*
    function mintForPlatform(address _platAddrs) public onlyOwner {
        require(_platAddrs != address(0), "platform addr cant be zero");
        uint256 platFee = (presaleAmount*teamFeePer)/100;
        ERC20(token).transfer(_platAddrs, platFee);
    }

    function mintForUniswap(address uniswapDep) public onlyOwner {

        require(uniswapDep != address(0x0),"uniswapDep addr cannot be zero");
        require(ERC20(token).transfer(uniswapDep, (uniAmount*extraAmountPerVal)/100),"unable to mint for uniDep from presale");
    }
*/

    //   function resetUserEthAmount(address contributor_addr) onlyOwner public {

    //    contributors[contributor_addr] = 0;

    //}

    /**
     * @dev override hasClosed to add minimal value logic
     * @return true if remained to achieve less than minimal
     */
    function hasClosed() public view returns (bool) {
        //bool remainValue = (hard_cap - weiRaised) < __min_max_eth[0];
        return (block.timestamp > endTime); // || remainValue;
    }

    function CheckSoftCap() public view returns (uint256) {
        return soft_cap;
    }

    /*
    function CheckHardCap() public view returns(uint256) {

        return hard_cap;
    }
*/

    function CheckTotalEthRaised() public view returns (uint256) {
        return weiRaised;
    }

    /*
     * @dev override purchase validation to add extra value logic.
     * @return true if sended more than minimal value
     */
    function _preValidatePurchase(address _beneficiary, uint256 _weiAmount)
        internal
    {
        require(msg.value >= __min_max_eth[0]);
        // require(msg.value >= 0);

        require(msg.value <= (__min_max_eth[1])); // it should be 10% in mainnet launch ***********************
        // require(msg.value <= 1000000000000000000);
        // require((weiRaised + _weiAmount) <= hard_cap,"contribution reaching over hcap");
        require(_beneficiary != address(0));
        require(_weiAmount != 0);
    }

    function addToWhitelist(address WhitelistAddress) public onlyOwner {
        //    require(!whitelist[WhitelistAddress], "already whitelisted");
        whitelist[WhitelistAddress] = true;
        AddWhitelistTracker[AddWhitelistNumber] = WhitelistAddress;
        AddWhitelistNumber++;
    }

    function removeFromWhitelist(address WhitelistAddress) public onlyOwner {
        require(whitelist[WhitelistAddress], "not in whitelist!");
        whitelist[WhitelistAddress] = false;
        //RemoveWhitelistTracker[RemoveWhitelistNumber] = WhitelistAddress;
        RemoveWhitelistNumber++;
    }

    function changeAffiliateState(
        bool _state,
        uint256 _newPer,
        bool _changeState,
        bool _changePer
    ) public {
        require(msg.sender == presaleCreator); // checking for presale owner address
        if (_changeState) {
            require(affiliate != _state, "already set");
            affiliate = _state;
        }
        if (_changePer) {
            require(_newPer <= 10, "invalid per");
            affiliatePer = _newPer * 10;
        }
    }

    function enableWhitelist() public onlyOwner {
        require(!whitelistEnabled, "already enabled");
        whitelistEnabled = true;
    }

    function disableWhitelist() public onlyOwner {
        require(whitelistEnabled, "already disabled");
        whitelistEnabled = false;
        disabledWhitelistTime = block.timestamp + whitelistCoolOff;
        whitelistDisabledInitiated = true;
    }

    /*
    function getAddlist() public view returns(address[] memory){

        address[] memory AddList = new address[](AddWhitelistNumber);  
        for (uint256 i = 0; i < AddWhitelistNumber; i++) {

            if(whitelist[AddWhitelistTracker[i]]){
                AddList[i] = AddWhitelistTracker[i];
            }
            else {

                AddList[i] = address(0x0);                
            }


        }

    return AddList;

    }
    */
    /*
    function getRemovelist() public view returns(address[] memory) {

        address[] memory RemoveList = new address[](RemoveWhitelistNumber); 
        for (uint256 i = 0; i < RemoveWhitelistNumber; i++) {

            RemoveList[i] = RemoveWhitelistTracker[i];


        }

    return RemoveList;
    

    }
    */
    /*
    function getPresaleDataAddr() view returns(address[] memory, uint256[7] memory) {

        address[] memory PresaleDataAddr = new address[](AddWhitelistNumber); 
        for (uint256 i = 0; i < AddWhitelistNumber; i++) {

            PresaleDataAddr[i] = AddWhitelistTracker[i];  //******************************************** NEED UPDATE TO ADD CORRECT ADDRESS DATA***************************************************


        }

    return (PresaleDataAddr,getPresaleDataUint());
    

    }
*/
    function getPresaleData()
        public
        view
        returns (
            uint256[10] memory,
            bool[4] memory,
            string memory
        )
    {
        uint256[10] memory PresaleDataUint;
        bool[4] memory presaleDataBool;
        PresaleDataUint = [
            soft_cap,
            presaleAmount,
            __min_max_eth[0],
            __min_max_eth[1],
            startTime,
            endTime,
            weiRaised,
            buyRate,
            uniAmount,
            uniswapPercentage
        ];
        presaleDataBool = [
            isFinalized,
            finalizeValid,
            vestingEnabled,
            refundEnabled
        ];

        return (PresaleDataUint, presaleDataBool, presaleType);
    }

    /*
        function getContributorData() public view returns(address[] memory,uint256[] memory) {

           // address[] memory WalletList = new address[](KYCsverifiedNumber);  
            address[] memory contributorAddresses = new address[](contributorCount);
            uint256[] memory contributedValues = new uint256[](contributorCount);
            for (uint256 i = 0; i < contributorCount;i++){

                contributorAddresses[i] = contributorsAddressTracker[i];
                contributedValues[i] = contributors[contributorsAddressTracker[i]];

            }



    return (contributorAddresses,contributedValues);
    

    }
    */

    /**
     * @dev fallback function ***DO NOT OVERRIDE***
     */
    receive() external payable {
        purchaseTokens(msg.value);
        /*
        require(block.timestamp > disabledWhitelistTime, "cool Off");
        require(!anytimeRefunded[msg.sender], "anytime refunded!"); //checking if user refunded from this presale at anytime

        if (whitelistEnabled) {

            require(whitelist[msg.sender], "not whitelisted");

        }
        require(contributors[msg.sender] <= (MaxAllowedContribution - msg.value),"contribution over max allowed");
        buyTokens(msg.sender);
        contributors[msg.sender] += msg.value;
        contributorsTracker[msg.sender] += msg.value;
        if(!contributed[msg.sender]){
            contributorsAddressTracker[contributorCount] = msg.sender;
            contributed[msg.sender] = true;
            contributorCount++;
        }
        */
    }

    function purchaseTokens(uint256 _buyAmount) internal {
        require(block.timestamp > disabledWhitelistTime, "cool Off");
        require(!anytimeRefunded[msg.sender], "anytime refunded!"); //checking if user refunded from this presale at anytime

        if (whitelistEnabled) {
            require(whitelist[msg.sender], "not whitelisted");
        }
        require(
            contributors[msg.sender] <= (MaxAllowedContribution - _buyAmount),
            "contribution over max allowed"
        );
        buyTokens(msg.sender, _buyAmount);
        contributors[msg.sender] += _buyAmount;
        contributorsTracker[msg.sender] += _buyAmount;
        if (!contributed[msg.sender]) {
            contributorsAddressTracker[contributorCount] = msg.sender;
            contributed[msg.sender] = true;
            contributorCount++;
        }
    }

    /**
     * @dev low level token purchase ***DO NOT OVERRIDE***
     * @param _beneficiary Address performing the token purchase
     */
    function buyTokens(address _beneficiary, uint256 _buyValue) internal {
        require(msg.sender == tx.origin, "no contracts");
        require(block.timestamp > disabledWhitelistTime, "cool Off");
        require(
            block.timestamp >= startTime && block.timestamp < endTime,
            "not active"
        );
        require(!anytimeRefunded[msg.sender], "anytime refunded!"); //checking if user refunded from this presale at anytime
        if (whitelistEnabled) {
            require(whitelist[msg.sender], "not whitelisted");
        }
        uint256 weiAmount = _buyValue;
        _preValidatePurchase(_beneficiary, weiAmount);

        // calculate token amount to be created
        uint256 tokens = _getTokenAmount(weiAmount);

        // update state
        weiRaised += weiAmount;

        //_processPurchase(_beneficiary, tokens);
        emit TokenPurchase(msg.sender, _beneficiary, weiAmount, tokens);

        // _updatePurchasingState(_beneficiary, weiAmount);

        //_forwardFunds();
        //_postValidatePurchase(_beneficiary, weiAmount);
    }

    function buyTokensReferral(address _referrer) public payable {
        //require(_referrer != address(0),"zero adr");
        require(!isContract(_referrer), "contract ref not allowed");
        require(affiliate, "refer mode not active");
        uint256 affiliateValue = (msg.value * affiliatePer) / 1000;
        purchaseTokens(msg.value - affiliateValue);
        payable(_referrer).call{value: affiliateValue}("");
        affiliatesAmount[_referrer] += affiliateValue;
        affiliatesAmountForBuyer[msg.sender] += affiliateValue;
        totalAffiliateAmount += affiliateValue;
        totalAffiliateCount++;
    }

    function _getTokenAmount(uint256 _weiAmount)
        internal
        view
        returns (uint256)
    {
        return (_weiAmount * buyRate) / (1 ether);
        // return _weiAmount.mul(rate);
    }

    function claimTokens() public {
        require(!refundEnabled, "refunded");
        require(!vestingEnabled, "use vesting");
        require(isFinalized, "Not Finalized");
        require(finalizeValid, "presale Failed!"); //checking if presale succeeded or not
        require(!(contributors[msg.sender] == 0), "no claim left");
        uint256 tokenValue = (
            uint256(contributors[msg.sender]).mul(uint256(buyRate))
        ).div(1 ether);
        // uint256 tokenValueDecimalOptimized = (tokenValue.mul(10 ** uint256(seeDecimals(token)))).div(1 ether);
        contributors[msg.sender] = 0;
        ERC20(token).transfer(msg.sender, tokenValue);
        contributorsClaim[msg.sender] = tokenValue;

        if (affiliatesAmountForBuyer[msg.sender] != 0) {
            claimTokensReferral();
        }
    }

    function claimTokensReferral() internal {
        //require(!refundEnabled,"was refunded");
        //require(!vestingEnabled,"please use vesting method to claim");
        //require(isFinalized, "Not Finalized");
        //require(finalizeValid, "presale Failed!"); //checking if presale succeeded or not
        //require(!(affiliatesAmountForBuyer[msg.sender] == 0), "ref no tokens for buyer");
        uint256 tokenValue = (uint256(affiliatesAmountForBuyer[msg.sender]) *
            (uint256(buyRate))) / (1 ether);
        // uint256 tokenValueDecimalOptimized = (tokenValue.mul(10 ** uint256(seeDecimals(token)))).div(1 ether);
        affiliatesAmountForBuyer[msg.sender] = 0;
        ERC20(token).transfer(msg.sender, tokenValue);
        affiliatesAmountClaimed[msg.sender] = tokenValue;
    }

    function vestToken() public {
        // require(!tokenDropFlag,"can't vest when token drop enabled!");
        require(!refundEnabled, "refunded");
        require(vestingEnabled, "not enabled");
        require(isFinalized, "Not Finalized");
        require(finalizeValid, "presale Failed!"); //checking if presale succeeded or not
        require(!(contributors[msg.sender] == 0), "no claim left");
        require(
            contributorsPayoutNumber[msg.sender] < numberOfVest,
            "all vested"
        );
        uint256 CurrentPayoutRounds = (
            ((block.timestamp).sub(finalizedTime)).div(vestingPeriod)
        ).add(1); // need to add 1 to allow partial token vest right away after presale
        if (CurrentPayoutRounds >= numberOfVest) {
            CurrentPayoutRounds = numberOfVest;
        }

        uint256 userPayoutRounds = CurrentPayoutRounds.sub(
            contributorsPayoutNumber[msg.sender]
        );
        require(
            userPayoutRounds > 0 && userPayoutRounds <= numberOfVest,
            "not claim window"
        );

        contributorsPayoutNumber[msg.sender] = CurrentPayoutRounds;

        uint256 tokenValue = (
            (
                (uint256(contributorsTracker[msg.sender]).mul(uint256(buyRate)))
                    .div(1 ether)
            ).mul(userPayoutRounds)
        ).div(numberOfVest);
        // uint256 tokenValueDecimalOptimized = (tokenValue.mul(10 ** uint256(seeDecimals(token)))).div(1 ether);
        uint256 totalTokensLeftForUser = (
            uint256(contributors[msg.sender]).mul(uint256(buyRate))
        ).div(1 ether);
        require(tokenValue <= totalTokensLeftForUser, "invalid claim");
        uint256 contributionsClaiming = contributorsTracker[msg.sender]
            .mul(userPayoutRounds)
            .div(numberOfVest);
        if (contributionsClaiming >= contributors[msg.sender]) {
            contributors[msg.sender] = 0;
        } else {
            contributors[msg.sender] = contributors[msg.sender].sub(
                contributionsClaiming
            );
        }
        ERC20(token).transfer(msg.sender, tokenValue);
        contributorsClaim[msg.sender] = contributorsClaim[msg.sender].add(
            tokenValue
        );

        if (affiliatesAmountForBuyer[msg.sender] != 0) {
            claimTokensReferral();
        }
    }

    function enableVesting(uint256 _numOfVest, uint256 _vestingPeriod) public {
        require(_numOfVest > 1, "num of vest invalid");
        require(_vestingPeriod > 0, "period invalid");
        require(
            block.timestamp < startTime.sub(600),
            "invalid after presale start"
        );
        require(!vestingEnabled, "already enabled");
        //require(!tokenDropFlag, "can't enable vest when airdrop is on");
        require(msg.sender == presaleCreator); // checking for presale owner address

        vestingEnabled = true;
        numberOfVest = _numOfVest;
        vestingPeriod = _vestingPeriod;
    }

    function disableVesting() public {
        require(msg.sender == presaleCreator);
        require(vestingEnabled, "already disabled");
        require(!isFinalized, "already finalized");
        vestingEnabled = false;
    }

    function claimRefund() public {
        require(isFinalized, "not finalized");
        require(
            !(goalReached()) || !finalizeValid,
            "goal reached or presale succeeded"
        );

        refund(msg.sender);
    }

    function claimRefundAnytime() public {
        require(!anytimeRefunded[msg.sender], "already refunded!");
        uint256 userContributed = contributors[msg.sender];
        require(userContributed > 0, "nothing to claim");
        require(!isFinalized, "already finalized!");
        require(!finalizeValid, "finalize valid");
        require(
            block.timestamp < endTime.sub(finalizeTimeout),
            "window expired!"
        );
        // require(!goalReached() || !finalizeValid,"goal reached");
        contributorsRefundAnytime[msg.sender] = userContributed; // added for V3 -- need to check
        weiRaised = weiRaised.sub(userContributed); // Subtract from total eth raised

        anytimeRefunded[msg.sender] = true;
        refundAnytime(msg.sender, userContributed);
    }

    function refund(address investor) internal {
        //have to see if onlyOwner works
        require(refundEnabled, "not enabled");
        uint256 depositedValue = contributors[investor];
        require(depositedValue > 0, "nothing to claim");
        contributors[investor] = 0;
        (bool refundSucess, ) = payable(investor).call{value: depositedValue}(
            ""
        );
        require(refundSucess, "refund failed");
        emit Refunded(investor, depositedValue);
    }

    function refundAnytime(address investor, uint256 _contributed) internal {
        // have to see if onlyOwner works
        //require(state == State.Refunding);
        //uint256 depositedValue = contributors[investor];
        //require(depositedValue > 0, "User has no investment to claim");
        uint256 penalty = _contributed.mul(20).div(100);
        uint256 refundValue = _contributed.sub(penalty);

        contributors[investor] = 0; // added for V3 -- need to check
        contributorsTracker[investor] = 0; // added for V3 -- need to check
        (bool feeContractPay, ) = payable(feeContract).call{value: penalty}("");
        (bool investorPay, ) = payable(investor).call{value: refundValue}("");
        require(feeContractPay && investorPay, "failed at payment");
        emit claimedBack(investor, _contributed);
    }

    function finalize(
        address[2] memory __finalizeInfo,
        uint256 refPer,
        bool validFinalize
    ) public onlyOwner returns (uint256) {
        require(!isFinalized, "already finalized");
        require(hasClosed(), "not closed");
        referrerAddr = __finalizeInfo[0];
        presaleCreator = __finalizeInfo[1];
        // uniswapDapAddress = __finalizeInfo[2];
        finalizeValid = validFinalize;
        if (goalReached() && finalizeValid) {
            setRate();
            close(presaleCreator, referrerAddr, refPer);
        } else {
            enableRefunds();
        }

        finalizedTime = block.timestamp;

        emit Finalized();

        isFinalized = true;
        /*
        if(tokenDropFlag && finalizeValid){
            tokenDrop();
        }
        */
        return 1;
    }

    /*
    function mintForUniswap(address _uniswapDapp) onlyOwner public {

        IERC20(token).transfer(_uniswapDapp,uniAmount);


    }
    */
    function mintForPlatform(
        address _platform,
        address _referrer,
        uint256 _refPer,
        bool tokenFeeToRef
    ) public onlyOwner returns (bool) {
        if (!alternateFee) {
            require(_platform != address(0), "no zero adr");
            uint256 platFee = (presaleAmount * teamFeePer) / 100;
            uint256 refFee;
            if (tokenFeeToRef) {
                refFee = (platFee * _refPer) / 100;
                ERC20(token).transfer(_platform, platFee - (refFee));
                ERC20(token).transfer(_referrer, refFee);
            } else {
                ERC20(token).transfer(_platform, platFee);
            }
        }
        return true;
    }

    /*
    function mintForPlatform(address _platform) onlyOwner public {

        uint256 platformFee = (presaleAmount*teamFeePer)/100;
        IERC20(token).transfer(_platform,platformFee);


    }
    */
    function finalizeAnytime(
        address[3] memory __finalizeInfo,
        bool validFinalize
    ) public onlyOwner returns (uint256) {
        require(!isFinalized, "already finalized");
        //   require(hasClosed());
        referrerAddr = __finalizeInfo[0];
        presaleCreator = __finalizeInfo[1];
        // uniswapDapAddress = __finalizeInfo[2];
        finalizeValid = validFinalize;
        enableRefunds();
        emit Finalized();

        isFinalized = true;

        return 1;
    }

    function enableRefunds() internal {
        refundEnabled = true;
        emit RefundsEnabled();
    }

    function setRate() internal {
        buyRate = (presaleAmount * (1 ether)) / CheckTotalEthRaised();
    }

    function getBackTokens() public {
        // require(block.timestamp > closingTime.add(burnDeltaTime), "cannot withdraw yet");
        require(msg.sender == presaleCreator, "not presale owner!");
        // require(hasClosed(), "presale not closed!");
        require(isFinalized, "not finalized!");
        require(!finalizeValid, "finalize valid");

        require(
            IERC20(token).transfer(
                presaleCreator,
                IERC20(token).balanceOf(address(this))
            ),
            "transfer fail"
        );
    }

    function returnUnsoldTokens(uint256 _amount) public {
        // require(block.timestamp > closingTime.add(burnDeltaTime), "cannot withdraw yet");
        require(msg.sender == presaleCreator, "not presale owner!");
        require(block.timestamp > (finalizedTime + tokenReturnLockTime));
        require(
            _amount <= IERC20(token).balanceOf(address(this)),
            "out of balance"
        );
        // require(hasClosed(), "presale not closed!");
        require(isFinalized, "not finalized!");
        require(finalizeValid, "not valid");
        //uint256 tokenUnsold = (((hard_cap-weiRaised)*uniswapRate*uniswapPercentage*extraAmountPerVal)/(10000 ether)) + ((hard_cap-weiRaised)*buyRate) + ((hard_cap-weiRaised)*buyRate * affiliatePer) / 1000;
        //require(IERC20(token).transfer(presaleCreator, tokenUnsold),"trans err unsold tkn");
        require(
            IERC20(token).transfer(presaleCreator, _amount),
            "trans err on unsold token"
        );
    }

    function selectNativeOnlyFee() public {
        require(msg.sender == presaleCreator, "not presale owner!");
        require(!isFinalized, "already finalized!");
        alternateFee = true;
        teamFeePer = (teamFeePer * nativeMultiplier) / 10;
    }

    function close(
        address __Creator,
        address _referrerAddr,
        uint256 _refPer
    ) internal {
        require(!isFinalized, "already finalized");
        emit Closed();

        uint256 feesAmount = address(this).balance.mul(teamFeePer).div(100);
        if (_refPer > 0) {
            uint256 refAmount = feesAmount.mul(_refPer).div(100);
            (bool refPay, ) = payable(_referrerAddr).call{value: refAmount}("");
            (bool feeContractClosePay, ) = payable(feeContract).call{
                value: feesAmount.sub(refAmount)
            }("");
            require(refPay && feeContractClosePay, "invalid ref or fee pay");
        } else {
            (bool feeContractOnlyPay, ) = payable(feeContract).call{
                value: feesAmount
            }("");
            require(feeContractOnlyPay, "invalid fee pay");
        }

        uint256 uniswapAmount = address(this)
            .balance
            .mul(uniswapPercentage)
            .div(100);
        // uint256 GoverningAmount = address(this).balance.mul(gov).div(100);

        require(address(this).balance >= uniswapAmount, "Not Enough Fund");
        //  require(address(this).balance > GoverningAmount, "Not Enough Fund to Transfer");

        // payable(__uniswapDep).transfer(uniswapAmount);
        AddLiquidity(uniAmount, uniswapAmount);
        // __GovContract.transfer(GoverningAmount);
        if (address(this).balance != 0) {
            (bool creatorPay, ) = payable(__Creator).call{
                value: address(this).balance
            }("");
            require(creatorPay, "unable to pay creator");
        }
    }

    function goalReached() public view returns (bool) {
        return weiRaised >= soft_cap;
    }

    function presaleEnded() public view returns (bool) {
        return block.timestamp > endTime;
    }

    mapping(address => bool) public validPairPartner;

    uint256 public hundred = 100;

    uint256 public locktime;
    address public ROUTER_ADDRESS;

    //address public dead = 0x000000000000000000000000000000000000dEaD;

    address public storedLPAddress;
    address public lockerAddress;
    bool public addLiquidityComplete;
    uint256 public returnVal;
    address public lpLockDeployer;
    string public logo = " ";

    function Approve(address _token) internal returns (bool) {
        uint256 amountIn = 100000000000000000000000000000000000000000000000000000000000000000000000000000;
        ERC20(_token).approve(ROUTER_ADDRESS, amountIn);
        return true;
    }

    function ApproveLock(address _lp, address _lockDeployer)
        internal
        returns (bool)
    {
        uint256 amountIn = 100000000000000000000000000000000000000000000000000000000000000000000000000000;
        ERC20(_lp).approve(_lockDeployer, amountIn);
        return true;
    }

    function getWrapAddr() public view returns (address) {
        return UniswapRouter02(ROUTER_ADDRESS).WETH();
    }

    function getpair(address _token1, address _token2)
        internal
        returns (address)
    {
        if (
            UniswapFactory(UniswapRouter02(ROUTER_ADDRESS).factory()).getPair(
                _token1,
                _token2
            ) != address(0)
        ) {
            return
                UniswapFactory(UniswapRouter02(ROUTER_ADDRESS).factory())
                    .getPair(_token1, _token2);
        } else {
            return
                UniswapFactory(UniswapRouter02(ROUTER_ADDRESS).factory())
                    .createPair(_token1, _token2);
        }
    }

    function AddLiquidity(uint256 amountTokenDesired, uint256 nativeForDex)
        internal
    {
        //   require(validPairPartner[_pairAlternative], "This is not a valid pair partner");

        uint256 amountETH = nativeForDex;
        uint256 amountETHMin = amountETH - ((amountETH * (10)) / (100));
        //uint256 amountTokenToAddLiq = amountTokenDesired * (hundred) / (extraAmountPerVal);
        uint256 amountTokenToAddLiq = amountTokenDesired;
        uint256 amountTokenMin = amountTokenToAddLiq -
            ((amountTokenToAddLiq * (10)) / (100));
        uint256 LP_WBNB_exp_balance;
        uint256 LP_token_balance;
        uint256 tokenToSend;

        storedLPAddress = getpair(token, getWrapAddr());
        LP_WBNB_exp_balance = ERC20(getWrapAddr()).balanceOf(storedLPAddress);
        LP_token_balance = ERC20(token).balanceOf(storedLPAddress);

        if (
            storedLPAddress != address(0x0) &&
            (LP_WBNB_exp_balance > 0 && LP_token_balance <= 0)
        ) {
            tokenToSend =
                (amountTokenToAddLiq * (LP_WBNB_exp_balance)) /
                (amountETH);

            ERC20(token).transfer(storedLPAddress, tokenToSend);

            LPToken(storedLPAddress).sync();
            // sync after adding token
        }
        Approve(token);

        UniswapRouter02(ROUTER_ADDRESS).addLiquidityETH{value: amountETH}(
            token,
            amountTokenToAddLiq,
            amountTokenMin,
            amountETHMin,
            address(this),
            block.timestamp + (300)
        );

        addLiquidityComplete = true;

        ApproveLock(storedLPAddress, lpLockDeployer);
        lockerAddress = lpLockDeployerInterface(lpLockDeployer).createLPLocker(
            storedLPAddress,
            locktime,
            logo,
            ERC20(storedLPAddress).balanceOf(address(this))
        );
    }
}

contract FairPresaleDapp is Ownable {
    using SafeMath for uint256;

    address public feeContract;
    address public lpLockDeployer;
    uint256 public teamFee = 2;
    uint256 public affiliatePerBaseThousand = 10;
    uint256 public tokenReturnTime = 604800;
    // uint256 public extraAmountPer = 2;
    uint256 public nativeMultiplier = 20;

    constructor(address _feeContract, address _lpLockDeployer) {
        feeContract = _feeContract;
        lpLockDeployer = _lpLockDeployer;
    }

    function CreatePresaleFair(
        address[4] memory presaleAddressInput_Router,
        uint256[2] memory start_end_time,
        uint256[5] memory softcap_preAmnt_uniAmnt_min_max_eth,
        uint256 uniPercentage,
        uint256[2] memory extraAmountPer_lockTime
    ) public returns (address) {
        DefiFairCrowdsale PresaleContract = new DefiFairCrowdsale(
            presaleAddressInput_Router[2],
            [
                softcap_preAmnt_uniAmnt_min_max_eth[1],
                softcap_preAmnt_uniAmnt_min_max_eth[2]
            ],
            start_end_time,
            [presaleAddressInput_Router[1], feeContract],
            [
                softcap_preAmnt_uniAmnt_min_max_eth[0],
                softcap_preAmnt_uniAmnt_min_max_eth[3],
                softcap_preAmnt_uniAmnt_min_max_eth[4]
            ],
            [uniPercentage, teamFee],
            [
                extraAmountPer_lockTime[0],
                extraAmountPer_lockTime[1],
                nativeMultiplier
            ],
            [lpLockDeployer, presaleAddressInput_Router[3]],
            affiliatePerBaseThousand,
            tokenReturnTime
        );

        PresaleContract.transferOwnership(presaleAddressInput_Router[0]);

        return address(PresaleContract);
    }

    function CheckBlockTimestamp() public view returns (uint256) {
        return block.timestamp;
    }

    function updateNativeMultiplier(uint256 _newMultiplier) public onlyOwner {
        nativeMultiplier = _newMultiplier;
    }

    function updateTeamFee(uint256 _newTeamFee) public onlyOwner {
        teamFee = _newTeamFee;
    }

    function updateAffiliatePer(uint256 _newPerThousand) public onlyOwner {
        affiliatePerBaseThousand = _newPerThousand;
    }

    function updateTokenReturnTime(uint256 _newReturnTimeDelta)
        public
        onlyOwner
    {
        tokenReturnTime = _newReturnTimeDelta;
    }

    function updateFeeContract(address _newFeeContract) public onlyOwner {
        feeContract = _newFeeContract;
    }
}

Please enter a contract address above to load the contract details and source code.

Context size (optional):