Transaction Hash:
Block:
11697160 at Jan-21-2021 06:27:15 AM +UTC
Transaction Fee:
0.0017772 ETH
$4.65
Gas Used:
44,430 Gas / 40 Gwei
Emitted Events:
170 |
WiseToken.Approval( owner=[Sender] 0xa5aa529dbc46c4515069e038fe99c93ddc30fb3c, spender=0x7924A6d4...42437E656, value=115792089237316195423570985008687907853269984665640564039457584007913129639935 )
|
Account State Difference:
Address | Before | After | State Difference | ||
---|---|---|---|---|---|
0x66a0f676...78BfF5bd6 | |||||
0xA5AA529d...dDc30fb3C |
0.005267269249693201 Eth
Nonce: 9
|
0.003490069249693201 Eth
Nonce: 10
| 0.0017772 | ||
0xD224cA0c...503B79f53
Miner
| (UUPool) | 622.381555909541108581 Eth | 622.383333109541108581 Eth | 0.0017772 |
Execution Trace
WiseToken.approve( spender=0x7924A6d4d5994cAe4C82481EEE253E342437E656, amount=115792089237316195423570985008687907853269984665640564039457584007913129639935 ) => ( True )
{"Declaration.sol":{"content":"// SPDX-License-Identifier: --🦉--\r\n\r\npragma solidity =0.7.6;\r\n\r\nimport \"./Global.sol\";\r\n\r\ninterface IUniswapV2Factory {\r\n\r\n function createPair(\r\n address tokenA,\r\n address tokenB\r\n ) external returns (\r\n address pair\r\n );\r\n}\r\n\r\ninterface IUniswapRouterV2 {\r\n\r\n function getAmountsOut(\r\n uint amountIn,\r\n address[] calldata path\r\n ) external view returns (\r\n uint[] memory amounts\r\n );\r\n\r\n function swapExactTokensForTokens(\r\n uint amountIn,\r\n uint amountOutMin,\r\n address[] calldata path,\r\n address to,\r\n uint deadline\r\n ) external returns (\r\n uint[] memory amounts\r\n );\r\n\r\n function swapExactETHForTokens(\r\n uint amountOutMin,\r\n address[] calldata path,\r\n address to,\r\n uint deadline\r\n ) external payable returns (\r\n uint[] memory amounts\r\n );\r\n}\r\n\r\ninterface IUniswapV2Pair {\r\n\r\n function getReserves() external view returns (\r\n uint112 reserve0,\r\n uint112 reserve1,\r\n uint32 blockTimestampLast\r\n );\r\n\r\n function token1() external view returns (address);\r\n}\r\n\r\ninterface ILiquidityGuard {\r\n function getInflation(uint32 _amount) external view returns (uint256);\r\n}\r\n\r\ninterface ERC20TokenI {\r\n\r\n function transferFrom(\r\n address _from,\r\n address _to,\r\n uint256 _value\r\n ) external returns (\r\n bool success\r\n );\r\n\r\n function approve(\r\n address _spender,\r\n uint256 _value\r\n ) external returns (\r\n bool success\r\n );\r\n}\r\n\r\nabstract contract Declaration is Global {\r\n\r\n uint256 constant _decimals = 18;\r\n uint256 constant YODAS_PER_WISE = 10 ** _decimals;\r\n\r\n uint32 constant SECONDS_IN_DAY = 86400 seconds;\r\n uint16 constant MIN_LOCK_DAYS = 1;\r\n uint16 constant FORMULA_DAY = 65;\r\n uint16 constant MAX_LOCK_DAYS = 15330; // 42 years\r\n uint16 constant MAX_BONUS_DAYS_A = 1825; // 5 years\r\n uint16 constant MAX_BONUS_DAYS_B = 13505; // 37 years\r\n uint16 constant MIN_REFERRAL_DAYS = 365;\r\n\r\n uint32 constant MIN_STAKE_AMOUNT = 1000000;\r\n uint32 constant REFERRALS_RATE = 366816973; // 1.000% (direct value, can be used right away)\r\n uint32 constant INFLATION_RATE_MAX = 103000; // 3.000% (indirect -\u003e checks throgh LiquidityGuard)\r\n\r\n uint32 public INFLATION_RATE = 103000; // 3.000% (indirect -\u003e checks throgh LiquidityGuard)\r\n uint32 public LIQUIDITY_RATE = 100006; // 0.006% (indirect -\u003e checks throgh LiquidityGuard)\r\n\r\n uint64 constant PRECISION_RATE = 1E18;\r\n\r\n uint96 constant THRESHOLD_LIMIT = 10000E18; // $10,000 DAI\r\n\r\n uint96 constant DAILY_BONUS_A = 13698630136986302; // 25%:1825 = 0.01369863013 per day;\r\n uint96 constant DAILY_BONUS_B = 370233246945576; // 5%:13505 = 0.00037023324 per day;\r\n\r\n uint256 immutable LAUNCH_TIME;\r\n\r\n address constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F;\r\n address constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;\r\n\r\n IUniswapRouterV2 public constant UNISWAP_ROUTER = IUniswapRouterV2(\r\n 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D\r\n );\r\n\r\n IUniswapV2Factory public constant UNISWAP_FACTORY = IUniswapV2Factory(\r\n 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f\r\n );\r\n\r\n ILiquidityGuard public constant LIQUIDITY_GUARD = ILiquidityGuard(\r\n 0x9C306CaD86550EC80D77668c0A8bEE6eB34684B6\r\n );\r\n\r\n IUniswapV2Pair public UNISWAP_PAIR;\r\n bool public isLiquidityGuardActive;\r\n\r\n uint256 public latestDaiEquivalent;\r\n address[] internal _path = [address(this), WETH, DAI];\r\n\r\n constructor() {\r\n LAUNCH_TIME = 1604966400; // (10th November 2020 @00:00 GMT == day 0)\r\n }\r\n\r\n function createPair() external {\r\n UNISWAP_PAIR = IUniswapV2Pair(\r\n UNISWAP_FACTORY.createPair(\r\n WETH, address(this)\r\n )\r\n );\r\n }\r\n\r\n struct Stake {\r\n uint256 stakesShares;\r\n uint256 stakedAmount;\r\n uint256 rewardAmount;\r\n uint64 startDay;\r\n uint64 lockDays;\r\n uint64 finalDay;\r\n uint64 closeDay;\r\n uint256 scrapeDay;\r\n uint256 daiEquivalent;\r\n uint256 referrerShares;\r\n address referrer;\r\n bool isActive;\r\n }\r\n\r\n struct ReferrerLink {\r\n address staker;\r\n bytes16 stakeID;\r\n uint256 rewardAmount;\r\n uint256 processedDays;\r\n bool isActive;\r\n }\r\n\r\n struct LiquidityStake {\r\n uint256 stakedAmount;\r\n uint256 rewardAmount;\r\n uint64 startDay;\r\n uint64 closeDay;\r\n bool isActive;\r\n }\r\n\r\n struct CriticalMass {\r\n uint256 totalAmount;\r\n uint256 activationDay;\r\n }\r\n\r\n mapping(address =\u003e uint256) public stakeCount;\r\n mapping(address =\u003e uint256) public referralCount;\r\n mapping(address =\u003e uint256) public liquidityStakeCount;\r\n\r\n mapping(address =\u003e CriticalMass) public criticalMass;\r\n mapping(address =\u003e mapping(bytes16 =\u003e uint256)) public scrapes;\r\n mapping(address =\u003e mapping(bytes16 =\u003e Stake)) public stakes;\r\n mapping(address =\u003e mapping(bytes16 =\u003e ReferrerLink)) public referrerLinks;\r\n mapping(address =\u003e mapping(bytes16 =\u003e LiquidityStake)) public liquidityStakes;\r\n\r\n mapping(uint256 =\u003e uint256) public scheduledToEnd;\r\n mapping(uint256 =\u003e uint256) public referralSharesToEnd;\r\n mapping(uint256 =\u003e uint256) public totalPenalties;\r\n}\r\n"},"ERC20.sol":{"content":"// SPDX-License-Identifier: --🦉--\r\n\r\npragma solidity =0.7.6;\r\n\r\ncontract Context {\r\n\r\n /**\r\n * @dev returns address executing the method\r\n */\r\n function _msgSender() internal view virtual returns (address payable) {\r\n return msg.sender;\r\n }\r\n\r\n /**\r\n * @dev returns data passed into the method\r\n */\r\n function _msgData() internal view virtual returns (bytes memory) {\r\n this;\r\n return msg.data;\r\n }\r\n}\r\n\r\ncontract ERC20 is Context {\r\n\r\n using SafeMath for uint256;\r\n\r\n mapping (address =\u003e uint256) private _balances;\r\n mapping (address =\u003e mapping (address =\u003e uint256)) private _allowances;\r\n\r\n /**\r\n * @dev initial private\r\n */\r\n string private _name;\r\n string private _symbol;\r\n uint8 private _decimals;\r\n\r\n /**\r\n * @dev 👻 ghost supply - unclaimable\r\n */\r\n uint256 private _totalSupply = 0.404 ether;\r\n\r\n event Transfer(\r\n address indexed from,\r\n address indexed to,\r\n uint256 value\r\n );\r\n\r\n event Approval(\r\n address indexed owner,\r\n address indexed spender,\r\n uint256 value\r\n );\r\n\r\n constructor (string memory tokenName, string memory tokenSymbol) {\r\n _name = tokenName;\r\n _symbol = tokenSymbol;\r\n _decimals = 18;\r\n }\r\n\r\n /**\r\n * @dev Returns the name of the token.\r\n */\r\n function name() public view returns (string memory) {\r\n return _name;\r\n }\r\n\r\n /**\r\n * @dev Returns the symbol of the token.\r\n */\r\n function symbol() public view returns (string memory) {\r\n return _symbol;\r\n }\r\n\r\n /**\r\n * @dev Returns the decimals of the token.\r\n */\r\n function decimals() public view returns (uint8) {\r\n return _decimals;\r\n }\r\n\r\n /**\r\n * @dev Returns the total supply of the token.\r\n */\r\n function totalSupply() public view returns (uint256) {\r\n return _totalSupply;\r\n }\r\n\r\n /**\r\n * @dev Returns the token balance of specific address.\r\n */\r\n function balanceOf(address account) public view returns (uint256) {\r\n return _balances[account];\r\n }\r\n\r\n function transfer(\r\n address recipient,\r\n uint256 amount\r\n )\r\n public\r\n returns (bool)\r\n {\r\n _transfer(\r\n _msgSender(),\r\n recipient,\r\n amount\r\n );\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * @dev Returns approved balance to be spent by another address\r\n * by using transferFrom method\r\n */\r\n function allowance(\r\n address owner,\r\n address spender\r\n )\r\n public\r\n view\r\n returns (uint256)\r\n {\r\n return _allowances[owner][spender];\r\n }\r\n\r\n /**\r\n * @dev Sets the token allowance to another spender\r\n */\r\n function approve(\r\n address spender,\r\n uint256 amount\r\n )\r\n public\r\n returns (bool)\r\n {\r\n _approve(\r\n _msgSender(),\r\n spender,\r\n amount\r\n );\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * @dev Allows to transfer tokens on senders behalf\r\n * based on allowance approved for the executer\r\n */\r\n function transferFrom(\r\n address sender,\r\n address recipient,\r\n uint256 amount\r\n )\r\n public\r\n returns (bool)\r\n {\r\n _approve(sender,\r\n _msgSender(), _allowances[sender][_msgSender()].sub(\r\n amount\r\n )\r\n );\r\n\r\n _transfer(\r\n sender,\r\n recipient,\r\n amount\r\n );\r\n return true;\r\n }\r\n\r\n /**\r\n * @dev Moves tokens `amount` from `sender` to `recipient`.\r\n *\r\n * Emits a {Transfer} event.\r\n * Requirements:\r\n *\r\n * - `sender` cannot be the zero address.\r\n * - `recipient` cannot be the zero address.\r\n * - `sender` must have a balance of at least `amount`.\r\n */\r\n function _transfer(\r\n address sender,\r\n address recipient,\r\n uint256 amount\r\n )\r\n internal\r\n virtual\r\n {\r\n require(\r\n sender != address(0x0)\r\n );\r\n\r\n require(\r\n recipient != address(0x0)\r\n );\r\n\r\n _balances[sender] =\r\n _balances[sender].sub(amount);\r\n\r\n _balances[recipient] =\r\n _balances[recipient].add(amount);\r\n\r\n emit Transfer(\r\n sender,\r\n recipient,\r\n amount\r\n );\r\n }\r\n\r\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\r\n * the total supply.\r\n *\r\n * Emits a {Transfer} event with `from` set to the zero address.\r\n * Requirements:\r\n *\r\n * - `to` cannot be the zero address.\r\n */\r\n function _mint(\r\n address account,\r\n uint256 amount\r\n )\r\n internal\r\n virtual\r\n {\r\n require(\r\n account != address(0x0)\r\n );\r\n\r\n _totalSupply =\r\n _totalSupply.add(amount);\r\n\r\n _balances[account] =\r\n _balances[account].add(amount);\r\n\r\n emit Transfer(\r\n address(0x0),\r\n account,\r\n amount\r\n );\r\n }\r\n\r\n /**\r\n * @dev Allows to burn tokens if token sender\r\n * wants to reduce totalSupply() of the token\r\n */\r\n function burn(\r\n uint256 amount\r\n )\r\n external\r\n {\r\n _burn(msg.sender, amount);\r\n }\r\n\r\n /**\r\n * @dev Destroys `amount` tokens from `account`, reducing the\r\n * total supply.\r\n *\r\n * Emits a {Transfer} event with `to` set to the zero address.\r\n *\r\n * Requirements:\r\n *\r\n * - `account` cannot be the zero address.\r\n * - `account` must have at least `amount` tokens.\r\n */\r\n function _burn(\r\n address account,\r\n uint256 amount\r\n )\r\n internal\r\n virtual\r\n {\r\n require(\r\n account != address(0x0)\r\n );\r\n\r\n _balances[account] =\r\n _balances[account].sub(amount);\r\n\r\n _totalSupply =\r\n _totalSupply.sub(amount);\r\n\r\n emit Transfer(\r\n account,\r\n address(0x0),\r\n amount\r\n );\r\n }\r\n\r\n /**\r\n * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.\r\n * Emits an {Approval} event.\r\n *\r\n * Requirements:\r\n *\r\n * - `owner` cannot be the zero address.\r\n * - `spender` cannot be the zero address.\r\n */\r\n function _approve(\r\n address owner,\r\n address spender,\r\n uint256 amount\r\n )\r\n internal\r\n virtual\r\n {\r\n require(\r\n owner != address(0x0)\r\n );\r\n\r\n require(\r\n spender != address(0x0)\r\n );\r\n\r\n _allowances[owner][spender] = amount;\r\n\r\n emit Approval(\r\n owner,\r\n spender,\r\n amount\r\n );\r\n }\r\n}\r\n\r\nimport \"./SafeMath.sol\";\r\n"},"Events.sol":{"content":"// SPDX-License-Identifier: --🦉--\r\n\r\npragma solidity =0.7.6;\r\n\r\ncontract Events {\r\n\r\n event StakeStart(\r\n bytes16 indexed stakeID,\r\n address indexed stakerAddress,\r\n address indexed referralAddress,\r\n uint256 stakedAmount,\r\n uint256 stakesShares,\r\n uint256 referralShares,\r\n uint256 startDay,\r\n uint256 lockDays,\r\n uint256 daiEquivalent\r\n );\r\n\r\n event StakeEnd(\r\n bytes16 indexed stakeID,\r\n address indexed stakerAddress,\r\n address indexed referralAddress,\r\n uint256 stakedAmount,\r\n uint256 stakesShares,\r\n uint256 referralShares,\r\n uint256 rewardAmount,\r\n uint256 closeDay,\r\n uint256 penaltyAmount\r\n );\r\n\r\n event InterestScraped(\r\n bytes16 indexed stakeID,\r\n address indexed stakerAddress,\r\n uint256 scrapeAmount,\r\n uint256 scrapeDay,\r\n uint256 stakersPenalty,\r\n uint256 referrerPenalty,\r\n uint256 currentWiseDay\r\n );\r\n\r\n event ReferralCollected(\r\n address indexed staker,\r\n bytes16 indexed stakeID,\r\n address indexed referrer,\r\n bytes16 referrerID,\r\n uint256 rewardAmount\r\n );\r\n\r\n event NewGlobals(\r\n uint256 totalShares,\r\n uint256 totalStaked,\r\n uint256 shareRate,\r\n uint256 referrerShares,\r\n uint256 indexed currentWiseDay\r\n );\r\n\r\n event NewSharePrice(\r\n uint256 newSharePrice,\r\n uint256 oldSharePrice,\r\n uint64 currentWiseDay\r\n );\r\n\r\n event UniswapReserves(\r\n uint112 reserveA,\r\n uint112 reserveB,\r\n uint32 blockTimestampLast\r\n );\r\n\r\n event LiquidityGuardStatus(\r\n bool isActive\r\n );\r\n}"},"Global.sol":{"content":"// SPDX-License-Identifier: --🦉--\r\n\r\npragma solidity =0.7.6;\r\n\r\nimport \"./ERC20.sol\";\r\nimport \"./Events.sol\";\r\n\r\nabstract contract Global is ERC20, Events {\r\n\r\n using SafeMath for uint256;\r\n\r\n struct Globals {\r\n uint256 totalStaked;\r\n uint256 totalShares;\r\n uint256 sharePrice;\r\n uint256 currentWiseDay;\r\n uint256 referralShares;\r\n uint256 liquidityShares;\r\n }\r\n\r\n Globals public globals;\r\n\r\n constructor() {\r\n globals.sharePrice = 100E15;\r\n }\r\n\r\n function _increaseGlobals(\r\n uint256 _staked,\r\n uint256 _shares,\r\n uint256 _rshares\r\n )\r\n internal\r\n {\r\n globals.totalStaked =\r\n globals.totalStaked.add(_staked);\r\n\r\n globals.totalShares =\r\n globals.totalShares.add(_shares);\r\n\r\n if (_rshares \u003e 0) {\r\n\r\n globals.referralShares =\r\n globals.referralShares.add(_rshares);\r\n }\r\n\r\n _logGlobals();\r\n }\r\n\r\n function _decreaseGlobals(\r\n uint256 _staked,\r\n uint256 _shares,\r\n uint256 _rshares\r\n )\r\n internal\r\n {\r\n globals.totalStaked =\r\n globals.totalStaked \u003e _staked ?\r\n globals.totalStaked - _staked : 0;\r\n\r\n globals.totalShares =\r\n globals.totalShares \u003e _shares ?\r\n globals.totalShares - _shares : 0;\r\n\r\n if (_rshares \u003e 0) {\r\n\r\n globals.referralShares =\r\n globals.referralShares \u003e _rshares ?\r\n globals.referralShares - _rshares : 0;\r\n\r\n }\r\n\r\n _logGlobals();\r\n }\r\n\r\n function _logGlobals()\r\n private\r\n {\r\n emit NewGlobals(\r\n globals.totalShares,\r\n globals.totalStaked,\r\n globals.sharePrice,\r\n globals.referralShares,\r\n globals.currentWiseDay\r\n );\r\n }\r\n}"},"Helper.sol":{"content":"// SPDX-License-Identifier: --🦉--\r\n\r\npragma solidity =0.7.6;\r\n\r\nimport \"./Timing.sol\";\r\n\r\nabstract contract Helper is Timing {\r\n\r\n using SafeMath for uint256;\r\n\r\n function notContract(address _addr) internal view returns (bool) {\r\n uint32 size;\r\n assembly {\r\n size := extcodesize(_addr)\r\n }\r\n return (size == 0);\r\n }\r\n\r\n function toBytes16(uint256 x) internal pure returns (bytes16 b) {\r\n return bytes16(bytes32(x));\r\n }\r\n\r\n function generateID(address x, uint256 y, bytes1 z) public pure returns (bytes16 b) {\r\n b = toBytes16(\r\n uint256(\r\n keccak256(\r\n abi.encodePacked(x, y, z)\r\n )\r\n )\r\n );\r\n }\r\n\r\n function generateStakeID(address _staker) internal view returns (bytes16 stakeID) {\r\n return generateID(_staker, stakeCount[_staker], 0x01);\r\n }\r\n\r\n function generateReferralID(address _referrer) internal view returns (bytes16 referralID) {\r\n return generateID(_referrer, referralCount[_referrer], 0x02);\r\n }\r\n\r\n function generateLiquidityStakeID(address _staker) internal view returns (bytes16 liquidityStakeID) {\r\n return generateID(_staker, liquidityStakeCount[_staker], 0x03);\r\n }\r\n\r\n function stakesPagination(\r\n address _staker,\r\n uint256 _offset,\r\n uint256 _length\r\n )\r\n external\r\n view\r\n returns (bytes16[] memory _stakes)\r\n {\r\n uint256 start = _offset \u003e 0 \u0026\u0026\r\n stakeCount[_staker] \u003e _offset ?\r\n stakeCount[_staker] - _offset : stakeCount[_staker];\r\n\r\n uint256 finish = _length \u003e 0 \u0026\u0026\r\n start \u003e _length ?\r\n start - _length : 0;\r\n\r\n uint256 i;\r\n\r\n _stakes = new bytes16[](start - finish);\r\n\r\n for (uint256 _stakeIndex = start; _stakeIndex \u003e finish; _stakeIndex--) {\r\n bytes16 _stakeID = generateID(_staker, _stakeIndex - 1, 0x01);\r\n if (stakes[_staker][_stakeID].stakedAmount \u003e 0) {\r\n _stakes[i] = _stakeID; i++;\r\n }\r\n }\r\n }\r\n\r\n function referralsPagination(\r\n address _referrer,\r\n uint256 _offset,\r\n uint256 _length\r\n )\r\n external\r\n view\r\n returns (bytes16[] memory _referrals)\r\n {\r\n uint256 start = _offset \u003e 0 \u0026\u0026\r\n referralCount[_referrer] \u003e _offset ?\r\n referralCount[_referrer] - _offset : referralCount[_referrer];\r\n\r\n uint256 finish = _length \u003e 0 \u0026\u0026\r\n start \u003e _length ?\r\n start - _length : 0;\r\n\r\n uint256 i;\r\n\r\n _referrals = new bytes16[](start - finish);\r\n\r\n for (uint256 _rIndex = start; _rIndex \u003e finish; _rIndex--) {\r\n bytes16 _rID = generateID(_referrer, _rIndex - 1, 0x02);\r\n if (_nonZeroAddress(referrerLinks[_referrer][_rID].staker)) {\r\n _referrals[i] = _rID; i++;\r\n }\r\n }\r\n }\r\n\r\n function latestStakeID(address _staker) external view returns (bytes16) {\r\n return stakeCount[_staker] == 0 ? bytes16(0) : generateID(_staker, stakeCount[_staker].sub(1), 0x01);\r\n }\r\n\r\n function latestReferralID(address _referrer) external view returns (bytes16) {\r\n return referralCount[_referrer] == 0 ? bytes16(0) : generateID(_referrer, referralCount[_referrer].sub(1), 0x02);\r\n }\r\n\r\n function latestLiquidityStakeID(address _staker) external view returns (bytes16) {\r\n return liquidityStakeCount[_staker] == 0 ? bytes16(0) : generateID(_staker, liquidityStakeCount[_staker].sub(1), 0x03);\r\n }\r\n\r\n function _increaseStakeCount(address _staker) internal {\r\n stakeCount[_staker] = stakeCount[_staker] + 1;\r\n }\r\n\r\n function _increaseReferralCount(address _referrer) internal {\r\n referralCount[_referrer] = referralCount[_referrer] + 1;\r\n }\r\n\r\n function _increaseLiquidityStakeCount(address _staker) internal {\r\n liquidityStakeCount[_staker] = liquidityStakeCount[_staker] + 1;\r\n }\r\n\r\n function _isMatureStake(Stake memory _stake) internal view returns (bool) {\r\n return _stake.closeDay \u003e 0\r\n ? _stake.finalDay \u003c= _stake.closeDay\r\n : _stake.finalDay \u003c= _currentWiseDay();\r\n }\r\n\r\n function _notCriticalMassReferrer(address _referrer) internal view returns (bool) {\r\n return criticalMass[_referrer].activationDay == 0;\r\n }\r\n\r\n function _stakeNotStarted(Stake memory _stake) internal view returns (bool) {\r\n return _stake.closeDay \u003e 0\r\n ? _stake.startDay \u003e _stake.closeDay\r\n : _stake.startDay \u003e _currentWiseDay();\r\n }\r\n\r\n function _stakeEnded(Stake memory _stake) internal view returns (bool) {\r\n return _stake.isActive == false || _isMatureStake(_stake);\r\n }\r\n\r\n function _daysLeft(Stake memory _stake) internal view returns (uint256) {\r\n return _stake.isActive == false\r\n ? _daysDiff(_stake.closeDay, _stake.finalDay)\r\n : _daysDiff(_currentWiseDay(), _stake.finalDay);\r\n }\r\n\r\n function _daysDiff(uint256 _startDate, uint256 _endDate) internal pure returns (uint256) {\r\n return _startDate \u003e _endDate ? 0 : _endDate.sub(_startDate);\r\n }\r\n\r\n function _calculationDay(Stake memory _stake) internal view returns (uint256) {\r\n return _stake.finalDay \u003e globals.currentWiseDay ? globals.currentWiseDay : _stake.finalDay;\r\n }\r\n\r\n function _startingDay(Stake memory _stake) internal pure returns (uint256) {\r\n return _stake.scrapeDay == 0 ? _stake.startDay : _stake.scrapeDay;\r\n }\r\n\r\n function _notFuture(uint256 _day) internal view returns (bool) {\r\n return _day \u003c= _currentWiseDay();\r\n }\r\n\r\n function _notPast(uint256 _day) internal view returns (bool) {\r\n return _day \u003e= _currentWiseDay();\r\n }\r\n\r\n function _nonZeroAddress(address _address) internal pure returns (bool) {\r\n return _address != address(0x0);\r\n }\r\n\r\n function _getLockDays(Stake memory _stake) internal pure returns (uint256) {\r\n return\r\n _stake.lockDays \u003e 1 ?\r\n _stake.lockDays - 1 : 1;\r\n }\r\n\r\n function _preparePath(\r\n address _tokenAddress,\r\n address _wiseAddress\r\n )\r\n internal\r\n pure\r\n returns (address[] memory _path)\r\n {\r\n _path = new address[](3);\r\n _path[0] = _tokenAddress;\r\n _path[1] = WETH;\r\n _path[2] = _wiseAddress;\r\n }\r\n\r\n function safeTransfer(\r\n address token,\r\n address to,\r\n uint256 value\r\n )\r\n internal\r\n {\r\n (bool success, bytes memory data) = token.call(\r\n abi.encodeWithSelector(\r\n 0xa9059cbb,\r\n to,\r\n value\r\n )\r\n );\r\n\r\n require(\r\n success \u0026\u0026 (data.length == 0 || abi.decode(data, (bool)))\r\n // \u0027WISE: transfer failed\u0027\r\n );\r\n }\r\n\r\n function safeTransferFrom(\r\n address token,\r\n address from,\r\n address to,\r\n uint value\r\n )\r\n internal\r\n {\r\n (bool success, bytes memory data) = token.call(\r\n abi.encodeWithSelector(\r\n 0x23b872dd,\r\n from,\r\n to,\r\n value\r\n )\r\n );\r\n\r\n require(\r\n success \u0026\u0026 (data.length == 0 || abi.decode(data, (bool)))\r\n // \u0027WISE: transferFrom failed\u0027\r\n );\r\n }\r\n}"},"LiquidityToken.sol":{"content":"// SPDX-License-Identifier: --🦉--\r\n\r\npragma solidity =0.7.6;\r\n\r\nimport \"./StakingToken.sol\";\r\n\r\nabstract contract LiquidityToken is StakingToken {\r\n\r\n using SafeMath for uint;\r\n\r\n /**\r\n * @notice A method for a staker to create a liquidity stake\r\n * @param _liquidityTokens amount of UNI-WISE staked.\r\n */\r\n function createLiquidityStake(\r\n uint256 _liquidityTokens\r\n )\r\n snapshotTrigger\r\n external\r\n returns (bytes16 liquidityStakeID)\r\n {\r\n require(\r\n isLiquidityGuardActive == true\r\n // WISE: LiquidityGuard is not active\r\n );\r\n\r\n safeTransferFrom(\r\n address(UNISWAP_PAIR),\r\n msg.sender,\r\n address(this),\r\n _liquidityTokens\r\n );\r\n\r\n LiquidityStake memory newLiquidityStake;\r\n\r\n liquidityStakeID = generateLiquidityStakeID(\r\n msg.sender\r\n );\r\n\r\n newLiquidityStake.startDay = _nextWiseDay();\r\n newLiquidityStake.stakedAmount = _liquidityTokens;\r\n newLiquidityStake.isActive = true;\r\n\r\n globals.liquidityShares =\r\n globals.liquidityShares.add(_liquidityTokens);\r\n\r\n liquidityStakes[msg.sender][liquidityStakeID] = newLiquidityStake;\r\n\r\n _increaseLiquidityStakeCount(\r\n msg.sender\r\n );\r\n }\r\n\r\n /**\r\n * @notice A method for a staker to end a liquidity stake\r\n * @param _liquidityStakeID - identification number\r\n */\r\n function endLiquidityStake(\r\n bytes16 _liquidityStakeID\r\n )\r\n snapshotTrigger\r\n external\r\n returns (uint256)\r\n {\r\n LiquidityStake memory liquidityStake =\r\n liquidityStakes[msg.sender][_liquidityStakeID];\r\n\r\n require(\r\n liquidityStake.isActive\r\n // \u0027WISE: not an active stake\u0027\r\n );\r\n\r\n liquidityStake.isActive = false;\r\n liquidityStake.closeDay = _currentWiseDay();\r\n\r\n liquidityStake.rewardAmount = _calculateRewardAmount(\r\n liquidityStake\r\n );\r\n\r\n _mint(\r\n msg.sender,\r\n liquidityStake.rewardAmount\r\n );\r\n\r\n safeTransfer(\r\n address(UNISWAP_PAIR),\r\n msg.sender,\r\n liquidityStake.stakedAmount\r\n );\r\n\r\n globals.liquidityShares =\r\n globals.liquidityShares.sub(liquidityStake.stakedAmount);\r\n\r\n liquidityStakes[msg.sender][_liquidityStakeID] = liquidityStake;\r\n\r\n return liquidityStake.rewardAmount;\r\n }\r\n\r\n /**\r\n * @notice returns full view and details of\r\n * a liquidity stake belonging to caller\r\n * @param _liquidityStakeID - stakeID\r\n */\r\n function checkLiquidityStakeByID(\r\n address _staker,\r\n bytes16 _liquidityStakeID\r\n )\r\n external\r\n view\r\n returns (\r\n uint256 startDay,\r\n uint256 stakedAmount,\r\n uint256 rewardAmount,\r\n uint256 closeDay,\r\n bool isActive\r\n )\r\n {\r\n LiquidityStake memory stake = liquidityStakes[_staker][_liquidityStakeID];\r\n startDay = stake.startDay;\r\n stakedAmount = stake.stakedAmount;\r\n rewardAmount = _calculateRewardAmount(stake);\r\n closeDay = stake.closeDay;\r\n isActive = stake.isActive;\r\n }\r\n\r\n /**\r\n * @notice calculates reward when closing liquidity stake\r\n * @param _liquidityStake - stake instance\r\n */\r\n function _calculateRewardAmount(\r\n LiquidityStake memory _liquidityStake\r\n )\r\n private\r\n view\r\n returns (uint256 _rewardAmount)\r\n {\r\n uint256 maxCalculationDay = _liquidityStake.startDay + MIN_REFERRAL_DAYS;\r\n\r\n uint256 calculationDay =\r\n globals.currentWiseDay \u003c maxCalculationDay ?\r\n globals.currentWiseDay : maxCalculationDay;\r\n\r\n for (uint256 _day = _liquidityStake.startDay; _day \u003c calculationDay; _day++) {\r\n _rewardAmount += _liquidityStake.stakedAmount * PRECISION_RATE / lsnapshots[_day].inflationAmount;\r\n }\r\n }\r\n}"},"ReferralToken.sol":{"content":"// SPDX-License-Identifier: --🦉--\r\n\r\npragma solidity =0.7.6;\r\n\r\nimport \"./Snapshot.sol\";\r\n\r\nabstract contract ReferralToken is Snapshot {\r\n\r\n using SafeMath for uint256;\r\n\r\n function _addReferrerSharesToEnd(\r\n uint256 _finalDay,\r\n uint256 _shares\r\n )\r\n internal\r\n {\r\n referralSharesToEnd[_finalDay] =\r\n referralSharesToEnd[_finalDay].add(_shares);\r\n }\r\n\r\n function _removeReferrerSharesToEnd(\r\n uint256 _finalDay,\r\n uint256 _shares\r\n )\r\n internal\r\n {\r\n if (_notPast(_finalDay)) {\r\n\r\n referralSharesToEnd[_finalDay] =\r\n referralSharesToEnd[_finalDay] \u003e _shares ?\r\n referralSharesToEnd[_finalDay] - _shares : 0;\r\n\r\n } else {\r\n\r\n uint256 _day = _previousWiseDay();\r\n rsnapshots[_day].scheduledToEnd =\r\n rsnapshots[_day].scheduledToEnd \u003e _shares ?\r\n rsnapshots[_day].scheduledToEnd - _shares : 0;\r\n }\r\n }\r\n\r\n function _belowThresholdLevel(\r\n address _referrer\r\n )\r\n private\r\n view\r\n returns (bool)\r\n {\r\n return criticalMass[_referrer].totalAmount \u003c THRESHOLD_LIMIT;\r\n }\r\n\r\n function _addCriticalMass(\r\n address _referrer,\r\n uint256 _daiEquivalent\r\n )\r\n internal\r\n {\r\n criticalMass[_referrer].totalAmount =\r\n criticalMass[_referrer].totalAmount.add(_daiEquivalent);\r\n criticalMass[_referrer].activationDay = _determineActivationDay(_referrer);\r\n }\r\n\r\n function _removeCriticalMass(\r\n address _referrer,\r\n uint256 _daiEquivalent,\r\n uint256 _startDay\r\n )\r\n internal\r\n {\r\n if (\r\n _notFuture(_startDay) == false \u0026\u0026\r\n _nonZeroAddress(_referrer)\r\n ) {\r\n criticalMass[_referrer].totalAmount =\r\n criticalMass[_referrer].totalAmount \u003e _daiEquivalent ?\r\n criticalMass[_referrer].totalAmount - _daiEquivalent : 0;\r\n criticalMass[_referrer].activationDay = _determineActivationDay(_referrer);\r\n }\r\n }\r\n\r\n function _determineActivationDay(\r\n address _referrer\r\n )\r\n private\r\n view\r\n returns (uint256)\r\n {\r\n return _belowThresholdLevel(_referrer) ? 0 : _activationDay(_referrer);\r\n }\r\n\r\n function _activationDay(\r\n address _referrer\r\n )\r\n private\r\n view\r\n returns (uint256)\r\n {\r\n return\r\n criticalMass[_referrer].activationDay \u003e 0 ?\r\n criticalMass[_referrer].activationDay : _currentWiseDay();\r\n }\r\n\r\n function _updateDaiEquivalent()\r\n internal\r\n returns (uint256)\r\n {\r\n try UNISWAP_ROUTER.getAmountsOut(\r\n YODAS_PER_WISE, _path\r\n ) returns (uint256[] memory results) {\r\n latestDaiEquivalent = results[2];\r\n return latestDaiEquivalent;\r\n } catch Error(string memory) {\r\n return latestDaiEquivalent;\r\n } catch (bytes memory) {\r\n return latestDaiEquivalent;\r\n }\r\n }\r\n\r\n function referrerInterest(\r\n bytes16 _referralID,\r\n uint256 _scrapeDays\r\n )\r\n external\r\n snapshotTrigger\r\n {\r\n _referrerInterest(\r\n msg.sender,\r\n _referralID,\r\n _scrapeDays\r\n );\r\n }\r\n\r\n function referrerInterestBulk(\r\n bytes16[] memory _referralIDs,\r\n uint256[] memory _scrapeDays\r\n )\r\n external\r\n snapshotTrigger\r\n {\r\n for(uint256 i = 0; i \u003c _referralIDs.length; i++) {\r\n _referrerInterest(\r\n msg.sender,\r\n _referralIDs[i],\r\n _scrapeDays[i]\r\n );\r\n }\r\n }\r\n\r\n function _referrerInterest(\r\n address _referrer,\r\n bytes16 _referralID,\r\n uint256 _processDays\r\n )\r\n internal\r\n {\r\n ReferrerLink memory link =\r\n referrerLinks[_referrer][_referralID];\r\n\r\n require(\r\n link.isActive == true\r\n );\r\n\r\n address staker = link.staker;\r\n bytes16 stakeID = link.stakeID;\r\n\r\n Stake memory stake = stakes[staker][stakeID];\r\n\r\n uint256 startDay = _determineStartDay(stake, link);\r\n uint256 finalDay = _determineFinalDay(stake);\r\n\r\n if (_stakeEnded(stake)) {\r\n\r\n if (\r\n _processDays \u003e 0 \u0026\u0026\r\n _processDays \u003c _daysDiff(startDay, finalDay)\r\n )\r\n {\r\n\r\n link.processedDays =\r\n link.processedDays.add(_processDays);\r\n\r\n finalDay =\r\n startDay.add(_processDays);\r\n\r\n } else {\r\n\r\n link.isActive = false;\r\n }\r\n\r\n } else {\r\n\r\n _processDays = _daysDiff(startDay, _currentWiseDay());\r\n\r\n link.processedDays =\r\n link.processedDays.add(_processDays);\r\n\r\n finalDay =\r\n startDay.add(_processDays);\r\n }\r\n\r\n uint256 referralInterest = _checkReferralInterest(\r\n stake,\r\n startDay,\r\n finalDay\r\n );\r\n\r\n link.rewardAmount =\r\n link.rewardAmount.add(referralInterest);\r\n\r\n referrerLinks[_referrer][_referralID] = link;\r\n\r\n _mint(\r\n _referrer,\r\n referralInterest\r\n );\r\n\r\n emit ReferralCollected(\r\n staker,\r\n stakeID,\r\n _referrer,\r\n _referralID,\r\n referralInterest\r\n );\r\n }\r\n\r\n function checkReferralsByID(\r\n address _referrer,\r\n bytes16 _referralID\r\n )\r\n external\r\n view\r\n returns (\r\n address staker,\r\n bytes16 stakeID,\r\n uint256 referrerShares,\r\n uint256 referralInterest,\r\n bool isActiveReferral,\r\n bool isActiveStake,\r\n bool isMatureStake,\r\n bool isEndedStake\r\n )\r\n {\r\n ReferrerLink memory link = referrerLinks[_referrer][_referralID];\r\n\r\n staker = link.staker;\r\n stakeID = link.stakeID;\r\n isActiveReferral = link.isActive;\r\n\r\n Stake memory stake = stakes[staker][stakeID];\r\n referrerShares = stake.referrerShares;\r\n\r\n referralInterest = _checkReferralInterest(\r\n stake,\r\n _determineStartDay(stake, link),\r\n _determineFinalDay(stake)\r\n );\r\n\r\n isActiveStake = stake.isActive;\r\n isEndedStake = _stakeEnded(stake);\r\n isMatureStake = _isMatureStake(stake);\r\n }\r\n\r\n function _checkReferralInterest(Stake memory _stake, uint256 _startDay, uint256 _finalDay) internal view returns (uint256 _referralInterest) {\r\n return _notCriticalMassReferrer(_stake.referrer) ? 0 : _getReferralInterest(_stake, _startDay, _finalDay);\r\n }\r\n\r\n function _getReferralInterest(Stake memory _stake, uint256 _startDay, uint256 _finalDay) private view returns (uint256 _referralInterest) {\r\n for (uint256 _day = _startDay; _day \u003c _finalDay; _day++) {\r\n _referralInterest += _stake.stakesShares * PRECISION_RATE / rsnapshots[_day].inflationAmount;\r\n }\r\n }\r\n\r\n function _determineStartDay(Stake memory _stake, ReferrerLink memory _link) internal view returns (uint256) {\r\n return (\r\n criticalMass[_stake.referrer].activationDay \u003e _stake.startDay ?\r\n criticalMass[_stake.referrer].activationDay : _stake.startDay\r\n ).add(_link.processedDays);\r\n }\r\n\r\n function _determineFinalDay(\r\n Stake memory _stake\r\n )\r\n internal\r\n view\r\n returns (uint256)\r\n {\r\n return\r\n _stake.closeDay \u003e 0 ?\r\n _stake.closeDay : _calculationDay(_stake);\r\n }\r\n}"},"SafeMath.sol":{"content":"// SPDX-License-Identifier: --🦉--\r\n\r\npragma solidity =0.7.6;\r\n\r\nlibrary SafeMath {\r\n\r\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\r\n uint256 c = a + b;\r\n require(c \u003e= a);\r\n return c;\r\n }\r\n\r\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\r\n require(b \u003c= a);\r\n uint256 c = a - b;\r\n return c;\r\n }\r\n\r\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\r\n\r\n if (a == 0) {\r\n return 0;\r\n }\r\n\r\n uint256 c = a * b;\r\n require(c / a == b);\r\n return c;\r\n }\r\n\r\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\r\n require(b \u003e 0);\r\n uint256 c = a / b;\r\n return c;\r\n }\r\n\r\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\r\n require(b != 0);\r\n return a % b;\r\n }\r\n}\r\n"},"Snapshot.sol":{"content":"// SPDX-License-Identifier: --🦉--\r\n\r\npragma solidity =0.7.6;\r\n\r\nimport \"./Helper.sol\";\r\n\r\nabstract contract Snapshot is Helper {\r\n\r\n using SafeMath for uint;\r\n\r\n // regular shares\r\n struct SnapShot {\r\n uint256 totalShares;\r\n uint256 inflationAmount;\r\n uint256 scheduledToEnd;\r\n }\r\n\r\n // referral shares\r\n struct rSnapShot {\r\n uint256 totalShares;\r\n uint256 inflationAmount;\r\n uint256 scheduledToEnd;\r\n }\r\n\r\n // liquidity shares\r\n struct lSnapShot {\r\n uint256 totalShares;\r\n uint256 inflationAmount;\r\n }\r\n\r\n mapping(uint256 =\u003e SnapShot) public snapshots;\r\n mapping(uint256 =\u003e rSnapShot) public rsnapshots;\r\n mapping(uint256 =\u003e lSnapShot) public lsnapshots;\r\n\r\n modifier snapshotTrigger() {\r\n _dailySnapshotPoint(_currentWiseDay());\r\n _;\r\n }\r\n\r\n /**\r\n * @notice allows to activate/deactivate\r\n * liquidity guard manually based on the\r\n * liquidity in UNISWAP pair contract\r\n */\r\n function liquidityGuardTrigger() public {\r\n\r\n (\r\n uint112 reserveA,\r\n uint112 reserveB,\r\n uint32 blockTimestampLast\r\n ) = UNISWAP_PAIR.getReserves();\r\n\r\n emit UniswapReserves(\r\n reserveA,\r\n reserveB,\r\n blockTimestampLast\r\n );\r\n\r\n uint256 onUniswap = UNISWAP_PAIR.token1() == WETH\r\n ? reserveA\r\n : reserveB;\r\n\r\n uint256 ratio = totalSupply() == 0\r\n ? 0\r\n : onUniswap\r\n .mul(200)\r\n .div(totalSupply());\r\n\r\n if (ratio \u003c 40 \u0026\u0026 isLiquidityGuardActive == false) enableLiquidityGuard();\r\n if (ratio \u003e 60 \u0026\u0026 isLiquidityGuardActive == true) disableLiquidityGuard();\r\n\r\n emit LiquidityGuardStatus(\r\n isLiquidityGuardActive\r\n );\r\n }\r\n\r\n function enableLiquidityGuard() private {\r\n isLiquidityGuardActive = true;\r\n }\r\n\r\n function disableLiquidityGuard() private {\r\n isLiquidityGuardActive = false;\r\n }\r\n\r\n /**\r\n * @notice allows volunteer to offload snapshots\r\n * to save on gas during next start/end stake\r\n */\r\n function manualDailySnapshot()\r\n external\r\n {\r\n _dailySnapshotPoint(_currentWiseDay());\r\n }\r\n\r\n /**\r\n * @notice allows volunteer to offload snapshots\r\n * to save on gas during next start/end stake\r\n * in case manualDailySnapshot reach block limit\r\n */\r\n function manualDailySnapshotPoint(\r\n uint64 _updateDay\r\n )\r\n external\r\n {\r\n require(\r\n _updateDay \u003e 0 \u0026\u0026\r\n _updateDay \u003c _currentWiseDay()\r\n // \u0027WISE: snapshot day does not exist yet\u0027\r\n );\r\n\r\n require(\r\n _updateDay \u003e globals.currentWiseDay\r\n // \u0027WISE: snapshot already taken for that day\u0027\r\n );\r\n\r\n _dailySnapshotPoint(_updateDay);\r\n }\r\n\r\n /**\r\n * @notice internal function that offloads\r\n * global values to daily snapshots\r\n * updates globals.currentWiseDay\r\n */\r\n function _dailySnapshotPoint(\r\n uint64 _updateDay\r\n )\r\n private\r\n {\r\n liquidityGuardTrigger();\r\n\r\n uint256 scheduledToEndToday;\r\n uint256 totalStakedToday = globals.totalStaked;\r\n\r\n for (uint256 _day = globals.currentWiseDay; _day \u003c _updateDay; _day++) {\r\n\r\n // ------------------------------------\r\n // prepare snapshot for regular shares\r\n // reusing scheduledToEndToday variable\r\n\r\n scheduledToEndToday = scheduledToEnd[_day] + snapshots[_day - 1].scheduledToEnd;\r\n\r\n SnapShot memory snapshot = snapshots[_day];\r\n snapshot.scheduledToEnd = scheduledToEndToday;\r\n\r\n snapshot.totalShares =\r\n globals.totalShares \u003e scheduledToEndToday ?\r\n globals.totalShares - scheduledToEndToday : 0;\r\n\r\n snapshot.inflationAmount = snapshot.totalShares\r\n .mul(PRECISION_RATE)\r\n .div(\r\n _inflationAmount(\r\n totalStakedToday,\r\n totalSupply(),\r\n totalPenalties[_day],\r\n LIQUIDITY_GUARD.getInflation(\r\n INFLATION_RATE\r\n )\r\n )\r\n );\r\n\r\n // store regular snapshot\r\n snapshots[_day] = snapshot;\r\n\r\n\r\n // ------------------------------------\r\n // prepare snapshot for referrer shares\r\n // reusing scheduledToEndToday variable\r\n\r\n scheduledToEndToday = referralSharesToEnd[_day] + rsnapshots[_day - 1].scheduledToEnd;\r\n\r\n rSnapShot memory rsnapshot = rsnapshots[_day];\r\n rsnapshot.scheduledToEnd = scheduledToEndToday;\r\n\r\n rsnapshot.totalShares =\r\n globals.referralShares \u003e scheduledToEndToday ?\r\n globals.referralShares - scheduledToEndToday : 0;\r\n\r\n rsnapshot.inflationAmount = rsnapshot.totalShares\r\n .mul(PRECISION_RATE)\r\n .div(\r\n _referralInflation(\r\n totalStakedToday,\r\n totalSupply()\r\n )\r\n );\r\n\r\n // store referral snapshot\r\n rsnapshots[_day] = rsnapshot;\r\n\r\n\r\n // ------------------------------------\r\n // prepare snapshot for liquidity shares\r\n // reusing scheduledToEndToday variable\r\n\r\n lSnapShot memory lsnapshot = lsnapshots[_day];\r\n lsnapshot.totalShares = globals.liquidityShares;\r\n\r\n lsnapshot.inflationAmount = lsnapshot.totalShares\r\n .mul(PRECISION_RATE).div(\r\n _liquidityInflation(\r\n totalStakedToday,\r\n totalSupply(),\r\n LIQUIDITY_GUARD.getInflation(\r\n LIQUIDITY_RATE\r\n )\r\n )\r\n );\r\n\r\n // store liquidity snapshot\r\n lsnapshots[_day] = lsnapshot;\r\n\r\n adjustLiquidityRates();\r\n globals.currentWiseDay++;\r\n }\r\n }\r\n\r\n /**\r\n * @notice moves inflation up and down by 0.006%\r\n * from regular shares to liquidity shares\r\n * if the liquidityGuard is active (visa-versa)\r\n */\r\n function adjustLiquidityRates() private {\r\n if (\r\n isLiquidityGuardActive == true \u0026\u0026\r\n LIQUIDITY_RATE \u003c INFLATION_RATE_MAX\r\n )\r\n {\r\n LIQUIDITY_RATE = LIQUIDITY_RATE + 6;\r\n INFLATION_RATE = INFLATION_RATE - 6;\r\n return;\r\n }\r\n if (\r\n isLiquidityGuardActive == false \u0026\u0026\r\n INFLATION_RATE \u003c INFLATION_RATE_MAX\r\n )\r\n {\r\n INFLATION_RATE = INFLATION_RATE + 6;\r\n LIQUIDITY_RATE = LIQUIDITY_RATE - 6;\r\n return;\r\n }\r\n }\r\n\r\n function _inflationAmount(uint256 _totalStaked, uint256 _totalSupply, uint256 _totalPenalties, uint256 _INFLATION_RATE) private pure returns (uint256) {\r\n return (_totalStaked + _totalSupply) * 10000 / _INFLATION_RATE + _totalPenalties;\r\n }\r\n\r\n function _referralInflation(uint256 _totalStaked, uint256 _totalSupply) private pure returns (uint256) {\r\n return (_totalStaked + _totalSupply) * 10000 / REFERRALS_RATE;\r\n }\r\n\r\n function _liquidityInflation(uint256 _totalStaked, uint256 _totalSupply, uint256 _LIQUIDITY_RATE) private pure returns (uint256) {\r\n return (_totalStaked + _totalSupply) * 10000 / _LIQUIDITY_RATE;\r\n }\r\n}"},"StakingToken.sol":{"content":"// SPDX-License-Identifier: --🦉--\r\n\r\npragma solidity =0.7.6;\r\n\r\nimport \"./ReferralToken.sol\";\r\n\r\nabstract contract StakingToken is ReferralToken {\r\n\r\n using SafeMath for uint256;\r\n\r\n /**\r\n * @notice A method for a staker to create multiple stakes\r\n * @param _stakedAmount amount of WISE staked.\r\n * @param _lockDays amount of days it is locked for.\r\n * @param _referrer address of the referrer\r\n */\r\n function createStakeBulk(\r\n uint256[] memory _stakedAmount,\r\n uint64[] memory _lockDays,\r\n address[] memory _referrer\r\n )\r\n external\r\n {\r\n for(uint256 i = 0; i \u003c _stakedAmount.length; i++) {\r\n createStake(\r\n _stakedAmount[i],\r\n _lockDays[i],\r\n _referrer[i]\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * @notice A method for a staker to create a stake\r\n * @param _stakedAmount amount of WISE staked.\r\n * @param _lockDays amount of days it is locked for.\r\n * @param _referrer address of the referrer\r\n */\r\n function createStake(\r\n uint256 _stakedAmount,\r\n uint64 _lockDays,\r\n address _referrer\r\n )\r\n snapshotTrigger\r\n public\r\n returns (bytes16, uint256, bytes16 referralID)\r\n {\r\n require(\r\n msg.sender != _referrer \u0026\u0026\r\n notContract(_referrer)\r\n // \u0027WISE: invalid referrer\u0027\r\n );\r\n\r\n require(\r\n _lockDays \u003e= MIN_LOCK_DAYS \u0026\u0026\r\n _lockDays \u003c= MAX_LOCK_DAYS\r\n // \u0027WISE: stake is not in range\u0027\r\n );\r\n\r\n require(\r\n _stakedAmount \u003e= MIN_STAKE_AMOUNT\r\n // \u0027WISE: stake is not large enough\u0027\r\n );\r\n\r\n (\r\n Stake memory newStake,\r\n bytes16 stakeID,\r\n uint256 _startDay\r\n ) =\r\n\r\n _createStake(msg.sender, _stakedAmount, _lockDays, _referrer);\r\n\r\n if (newStake.referrerShares \u003e 0) {\r\n\r\n ReferrerLink memory referrerLink;\r\n\r\n referrerLink.staker = msg.sender;\r\n referrerLink.stakeID = stakeID;\r\n referrerLink.isActive = true;\r\n\r\n referralID = generateReferralID(_referrer);\r\n referrerLinks[_referrer][referralID] = referrerLink;\r\n\r\n _increaseReferralCount(\r\n _referrer\r\n );\r\n\r\n _addReferrerSharesToEnd(\r\n newStake.finalDay,\r\n newStake.referrerShares\r\n );\r\n }\r\n\r\n stakes[msg.sender][stakeID] = newStake;\r\n\r\n _increaseStakeCount(\r\n msg.sender\r\n );\r\n\r\n _increaseGlobals(\r\n newStake.stakedAmount,\r\n newStake.stakesShares,\r\n newStake.referrerShares\r\n );\r\n\r\n _addScheduledShares(\r\n newStake.finalDay,\r\n newStake.stakesShares\r\n );\r\n\r\n emit StakeStart(\r\n stakeID,\r\n msg.sender,\r\n _referrer,\r\n newStake.stakedAmount,\r\n newStake.stakesShares,\r\n newStake.referrerShares,\r\n newStake.startDay,\r\n newStake.lockDays,\r\n newStake.daiEquivalent\r\n );\r\n\r\n return (stakeID, _startDay, referralID);\r\n }\r\n\r\n /**\r\n * @notice A method for a staker to start a stake\r\n * @param _staker ...\r\n * @param _stakedAmount ...\r\n * @param _lockDays ...\r\n */\r\n function _createStake(\r\n address _staker,\r\n uint256 _stakedAmount,\r\n uint64 _lockDays,\r\n address _referrer\r\n )\r\n private\r\n returns (\r\n Stake memory _newStake,\r\n bytes16 _stakeID,\r\n uint64 _startDay\r\n )\r\n {\r\n _burn(\r\n _staker,\r\n _stakedAmount\r\n );\r\n\r\n _startDay = _nextWiseDay();\r\n _stakeID = generateStakeID(_staker);\r\n\r\n _newStake.lockDays = _lockDays;\r\n _newStake.startDay = _startDay;\r\n _newStake.finalDay = _startDay + _lockDays;\r\n _newStake.isActive = true;\r\n\r\n _newStake.stakedAmount = _stakedAmount;\r\n _newStake.stakesShares = _stakesShares(\r\n _stakedAmount,\r\n _lockDays,\r\n _referrer,\r\n globals.sharePrice\r\n );\r\n\r\n _updateDaiEquivalent();\r\n\r\n _newStake.daiEquivalent = latestDaiEquivalent\r\n .mul(_newStake.stakedAmount)\r\n .div(YODAS_PER_WISE);\r\n\r\n if (_nonZeroAddress(_referrer)) {\r\n\r\n _newStake.referrer = _referrer;\r\n\r\n _addCriticalMass(\r\n _newStake.referrer,\r\n _newStake.daiEquivalent\r\n );\r\n\r\n _newStake.referrerShares = _referrerShares(\r\n _stakedAmount,\r\n _lockDays,\r\n _referrer\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * @notice A method for a staker to remove a stake\r\n * belonging to his address by providing ID of a stake.\r\n * @param _stakeID unique bytes sequence reference to the stake\r\n */\r\n function endStake(\r\n bytes16 _stakeID\r\n )\r\n snapshotTrigger\r\n external\r\n returns (uint256)\r\n {\r\n (\r\n Stake memory endedStake,\r\n uint256 penaltyAmount\r\n ) =\r\n\r\n _endStake(\r\n msg.sender,\r\n _stakeID\r\n );\r\n\r\n _decreaseGlobals(\r\n endedStake.stakedAmount,\r\n endedStake.stakesShares,\r\n endedStake.referrerShares\r\n );\r\n\r\n _removeScheduledShares(\r\n endedStake.finalDay,\r\n endedStake.stakesShares\r\n );\r\n\r\n _removeReferrerSharesToEnd(\r\n endedStake.finalDay,\r\n endedStake.referrerShares\r\n );\r\n\r\n _removeCriticalMass(\r\n endedStake.referrer,\r\n endedStake.daiEquivalent,\r\n endedStake.startDay\r\n );\r\n\r\n _storePenalty(\r\n endedStake.closeDay,\r\n penaltyAmount\r\n );\r\n\r\n _sharePriceUpdate(\r\n endedStake.stakedAmount \u003e penaltyAmount ?\r\n endedStake.stakedAmount - penaltyAmount : 0,\r\n endedStake.rewardAmount + scrapes[msg.sender][_stakeID],\r\n endedStake.referrer,\r\n endedStake.lockDays,\r\n endedStake.stakesShares\r\n );\r\n\r\n emit StakeEnd(\r\n _stakeID,\r\n msg.sender,\r\n endedStake.referrer,\r\n endedStake.stakedAmount,\r\n endedStake.stakesShares,\r\n endedStake.referrerShares,\r\n endedStake.rewardAmount,\r\n endedStake.closeDay,\r\n penaltyAmount\r\n );\r\n\r\n return endedStake.rewardAmount;\r\n }\r\n\r\n function _endStake(\r\n address _staker,\r\n bytes16 _stakeID\r\n )\r\n private\r\n returns (\r\n Stake storage _stake,\r\n uint256 _penalty\r\n )\r\n {\r\n require(\r\n stakes[_staker][_stakeID].isActive\r\n // \u0027WISE: not an active stake\u0027\r\n );\r\n\r\n _stake = stakes[_staker][_stakeID];\r\n _stake.closeDay = _currentWiseDay();\r\n _stake.rewardAmount = _calculateRewardAmount(_stake);\r\n _penalty = _calculatePenaltyAmount(_stake);\r\n\r\n _stake.isActive = false;\r\n\r\n _mint(\r\n _staker,\r\n _stake.stakedAmount \u003e _penalty ?\r\n _stake.stakedAmount - _penalty : 0\r\n );\r\n\r\n _mint(\r\n _staker,\r\n _stake.rewardAmount\r\n );\r\n }\r\n\r\n /**\r\n * @notice alloes to scrape interest from active stake\r\n * @param _stakeID unique bytes sequence reference to the stake\r\n * @param _scrapeDays amount of days to proccess, 0 = all\r\n */\r\n function scrapeInterest(\r\n bytes16 _stakeID,\r\n uint64 _scrapeDays\r\n )\r\n external\r\n snapshotTrigger\r\n returns (\r\n uint256 scrapeDay,\r\n uint256 scrapeAmount,\r\n uint256 remainingDays,\r\n uint256 stakersPenalty,\r\n uint256 referrerPenalty\r\n )\r\n {\r\n require(\r\n stakes[msg.sender][_stakeID].isActive\r\n // \u0027WISE: not an active stake\u0027\r\n );\r\n\r\n Stake memory stake = stakes[msg.sender][_stakeID];\r\n\r\n scrapeDay = _scrapeDays \u003e 0\r\n ? _startingDay(stake).add(_scrapeDays)\r\n : _calculationDay(stake);\r\n\r\n scrapeDay = scrapeDay \u003e stake.finalDay\r\n ? _calculationDay(stake)\r\n : scrapeDay;\r\n\r\n scrapeAmount = _loopRewardAmount(\r\n stake.stakesShares,\r\n _startingDay(stake),\r\n scrapeDay\r\n );\r\n\r\n if (_isMatureStake(stake) == false) {\r\n\r\n remainingDays = _daysLeft(stake);\r\n\r\n stakersPenalty = _stakesShares(\r\n scrapeAmount,\r\n remainingDays,\r\n msg.sender,\r\n globals.sharePrice\r\n );\r\n\r\n stake.stakesShares =\r\n stake.stakesShares.sub(stakersPenalty);\r\n\r\n _removeScheduledShares(\r\n stake.finalDay,\r\n stakersPenalty\r\n );\r\n\r\n if (stake.referrerShares \u003e 0) {\r\n\r\n referrerPenalty = _stakesShares(\r\n scrapeAmount,\r\n remainingDays,\r\n address(0x0),\r\n globals.sharePrice\r\n );\r\n\r\n stake.referrerShares =\r\n stake.referrerShares.sub(referrerPenalty);\r\n\r\n _removeReferrerSharesToEnd(\r\n stake.finalDay,\r\n referrerPenalty\r\n );\r\n }\r\n\r\n _decreaseGlobals(\r\n 0,\r\n stakersPenalty,\r\n referrerPenalty\r\n );\r\n\r\n _sharePriceUpdate(\r\n stake.stakedAmount,\r\n scrapeAmount,\r\n stake.referrer,\r\n stake.lockDays,\r\n stake.stakesShares\r\n );\r\n }\r\n else {\r\n scrapes[msg.sender][_stakeID] =\r\n scrapes[msg.sender][_stakeID].add(scrapeAmount);\r\n\r\n _sharePriceUpdate(\r\n stake.stakedAmount,\r\n scrapes[msg.sender][_stakeID],\r\n stake.referrer,\r\n stake.lockDays,\r\n stake.stakesShares\r\n );\r\n }\r\n\r\n stake.scrapeDay = scrapeDay;\r\n stakes[msg.sender][_stakeID] = stake;\r\n\r\n _mint(\r\n msg.sender,\r\n scrapeAmount\r\n );\r\n\r\n emit InterestScraped(\r\n _stakeID,\r\n msg.sender,\r\n scrapeAmount,\r\n scrapeDay,\r\n stakersPenalty,\r\n referrerPenalty,\r\n _currentWiseDay()\r\n );\r\n }\r\n\r\n function _addScheduledShares(\r\n uint256 _finalDay,\r\n uint256 _shares\r\n )\r\n internal\r\n {\r\n scheduledToEnd[_finalDay] =\r\n scheduledToEnd[_finalDay].add(_shares);\r\n }\r\n\r\n function _removeScheduledShares(\r\n uint256 _finalDay,\r\n uint256 _shares\r\n )\r\n internal\r\n {\r\n if (_notPast(_finalDay)) {\r\n\r\n scheduledToEnd[_finalDay] =\r\n scheduledToEnd[_finalDay] \u003e _shares ?\r\n scheduledToEnd[_finalDay] - _shares : 0;\r\n\r\n } else {\r\n\r\n uint256 _day = _previousWiseDay();\r\n snapshots[_day].scheduledToEnd =\r\n snapshots[_day].scheduledToEnd \u003e _shares ?\r\n snapshots[_day].scheduledToEnd - _shares : 0;\r\n }\r\n }\r\n\r\n function _sharePriceUpdate(\r\n uint256 _stakedAmount,\r\n uint256 _rewardAmount,\r\n address _referrer,\r\n uint256 _lockDays,\r\n uint256 _stakeShares\r\n )\r\n private\r\n {\r\n if (_stakeShares \u003e 0 \u0026\u0026 _currentWiseDay() \u003e FORMULA_DAY) {\r\n\r\n uint256 newSharePrice = _getNewSharePrice(\r\n _stakedAmount,\r\n _rewardAmount,\r\n _stakeShares,\r\n _lockDays,\r\n _referrer\r\n );\r\n\r\n if (newSharePrice \u003e globals.sharePrice) {\r\n\r\n newSharePrice =\r\n newSharePrice \u003c globals.sharePrice.mul(110).div(100) ?\r\n newSharePrice : globals.sharePrice.mul(110).div(100);\r\n\r\n emit NewSharePrice(\r\n newSharePrice,\r\n globals.sharePrice,\r\n _currentWiseDay()\r\n );\r\n\r\n globals.sharePrice = newSharePrice;\r\n }\r\n\r\n return;\r\n }\r\n\r\n if (_currentWiseDay() == FORMULA_DAY) {\r\n globals.sharePrice = 110E15;\r\n }\r\n }\r\n\r\n function _getNewSharePrice(\r\n uint256 _stakedAmount,\r\n uint256 _rewardAmount,\r\n uint256 _stakeShares,\r\n uint256 _lockDays,\r\n address _referrer\r\n )\r\n private\r\n pure\r\n returns (uint256)\r\n {\r\n\r\n uint256 _bonusAmount = _getBonus(\r\n _lockDays, _nonZeroAddress(_referrer) ? 11E9 : 10E9\r\n );\r\n\r\n return\r\n _stakedAmount\r\n .add(_rewardAmount)\r\n .mul(_bonusAmount)\r\n .mul(1E8)\r\n .div(_stakeShares);\r\n }\r\n\r\n function checkMatureStake(\r\n address _staker,\r\n bytes16 _stakeID\r\n )\r\n external\r\n view\r\n returns (bool isMature)\r\n {\r\n Stake memory stake = stakes[_staker][_stakeID];\r\n isMature = _isMatureStake(stake);\r\n }\r\n\r\n function checkStakeByID(\r\n address _staker,\r\n bytes16 _stakeID\r\n )\r\n external\r\n view\r\n returns (\r\n uint256 startDay,\r\n uint256 lockDays,\r\n uint256 finalDay,\r\n uint256 closeDay,\r\n uint256 scrapeDay,\r\n uint256 stakedAmount,\r\n uint256 stakesShares,\r\n uint256 rewardAmount,\r\n uint256 penaltyAmount,\r\n bool isActive,\r\n bool isMature\r\n )\r\n {\r\n Stake memory stake = stakes[_staker][_stakeID];\r\n startDay = stake.startDay;\r\n lockDays = stake.lockDays;\r\n finalDay = stake.finalDay;\r\n closeDay = stake.closeDay;\r\n scrapeDay = stake.scrapeDay;\r\n stakedAmount = stake.stakedAmount;\r\n stakesShares = stake.stakesShares;\r\n rewardAmount = _checkRewardAmount(stake);\r\n penaltyAmount = _calculatePenaltyAmount(stake);\r\n isActive = stake.isActive;\r\n isMature = _isMatureStake(stake);\r\n }\r\n\r\n function _stakesShares(\r\n uint256 _stakedAmount,\r\n uint256 _lockDays,\r\n address _referrer,\r\n uint256 _sharePrice\r\n )\r\n private\r\n pure\r\n returns (uint256)\r\n {\r\n return _nonZeroAddress(_referrer)\r\n ? _sharesAmount(_stakedAmount, _lockDays, _sharePrice, 11E9)\r\n : _sharesAmount(_stakedAmount, _lockDays, _sharePrice, 10E9);\r\n }\r\n\r\n function _sharesAmount(\r\n uint256 _stakedAmount,\r\n uint256 _lockDays,\r\n uint256 _sharePrice,\r\n uint256 _extraBonus\r\n )\r\n private\r\n pure\r\n returns (uint256)\r\n {\r\n return _baseAmount(_stakedAmount, _sharePrice)\r\n .mul(_getBonus(_lockDays, _extraBonus))\r\n .div(10E9);\r\n }\r\n\r\n function _getBonus(\r\n uint256 _lockDays,\r\n uint256 _extraBonus\r\n )\r\n private\r\n pure\r\n returns (uint256)\r\n {\r\n return\r\n _regularBonus(_lockDays, DAILY_BONUS_A, MAX_BONUS_DAYS_A) +\r\n _regularBonus(\r\n _lockDays \u003e MAX_BONUS_DAYS_A ?\r\n _lockDays - MAX_BONUS_DAYS_A : 0, DAILY_BONUS_B, MAX_BONUS_DAYS_B\r\n ) + _extraBonus;\r\n }\r\n\r\n function _regularBonus(\r\n uint256 _lockDays,\r\n uint256 _daily,\r\n uint256 _maxDays\r\n )\r\n private\r\n pure\r\n returns (uint256)\r\n {\r\n return (\r\n _lockDays \u003e _maxDays\r\n ? _maxDays.mul(_daily)\r\n : _lockDays.mul(_daily)\r\n ).div(10E9);\r\n }\r\n\r\n function _baseAmount(\r\n uint256 _stakedAmount,\r\n uint256 _sharePrice\r\n )\r\n private\r\n pure\r\n returns (uint256)\r\n {\r\n return\r\n _stakedAmount\r\n .mul(PRECISION_RATE)\r\n .div(_sharePrice);\r\n }\r\n\r\n function _referrerShares(\r\n uint256 _stakedAmount,\r\n uint256 _lockDays,\r\n address _referrer\r\n )\r\n private\r\n view\r\n returns (uint256)\r\n {\r\n return\r\n _notCriticalMassReferrer(_referrer) ||\r\n _lockDays \u003c MIN_REFERRAL_DAYS\r\n ? 0\r\n : _sharesAmount(\r\n _stakedAmount,\r\n _lockDays,\r\n globals.sharePrice,\r\n 10E9\r\n );\r\n }\r\n\r\n function _checkRewardAmount(Stake memory _stake) private view returns (uint256) {\r\n return _stake.isActive ? _detectReward(_stake) : _stake.rewardAmount;\r\n }\r\n\r\n function _detectReward(Stake memory _stake) private view returns (uint256) {\r\n return _stakeNotStarted(_stake) ? 0 : _calculateRewardAmount(_stake);\r\n }\r\n\r\n function _storePenalty(\r\n uint64 _storeDay,\r\n uint256 _penalty\r\n )\r\n private\r\n {\r\n if (_penalty \u003e 0) {\r\n totalPenalties[_storeDay] =\r\n totalPenalties[_storeDay].add(_penalty);\r\n }\r\n }\r\n\r\n function _calculatePenaltyAmount(\r\n Stake memory _stake\r\n )\r\n private\r\n view\r\n returns (uint256)\r\n {\r\n return _stakeNotStarted(_stake) || _isMatureStake(_stake) ? 0 : _getPenalties(_stake);\r\n }\r\n\r\n function _getPenalties(Stake memory _stake)\r\n private\r\n view\r\n returns (uint256)\r\n {\r\n return _stake.stakedAmount * (100 + (800 * (_daysLeft(_stake) - 1) / (_getLockDays(_stake)))) / 1000;\r\n }\r\n\r\n function _calculateRewardAmount(\r\n Stake memory _stake\r\n )\r\n private\r\n view\r\n returns (uint256)\r\n {\r\n return _loopRewardAmount(\r\n _stake.stakesShares,\r\n _startingDay(_stake),\r\n _calculationDay(_stake)\r\n );\r\n }\r\n\r\n function _loopRewardAmount(\r\n uint256 _stakeShares,\r\n uint256 _startDay,\r\n uint256 _finalDay\r\n )\r\n private\r\n view\r\n returns (uint256 _rewardAmount)\r\n {\r\n for (uint256 _day = _startDay; _day \u003c _finalDay; _day++) {\r\n _rewardAmount += _stakeShares * PRECISION_RATE / snapshots[_day].inflationAmount;\r\n }\r\n }\r\n}"},"Timing.sol":{"content":"// SPDX-License-Identifier: --🦉--\r\n\r\npragma solidity =0.7.6;\r\n\r\nimport \"./Declaration.sol\";\r\n\r\nabstract contract Timing is Declaration {\r\n\r\n function currentWiseDay() public view returns (uint64) {\r\n return _getNow() \u003e= LAUNCH_TIME ? _currentWiseDay() : 0;\r\n }\r\n\r\n function _currentWiseDay() internal view returns (uint64) {\r\n return _wiseDayFromStamp(_getNow());\r\n }\r\n\r\n function _nextWiseDay() internal view returns (uint64) {\r\n return _currentWiseDay() + 1;\r\n }\r\n\r\n function _previousWiseDay() internal view returns (uint64) {\r\n return _currentWiseDay() - 1;\r\n }\r\n\r\n function _wiseDayFromStamp(uint256 _timestamp) internal view returns (uint64) {\r\n return uint64((_timestamp - LAUNCH_TIME) / SECONDS_IN_DAY);\r\n }\r\n\r\n function _getNow() internal view returns (uint256) {\r\n return block.timestamp;\r\n }\r\n}"},"WiseToken.sol":{"content":"// SPDX-License-Identifier: --🦉--\r\n\r\npragma solidity =0.7.6;\r\n\r\nimport \"./LiquidityToken.sol\";\r\n\r\ncontract WiseToken is LiquidityToken {\r\n\r\n address public LIQUIDITY_TRANSFORMER;\r\n address public transformerGateKeeper;\r\n\r\n constructor() ERC20(\"Wise Token\", \"WISE\") {\r\n transformerGateKeeper = msg.sender;\r\n }\r\n\r\n receive() external payable {\r\n revert();\r\n }\r\n\r\n /**\r\n * @notice ability to define liquidity transformer contract\r\n * @dev this method renounce transformerGateKeeper access\r\n * @param _immutableTransformer contract address\r\n */\r\n function setLiquidityTransfomer(\r\n address _immutableTransformer\r\n )\r\n external\r\n {\r\n require(\r\n transformerGateKeeper == msg.sender\r\n // \u0027WISE: transformer defined\u0027\r\n );\r\n LIQUIDITY_TRANSFORMER = _immutableTransformer;\r\n transformerGateKeeper = address(0x0);\r\n }\r\n\r\n /**\r\n * @notice allows liquidityTransformer to mint supply\r\n * @dev executed from liquidityTransformer upon UNISWAP transfer\r\n * and during reservation payout to contributors and referrers\r\n * @param _investorAddress address for minting WISE tokens\r\n * @param _amount of tokens to mint for _investorAddress\r\n */\r\n function mintSupply(\r\n address _investorAddress,\r\n uint256 _amount\r\n )\r\n external\r\n {\r\n require(\r\n msg.sender == LIQUIDITY_TRANSFORMER\r\n // \u0027WISE: wrong transformer\u0027\r\n );\r\n\r\n _mint(\r\n _investorAddress,\r\n _amount\r\n );\r\n }\r\n\r\n /**\r\n * @notice allows to grant permission to CM referrer status\r\n * @dev called from liquidityTransformer if user referred 50 ETH\r\n * @param _referrer - address that becomes a CM reffer\r\n */\r\n function giveStatus(\r\n address _referrer\r\n )\r\n external\r\n {\r\n require(\r\n msg.sender == LIQUIDITY_TRANSFORMER\r\n // \u0027WISE: wrong transformer\u0027\r\n );\r\n criticalMass[_referrer].totalAmount = THRESHOLD_LIMIT;\r\n criticalMass[_referrer].activationDay = _nextWiseDay();\r\n }\r\n\r\n /**\r\n * @notice allows to create stake directly with ETH\r\n * if you don\u0027t have WISE tokens method will convert\r\n * and use amount returned from UNISWAP to open a stake\r\n * @param _lockDays amount of days it is locked for.\r\n * @param _referrer referrer address for +10% bonus\r\n */\r\n function createStakeWithETH(\r\n uint64 _lockDays,\r\n address _referrer\r\n )\r\n external\r\n payable\r\n returns (bytes16, uint256, bytes16 referralID)\r\n {\r\n address[] memory path = new address[](2);\r\n path[0] = WETH;\r\n path[1] = address(this);\r\n\r\n uint256[] memory amounts =\r\n UNISWAP_ROUTER.swapExactETHForTokens{value: msg.value}(\r\n 1,\r\n path,\r\n msg.sender,\r\n block.timestamp + 2 hours\r\n );\r\n\r\n return createStake(\r\n amounts[1],\r\n _lockDays,\r\n _referrer\r\n );\r\n }\r\n\r\n /**\r\n * @notice allows to create stake with another token\r\n * if you don\u0027t have WISE tokens method will convert\r\n * and use amount returned from UNISWAP to open a stake\r\n * @dev the token must have WETH pair on UNISWAP\r\n * @param _tokenAddress any ERC20 token address\r\n * @param _tokenAmount amount to be converted to WISE\r\n * @param _lockDays amount of days it is locked for.\r\n * @param _referrer referrer address for +10% bonus\r\n */\r\n function createStakeWithToken(\r\n address _tokenAddress,\r\n uint256 _tokenAmount,\r\n uint64 _lockDays,\r\n address _referrer\r\n )\r\n external\r\n returns (bytes16, uint256, bytes16 referralID)\r\n {\r\n ERC20TokenI token = ERC20TokenI(\r\n _tokenAddress\r\n );\r\n\r\n token.transferFrom(\r\n msg.sender,\r\n address(this),\r\n _tokenAmount\r\n );\r\n\r\n token.approve(\r\n address(UNISWAP_ROUTER),\r\n _tokenAmount\r\n );\r\n\r\n address[] memory path = _preparePath(\r\n _tokenAddress,\r\n address(this)\r\n );\r\n\r\n uint256[] memory amounts =\r\n UNISWAP_ROUTER.swapExactTokensForTokens(\r\n _tokenAmount,\r\n 1,\r\n path,\r\n msg.sender,\r\n block.timestamp + 2 hours\r\n );\r\n\r\n return createStake(\r\n amounts[2],\r\n _lockDays,\r\n _referrer\r\n );\r\n }\r\n}"}}