// File: contracts/token/context.sol contract Context { constructor () internal { } function _msgSender() internal view returns (address payable) { return msg.sender; } function _msgData() internal view returns (bytes memory) { this; return msg.data; } } contract HasOwner is Context { address _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); constructor () internal { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } modifier onlyAdmin() { require(_owner == _msgSender(), "Caller is not the owner"); _; } function renounceOwnership() public onlyAdmin { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } function transferOwnership(address newOwner) public onlyAdmin { require(newOwner != address(0), "New owner cannot have zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } } // File: contracts/token/math.sol library SafeMath { function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; return c; } function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } function ceil(uint a, uint m) internal pure returns (uint r) { return (a + m - 1) / m * m; } } // File: contracts/token/interfaces.sol pragma solidity ^0.5.17; interface WOWotherContract { function ADDFUNDS(uint256 amount) external; } interface IBEP20 { /** * @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 IPancakeRouter01 { function factory() external pure returns (address); function WETH() external pure returns (address); function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB); 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); function addLiquidityETH( address token, uint amountTokenDesired, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external payable returns (uint amountToken, uint amountETH, uint liquidity); } interface IPancakeRouter02 { function swapExactETHForTokensSupportingFeeOnTransferTokens( uint amountOutMin, address[] calldata path, address to, uint deadline ) external payable; function removeLiquidityETH( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountToken, uint amountETH); function removeLiquidityETHSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountETH); } interface IPancakeFactory { event PairCreated(address indexed token0, address indexed token1, address pair, uint); function feeTo() external view returns (address); function feeToSetter() external view returns (address); function migrator() external view returns (address); function getPair(address tokenA, address tokenB) external view returns (address pair); function allPairs(uint) external view returns (address pair); function allPairsLength() external view returns (uint); function createPair(address tokenA, address tokenB) external returns (address pair); function setFeeTo(address) external; function setFeeToSetter(address) external; function setMigrator(address) external; } // File: contracts/token/base.sol pragma solidity ^0.5.17; library Roles { struct Role { mapping (address => bool) bearer; } function add(Role storage role, address account) internal { require(!has(role, account), "Roles: account already has role"); role.bearer[account] = true; } function remove(Role storage role, address account) internal { require(has(role, account), "Roles: account does not have role"); role.bearer[account] = false; } function has(Role storage role, address account) internal view returns (bool) { require(account != address(0), "Roles: account is the zero address"); return role.bearer[account]; } } // File: contracts/token/token.sol pragma solidity ^0.5.17; contract WOW is Context, IBEP20, HasOwner { using SafeMath for uint256; /** * token preconfig * https://wow.finance/ * - token symbol is $WOW */ string private constant _name = "wow.finance"; string private constant _symbol = "WOW"; uint8 private constant _decimals = 18; /** * +----------------------------------------------+ * | TOKENOMICS | * +-----------------+----------------------------+ * | 1 500 000 WOW | TOTAL SUPPLY | * | 600 000 WOW | PRESALE | * | 336 000 WOW | PANCAKESWAP | * | 450 000 WOW | FARM | * | 114 000 WOW | TEAM ( 5% monthly vest ) | * +-----------------+----------------------------+ */ uint256 private _totalSupply = 1500000 * 1e18; uint256 private constant _presaleBudget = 600000 * 1e18; uint256 private constant _pancakeBudget = 336000 * 1e18; uint256 private constant _farmBudget = 450000 * 1e18; uint256 private _teamFundsBudget = 114000 * 1e18; /** * anti dump preconfig */ uint256 public anitDumpRate = 2; /** * buy back preconfig * - init rate is 1% * - this function can be triggered by any individual with at least 100 WOW * - 4% goes to any individual who triggered this function * - init interval is 2 hours */ uint256 public BuyBackRate = 1; uint256 public BuyBackUserMinBalance = 100 * 1e18; uint256 public BuyBackUserRewardPercentage = 4; uint256 public BuyBackInterval = 2 hours; uint256 public lastBuyBack; /** * pancake preconfig */ // address public PancakeRouter = 0x8f94A203B3e1127029Ed1E759c1a0Bb42Ab83971; // address public PancakeFactory = 0x67078E881E8B686605bFCc320a5c7D8906de3109; address public constant PancakeRouter = 0x07d090e7FcBC6AFaA507A3441C7c5eE507C457e6; address public constant PancakeFactory = 0xd417A0A4b65D24f5eBD0898d9028D92E3592afCC; address public PancakePair = address(0); /** * token address preconfig */ address public constant BURNaddr = address(0); address public STAKE = address(0); address public PRESALE = address(0); address public FARM = address(0); /** * events */ event BUYBACKTRIGGERED(uint256 tokenBurnt); event SUPPLYSTAKE(uint256 tokenAmount); event STAKENEWFUNDS(uint256 stakingRewards); /** * Marketing address preconfig */ address public MARKETINGaddr; /** * variable magnification during the transaction */ uint256 public SellFee4STAKE = 0; uint256 public BuyerRewardFunds = 0; /** * team funds variables * - team funds max 114 000 WOW * - every month (30 days) team can get 5 700 WOW */ uint256 public lastTeamFunds = 0; address public TEAMaddr = address(0); uint256 public constant TeamFundsInterval = 30 days; uint256 public constant TeamFundsOnce = 5700 * 1e18; /** * token owners variables */ mapping (address => uint256) private _balances; mapping (address => mapping (address => uint256)) private _allowances; mapping (address => bool) public addrWithoutFee; mapping (address => bool) public addrUnPaused; /** * balance pancakeswap liquidity pool */ Balancer balancer; /** * others */ bool public pause = true; /** * Lock Liquidity * - for 6 months = 180 days */ uint256 public LiquidityLockTimeout; uint256 public constant LiquidityLockInterval = 180 days; constructor() public { balancer = new Balancer(); lastBuyBack = block.timestamp; lastTeamFunds = block.timestamp.sub( TeamFundsInterval ); LiquidityLockTimeout = ( block.timestamp ).add( LiquidityLockInterval ); MARKETINGaddr = msg.sender; TEAMaddr = msg.sender; addrWithoutFee[address(this)] = true; addrWithoutFee[address(balancer)] = true; addrWithoutFee[address(PancakeRouter)] = true; addrWithoutFee[address(PancakeFactory)] = true; addrUnPaused[msg.sender] = false; // PAUSE owner addrUnPaused[address(this)] = true; addrUnPaused[address(balancer)] = true; addrUnPaused[address(PancakeRouter)] = true; _createPancakePair(); _balances[ address(this) ] = _totalSupply; emit Transfer(address(0), address(this), _totalSupply); } function name() public view returns (string memory) { return _name; } function symbol() public view returns (string memory) { return _symbol; } function decimals() public view returns (uint8) { return _decimals; } function totalSupply() public view returns (uint256) { return _totalSupply; } function balanceOf(address account) public view returns (uint256) { return _balances[account]; } function transfer(address recipient, uint256 amount) public returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } function allowance(address owner, address spender) public view returns (uint256) { return _allowances[owner][spender]; } function approve(address spender, uint256 amount) public returns (bool) { _approve(_msgSender(), spender, amount); return true; } function transferFrom(address sender, address recipient, uint256 amount) public returns (bool) { _transfer(sender, recipient, amount); _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "BEP20: WOW: transfer amount exceeds allowance")); return true; } function increaseAllowance(address spender, uint256 addedValue) public returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue)); return true; } function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "BEP20: WOW: decreased allowance below zero")); return true; } function burn(uint amount) public { require(amount > 0); require(balanceOf(msg.sender) >= amount); _burn(msg.sender, amount); } function _burn(address account, uint256 amount) internal { require(account != address(0), "BEP20: WOW: burn from the zero address"); _balances[account] = _balances[account].sub(amount, "BEP20: WOW: burn amount exceeds balance"); _totalSupply = _totalSupply.sub(amount); emit Transfer(account, address(0), amount); } function _approve(address owner, address spender, uint256 amount) internal { require(owner != address(0), "BEP20: WOW: approve from the zero address"); require(spender != address(0), "BEP20: WOW: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } function _burnFrom(address account, uint256 amount) internal { _burn(account, amount); _approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount, "BEP20: WOW: burn amount exceeds allowance")); } function _superTransfer (address sender, address recipient, uint256 amount) internal { require(sender != address(0), "BEP20: WOW: transfer from the zero address"); require(recipient != address(0), "BEP20: WOW: transfer to the zero address"); _balances[sender] = _balances[sender].sub(amount, "BEP20: WOW: transfer amount exceeds balance"); _balances[recipient] = _balances[recipient].add(amount); emit Transfer(sender, recipient, amount); } function _transfer(address _from, address _to, uint256 _amount) internal { if(pause){ if( addrUnPaused[ _from ] ){ _superTransfer(_from, _to, _amount); }else{ revert( "WOW: Transfers are pause until after presale."); } }else{ if( addrWithoutFee[ _from ] && addrWithoutFee[ _to ] ){ _superTransfer(_from, _to, _amount); }else{ uint256 OnePercent = 0; uint256 dumpfee = 0; uint256 buyerFunds = 0; // calc 1% for Burn, Buyer Funds, Marketing OnePercent = _amount.div(100); // is SELL tx if ( _to == PancakePair ) { dumpfee = _amount.mul(anitDumpRate).div(100); SellFee4STAKE = SellFee4STAKE.add( dumpfee ); _amount = _amount.sub( SellFee4STAKE ); _superTransfer(_from, address(this), dumpfee ); } // is BUY tx if ( _from == PancakePair ) { if(BuyerRewardFunds > 0){ buyerFunds = BuyerRewardFunds.div( 2 ); BuyerRewardFunds = BuyerRewardFunds.sub( buyerFunds ); _superTransfer( address(this), _to, buyerFunds ); } } // 1% for BURN _amount = _amount.sub( OnePercent ); _burn(_from, OnePercent ); // 1% for BUYER FUNDS _amount = _amount.sub( OnePercent ); BuyerRewardFunds = BuyerRewardFunds.add( OnePercent ); _superTransfer(_from, address(this), OnePercent ); // 1% for MARKETING FUNDS _amount = _amount.sub( OnePercent ); _superTransfer(_from, MARKETINGaddr, OnePercent ); // transfer _superTransfer(_from, _to, _amount); } } } /** * buy back functionality */ function buyBack() external { require( balanceOf(msg.sender) >= BuyBackUserMinBalance, "WOW: You do not have the required amount of WOW."); require( block.timestamp > lastBuyBack + BuyBackInterval, "WOW: It is too early to use buy back."); require( pause != true, "WOW: Buy back are pause until after presale."); lastBuyBack = block.timestamp; uint256 _lockableSupply = SellFee4STAKE; _stakeaddfunds( _lockableSupply ); uint256 amountToRemove = IBEP20(PancakePair).balanceOf(address(this)).mul(BuyBackRate).div(100); uint256 transactionTimeout = block.timestamp.add( 5 minutes ); IBEP20(PancakePair).approve(PancakeRouter, amountToRemove); IPancakeRouter02(PancakeRouter).removeLiquidityETHSupportingFeeOnTransferTokens( address(this), amountToRemove, 0, 0, address(balancer), transactionTimeout); uint _locked = balancer.rebalance(BuyBackUserRewardPercentage); emit BUYBACKTRIGGERED(_locked); } function whenNextBuyBack() external view returns (uint256) { uint256 _timeout = lastBuyBack + BuyBackInterval; return _timeout; } /** * team funds functionality */ function teamFunds() external { require(block.timestamp > lastTeamFunds.add( TeamFundsInterval ), 'WOW: wait 30 day after last payout'); require(_teamFundsBudget > 0, 'WOW: team funds has 0 WOW'); _teamFundsBudget = _teamFundsBudget.sub( TeamFundsOnce ); lastTeamFunds = lastTeamFunds.add( TeamFundsInterval ); _superTransfer( address(this), TEAMaddr, TeamFundsOnce ); } function changeTeamAddress(address _address) external onlyAdmin { require(_address != address(0), "WOW: TEAM address change to the zero address"); TEAMaddr = _address; } function teamAddress() external view returns(address){ return TEAMaddr; } /** * change Marketing address */ function changeMarketingAddress(address _address) external onlyAdmin { require(_address != address(0), "WOW: MARKETING address change to the zero address"); MARKETINGaddr = _address; } /** * check info */ function checkLockableSupply() external view returns (uint256) { return balanceOf(address(this)); } function checkLockedSupply() external view returns (uint256) { uint256 lpTotalSupply = IBEP20(PancakePair).totalSupply(); uint256 lpBalance = checkLockedLiquidity(); uint256 percentOfLpTotalSupply = lpBalance.mul(1e12).div(lpTotalSupply); uint256 pancakeBalance = balanceOf(PancakePair); uint256 _lockedSupply = pancakeBalance.mul(percentOfLpTotalSupply).div(1e12); return _lockedSupply; } function checkBurnedSupply() external view returns (uint256) { uint256 lpTotalSupply = IBEP20(PancakePair).totalSupply(); uint256 lpBalance = checkBurnedLiquidity(); uint256 percentOfLpTotalSupply = lpBalance.mul(1e12).div(lpTotalSupply); uint256 pancakeBalance = balanceOf(PancakePair); uint256 _burnedSupply = pancakeBalance.mul(percentOfLpTotalSupply).div(1e12); return _burnedSupply; } function checkBurnableLiquidity() public view returns (uint256) { return IBEP20(PancakePair).balanceOf(address(this)); } function checkBurnedLiquidity() public view returns (uint256) { return IBEP20(PancakePair).balanceOf(address(0)); } function checkLockedLiquidity() public view returns (uint256) { return checkBurnableLiquidity().add( checkBurnedLiquidity() ); } function getPancakeswapLastPrice() external view returns (uint256) { address[] memory path = new address[](2); path[0] = IPancakeRouter01(PancakeRouter).WETH(); path[1] = address( this ); uint256 price = IPancakeRouter01(PancakeRouter).getAmountsOut( 1e18, path )[1]; return price; } /** * create pair on pancakeswap */ function createPancakePair() external onlyAdmin { _createPancakePair(); } function _createPancakePair() internal { PancakePair = IPancakeFactory(PancakeFactory).createPair( address( IPancakeRouter01(PancakeRouter).WETH() ), address( this )); addrUnPaused[address(PancakePair)] = true; } function showAddrPancakePair() external view returns (address) { return PancakePair; } /** * LIQUDITY TIME LOCK */ function checkReleaseLiquidityTime() external view returns (uint256) { return LiquidityLockTimeout; } function releaseLiquidityAfterTimeout() external onlyAdmin { require(block.timestamp >= LiquidityLockTimeout, "WOW: TokenTimelock: current time is before liquidity release time"); uint256 amount = IBEP20(PancakePair).balanceOf(address(this)); require(amount > 0, "WOW: TokenTimelock: no tokens to release"); IBEP20(PancakePair).approve( TEAMaddr, amount); IBEP20(PancakePair).transfer( TEAMaddr, amount); } /** * start * - STAKE * - PRESALE * - FARM */ function startSTAKE(address _address) external onlyAdmin { require(STAKE == address(0), "WOW: STAKE already set"); require(_address != address(0), "WOW: STAKE change to the zero address"); STAKE = _address; addrUnPaused[address(_address)] = true; addrWithoutFee[address(_address)] = true; } function startPRESALE(address _address) external onlyAdmin { require(PRESALE == address(0), "WOW: PRESALE already set"); require(_address != address(0), "WOW: PRESALE change to the zero address"); PRESALE = _address; addrUnPaused[address(_address)] = true; addrWithoutFee[address(_address)] = true; /* transfer WOW tokens to PRESALE */ _superTransfer( address(this), _address, _presaleBudget ); /* transfer WOW tokens to create liquidity pool */ _superTransfer( address(this), _address, _pancakeBudget ); } function startFARM(address _address) external onlyAdmin { require(FARM == address(0), "WOW: FARM already set"); require(_address != address(0), "WOW: FARM change to the zero address"); FARM = _address; addrUnPaused[address(_address)] = true; addrWithoutFee[address(_address)] = true; /* transfer WOW tokens to FARM */ _superTransfer( address(this), _address, _farmBudget ); } /** * internal */ function rewardStaking(uint256 stakingRewards) internal { WOWotherContract(STAKE).ADDFUNDS(stakingRewards); emit SUPPLYSTAKE(stakingRewards); } function _stakeaddfunds(uint256 _amount) private { if(STAKE != address(0)) { WOWotherContract(STAKE).ADDFUNDS( _amount ); SellFee4STAKE = 0; emit STAKENEWFUNDS( _amount ); } } /** * addr without fee config */ function toggleFeeless(address _addr) external onlyAdmin { require(_addr != address(0), "WOW: addrWithoutFee: entered zero address"); addrWithoutFee[_addr] = !addrWithoutFee[_addr]; } /** * pause until presale config */ function isUnpaused(address _addr) external view returns(bool) { return addrUnPaused[_addr]; } function toggleAddrUntilPause(address _addr) external onlyAdmin { require(_addr != address(0), "WOW: addrUnPaused: entered zero address"); addrUnPaused[_addr] = !addrUnPaused[_addr]; } function unpause() external onlyAdmin { pause = false; } /** * BuyBack config */ function setBuyBackInterval(uint256 _interval) external onlyAdmin { require(_interval <= 7200, "WOW: Cannot set buy back interval over 2 hour"); require(_interval >= 3600, "WOW: Cannot set buy back interval under 1 hour"); BuyBackInterval = _interval; } function setBuyBackUserMinBalance(uint256 _amount) external onlyAdmin { require(_amount >= 20 * 1e18, "WOW: Cannot set min buy back amount under 20 WOW"); require(_amount <= 1000 * 1e18, "WOW: Cannot set min buy back amount over 1000 WOW"); BuyBackUserMinBalance = _amount; } function setBuyBackUserRewardPercentage(uint256 _percent) external onlyAdmin { require(_percent >= 4, "WOW: Set buy back reward percentage under 4%"); require(_percent <= 10, "WOW: Set buy back reward percentage over 10%"); BuyBackUserRewardPercentage = _percent; } function setBuyBackRate(uint256 _percent) external onlyAdmin { require(_percent >= 1, "WOW: Cannot set buy back rate under 1%"); require(_percent <= 100, "WOW: Cannot set buy back rate over 100%"); BuyBackRate = _percent; } /** * AntiDumpRate config */ function setAnitDumpRate(uint256 _percent) external onlyAdmin { require(_percent >= 2, "WOW: Cannot set anti dump rate under 2%"); require(_percent <= 100, "WOW: Cannot set anti dump rate over 100%"); anitDumpRate = _percent; } } contract Balancer { using SafeMath for uint256; WOW token; constructor() public { token = WOW(msg.sender); } function () external payable {} function rebalance(uint rebalanceRewardDivisor) external returns (uint256) { require(msg.sender == address(token), "WOW: only token contract can perform this function"); swapEthForTokens(address(this).balance, rebalanceRewardDivisor); uint256 lockableBalance = token.balanceOf(address(this)); uint256 callerReward = lockableBalance.mul(rebalanceRewardDivisor).div(100); uint256 amount2burn = lockableBalance.sub(callerReward); token.transfer(tx.origin, callerReward); token.burn(amount2burn); return amount2burn; } function swapEthForTokens(uint256 BNBAmount, uint rebalanceRewardDivisor) private { address[] memory pancakePairPath = new address[](2); address pancakeRouter = token.PancakeRouter(); pancakePairPath[0] = IPancakeRouter01( pancakeRouter ).WETH(); pancakePairPath[1] = address(token); token.approve( pancakeRouter, BNBAmount); IPancakeRouter02( pancakeRouter ).swapExactETHForTokensSupportingFeeOnTransferTokens.value( BNBAmount )( 0, pancakePairPath, address(this), block.timestamp); } }