S Price: $0.770935 (-1.36%)

Contract Diff Checker

Contract Name:
PresaleDapp

Contract Source Code:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
//pragma experimental ABIEncoderV2;
//import "https://github.com/Uniswap/uniswap-v2-periphery/blob/master/contracts/interfaces/IUniswapV2Router02.sol";



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


    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, uint value);
    event Transfer(address indexed from, address indexed to, uint 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(uint);

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

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

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

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

    function transferFrom(address from, address to, uint 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,
        uint amountADesired,
        uint amountBDesired,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline
    ) external returns(uint amountA, uint amountB, uint liquidity);

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

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



    function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)
    external
    payable
    returns(uint[] memory amounts);
    function swapExactBNBForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)
    external
    payable
    returns(uint[] 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(uint amountIn, address[] calldata path) external view returns(uint[] memory amounts);

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









interface lpLockDeployerInterface {

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


}



contract Consts {
   // uint constant TOKEN_DECIMALS = 18;
   // uint8 constant TOKEN_DECIMALS_UINT8 = 18;
   // uint constant TOKEN_DECIMAL_MULTIPLIER = 10 ** TOKEN_DECIMALS;
   // bool constant CONTINUE_MINTING = false;
   // uint256 constant minPlatTokenReq = 1000 * TOKEN_DECIMAL_MULTIPLIER;
   // uint256 constant airdropTokenPercentage = 2;
}

contract DefiCrowdsale is Consts, 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();
    event Initialized();
    event TimesChanged(uint startTime, uint endTime, uint oldStartTime, uint oldEndTime);

    string public presaleType = "IDO";

    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;
    mapping(uint256 => address) public AddWhitelistTracker;
    //mapping(uint256 => address) public RemoveWhitelistTracker;

    uint256 public contributorCount;
    uint256 public AddWhitelistNumber;
    uint256 public RemoveWhitelistNumber;
    uint256 public presaleGoalReachedTime = 0;
    uint256 public buyRate;
    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 = 600;
    uint256 public finalizeTimeout = 600; //604800;  //time for presale owner to finalize
    uint256 public disabledWhitelistTime;
    uint public teamFeePer = 2; // team fees percentage

    bool public initialized = false;
    bool public Preaslefinalized = false;
    bool public whitelistEnabled;
    bool public whitelistDisabledInitiated;
    bool public isFinalized;
    bool public finalizeValid;
    bool public vestingEnabled;
    bool public refundEnabled;
    bool public alternateFee;

    uint256 public MaxAllowedContribution;
    uint256 public numberOfVest;
    uint256 public finalizedTime;
    uint256 public vestingPeriod;
    uint256 public uniswapPercentage;
    uint256 public uniswapRate;
    uint256 public extraAmountPerVal;
    uint256 public nativeMultiplier = 20;
    uint256 public burnLockPeriod = 1209600;
    uint256 public totalTokenRequired;

   // address[] public AddWhitelistTrackerArray;
   // address[] public RemoveWhitelistTrackerArray;
    address public token;
    address public presaleCreator;
    address public feeContract;
    address public referrerAddr;
    address[3] public altAssets;
   // address public uniswapDapAddress;
    

    
    // address[] teamAddresses;
    // uint256[] teamAmounts;
    // uint256[] teamFreezeTimes;
    //uint256 totalTeamTokensMinted;

    constructor(address _token, uint256 _rate, uint256[2] memory start_end_time, address[2] memory targetWallets, uint256[2] memory soft_hard_cap, uint256[2] memory _min_max_eth, uint256[2] memory _UniRatePercentage, uint _teamFeePer, uint256[2] memory _extraAmountPer_lockTime, uint256 _nativeMul, address[5] memory _lpLockDepAndRouter_AltAssets)
    


    //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");
        
        __min_max_eth = _min_max_eth;
        soft_cap = soft_hard_cap[0];
        hard_cap = soft_hard_cap[1];
        startTime = start_end_time[0];
        endTime = start_end_time[1];
        token = _token;
        MaxAllowedContribution = _min_max_eth[1];
        presaleCreator = targetWallets[0];
        feeContract = targetWallets[1];
        teamFeePer = _teamFeePer;
        uniswapPercentage = _UniRatePercentage[1];
        //uniswapRate = _UniRatePercentage[0] * 10**IERC20(token).decimals();
        uniswapRate = _UniRatePercentage[0];
        //buyRate = _rate * 10**IERC20(token).decimals();
        buyRate = _rate;
        extraAmountPerVal = _extraAmountPer_lockTime[0] + 100;
        nativeMultiplier = _nativeMul;
        lpLockDeployer = _lpLockDepAndRouter_AltAssets[0];
        ROUTER_ADDRESS = _lpLockDepAndRouter_AltAssets[1];
        locktime = _extraAmountPer_lockTime[1];
        totalTokenRequired = ((buyRate*hard_cap + uniswapRate*((hard_cap*uniswapPercentage)/100))/(10 ** 18)) * (teamFeePer+100) / 100;
        altAssets[0] = _lpLockDepAndRouter_AltAssets[2];
        altAssets[1] = _lpLockDepAndRouter_AltAssets[3];
        altAssets[2] = _lpLockDepAndRouter_AltAssets[4];


            validPairPartner[altAssets[0]] = true;
            validPairPartner[altAssets[1]] = true;
            validPairPartner[altAssets[2]] = true;
  

    }



    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 mintForPlatform(address _platform, address _referrer, uint256 _refPer, bool tokenFeeToRef) public onlyOwner returns(bool) {
        if(!alternateFee){
            require(_platform != address(0), "platform addr cant be zero");
            uint256 platFee = (weiRaised*buyRate*teamFeePer)/(100 ether);
            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 mintForUniswap(address uniswapDep) public onlyOwner {
        uint256 tokenFee = (weiRaised*uniswapRate*uniswapPercentage*extraAmountPerVal)/(10000 ether);
        require(uniswapDep != address(0x0),"uniswapDep addr cannot be zero");
        require(ERC20(token).transfer(uniswapDep, tokenFee),"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 enableWhitelist() public onlyOwner {

        require(!whitelistEnabled, "whitelist already enabled");
        whitelistEnabled = true;


    }


    function disableWhitelist() public onlyOwner {

        require(whitelistEnabled, "whitelist 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());
    

    }
*/    


    /**
     * @dev fallback function ***DO NOT OVERRIDE***
     */
    receive() external payable {

        require(block.timestamp > disabledWhitelistTime, "In whitelist disabled cool Off");
        require(!anytimeRefunded[msg.sender], "User used anytime refund!"); //checking if user refunded from this presale at anytime

        if (whitelistEnabled) {

            require(whitelist[msg.sender], "user 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++;
        }
    }


    /**
     * @dev low level token purchase ***DO NOT OVERRIDE***
     * @param _beneficiary Address performing the token purchase
     */
    function buyTokens(address _beneficiary) internal {
        require(msg.sender == tx.origin,"can't contribute via contracts");
        require(block.timestamp > disabledWhitelistTime, "In whitelist disabled cool Off internal");
        require (block.timestamp >= startTime && block.timestamp < endTime,"IDO not active");
        require(!anytimeRefunded[msg.sender], "User used anytime refund!"); //checking if user refunded from this presale at anytime
        if (whitelistEnabled) {

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

        }
        uint256 weiAmount = msg.value;
        _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 _getTokenAmount(uint256 _weiAmount)
    internal view returns(uint256) {
        return _weiAmount*buyRate/(1 ether);
        // return _weiAmount.mul(rate);
    }


    function claimTokens() public {
        require(!refundEnabled,"presale was refunded");
        require(!vestingEnabled,"please use vesting method to claim");
        require(isFinalized, "Not Finalized yet!");
        require(finalizeValid, "presale Failed!"); //checking if presale succeeded or not
        require(!(contributors[msg.sender] == 0), "user has no more tokens to claim!");
        uint256 tokenValue = (uint256(contributors[msg.sender]) * (uint256(buyRate))) / (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;

    }

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

        contributorsPayoutNumber[msg.sender] = CurrentPayoutRounds;
        
        uint256 tokenValue = (((uint256(contributorsTracker[msg.sender]) * (uint256(buyRate))) / (1 ether)) * (userPayoutRounds)) / (numberOfVest);
        // uint256 tokenValueDecimalOptimized = (tokenValue.mul(10 ** uint256(seeDecimals(token)))).div(1 ether);
        uint256 totalTokensLeftForUser = (uint256(contributors[msg.sender]) * (uint256(buyRate))) / (1 ether);
        require(tokenValue <= totalTokensLeftForUser,"can't claim more than allowed");
        uint256 contributionsClaiming = contributorsTracker[msg.sender] * (userPayoutRounds) / (numberOfVest);
        if(contributionsClaiming >= contributors[msg.sender]){
            contributors[msg.sender] = 0;
        }
        else{
            contributors[msg.sender] = contributors[msg.sender] - (contributionsClaiming);
        }
        ERC20(token).transfer(msg.sender, tokenValue);
        contributorsClaim[msg.sender] = contributorsClaim[msg.sender] + (tokenValue);       

    }

    function enableVesting(uint256 _numOfVest, uint256 _vestingPeriod) public{
        require(_numOfVest > 1,"num of vest has to be grtr than 1");
        require(_vestingPeriod > 0,"vesting period invalid");   
        require(block.timestamp < startTime - (600),"can't enable vest after presale start");    
        require(!vestingEnabled,"vesting 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,"vesting already disabled");
        require(!isFinalized,"presale 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, "already succesfully finalized");
        require(block.timestamp < endTime - (finalizeTimeout), "withdrawal window expired!");
        // require(!goalReached() || !finalizeValid,"goal reached");
        contributorsRefundAnytime[msg.sender] = userContributed; // added for V3 -- need to check
        weiRaised = weiRaised - (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,"refund not enabled");
        uint256 depositedValue = contributors[investor];
        require(depositedValue > 0, "User has no investment to claim");
        contributors[investor] = 0;
        payable(investor).call{value:depositedValue}("");
        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*(20)/(100);
        uint256 refundValue = _contributed - (penalty);

        contributors[investor] = 0; // added for V3 -- need to check
        contributorsTracker[investor] = 0; // added for V3 -- need to check
        payable(address(feeContract)).call{value:penalty}("");
        payable(investor).call{value:refundValue}("");
        emit claimedBack(investor, _contributed);
    }

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

        } else {
            enableRefunds();
        }

        finalizedTime = block.timestamp;

        emit Finalized();

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


    }

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

        isFinalized = true;



        return true;


    }

    function enableRefunds() internal {

        refundEnabled = true;
        emit RefundsEnabled();
    }


    function getBackTokens() public {

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

        require(IERC20(token).transfer(presaleCreator, IERC20(token).balanceOf(address(this))),"cannot transfer token back");

    }

        function burnUnsoldTokens() public {

       // require(block.timestamp > closingTime.add(burnDeltaTime), "cannot withdraw yet");
        require(msg.sender == presaleCreator, "initiator is not presale owner!");
        require(block.timestamp > (finalizedTime + burnLockPeriod));
       // require(hasClosed(), "presale not closed!");
        require(isFinalized, "presale not finalized!");
        require(finalizeValid, "finalize was valid");
        uint256 tokenUnsold = (((hard_cap-weiRaised)*uniswapRate*uniswapPercentage*extraAmountPerVal)/(10000 ether)) + ((hard_cap-weiRaised)*buyRate);
        require(IERC20(token).transfer(dead, tokenUnsold),"cannot transfer token to dead");

    }

    function selectNativeOnlyFee() public {

        require(msg.sender == presaleCreator, "initiator is not presale owner!");
        require(!isFinalized, "presale already finalized!");
        alternateFee = true;
        teamFeePer = (teamFeePer * nativeMultiplier)/10;

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

        uint256 feesAmount = (address(this).balance * teamFeePer) / (100);
        if(_refPer > 0){
            uint256 refAmount = (feesAmount * _refPer) / (100);
            payable(address(_referrerAddr)).call{value:refAmount}("");
            payable(address(feeContract)).call{value:(feesAmount - refAmount)}("");
        }
        else{

            payable(address(feeContract)).call{value:feesAmount}("");

        }
        

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

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

        //payable(__uniswapDep).transfer(uniswapAmount);
        AddLiquidity((weiRaised*uniswapRate*uniswapPercentage*extraAmountPerVal)/(10000 ether),uniswapAmount);
        // __GovContract.transfer(GoverningAmount);
        if(address(this).balance != 0){
            payable(address(__Creator)).call{value:address(this).balance}("");
        }

    }

    function goalReached() public view returns(bool) {

        return weiRaised >= soft_cap;

    }
    function presaleEnded() public view returns(bool) {

        return block.timestamp > endTime;

    }

// DATA functions for UI to fetch and read

        function getPresaleData() public view returns(uint256[10] memory,bool[4] memory, string memory) {


            uint256[10] memory PresaleDataUint;
            bool[4] memory presaleDataBool;
            PresaleDataUint = [soft_cap,hard_cap,__min_max_eth[0],__min_max_eth[1],startTime,endTime,weiRaised,buyRate,uniswapRate,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);
    

        }

*/


    mapping(address => bool) public validPairPartner;
    //mapping(uint256 => address) public altList;
   // mapping(address => bool) public swapRouterMap;
   // mapping(uint256 => string) public altListName;
    //address public pairPartner;

   // uint256 public hundred = 100;
   // uint256 public extraAmountPerVal;
  //  address public tokenAddress;
  //  address public creatorAddress;
    uint256 public locktime;
    address public ROUTER_ADDRESS;
   // address public swapRouter_Address;
   // address public factoryAddress;
    address public dead = 0x000000000000000000000000000000000000dEaD;
	
   //address[] public altRouter;
   // string[] public altRouterNames;
	address public storedLPAddress;
	address public lockerAddress;
   // bool public blocked = false;
    bool public addLiquidityComplete;
    address public alternativeCurrency;
    bool public useAlternativeCurrency;
    uint256 public returnVal;
    address public lpLockDeployer;
    string public logo = "default";

    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 getWrapAddrRouterSpecific(address _router) public view returns (address){

            return UniswapRouter02(_router).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 setAlternateCurrency(address _newCurrency) public {
        require(_newCurrency != address(0),"currency cannot be Zero addr");
       // require(swapRouterMap[_swapRouter],"invalid router");
        require(validPairPartner[_newCurrency],"invalid asset selected");
        require(!addLiquidityComplete,"Liquidity is added already");
        require(msg.sender == presaleCreator,"not the presale creator");
       // swapRouter_Address = _swapRouter;
        alternativeCurrency = _newCurrency;
        useAlternativeCurrency = true;
    }

     function revertToNative() public{ 
        require(!addLiquidityComplete,"Liquidity is added already");
        require(msg.sender == presaleCreator,"not the presale creator");
        useAlternativeCurrency = false;
    }   
    function getAmountsMinToken(address _tokenAddress, uint256 _ethIN) public view returns(uint256) {

      //  UniswapRouter02 pancakeRouter = UniswapRouter02(_router);
        // generate the pair path of token -> weth
        uint256[] memory amountMinArr;
        uint256 AmountMin;
        address[] memory path = new address[](2);
        path[0] = getWrapAddr();
        path[1] = address(_tokenAddress);

        amountMinArr = UniswapRouter02(ROUTER_ADDRESS).getAmountsOut(_ethIN, path);
        AmountMin = uint256(amountMinArr[1]);

        return AmountMin;


    }

/*
       function getAmountsMinETH(address _tokenAddress, uint256 _tokenIN) public view returns(uint256) {

      //  UniswapRouter02 pancakeRouter = UniswapRouter02(_router);
        // generate the pair path of token -> weth
        uint256[] memory amountMinArr;
        uint256 AmountMin;
        address[] memory path = new address[](2);
        path[0] = address(_tokenAddress);
        path[1] = getWrapAddr();

        amountMinArr = UniswapRouter02(swapRouter_Address).getAmountsOut(_tokenIN, path);
        AmountMin = uint256(amountMinArr[1]);

        return AmountMin;


    }
    */
    function swapETHForTokens(uint256 _nativeForDex) private {
        require(useAlternativeCurrency,"alt currency not selected");
        address[] memory path = new address[](2);

        //path[0] = address(this);
        path[0] = getWrapAddr();
        path[1] = alternativeCurrency;

        Approve(alternativeCurrency);

        // make the swap
         UniswapRouter02(ROUTER_ADDRESS).swapExactETHForTokens{value:_nativeForDex}(
            getAmountsMinToken(alternativeCurrency,_nativeForDex),
            path,
            address(this),
            block.timestamp + (300)
            );
                
                returnVal = ERC20(alternativeCurrency).balanceOf(address(this));
                

            
            

    }

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

        uint256 amountETH = nativeForDex;
        uint256 amountETHMin = (amountETH * 90)/100;
        uint256 amountTokenToAddLiq = (amountTokenDesired * 100) / (extraAmountPerVal);
        uint256 amountTokenMin = (amountTokenToAddLiq * 90)/100;
        uint256 LP_WBNB_exp_balance;
        uint256 LP_token_balance;
        uint256 tokenToSend;
        if (useAlternativeCurrency) {

            swapETHForTokens(nativeForDex);

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

        else{

            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);

        if (useAlternativeCurrency) {
            UniswapRouter02(ROUTER_ADDRESS).addLiquidity(token, alternativeCurrency,amountTokenDesired,ERC20(alternativeCurrency).balanceOf(address(this)),amountTokenDesired,ERC20(alternativeCurrency).balanceOf(address(this)),address(this), block.timestamp + (300));
        }
        else{
            
            UniswapRouter02(ROUTER_ADDRESS).addLiquidityETH{value:amountETH}(token, amountTokenToAddLiq, amountTokenMin, amountETHMin, address(this), block.timestamp + (300));
        

        }

           // if (ERC20(token).balanceOf(address(this)) != 0) {
           //     ERC20(token).transfer(dead, ERC20(token).balanceOf(address(this)));
                //Burn remaining tokens
           // }


      /*  } else {
			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.mul(LP_WBNB_exp_balance).div(amountETH);

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

                LPToken(storedLPAddress).sync();
                // sync after adding token
            }
            
            Approve(token);
           
           UniswapRouter02(ROUTER_ADDRESS).addLiquidityETH{value:address(this).balance}(token, amountTokenToAddLiq, amountTokenMin, amountETHMin, address(this), block.timestamp.add(300));
        

            if (ERC20(token).balanceOf(address(this)) != 0) {
                ERC20(token).transfer(dead, ERC20(token).balanceOf(address(this)));
                //Burn remaining tokens
            }
    */

        

        addLiquidityComplete = true;

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




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

        address[] memory altAssetData = new address[](altAssets.length);
       // string[] memory  altListName = new string[](altAssets.length);
       // string[] memory  altListSym = new string[](altAssets.length);
        for(uint256 i=0;i<altAssets.length;i++){

            altAssetData[i] = altAssets[i];
           // altListName[i] = ERC20(altAssets[i]).name();
           // altListSym[i] = ERC20(altAssets[i]).symbol();
        }    
        return(altAssetData);
    }
    */
    /*
    function getAltRouterData() public view returns(address[] memory, string[] memory){

        address[] memory altRouterData = new address[](altRouter.length);
        string[] memory  altRouterName = new string[](altRouterNames.length);
        for(uint256 i=0;i<altRouter.length;i++){

            altRouterData[i] = altRouter[i];
            altRouterName[i] = altRouterNames[i];
        }    
        return(altRouterData,altRouterName);
    }
    */
       
}




contract PresaleDapp is Consts, Ownable {



   // address public lpLockDeployer;
   // address public feeContract;
    address[5] public feeContract_lplockDep_altAssets;
    uint256 public teamFee = 2;
    uint256 public nativeMultiplier = 20;
    constructor(address[5] memory _feeContract_lplockDep_altAssets) {

        feeContract_lplockDep_altAssets = _feeContract_lplockDep_altAssets;


    }

    function CreatePresaleRegular(address[4] memory presaleAddressInput_router, uint256[2] memory start_end_time, uint256[5] memory soft_hard_cap_rate_min_max_eth, uint256[2] memory uniRatePercentage, uint256[2] memory extraAmountPer_lockTime) public returns(address) {


        //require(uniRatePercentage[1] <= 100, "total percentages > 100!"); // This is to make sure that more eth is not requested than available

        //uint256[2] memory min_max_eth = [soft_hard_cap_rate_min_max_eth_GOV[3], soft_hard_cap_rate_min_max_eth_GOV[4]];
        //address _mainDapp = presaleAddressInput[0];
        //address creator = presaleAddressInput[1];
        //address tokenAddr = presaleAddressInput[2];
        //uint256[2] memory _soft_hard_cap = [soft_hard_cap_rate_min_max_eth_GOV[0], soft_hard_cap_rate_min_max_eth_GOV[1]];
        //uint256 UniPercentage = uniPercentage;
        address[2] memory targetWallets = [presaleAddressInput_router[1], feeContract_lplockDep_altAssets[0]];

        address router = presaleAddressInput_router[3];


        DefiCrowdsale PresaleContract = new DefiCrowdsale(presaleAddressInput_router[2], soft_hard_cap_rate_min_max_eth[2], start_end_time, targetWallets, [soft_hard_cap_rate_min_max_eth[0], soft_hard_cap_rate_min_max_eth[1]], [soft_hard_cap_rate_min_max_eth[3], soft_hard_cap_rate_min_max_eth[4]], uniRatePercentage,teamFee,extraAmountPer_lockTime,nativeMultiplier,[feeContract_lplockDep_altAssets[1],router,feeContract_lplockDep_altAssets[2],feeContract_lplockDep_altAssets[3],feeContract_lplockDep_altAssets[4]]);


        PresaleContract.transferOwnership(presaleAddressInput_router[0]);



        return address(PresaleContract);
    }




    function updateTeamFee(uint256 _newTeamFee) public onlyOwner {


        teamFee = _newTeamFee;




    }

    function updateNativeMultiplier(uint256 _newMultiplier) public onlyOwner {


        nativeMultiplier = _newMultiplier;




    }



    function updateFeeContract(address _newFeeContract) public onlyOwner {


        feeContract_lplockDep_altAssets[0] = _newFeeContract;




    }

    function updateAltAssets(uint index, address _newAltAssets) public onlyOwner {

        require(index > 1,"cannot update fee or lpdep contract");
        feeContract_lplockDep_altAssets[index] = _newAltAssets;

    }

}

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

Context size (optional):