ETH Price: $2,614.96 (-2.94%)

Transaction Decoder

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 Code
0x66a0f676...78BfF5bd6
0xA5AA529d...dDc30fb3C
0.005267269249693201 Eth
Nonce: 9
0.003490069249693201 Eth
Nonce: 10
0.0017772
(UUPool)
622.381555909541108581 Eth622.383333109541108581 Eth0.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}"}}