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