ETH Price: $2,781.46 (+2.66%)

Transaction Decoder

Block:
22364275 at Apr-28-2025 01:27:35 AM +UTC
Transaction Fee:
0.0000231435 ETH $0.06
Gas Used:
46,287 Gas / 0.5 Gwei

Emitted Events:

165 TEXAN.Approval( owner=[Sender] 0x6499dbce7751de048ced08b6a9fb0b8f182ee862, spender=0xaaaaaaae...d26D23D4d, value=1000000000000000000000000 )

Account State Difference:

  Address   Before After State Difference Code
0x6499dBCe...f182Ee862
0.000059370197576619 Eth
Nonce: 16
0.000036226697576619 Eth
Nonce: 17
0.0000231435
(beaverbuild)
16.275344961435007919 Eth16.275350729964232391 Eth0.000005768529224472
0xcFCFfE43...77B2A88d7

Execution Trace

TEXAN.approve( spender=0xaaaaaaae92Cc1cEeF79a038017889fDd26D23D4d, amount=1000000000000000000000000 ) => ( True )
{"Context.sol":{"content":"// SPDX-License-Identifier: UNLICENSED\r\n// @title Stakeable Endowment Token\r\n// @author Origin Addrress\r\n\r\npragma solidity ^0.8.13;\r\n\r\n// @dev Provides information about the current execution context, including the\r\n// sender of the transaction and its data. While these are generally available\r\n// via msg.sender and msg.data, they should not be accessed in such a direct\r\n// manner, since when dealing with meta-transactions the account sending and\r\n// paying for execution may not be the actual sender (as far as an application\r\n// is concerned).\r\n// This contract is only required for intermediate, library-like contracts.\r\nabstract contract Context {\r\n    function _msgSender()\r\n    internal\r\n    view\r\n    virtual\r\n    returns (address)\r\n    {\r\n        return msg.sender;\r\n    }\r\n\r\n    function _msgData()\r\n    internal\r\n    view\r\n    virtual\r\n    returns (bytes calldata)\r\n    {\r\n        return msg.data;\r\n    }\r\n}"},"ERC20.sol":{"content":"// SPDX-License-Identifier: UNLICENSED\r\n// @title Stakeable Endowment Token\r\n// @author Origin Addrress\r\n\r\npragma solidity ^0.8.13;\r\n\r\n// Import Context\r\nimport \"./IERC20Metadata.sol\";\r\n\r\n/**\r\n * @dev Implementation of the {IERC20} interface.\r\n *\r\n * This implementation is agnostic to the way tokens are created. This means\r\n * that a supply mechanism has to be added in a derived contract using {_mint}.\r\n * For a generic mechanism see {ERC20PresetMinterPauser}.\r\n *\r\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\r\n * instead returning `false` on failure. This behavior is nonetheless\r\n * conventional and does not conflict with the expectations of ERC20\r\n * applications.\r\n *\r\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\r\n * This allows applications to reconstruct the allowance for all accounts just\r\n * by listening to said events. Other implementations of the EIP may not emit\r\n * these events, as it isn\u0027t required by the specification.\r\n *\r\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\r\n * functions have been added to mitigate the well-known issues around setting\r\n * allowances. See {IERC20-approve}.\r\n */\r\n\r\ncontract ERC20 is Context, IERC20, IERC20Metadata {\r\n    mapping(address =\u003e uint256) private _balances;\r\n\r\n    mapping(address =\u003e mapping(address =\u003e uint256)) private _allowances;\r\n\r\n    uint256 private _totalSupply;\r\n\r\n    string private _tokenName;\r\n    string private _tokenSymbol;\r\n\r\n    function setNameAndSymbol(string memory nameOfToken, string memory symbolOfToken) internal {\r\n        _tokenName = nameOfToken;\r\n        _tokenSymbol = symbolOfToken;\r\n    }\r\n\r\n\r\n    /**\r\n     * @dev Returns the name of the token.\r\n     */\r\n    function name() public view virtual override returns (string memory) {\r\n        return _tokenName;\r\n    }\r\n\r\n    /**\r\n     * @dev Returns the symbol of the token, usually a shorter version of the\r\n     * name.\r\n     */\r\n    function symbol() public view virtual override returns (string memory) {\r\n        return _tokenSymbol;\r\n    }\r\n\r\n    /**\r\n     * @dev Returns the number of decimals used to get its user representation.\r\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\r\n     * be displayed to a user as `5.05` (`505 / 10 ** 2`).\r\n     *\r\n     * Tokens usually opt for a value of 18, imitating the relationship between\r\n     * Ether and Wei. This is the value {ERC20} uses, unless this function is\r\n     * overridden;\r\n     *\r\n     * NOTE: This information is only used for _display_ purposes: it in\r\n     * no way affects any of the arithmetic of the contract, including\r\n     * {IERC20-balanceOf} and {IERC20-transfer}.\r\n     */\r\n    function decimals() public view virtual override returns (uint8) {\r\n        return 18;\r\n    }\r\n\r\n    /**\r\n     * @dev See {IERC20-totalSupply}.\r\n     */\r\n    function totalSupply() public view virtual override returns (uint256) {\r\n        return _totalSupply;\r\n    }\r\n\r\n    /**\r\n     * @dev See {IERC20-balanceOf}.\r\n     */\r\n    function balanceOf(address account) public view virtual override returns (uint256) {\r\n        return _balances[account];\r\n    }\r\n\r\n    /**\r\n     * @dev See {IERC20-transfer}.\r\n     *\r\n     * Requirements:\r\n     *\r\n     * - `recipient` cannot be the zero address.\r\n     * - the caller must have a balance of at least `amount`.\r\n     */\r\n    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\r\n        _transfer(_msgSender(), recipient, amount);\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * @dev See {IERC20-allowance}.\r\n     */\r\n    function allowance(address owner, address spender) public view virtual override returns (uint256) {\r\n        return _allowances[owner][spender];\r\n    }\r\n\r\n    /**\r\n     * @dev See {IERC20-approve}.\r\n     *\r\n     * Requirements:\r\n     *\r\n     * - `spender` cannot be the zero address.\r\n     */\r\n    function approve(address spender, uint256 amount) public virtual override returns (bool) {\r\n        _approve(_msgSender(), spender, amount);\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * @dev See {IERC20-transferFrom}.\r\n     *\r\n     * Emits an {Approval} event indicating the updated allowance. This is not\r\n     * required by the EIP. See the note at the beginning of {ERC20}.\r\n     *\r\n     * Requirements:\r\n     *\r\n     * - `sender` and `recipient` cannot be the zero address.\r\n     * - `sender` must have a balance of at least `amount`.\r\n     * - the caller must have allowance for ``sender``\u0027s tokens of at least\r\n     * `amount`.\r\n     */\r\n    function transferFrom(\r\n        address sender,\r\n        address recipient,\r\n        uint256 amount\r\n    ) public virtual override returns (bool) {\r\n        _transfer(sender, recipient, amount);\r\n\r\n        uint256 currentAllowance = _allowances[sender][_msgSender()];\r\n        require(currentAllowance \u003e= amount, \"ERC20: transfer amount exceeds allowance\");\r\n        unchecked {\r\n            _approve(sender, _msgSender(), currentAllowance - amount);\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * @dev Atomically increases the allowance granted to `spender` by the caller.\r\n     *\r\n     * This is an alternative to {approve} that can be used as a mitigation for\r\n     * problems described in {IERC20-approve}.\r\n     *\r\n     * Emits an {Approval} event indicating the updated allowance.\r\n     *\r\n     * Requirements:\r\n     *\r\n     * - `spender` cannot be the zero address.\r\n     */\r\n    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\r\n        _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * @dev Atomically decreases the allowance granted to `spender` by the caller.\r\n     *\r\n     * This is an alternative to {approve} that can be used as a mitigation for\r\n     * problems described in {IERC20-approve}.\r\n     *\r\n     * Emits an {Approval} event indicating the updated allowance.\r\n     *\r\n     * Requirements:\r\n     *\r\n     * - `spender` cannot be the zero address.\r\n     * - `spender` must have allowance for the caller of at least\r\n     * `subtractedValue`.\r\n     */\r\n    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\r\n        uint256 currentAllowance = _allowances[_msgSender()][spender];\r\n        require(currentAllowance \u003e= subtractedValue, \"ERC20: decreased allowance below zero\");\r\n        unchecked {\r\n            _approve(_msgSender(), spender, currentAllowance - subtractedValue);\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * @dev Moves `amount` of tokens from `sender` to `recipient`.\r\n     *\r\n     * This internal function is equivalent to {transfer}, and can be used to\r\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\r\n     *\r\n     * Emits a {Transfer} event.\r\n     *\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    ) internal virtual {\r\n        require(sender != address(0), \"ERC20: transfer from the zero address\");\r\n        require(recipient != address(0), \"ERC20: transfer to the zero address\");\r\n\r\n        _beforeTokenTransfer(sender, recipient, amount);\r\n\r\n        uint256 senderBalance = _balances[sender];\r\n        require(senderBalance \u003e= amount, \"ERC20: transfer amount exceeds balance\");\r\n        unchecked {\r\n            _balances[sender] = senderBalance - amount;\r\n        }\r\n        _balances[recipient] += amount;\r\n\r\n        emit Transfer(sender, recipient, amount);\r\n\r\n        _afterTokenTransfer(sender, recipient, amount);\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     *\r\n     * Requirements:\r\n     *\r\n     * - `account` cannot be the zero address.\r\n     */\r\n    function _mint(address account, uint256 amount) internal virtual {\r\n        require(account != address(0), \"ERC20: mint to the zero address\");\r\n\r\n        _beforeTokenTransfer(address(0), account, amount);\r\n\r\n        _totalSupply += amount;\r\n        _balances[account] += amount;\r\n        emit Transfer(address(0), account, amount);\r\n\r\n        _afterTokenTransfer(address(0), account, 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(address account, uint256 amount) internal virtual {\r\n        require(account != address(0), \"ERC20: burn from the zero address\");\r\n\r\n        _beforeTokenTransfer(account, address(0), amount);\r\n\r\n        uint256 accountBalance = _balances[account];\r\n        require(accountBalance \u003e= amount, \"ERC20: burn amount exceeds balance\");\r\n        unchecked {\r\n            _balances[account] = accountBalance - amount;\r\n        }\r\n        _totalSupply -= amount;\r\n\r\n        emit Transfer(account, address(0), amount);\r\n\r\n        _afterTokenTransfer(account, address(0), amount);\r\n    }\r\n\r\n    /**\r\n     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\r\n     *\r\n     * This internal function is equivalent to `approve`, and can be used to\r\n     * e.g. set automatic allowances for certain subsystems, etc.\r\n     *\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    ) internal virtual {\r\n        require(owner != address(0), \"ERC20: approve from the zero address\");\r\n        require(spender != address(0), \"ERC20: approve to the zero address\");\r\n\r\n        _allowances[owner][spender] = amount;\r\n        emit Approval(owner, spender, amount);\r\n    }\r\n\r\n    /**\r\n     * @dev Hook that is called before any transfer of tokens. This includes\r\n     * minting and burning.\r\n     *\r\n     * Calling conditions:\r\n     *\r\n     * - when `from` and `to` are both non-zero, `amount` of ``from``\u0027s tokens\r\n     * will be transferred to `to`.\r\n     * - when `from` is zero, `amount` tokens will be minted for `to`.\r\n     * - when `to` is zero, `amount` of ``from``\u0027s tokens will be burned.\r\n     * - `from` and `to` are never both zero.\r\n     *\r\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\r\n     */\r\n    function _beforeTokenTransfer(\r\n        address from,\r\n        address to,\r\n        uint256 amount\r\n    ) internal virtual {}\r\n\r\n    /**\r\n     * @dev Hook that is called after any transfer of tokens. This includes\r\n     * minting and burning.\r\n     *\r\n     * Calling conditions:\r\n     *\r\n     * - when `from` and `to` are both non-zero, `amount` of ``from``\u0027s tokens\r\n     * has been transferred to `to`.\r\n     * - when `from` is zero, `amount` tokens have been minted for `to`.\r\n     * - when `to` is zero, `amount` of ``from``\u0027s tokens have been burned.\r\n     * - `from` and `to` are never both zero.\r\n     *\r\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\r\n     */\r\n    function _afterTokenTransfer(\r\n        address from,\r\n        address to,\r\n        uint256 amount\r\n    ) internal virtual {}\r\n}\r\n"},"IERC20.sol":{"content":"// SPDX-License-Identifier: UNLICENSED\r\n// @title Stakeable Endowment Token\r\n// @author Origin Addrress\r\n\r\npragma solidity ^0.8.13;\r\n\r\n// Import Context\r\nimport \"./Context.sol\";\r\n\r\n/**\r\n * @dev Interface of the ERC20 standard as defined in the EIP.\r\n */\r\ninterface IERC20 {\r\n    /**\r\n     * @dev Returns the amount of tokens in existence.\r\n     */\r\n    function totalSupply() external view returns (uint256);\r\n\r\n    /**\r\n     * @dev Returns the amount of tokens owned by `account`.\r\n     */\r\n    function balanceOf(address account) external view returns (uint256);\r\n\r\n    /**\r\n     * @dev Moves `amount` tokens from the caller\u0027s account to `recipient`.\r\n     *\r\n     * Returns a boolean value indicating whether the operation succeeded.\r\n     *\r\n     * Emits a {Transfer} event.\r\n     */\r\n    function transfer(address recipient, uint256 amount) external returns (bool);\r\n\r\n    /**\r\n     * @dev Returns the remaining number of tokens that `spender` will be\r\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\r\n     * zero by default.\r\n     *\r\n     * This value changes when {approve} or {transferFrom} are called.\r\n     */\r\n    function allowance(address owner, address spender) external view returns (uint256);\r\n\r\n    /**\r\n     * @dev Sets `amount` as the allowance of `spender` over the caller\u0027s tokens.\r\n     *\r\n     * Returns a boolean value indicating whether the operation succeeded.\r\n     *\r\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\r\n     * that someone may use both the old and the new allowance by unfortunate\r\n     * transaction ordering. One possible solution to mitigate this race\r\n     * condition is to first reduce the spender\u0027s allowance to 0 and set the\r\n     * desired value afterwards:\r\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\r\n     *\r\n     * Emits an {Approval} event.\r\n     */\r\n    function approve(address spender, uint256 amount) external returns (bool);\r\n\r\n    /**\r\n     * @dev Moves `amount` tokens from `sender` to `recipient` using the\r\n     * allowance mechanism. `amount` is then deducted from the caller\u0027s\r\n     * allowance.\r\n     *\r\n     * Returns a boolean value indicating whether the operation succeeded.\r\n     *\r\n     * Emits a {Transfer} event.\r\n     */\r\n    function transferFrom(\r\n        address sender,\r\n        address recipient,\r\n        uint256 amount\r\n    ) external returns (bool);\r\n\r\n    /**\r\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\r\n     * another (`to`).\r\n     *\r\n     * Note that `value` may be zero.\r\n     */\r\n    event Transfer(address indexed from, address indexed to, uint256 value);\r\n\r\n    /**\r\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\r\n     * a call to {approve}. `value` is the new allowance.\r\n     */\r\n    event Approval(address indexed owner, address indexed spender, uint256 value);\r\n}"},"IERC20Metadata.sol":{"content":"// SPDX-License-Identifier: UNLICENSED\r\n// @title Stakeable Endowment Token\r\n// @author Origin Addrress\r\n\r\npragma solidity ^0.8.13;\r\n\r\n// Import Context\r\nimport \"./IERC20.sol\";\r\n\r\n/**\r\n * @dev Interface for the optional metadata functions from the ERC20 standard.\r\n *\r\n * _Available since v4.1._\r\n */\r\ninterface IERC20Metadata is IERC20 {\r\n    /**\r\n     * @dev Returns the name of the token.\r\n     */\r\n    function name() external view returns (string memory);\r\n\r\n    /**\r\n     * @dev Returns the symbol of the token.\r\n     */\r\n    function symbol() external view returns (string memory);\r\n\r\n    /**\r\n     * @dev Returns the decimals places of the token.\r\n     */\r\n    function decimals() external view returns (uint8);\r\n}"},"StakableEndowmentToken.sol":{"content":"// SPDX-License-Identifier: UNLICENSED\r\n// @title Stakeable Endowment Token\r\n// @author Origin Addrress\r\n// @notice This contract is proprietary and may not be copied or used without permission.\r\n// @dev Stakable Endowment Main Functions for Staking, Scraping, and Ending Stakes\r\n// @notice These are the main public functions for the token.\r\n\r\npragma solidity ^0.8.13;\r\n\r\nimport \"./ERC20.sol\";\r\n\r\nabstract contract StakableEndowmentToken is ERC20 {\r\n    // Launch timeTime \r\n    // Dec 22 12AM GMT\r\n    uint256 internal constant LAUNCH_TIME = 1671667200;  //The time of launch\r\n                                            \r\n    // Global Constants Constants\r\n    uint256 internal constant MIN_STAKE_DAYS = 1;\r\n    uint256 internal constant MAX_STAKE_DAYS = 8036; // Approx 22 years and half a day\r\n    uint256 internal constant MAX_STAKE_YEARS = 22; //\r\n\r\n    uint256 internal constant MIN_STAKE_AMOUNT = 10000;\r\n    uint256 internal constant MAX_STAKE_AMOUNT = 1e29; // 100B Stake is the max (100000000000000000000000000000)\r\n\r\n    // This is the Endowment Supply. For security reasons we made this an \r\n    // internal variable that only this contract can change.\r\n    \r\n    // The initial supply is 97 Trillion locked in the contract\r\n    uint256 internal _endowmentSupply = (97 * 1e30);\r\n\r\n    // Global Variables\r\n    uint256 g_latestStakeId = 0;     // the global stake id starting at zero so first take will be 1\r\n    uint256 g_stakedStars = 0;      // the amount of wei that is already staked\r\n    uint256 g_stakedPrincipleStars = 0;      // the amount of principle that is staked in wei\r\n    uint256 g_penalizedStars = 0;  // these are the Stars that have been set aside from penalties\r\n    uint256 g_stakedCount = 0;  // current count of active stakes based on + and - in startStake and endStake\r\n\r\n    // For Calculations\r\n    uint256 constant PRECISION = 1e18;   // 18 decimals\r\n    uint256 constant YEARDIVIDER = 36525;  // must use yearprecision multiplier with this (100)\r\n    uint256 constant YEARPRECISION = 100;  // because of integers only multiple by precision, divide by precision\r\n\r\n\r\n\r\n    // @notice This contract has the utilities necessary for the Staking Endowment Token below\r\n    event StartStake(\r\n        address indexed stakeAddress,  // Address\r\n        uint256 indexed stakeId,\r\n        uint256 indexed eventName,\r\n        uint256 startDay,\r\n        uint256 stakedDays,\r\n        uint256 principle,\r\n        uint256 possibleInterest\r\n    );\r\n\r\n    event ScrapeStake(\r\n        address indexed stakeAddress,\r\n        uint256 indexed stakeId,\r\n        uint256 indexed eventName,\r\n        uint256 scrapeDay,\r\n        uint256 previousScrapedInterest,\r\n        uint256 oldPossibleInterest,\r\n        uint256 scrapedInterest,\r\n        uint possibleInterest\r\n    );\r\n\r\n    event EndStake(\r\n        address indexed stakeAddress,\r\n        uint256 indexed stakeId,\r\n        uint256 indexed eventName,\r\n        uint256 endStakeDay,\r\n        uint256 principle,\r\n        uint256 oldPossibleInterest,\r\n        uint256 scrapedInterest,\r\n        uint256 penalties,\r\n        uint256 stakeTotal\r\n    );\r\n\r\n    // @dev Memory resident Stake for temporary use\r\n    // @param uint256 _stakeId\r\n    // @param uint256 _stakedPrinciple\r\n    // @param uint256 _startDay\r\n    // @param uint256 _scrapeDay\r\n    // @param uint256 _stakedDays\r\n    // @param uint256 _scrapedInterest\r\n    // @param uint256 _possibleStars\r\n    struct TempStake {\r\n        uint256 _stakeId;\r\n        uint256 _stakedPrinciple;\r\n        uint256 _startDay;\r\n        uint256 _scrapeDay;\r\n        uint256 _stakedDays;\r\n        uint256 _scrapedInterest;\r\n        uint256 _possibleStars;\r\n    }\r\n\r\n    // @dev Permenant Stake for Storage\r\n    // @param uint256 stakeId The stake ID\r\n    // @param uint256 stakedPrinciple The initial principle staked\r\n    // @param uint256 startDay The day the stake was started\r\n    // @param uint256 scrapeDay The day the stake was scraped\r\n    // @param uint256 stakedDays The days of the stake commitment\r\n    // @param uint256 scrapedInterest The interest that has been scraped if any\r\n    // @param uint256 possibleStars The potential amount of stars for this stake\r\n    struct PermStake {\r\n        uint256 stakeId;\r\n        uint256 stakedPrinciple;\r\n        uint256 startDay;\r\n        uint256 scrapeDay;\r\n        uint256 stakedDays;\r\n        uint256 scrapedInterest;\r\n        uint256 possibleStars;\r\n    }\r\n\r\n    // initialize the Store of Stakes.\r\n    mapping(address =\u003e PermStake[]) public Stakes;\r\n\r\n    // @dev Private: This emits the event\r\n    // and was moved due to stack limits\r\n    // @param uint256 stakeId - the stake id\r\n    // @param uint256 interestDays the days of interest applied in this case\r\n    // @param uint256 previousInterest - the amount of interest previously scraped\r\n    // @param uint256 previousPossibleStars - what the previous amount of interest was before the scrape\r\n    // @param uint256 scrapedInterest - the amount of interest scraped by this action\r\n    // @param uint256 newPossibleIntest - the possible interest\r\n    function emitScrapeEvent(uint256 stakeId, uint256 interestDays, uint256 previousInterest, uint256 previousPossibleStars, uint256 scrapedInterest, uint256 newPossibleInterest ) \r\n    internal \r\n    {\r\n        // Emit the stake scrape event\r\n        emit ScrapeStake(\r\n            msg.sender,         // event Sender set here\r\n            stakeId,            // stake Id\r\n            uint(2),            // event id is 2\r\n            interestDays,\r\n            previousInterest,\r\n            previousPossibleStars,\r\n            scrapedInterest,\r\n            newPossibleInterest\r\n        );\r\n    }\r\n\r\n    // @dev Public Function: Open a stake.\r\n    // @param uint256 stakedPrinciple Number of Stars to stake\r\n    // @param uint256 stakedDays length of days in the stake\r\n    function startStake(uint256 stakedPrinciple, uint256 stakedDays)\r\n    external\r\n    {\r\n        // make sure the stake params are within guidelines or throw an error\r\n        _assurePrincipleAndStakedDaysAreValid(stakedPrinciple, stakedDays);\r\n        \r\n        //Calculate possible payout\r\n        uint256 possibleInterest = _calculateInterest(stakedPrinciple, stakedDays);\r\n        \r\n        // Create total possible stars\r\n        uint256 possibleStars = possibleInterest + stakedPrinciple;  // ALL possible interest AND principle\r\n        \r\n        require(_endowmentSupply \u003e  possibleInterest, \"There is not enough to cover your stake\");\r\n\r\n        // Start the stake\r\n        _startStake(stakedPrinciple, stakedDays, possibleStars);\r\n        \r\n\r\n        // the principle is burned from token supply, and the possible interest is pulled from the endowmentSupply\r\n        _endowmentSupply = _endowmentSupply - possibleInterest; \r\n        \r\n        \r\n        // Add to global counter\r\n        // Add principle only\r\n        g_stakedPrincipleStars += stakedPrinciple;\r\n        // Add all possible interest and principle to stakedStars.\r\n        g_stakedStars += possibleStars;\r\n        // Stake is official Ready to go\r\n    }\r\n\r\n    // @dev Public Function: Scrape stake\r\n    // @dev This will calculate the eligible days since the previous stake\r\n    // and mint the interest back to the user. This will also recalculate\r\n    // the possible amount of interest.\r\n    // @param uint256 stakeIndex  the index of the stake based on the order of active stakes\r\n    // @param uint256 myStakeId The stake\u0027s id that is unique to the stake\r\n    function scrapeStake(uint256 stakeIndex, uint256 myStakeId)\r\n    external\r\n    {\r\n        PermStake[] storage permStakes = Stakes[msg.sender];\r\n        require(permStakes.length != 0, \"Empty stake list\");\r\n        require(stakeIndex \u003c permStakes.length, \"stakeIndex invalid\");\r\n        \r\n        // load a copy of temporary stake \r\n        TempStake memory stake = TempStake(0,0,0,0,0,0,0);\r\n\r\n        _loadStake(permStakes[stakeIndex], myStakeId, stake);\r\n        // load up the stake reference also\r\n        PermStake storage permStakeRef = Stakes[msg.sender][stakeIndex];\r\n        // Defaults\r\n        uint256 previousInterest = stake._scrapedInterest;\r\n        uint256 previousPossibleStars = stake._possibleStars;\r\n        // Calculate Days\r\n        uint[6] memory calcDays = _calculateStakeDays(stake._startDay, stake._stakedDays, stake._scrapeDay);\r\n        // Returns Calculated Days in an array like below\r\n        // 0 curDay - Current Day\r\n        // 1 startDay - Start Day\r\n        // 2 scrapeDay - The previous day this was scraped - (default to startDay, and is set when scraped)\r\n        // 3 endOfStakeDay - The final day of this stake (startDay + stakedDays or total days in stake)\r\n        // 4 interestDays - Days that are used to CALCULATE INTEREST\r\n        // 5 possibleDays -  (endOfStakeDays - currentDay)\r\n        // scrapeServedDays // days that are interest bearing days\r\n        uint256 currentInterest = 0;\r\n        uint256 lostInterest = 0;\r\n        uint256 newPossibleInterest = 0;\r\n        uint256 curDay = calcDays[0];\r\n        // the stake start day must be \u003c the currentDay\r\n        require(curDay \u003e stake._startDay, \"Scraping is not allowed, stake must start first\");\r\n        // make sure the curDay is within the scope of \"scrapeable days\"\r\n        require(curDay \u003c= calcDays[3], \"Scraping is not allowed, must end stake\");\r\n\r\n        \r\n        // Scraping is allowed only if the curDay is greater than the scrapeDay\r\n        //PER SEI-04 - to save possible gas for the user\r\n        require(curDay \u003e calcDays[2], \"Scraping is not allowed until 1 or more staked days has completed\");\r\n\r\n        // we will require this check so it doesn\u0027t waste resource by running these other calcs\r\n        // you can\u0027t scrape twice on the same day so current Day must greater than previous scraped day\r\n        // will equal 0 or previous accumulated amount\r\n        previousInterest = stake._scrapedInterest;\r\n        // total possible interest that was reserved for your stake\r\n        // previousPossibleStars = stake._possibleStars; //includes principle\r\n        // Calculate total based on interestDays\r\n        currentInterest = _calculateInterest(stake._stakedPrinciple, calcDays[4]);\r\n        // Calculate NEW possibleInterest based on EndofStake Days - currentDay\r\n        newPossibleInterest = _calculateInterest(stake._stakedPrinciple, (calcDays[3]-calcDays[0]));\r\n        uint newPossibleInterestPlusPrinciple = newPossibleInterest + stake._stakedPrinciple;\r\n        // Lost interest = the interest you could have had - what you have now\r\n        // What I have: \r\n            // previousPossibleStars - (includes principle)\r\n            // newPossibleInterestPlusPrinciple  - newPossibleInterest also include principle\r\n            // currentInterest - what we are minting for interest\r\n        // just in case the previous possible interest is less than the new possible interest\r\n        uint previousStarsAndCurrentInterest = previousPossibleStars \u003e currentInterest ? (previousPossibleStars - currentInterest) : 0;\r\n        if (previousStarsAndCurrentInterest \u003e newPossibleInterestPlusPrinciple) {\r\n            // lost interest gets minted back to the OA\r\n            lostInterest = previousStarsAndCurrentInterest - newPossibleInterestPlusPrinciple;\r\n        }\r\n        // Now do the work based on values above calculate actual payout\r\n        // penalties do not happen here, because there is a force closed function.\r\n        // If there is accrued interest, send this back to the user\r\n        // If there is no accrued interest, then nothing changes and all stays the same.\r\n        if (currentInterest != 0) {\r\n\r\n            // Mint this back to message sender\r\n            _mint(msg.sender, currentInterest);\r\n            \r\n            // Mint lost interest back to the endowment supply\r\n            if (lostInterest \u003e 0) {\r\n                 _endowmentSupply = _endowmentSupply + lostInterest;\r\n            }\r\n\r\n\r\n            // Set the total amount of accrued interest\r\n            stake._scrapedInterest = previousInterest + currentInterest;\r\n            // set the new possible interest in the stake... should continually get smaller and smaller\r\n            stake._possibleStars  = newPossibleInterestPlusPrinciple;\r\n            // Set the Scrape day to today\r\n            stake._scrapeDay = curDay;\r\n            //update the current stake to the new values\r\n            _updateStake(permStakeRef, stake);\r\n            // Emit the stake scrape event\r\n            emitScrapeEvent(\r\n                stake._stakeId,\r\n                uint256(calcDays[4]),\r\n                uint256(previousInterest),\r\n                previousPossibleStars,\r\n                stake._scrapedInterest,\r\n                newPossibleInterest\r\n            );\r\n            // update global values\r\n            // Adds back previous possible interest to the global variable\r\n            g_stakedStars -= previousPossibleStars;\r\n            // Removes the new current possible interest \r\n            g_stakedStars += newPossibleInterestPlusPrinciple;\r\n        }\r\n    }\r\n\r\n    // @dev Public Function: End the Stake: This will calculate the amount of\r\n    // interest, mint it back to the user, and remove the stake from the stakeList Map\r\n    // @param uint256 stakeIndex  the index of the stake based on order and may change based on active stakes\r\n    // @param uint256 myStakeId The stake\u0027s id\r\n    function endStake(uint256 stakeIndex, uint256 myStakeId)\r\n    external\r\n    {\r\n        PermStake[] storage permStakes = Stakes[msg.sender];\r\n        require(permStakes.length != 0, \"Stake List is Empty\");\r\n        require(stakeIndex \u003c permStakes.length, \"not a valid stakeIndex\");\r\n        \r\n        // get temporary stake into memory\r\n        TempStake memory stake = TempStake(0,0,0,0,0,0,0);\r\n\r\n        _loadStake(permStakes[stakeIndex], myStakeId, stake);\r\n        // Defaults\r\n        uint256 servedDays = 0;\r\n        uint256 stakeTotal;\r\n        uint256 interestAccrued = 0;\r\n        uint256 penalty = 0;\r\n        // Calculate Days - returns Calculated Days in an array like below\r\n        // 0 curDay - Current Day\r\n        // 1 startDay - Start Day\r\n        // 2 scrapeDay - The previous day this was scraped - (default to startDay, and is set when scraped)\r\n        // 3 endOfStakeDay - The final day of this stake (startDay + stakedDays or total days in stake)\r\n        // 4 interestDays - Days that are used to CALCULATE INTEREST\r\n        // 5 possibleDays -  (endOfStakeDays - currentDay)\r\n        uint[6] memory calcDays = _calculateStakeDays(stake._startDay, stake._stakedDays, stake._scrapeDay);\r\n        // Stake Insurance - in case someone makes a mistake\r\n        // if The stake has not started, then mint all possible back to the OA (removed)\r\n        // if The stake has not started, then mint all possible back to the Endowment Supply\r\n        if (calcDays[0] \u003c calcDays[1]) {\r\n\r\n            // Add the possible stars back to the endowment supply (minus the principle of course)\r\n            _endowmentSupply = _endowmentSupply + (stake._possibleStars - stake._stakedPrinciple);\r\n\r\n            \r\n            // make sure that stakeTotal and penalty = 0 \r\n            stakeTotal = 0;\r\n            penalty = 0;\r\n            // Add principle back to user\r\n            _mint(msg.sender, stake._stakedPrinciple);\r\n            // remove this from global stats\r\n            g_stakedStars -= stake._possibleStars;\r\n             \r\n\r\n            // remove from the global principle stats\r\n            g_stakedPrincipleStars -= stake._stakedPrinciple;\r\n        \r\n        } else {\r\n            // served days is day from start day\r\n            servedDays = calcDays[0] - calcDays[1];\r\n            // calculate stake performance\r\n            (stakeTotal, interestAccrued, penalty) = _calculateStakeTotal(stake);\r\n\r\n            // Check for penalties\r\n            if (penalty \u003e 0) {\r\n                // Zero interest gets returned\r\n                // Possible Interest should get sent back to Endowment Supply\r\n                _endowmentSupply += (stake._possibleStars - stake._stakedPrinciple);\r\n                \r\n                // Update global variables - to keep track of penalizedStars\r\n                g_penalizedStars += penalty;\r\n\r\n                // Remove possible stars from the global variable g_stakedStars\r\n                if(g_stakedStars \u003e= (stake._possibleStars)){\r\n                    g_stakedStars -= (stake._possibleStars);\r\n                }\r\n                                \r\n                // Remove the principle amount from global variable g_stakedPrincipleStars\r\n                if(g_stakedPrincipleStars \u003e= stake._stakedPrinciple){\r\n                    g_stakedPrincipleStars -= stake._stakedPrinciple;\r\n                }\r\n\r\n            } else {\r\n                // This is a good stake\r\n                // There are no possible stars anymore\r\n                // There is only interestAccrued, so remove that from global variable g_stakedStars\r\n\r\n                // Remove all possible stars from g_stakedstars\r\n                if (g_stakedStars \u003e= interestAccrued){\r\n                    g_stakedStars -= interestAccrued;    \r\n                }\r\n                // Possible Stars has Principle Included... InterestAccrued does not.\r\n                // so we need to back out the principle also\r\n                if (g_stakedStars \u003e= stake._stakedPrinciple){\r\n                    g_stakedStars -= stake._stakedPrinciple;    \r\n                }\r\n\r\n                // NOTE: Stake Total is Both the interestAccrued + Principle and that \r\n                // goes back to the user\r\n\r\n                // Speaking of principle, let\u0027s also remove it from g_stakedPrincipleStars\r\n                if(g_stakedPrincipleStars \u003e= stake._stakedPrinciple){\r\n                    g_stakedPrincipleStars -= stake._stakedPrinciple;    \r\n                }\r\n            }\r\n\r\n            // Calculations are done, so let\u0027s mint back to the user,\r\n            // Stake total could equal principle + stars, or principle - penalty\r\n            if (stakeTotal != 0) {\r\n                // We do not mint penalties back\r\n                // This amount should be principle + any Interest Earned\r\n                // OR if penalties, then this is principle minus penalties\r\n                \r\n                _mint(msg.sender, stakeTotal);\r\n                \r\n                // minted stake total back to user\r\n                // ready to end the stake, so continue\r\n\r\n            }\r\n        } // end else\r\n        \r\n        // emit the stake end event and remove the stake from Stakes\r\n        emit EndStake(\r\n            msg.sender,\r\n            stake._stakeId,\r\n            uint256(3), // stake event id\r\n            uint256(calcDays[3]),\r\n            uint256(stake._stakedPrinciple),\r\n            uint256(stake._possibleStars),\r\n            uint256(stake._scrapedInterest),\r\n            uint256(penalty),\r\n            uint256(stakeTotal)\r\n        );\r\n        // Remove the Stake from your stake list\r\n        uint256 lastIndex = permStakes.length - 1;\r\n        // If it\u0027s the last element, then skip\r\n        if (stakeIndex != lastIndex) {\r\n            permStakes[stakeIndex] = permStakes[lastIndex];\r\n        }\r\n        permStakes.pop();\r\n        // stake remove is finished - remove from the the global Active Stakes Count\r\n\r\n        g_stakedCount = g_stakedCount - 1;\r\n    }\r\n\r\n    // @dev get the allocated supply of the token\r\n    function allocatedSupply()\r\n    external\r\n    view\r\n    returns (\r\n        uint256\r\n    )\r\n    {\r\n        return _allocatedSupply();\r\n    }\r\n\r\n    // @dev Public Function: Returns the current Day since the launch date\r\n    // @return current day number\r\n    function currentDay()\r\n    external\r\n    view\r\n    returns (\r\n        uint\r\n    )\r\n    {\r\n        return _currentDay();\r\n    }\r\n\r\n    // @dev Reports Global gives a list of global variables for reporting\r\n    // returns:\r\n    // uint256 staked_stars,  sum of interest + principle\r\n    // uint256 staked_principle_stars  // total staked based only on principle, what users actually staked,\r\n    // uint256 total_supply, \r\n    // uint256 allocated_supply,\r\n    // uint256 penalized_stars,\r\n    // uint256 current_day,\r\n    // uint256 latest_stake_id\r\n    // uint256 staked_count total active stakes + and - at the end of startStake and endStake\r\n    function reportGlobals()\r\n    external\r\n    view\r\n    returns (\r\n        uint256 staked_stars, \r\n        uint256 staked_principle_stars,\r\n        uint256 total_supply,\r\n        uint256 allocated_supply,\r\n        uint256 penalized_stars,\r\n        uint256 current_day,\r\n        uint256 latest_stake_id,\r\n        uint256 staked_count,\r\n        uint256 endowment_supply\r\n    )\r\n    {\r\n        staked_stars = g_stakedStars;\r\n        staked_principle_stars = g_stakedPrincipleStars;\r\n        \r\n\r\n        total_supply = super.totalSupply() + g_stakedStars + _endowmentSupply;\r\n        \r\n\r\n        allocated_supply = _allocatedSupply();\r\n        penalized_stars = g_penalizedStars;\r\n        current_day = _currentDay();\r\n        latest_stake_id = g_latestStakeId;\r\n        staked_count = g_stakedCount;\r\n        endowment_supply = _endowmentSupply;\r\n\r\n        return (staked_stars, staked_principle_stars, total_supply, allocated_supply, penalized_stars, current_day, latest_stake_id, staked_count, endowment_supply);\r\n    }\r\n\r\n    // @dev Public Function: Return the count of stakes in the stakeList map\r\n    // @param address userAddress - address of staker\r\n    function countStakes(address userAddress)\r\n    external\r\n    view\r\n    returns (\r\n        uint256\r\n    )\r\n    {\r\n        return Stakes[userAddress].length;\r\n    }\r\n\r\n    // Calculate Days\r\n    // Returns Calculated Days in an array like below\r\n    // 0 curDay - Current Day\r\n    // 1 startDay - Start Day\r\n    // 2 scrapeDay - The previous day this was scraped - (default to startDay, and is set when scraped)\r\n    // 3 endOfStakeDay - The final day of this stake (startDay + stakedDays or total days in stake)\r\n    // 4 interestDays - Days that are used to CALCULATE INTEREST\r\n    // 5 possibleDays -  (endOfStakeDays - currentDay)\r\n    // @param uint256 tempStartDay\r\n    // @param uint256 tempStakedDays\r\n    // @param uint256 tempScrapeDay\r\n    function calculateStakeDays(uint256 tempStartDay, uint256 tempStakedDays, uint256 tempScrapeDay)\r\n    external\r\n    view\r\n    returns (\r\n        uint[6] memory\r\n    )\r\n    {\r\n        uint[6] memory calcDays = _calculateStakeDays(tempStartDay, tempStakedDays, tempScrapeDay);\r\n        return (calcDays);\r\n    }\r\n\r\n    // @dev Calculate the interest of a scenario\r\n    // @param uint256 stakedPrinciple The amount of principle for the stake\r\n    // @param uint256 stakedDays the number of days to commit to a stake\r\n    function calculateInterest(uint256 stakedPrinciple, uint256 stakedDays)\r\n    external\r\n    pure\r\n    returns(\r\n        uint256 interest\r\n    )\r\n    {\r\n        _assurePrincipleAndStakedDaysAreValid(stakedPrinciple, stakedDays);\r\n        interest = _calculateInterest(stakedPrinciple, stakedDays);\r\n\r\n        return (interest);\r\n    }\r\n\r\n    // @dev This give the totalsupply plus the totalstaked.  Total staked also\r\n    // includes the interest that may be accrued from time and principle.\r\n    // @return Allocated Supply in Stars\r\n    function _allocatedSupply()\r\n    private\r\n    view\r\n    returns (\r\n        uint256\r\n    )\r\n    {\r\n\r\n        return super.totalSupply() + g_stakedStars;\r\n\r\n    }\r\n\r\n    // @dev Private function that calculates the current day from day 1\r\n    // @return Current day number\r\n    function _currentDay()\r\n    internal\r\n    view\r\n    returns (\r\n        uint256 temp_currentDay\r\n    )\r\n    {\r\n        return (block.timestamp - LAUNCH_TIME) / 1 days;\r\n    }\r\n\r\n    // @dev Private Function to load the stake into memory\r\n    // Takes stake store and pushes the values into it\r\n    // @param PermStake stakeRef reference of values to get\r\n    // @param uint256 myStakeId or the globalStakeId\r\n    // @param TempStake stake to load into memory as st or current stake\r\n    // Requirements:\r\n    // `stakeId must exist in the list`, so both the position (zero index AND stakeID must be correct)\r\n    function _loadStake(PermStake storage stakeRef, uint256 myStakeId, TempStake memory stake)\r\n    internal\r\n    view\r\n    {\r\n        //require current stake index is valid\r\n        require(myStakeId == stakeRef.stakeId, \"myStakeId not in stake\");\r\n        stake._stakeId = stakeRef.stakeId;\r\n        stake._stakedPrinciple = stakeRef.stakedPrinciple;\r\n        stake._startDay = stakeRef.startDay;\r\n        stake._scrapeDay = stakeRef.scrapeDay;\r\n        stake._stakedDays = stakeRef.stakedDays;\r\n        stake._scrapedInterest = stakeRef.scrapedInterest;\r\n        stake._possibleStars = stakeRef.possibleStars;\r\n    }\r\n\r\n    // @dev Private Function for updating the stake\r\n    // returns nothing, it just updates the stake passed to it\r\n    // @param PermStake stakeRef the reference to the original mapping of the stake store\r\n    // @param TempStake stake the new instance to update from\r\n    function _updateStake(PermStake storage stakeRef, TempStake memory stake)\r\n    internal\r\n    {\r\n        stakeRef.stakeId = stake._stakeId;\r\n        stakeRef.stakedPrinciple = uint256(stake._stakedPrinciple);\r\n        stakeRef.startDay = uint256(stake._startDay);\r\n        stakeRef.scrapeDay = uint256(stake._scrapeDay);\r\n        stakeRef.stakedDays = uint256(stake._stakedDays);\r\n        stakeRef.scrapedInterest = uint256(stake._scrapedInterest);\r\n        stakeRef.possibleStars = uint256(stake._possibleStars);\r\n    }\r\n\r\n    // @dev Internal Function Start a Stake Internal Function\r\n    // @param uint256 stakedPrinciple\r\n    // @param uint256 stakedDays length of days in the stake\r\n    // @param uint256 possibleStars allocated total for this stake\r\n    function _startStake(\r\n        uint256 stakedPrinciple,\r\n        uint256 stakedDays,\r\n        uint256 possibleStars\r\n    )\r\n    private\r\n    {\r\n        // Get the current day\r\n        uint256 cday = _currentDay();\r\n        // starts the next day\r\n        uint256 startDay = cday + 1;\r\n        // automaticall set scrape day to start day\r\n        uint256 scrapeDay = startDay;\r\n        // Burn the tokens from the sender\r\n        _burn(msg.sender, stakedPrinciple);\r\n        // Get the global stake id and create the stake\r\n        uint256 newStakeId = ++g_latestStakeId;\r\n        // push the new stake into the sender\u0027s stake list\r\n        Stakes[msg.sender].push(\r\n            PermStake(\r\n                newStakeId,\r\n                stakedPrinciple,\r\n                startDay,\r\n                scrapeDay,\r\n                stakedDays,\r\n                uint256(0),\r\n                possibleStars\r\n            )\r\n        );\r\n        // emit the stake start event\r\n        emit StartStake(\r\n            msg.sender,\r\n            uint256(newStakeId),\r\n            uint256(1),\r\n            startDay,\r\n            stakedDays,\r\n            stakedPrinciple,\r\n            possibleStars\r\n        );\r\n        // Add to the global Active Stakes\r\n        g_stakedCount = g_stakedCount + 1;\r\n    }\r\n\r\n    // @dev Require and validate the basic min/max stake parameters\r\n    // @param uint256 principle\r\n    // @param uint256 servedDays\r\n    function _assurePrincipleAndStakedDaysAreValid(uint256 principle, uint256 servedDays)\r\n    internal\r\n    pure\r\n    {\r\n        // validate the stake days and principle \r\n        require(servedDays \u003e= MIN_STAKE_DAYS, \"Stake length is too small\");\r\n        require(servedDays \u003c= MAX_STAKE_DAYS, \"Stake length is too large\");\r\n        require(principle \u003e= MIN_STAKE_AMOUNT, \"Principle is not high enough\");\r\n        require(principle \u003c= MAX_STAKE_AMOUNT, \"Principle is too high\");\r\n    }\r\n\r\n    // @dev Calculate Interest Function\r\n    // @notice This calculates the amount of interest for the number of servedDays.\r\n    // This divides up served days into buckets of yearly increments based on 365.25 days\r\n    // Then applies the rate of return based on the interestTable.\r\n    // @param uint256 principle - the principle to apply\r\n    // @param uint256 servedDays - the number of days to calculate.\r\n    function _calculateInterest(uint256 principle, uint256 servedDays)\r\n    internal\r\n    pure\r\n    returns(\r\n        uint256 totalInterest\r\n    )\r\n    {\r\n        // year is 365.25, but we need to multiply by 100 to keep it integer\u0027istic\r\n        uint256 workingDays = servedDays * YEARPRECISION;\r\n        // This will fill up based on the days.\r\n        // Daily Interest Table is based on 18 decimals so\r\n        uint[23] memory dailyInterestTable = _getDailyInterestTable();\r\n        // Set an index to increment for the while loops\r\n        uint256 workingidx = 0;\r\n        uint256 appliedInterestRate = 0;\r\n        uint256 tempInterestAmount = 0;\r\n        uint256 current = 0;\r\n\r\n        while (workingidx \u003c MAX_STAKE_YEARS) {\r\n            if (workingDays \u003e YEARDIVIDER) {\r\n                current = YEARDIVIDER;\r\n                workingDays -= YEARDIVIDER;\r\n            } else {\r\n                // x is less than than MaxStakeYears, so set the remainder to this.\r\n                current = workingDays;  // this will give the days left over\r\n                workingDays = 0;\r\n            }\r\n            // apply this years interest rate to the days inside that year\r\n            appliedInterestRate = dailyInterestTable[workingidx];\r\n            \r\n            // days (36525) * interest for this year divided by 100 multiplied by principle then divide py precision\r\n            \r\n            // tempInterestAmount = (((current * appliedInterestRate) / YEARPRECISION) * principle) / (PRECISION * PRECISION); //36 decimals\r\n            \r\n            uint tempInterestAmountNumerator = 0;\r\n            tempInterestAmountNumerator = ((current * appliedInterestRate) * principle) / YEARPRECISION;\r\n            tempInterestAmount = tempInterestAmountNumerator / (PRECISION * PRECISION); //36\r\n\r\n            // apply the principle and add it to the running total of interest\r\n            totalInterest += tempInterestAmount;   // divide by 100 because of our days... days return as 36525 and not 365.25\r\n            workingidx = workingidx + 1;  // keep running for the full 22 years.\r\n            if (workingDays == 0) {\r\n                break;\r\n            }\r\n        }\r\n\r\n        return (totalInterest);\r\n    }\r\n\r\n    // @dev CalculatePenalty\r\n    // @notice This calculates the penalty if there is one.\r\n    // The rules for penalty:\r\n    //     - if a stake is less than 50% complete, then you get 50% of your principle returned\r\n    //     - if a stake is greater than 50%, you get the percentage back for each day from 100%\r\n    //         example: Stake is 60% complete. You should receive 60% of your principle back.\r\n    // @param TempStake stake the stake to calculate penalties for\r\n    function _calculatePenalty(TempStake memory stake)\r\n    internal\r\n    view\r\n    returns(\r\n        uint256 penaltyAmount\r\n    )\r\n    {\r\n        // calculate the penalty for forcing and end stake\r\n        uint[6] memory calcDays = _calculateStakeDays(stake._startDay, stake._stakedDays, stake._scrapeDay);\r\n        uint256 pct = 0;\r\n        uint256 pctleft = 0;\r\n        uint256 pctprecision = 100;\r\n        uint256 daysSinceStart = 0;\r\n        uint256 totalStakeDays = stake._stakedDays * pctprecision;\r\n        // Check served days to make sure it\u0027s at least 1\r\n        if (totalStakeDays \u003c= 0) {\r\n            totalStakeDays = 1 * pctprecision; //sets minimum amt for calculation        \r\n        }\r\n        if (calcDays[0] \u003c calcDays[1]) {\r\n            // should never happen... condition handled in parent\r\n        } else if (calcDays[0] == calcDays[1]) {\r\n            daysSinceStart = (1 * pctprecision);\r\n        } else {\r\n            // number of days since start day\r\n            daysSinceStart = (calcDays[0] - calcDays[1]) * pctprecision;\r\n        }\r\n        // basic pct made here\r\n        pct = (daysSinceStart * pctprecision) / totalStakeDays;\r\n        // decision time - anything 50 or less is counted as 50\r\n        if (pct \u003c= 50) {\r\n            pctleft = 50;\r\n        } else if (pct \u003e 50 \u0026\u0026 pct \u003c 100) {\r\n            pctleft = 100 - pct;\r\n        } else {\r\n            pctleft = 0;\r\n        }\r\n        // calculate penalties from pctleft\r\n        penaltyAmount = (stake._stakedPrinciple * pctleft) / 100;\r\n        // This cannot be less than zero\r\n        if (penaltyAmount \u003c= 0) {\r\n            penaltyAmount = 0;\r\n        }\r\n        // this should never exceed the amount, but just in case lets test for it anyway\r\n        if (penaltyAmount \u003e stake._stakedPrinciple) {\r\n            penaltyAmount = stake._stakedPrinciple;\r\n        }\r\n\r\n        return (penaltyAmount);\r\n    }\r\n\r\n    // @param TempStake stake\r\n    function _calculateStakeTotal(TempStake memory stake)\r\n    internal\r\n    view\r\n    returns (\r\n        uint256 stakeTotal,\r\n        uint256 currentInterest,\r\n        uint256 penalty\r\n    )\r\n    {\r\n        penalty = 0;\r\n        stakeTotal = 0;  // total return of the stake\r\n        currentInterest = 0;\r\n        uint256 appliedPrinciple = 0;\r\n        uint256 previousInterest = stake._scrapedInterest;\r\n        uint[6] memory calcDays = _calculateStakeDays(stake._startDay, stake._stakedDays, stake._scrapeDay);\r\n        // Returns Calculated Days in an array like below\r\n        // 0 curDay - Current Day\r\n        // 1 startDay - Start Day\r\n        // 2 scrapeDay - The previous day this was scraped - (default to startDay, and is set when scraped)\r\n        // 3 endOfStakeDay - The final day of this stake (startDay + stakedDays or total days in stake)\r\n        // 4 interestDays - Days that are used to CALCULATE INTEREST\r\n        // 5 possibleDays -  (endOfStakeDays - currentDay)\r\n        // if InterestDays is less than staked days\r\n        // if (calcDays[4] \u003c stake._stakedDays) {\r\n        // if currentDay is less than endofstake day\r\n        if (calcDays[0] \u003c calcDays[3]) {\r\n            // calculate the penalty if any\r\n            penalty = _calculatePenalty(stake);\r\n            if (penalty \u003e stake._stakedPrinciple) {\r\n                // this should never happen but if it does, then set to 50% of the principle\r\n                appliedPrinciple = stake._stakedPrinciple / 2;\r\n            } else {\r\n                // this should return a \"prorated\" amount of principle from 51% to 99%\r\n                appliedPrinciple = (stake._stakedPrinciple - penalty);\r\n            }\r\n            // A broken stake will only give you the portion of your principle back, not your interest.\r\n            stakeTotal = appliedPrinciple;\r\n            currentInterest = 0;\r\n        } else {\r\n            // There is no penalty if stake is completed\r\n            currentInterest = _calculateInterest(stake._stakedPrinciple, calcDays[4]);\r\n            // Set the total amount of accrued interest\r\n            stake._scrapedInterest = previousInterest + currentInterest;\r\n            // stake is finished, so we set this to zero\r\n            stake._possibleStars = 0;\r\n            // total amount of stake to be returned to user\r\n            stakeTotal = currentInterest + stake._stakedPrinciple;\r\n            penalty = 0;\r\n        }\r\n    }\r\n\r\n    // This returns days in this order:\r\n    // 0 curDay - Current Day\r\n    // 1 startDay - Start Day\r\n    // 2 scrapeDay - The previous day this was scraped - (default to startDay, and is set when scraped)\r\n    // 3 endOfStakeDay - The final day of this stake (startDay + stakedDays or total days in stake)\r\n    // 4 interestDays - Days that are used to CALCULATE INTEREST\r\n    // 5 possibleDays -  (endOfStakeDays - currentDay)\r\n    // @dev Calculate Days\r\n    // @notice This returns an array of calculated days of your stake based on the current day.\r\n    // @param uint256 startDay\r\n    // @param uint256 stakedDays length of days in the stake\r\n    // @param uint256 scrapeDay\r\n    function _calculateStakeDays(uint256 startDay, uint256 stakedDays, uint256 scrapeDay)\r\n    internal\r\n    view\r\n    returns (uint[6] memory)\r\n    {\r\n        // if the stakedDays is less than the minimum, throw an error\r\n        require(stakedDays \u003e= MIN_STAKE_DAYS, \"stake days must be greater than 1\");\r\n        uint256 curDay = _currentDay();  //ex. day 25\r\n        uint256 endOfStakeDay = startDay + stakedDays; //ex. Day 52\r\n        // find the higher of the two days ( startDay or a more recent scrapeDay )\r\n        uint256 targetStartDay = scrapeDay \u003e= startDay ? scrapeDay : startDay;\r\n        // the possible interest bearing days\r\n        uint256 possibleDays = endOfStakeDay - targetStartDay;\r\n        uint256 interestDays = 0;\r\n        // if the currentDay is greater than the end stake day, we subtract:\r\n        // targetStartDay from the endOfStakeDay giving us the interest days.\r\n        // otherwise we take the currentDay and subtract the same targetStartDay because it\u0027s still an active stake.\r\n        if (targetStartDay \u003e curDay) {\r\n            // probably a new stake so we\u0027ll default to zero\r\n            // this also keeps this from subtracting current day from target day\r\n            // and for the beginning of a stake, it will be a negative 1\r\n            interestDays = 0;\r\n        } else {\r\n            interestDays = curDay \u003e= endOfStakeDay ? (endOfStakeDay - targetStartDay) : (curDay - targetStartDay);\r\n        }\r\n\r\n        return [\r\n            uint(curDay),\r\n            startDay,\r\n            scrapeDay,\r\n            endOfStakeDay,\r\n            interestDays,\r\n            possibleDays\r\n        ];\r\n    }\r\n\r\n    // @dev getDailyInterestTable\r\n    // @notice This table has precalculated values for the 22 year buckets that calculate the interest\r\n    // based on the number of days you have within each year.\r\n    function _getDailyInterestTable()\r\n    internal\r\n    pure\r\n    returns (uint[23] memory tableOfInterest)\r\n    {\r\n        // These values are precalculated and will never change once this is made live.\r\n        // based on 36 decimals\r\n        tableOfInterest = [\r\n        uint(136892539356605065023956194387405), \r\n             164271047227926078028747433264887, \r\n             219028062970568104038329911019849, \r\n             301163586584531143052703627652292, \r\n             410677618069815195071868583162217, \r\n             547570157426420260095824777549623, \r\n             711841204654346338124572210814510, \r\n             903490759753593429158110882956878, \r\n             1122518822724161533196440793976728, \r\n             1368925393566050650239561943874058, \r\n             1642710472279260780287474332648870, \r\n             1943874058863791923340177960301163, \r\n             2272416153319644079397672826830937, \r\n             2628336755646817248459958932238193, \r\n             3011635865845311430527036276522929, \r\n             3422313483915126625598904859685147, \r\n             3860369609856262833675564681724845, \r\n             4325804243668720054757015742642026, \r\n             4818617385352498288843258042436687, \r\n             5338809034907597535934291581108829, \r\n             5886379192334017796030116358658453, \r\n             6461327857631759069130732375085557, \r\n             0\r\n            ];\r\n\r\n        return (tableOfInterest);\r\n    }\r\n\r\n\r\n    /**\r\n     * @dev See {IERC20-totalSupply}.\r\n     */\r\n    function totalSupply() public view override returns (uint256) {\r\n        // The Endowment Supply is the total amount of token available for staking rewards to the stakers.\r\n        // A proper representation of Total Supply is the Endowment Supply + what is in the ERC20 total supply\r\n        uint totSupply = super.totalSupply() + g_stakedStars + _endowmentSupply;\r\n\r\n        return (totSupply);\r\n    }\r\n    /**\r\n     * @dev Follows same convention as IERC20-totalsupply\r\n     */\r\n    function endowmentSupply() public view returns (uint256) {\r\n        // The Endowment Supply is the total amount of token available for staking rewards to the stakers.\r\n        // A proper representation of Total Supply is the Endowment Supply + what is in the ERC20 total supply\r\n        return _endowmentSupply;\r\n    }    \r\n    \r\n    /**\r\n     * @dev Follows same convention as IERC20-totalsupply\r\n     */\r\n    function originalSupply() public view returns (uint256) {\r\n        // The Endowment Supply is the total amount of token available for staking rewards to the stakers.\r\n        // A proper representation of Total Supply is the Endowment Supply + what is in the ERC20 total supply\r\n        return (super.totalSupply());\r\n    }\r\n\r\n}"},"TEXAN.sol":{"content":"/// SPDX-License-Identifier: UNLICENSED\r\n// @title Stakeable Endowment Token\r\n// @author Origin Address\r\n// @notice This contract is proprietary and may not be copied or used without permission.\r\n\r\npragma solidity ^0.8.13;\r\n\r\nimport \"./StakableEndowmentToken.sol\";\r\n\r\ncontract TEXAN is StakableEndowmentToken {\r\n\r\n    constructor() {\r\n        setNameAndSymbol(\"TEXAN Token\", \"TEXAN\");\r\n\r\n        // NOTE: This has been modified so the original Owner Address does NOT hold\r\n        // the supply. The Endowment Supply holds 97T stars for available rewards  \r\n        // and is no longer held by the OA account.  We think this is good for security purposes.\r\n        //\r\n        //  These 3T tokens are for initial circulation.  (most will be staked)\r\n        uint intitialTotalSupply = 3 * 1e30; // 3 Trillion Tokens ( 1e12 * decimals(1e18)) \r\n\r\n        _mint(msg.sender, intitialTotalSupply);\r\n    }\r\n\r\n    receive()\r\n    payable\r\n    external\r\n    {\r\n        uint256 fbfail = 1;\r\n        require(fbfail == 0, string(abi.encodePacked(name(), \": You can not send ETH to this contract!\")));\r\n    }\r\n\r\n    fallback() external {}\r\n}"}}