Transaction Hash:
Block:
22364275 at Apr-28-2025 01:27:35 AM +UTC
Transaction Fee:
0.0000231435 ETH
$0.09
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 | ||
---|---|---|---|---|---|
0x6499dBCe...f182Ee862 |
0.000059370197576619 Eth
Nonce: 16
|
0.000036226697576619 Eth
Nonce: 17
| 0.0000231435 | ||
0x95222290...5CC4BAfe5
Miner
| (beaverbuild) | 16.275344961435007919 Eth | 16.275350729964232391 Eth | 0.000005768529224472 | |
0xcFCFfE43...77B2A88d7 |
Execution Trace
TEXAN.approve( spender=0xaaaaaaae92Cc1cEeF79a038017889fDd26D23D4d, amount=1000000000000000000000000 ) => ( True )
1{"Context.sol":{"content":"// SPDX-License-Identifier: UNLICENSED\r\n// @title Stakeable Endowment Token\r\n// @author Origin Addrress\r\n\r\npragmasolidity ^0.8.13;\r\n\r\n// @dev Provides information about the current execution context, including the\r\n// sender of the transaction and itsdata. 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 whendealing 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// isconcerned).\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\nfunction _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\npragmasolidity ^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 derivedcontract using {_mint}.\r\n * For a generic mechanism see {ERC20PresetMinterPauser}.\r\n *\r\n * We have followed general OpenZeppelin Contractsguidelines: functions revert\r\n * instead returning `false` on failure. This behavior is nonetheless\r\n * conventional and does not conflict withthe expectations of ERC20\r\n * applications.\r\n *\r\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\r\n * Thisallows applications to reconstruct the allowance for all accounts just\r\n * by listening to said events. Other implementations of the EIP may notemit\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\nstring 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 virtualoverride returns (string memory) {\r\n return _tokenSymbol;\r\n }\r\n\r\n /**\r\n * @dev Returns the number of decimals used toget 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 overridereturns (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} eventindicating 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 functiontransferFrom(\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 allowancegranted 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 * problemsdescribed 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 analternative 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 usedto\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\nuint256 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\nuint256 senderBalance = _balances[sender];\r\n require(senderBalance \u003e= amount, \"ERC20: transfer amount exceeds balance\");\r\nunchecked {\r\n _balances[sender] = senderBalance - amount;\r\n }\r\n _balances[recipient] += amount;\r\n\r\n emitTransfer(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 thezero 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 emitTransfer(address(0), account, amount);\r\n\r\n _afterTokenTransfer(address(0), account, amount);\r\n }\r\n\r\n /**\r\n * @devDestroys `amount` tokens from `account`, reducing the\r\n * total supply.\r\n *\r\n * Emits a {Transfer} event with `to` set to thezero address.\r\n *\r\n * Requirements:\r\n *\r\n * - `account` cannot be the zero address.\r\n * - `account` must have atleast `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. setautomatic 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 addressowner,\r\n address spender,\r\n uint256 amount\r\n ) internal virtual {\r\n require(owner != address(0), \"ERC20: approvefrom 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 calledbefore 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 transferredto `to`.\r\n * - when `from` is zero, `amount` tokens have been minted for `to`.\r\n * - when `to` is zero, `amount` of ``from``\u0027stokens 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// @titleStakeable 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 theamount of tokens in existence.\r\n */\r\n function totalSupply() external view returns (uint256);\r\n\r\n /**\r\n * @dev Returns theamount 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 theoperation succeeded.\r\n *\r\n * Emits a {Transfer} event.\r\n */\r\n function transfer(address recipient, uint256 amount) externalreturns (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} arecalled.\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 operationsucceeded.\r\n *\r\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\r\n * that someone may use boththe old and the new allowance by unfortunate\r\n * transaction ordering. One possible solution to mitigate this race\r\n * condition is tofirst 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 operationsucceeded.\r\n *\r\n * Emits a {Transfer} event.\r\n */\r\n function transferFrom(\r\n address sender,\r\n addressrecipient,\r\n uint256 amount\r\n ) external returns (bool);\r\n\r\n /**\r\n * @dev Emitted when `value` tokens are moved from oneaccount (`from`) to\r\n * another (`to`).\r\n *\r\n * Note that `value` may be zero.\r\n */\r\n event Transfer(address indexedfrom, 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 OriginAddrress\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 optionalmetadata 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 Returnsthe symbol of the token.\r\n */\r\n function symbol() external view returns (string memory);\r\n\r\n /**\r\n * @dev Returns thedecimals 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 isproprietary and may not be copied or used without permission.\r\n// @dev Stakable Endowment Main Functions for Staking, Scraping, and EndingStakes\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 constantLAUNCH_TIME = 1671667200; //The time of launch\r\n \r\n // Global Constants Constants\r\n uint256internal constant MIN_STAKE_DAYS = 1;\r\n uint256 internal constant MAX_STAKE_DAYS = 8036; // Approx 22 years and half a day\r\n uint256internal constant MAX_STAKE_YEARS = 22; //\r\n\r\n uint256 internal constant MIN_STAKE_AMOUNT = 10000;\r\n uint256 internal constantMAX_STAKE_AMOUNT = 1e29; // 100B Stake is the max (100000000000000000000000000000)\r\n\r\n // This is the Endowment Supply. For security reasonswe 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 thecontract\r\n uint256 internal _endowmentSupply = (97 * 1e30);\r\n\r\n // Global Variables\r\n uint256 g_latestStakeId = 0; // theglobal 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\nuint256 g_stakedPrincipleStars = 0; // the amount of principle that is staked in wei\r\n uint256 g_penalizedStars = 0; // these are theStars that have been set aside from penalties\r\n uint256 g_stakedCount = 0; // current count of active stakes based on + and - in startStakeand 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 byprecision, 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\nevent 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\nevent ScrapeStake(\r\n address indexed stakeAddress,\r\n uint256 indexed stakeId,\r\n uint256 indexed eventName,\r\nuint256 scrapeDay,\r\n uint256 previousScrapedInterest,\r\n uint256 oldPossibleInterest,\r\n uint256 scrapedInterest,\r\nuint possibleInterest\r\n );\r\n\r\n event EndStake(\r\n address indexed stakeAddress,\r\n uint256 indexed stakeId,\r\nuint256 indexed eventName,\r\n uint256 endStakeDay,\r\n uint256 principle,\r\n uint256 oldPossibleInterest,\r\nuint256 scrapedInterest,\r\n uint256 penalties,\r\n uint256 stakeTotal\r\n );\r\n\r\n // @dev Memory resident Stake fortemporary use\r\n // @param uint256 _stakeId\r\n // @param uint256 _stakedPrinciple\r\n // @param uint256 _startDay\r\n // @paramuint256 _scrapeDay\r\n // @param uint256 _stakedDays\r\n // @param uint256 _scrapedInterest\r\n // @param uint256 _possibleStars\r\nstruct 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 PermenantStake 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 uint256stakedDays The days of the stake commitment\r\n // @param uint256 scrapedInterest The interest that has been scraped if any\r\n // @paramuint256 possibleStars The potential amount of stars for this stake\r\n struct PermStake {\r\n uint256 stakeId;\r\n uint256stakedPrinciple;\r\n uint256 startDay;\r\n uint256 scrapeDay;\r\n uint256 stakedDays;\r\n uint256 scrapedInterest;\r\nuint256 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 interestpreviously scraped\r\n // @param uint256 previousPossibleStars - what the previous amount of interest was before the scrape\r\n // @paramuint256 scrapedInterest - the amount of interest scraped by this action\r\n // @param uint256 newPossibleIntest - the possible interest\r\nfunction 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\ninterestDays,\r\n previousInterest,\r\n previousPossibleStars,\r\n scrapedInterest,\r\nnewPossibleInterest\r\n );\r\n }\r\n\r\n // @dev Public Function: Open a stake.\r\n // @param uint256 stakedPrinciple Number ofStars to stake\r\n // @param uint256 stakedDays length of days in the stake\r\n function startStake(uint256 stakedPrinciple, uint256stakedDays)\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 uint256possibleInterest = _calculateInterest(stakedPrinciple, stakedDays);\r\n \r\n // Create total possible stars\r\n uint256possibleStars = possibleInterest + stakedPrinciple; // ALL possible interest AND principle\r\n \r\n require(_endowmentSupply \u003epossibleInterest, \"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 theendowmentSupply\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 tostakedStars.\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. Thiswill also recalculate\r\n // the possible amount of interest.\r\n // @param uint256 stakeIndex the index of the stake based on the order ofactive 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 oftemporary 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\nuint256 lostInterest = 0;\r\n uint256 newPossibleInterest = 0;\r\n uint256 curDay = calcDays[0];\r\n // the stake startday 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, mustend 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 savepossible 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 scrapetwice on the same day so current Day must greater than previous scraped day\r\n // will equal 0 or previous accumulated amount\r\npreviousInterest = 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\nnewPossibleInterest = _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 // WhatI have: \r\n // previousPossibleStars - (includes principle)\r\n // newPossibleInterestPlusPrinciple - newPossibleInterestalso include principle\r\n // currentInterest - what we are minting for interest\r\n // just in case the previous possibleinterest 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, becausethere is a force closed function.\r\n // If there is accrued interest, send this back to the user\r\n // If there is no accruedinterest, then nothing changes and all stays the same.\r\n if (currentInterest != 0) {\r\n\r\n // Mint this back to messagesender\r\n _mint(msg.sender, currentInterest);\r\n \r\n // Mint lost interest back to the endowment supply\r\nif (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 thenew 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 //updatethe current stake to the new values\r\n _updateStake(permStakeRef, stake);\r\n // Emit the stake scrape event\r\nemitScrapeEvent(\r\n stake._stakeId,\r\n uint256(calcDays[4]),\r\n uint256(previousInterest),\r\npreviousPossibleStars,\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 stakebased on order and may change based on active stakes\r\n // @param uint256 myStakeId The stake\u0027s id\r\n function endStake(uint256stakeIndex, 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\nuint256 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 tostartDay, 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 makesa 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 starsback 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\npenalty = 0;\r\n // Add principle back to user\r\n _mint(msg.sender, stake._stakedPrinciple);\r\n // remove thisfrom global stats\r\n g_stakedStars -= stake._possibleStars;\r\n \r\n\r\n // remove from the global principlestats\r\n g_stakedPrincipleStars -= stake._stakedPrinciple;\r\n \r\n } else {\r\n // served days is day fromstart 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 keeptrack of penalizedStars\r\n g_penalizedStars += penalty;\r\n\r\n // Remove possible stars from the global variableg_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 variableg_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 // Thereare 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\ng_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\ng_stakedStars -= stake._stakedPrinciple; \r\n }\r\n\r\n // NOTE: Stake Total is Both theinterestAccrued + Principle and that \r\n // goes back to the user\r\n\r\n // Speaking of principle, let\u0027s alsoremove it from g_stakedPrincipleStars\r\n if(g_stakedPrincipleStars \u003e= stake._stakedPrinciple){\r\ng_stakedPrincipleStars -= stake._stakedPrinciple; \r\n }\r\n }\r\n\r\n // Calculations are done, solet\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\nmsg.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\npermStakes[stakeIndex] = permStakes[lastIndex];\r\n }\r\n permStakes.pop();\r\n // stake remove is finished - remove from thethe 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 thetoken\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 daynumber\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 // uint256latest_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 uint256total_supply,\r\n uint256 allocated_supply,\r\n uint256 penalized_stars,\r\n uint256 current_day,\r\n uint256latest_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\ncurrent_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 // ReturnsCalculated Days in an array like below\r\n // 0 curDay - Current Day\r\n // 1 startDay - Start Day\r\n // 2 scrapeDay - The previous daythis was scraped - (default to startDay, and is set when scraped)\r\n // 3 endOfStakeDay - The final day of this stake (startDay + stakedDays ortotal 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 functioncalculateStakeDays(uint256 tempStartDay, uint256 tempStakedDays, uint256 tempScrapeDay)\r\n external\r\n view\r\n returns (\r\nuint[6] memory\r\n )\r\n {\r\n uint[6] memory calcDays = _calculateStakeDays(tempStartDay, tempStakedDays, tempScrapeDay);\r\nreturn (calcDays);\r\n }\r\n\r\n // @dev Calculate the interest of a scenario\r\n // @param uint256 stakedPrinciple The amount ofprinciple for the stake\r\n // @param uint256 stakedDays the number of days to commit to a stake\r\n function calculateInterest(uint256stakedPrinciple, 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\nreturn (interest);\r\n }\r\n\r\n // @dev This give the totalsupply plus the totalstaked. Total staked also\r\n // includes theinterest that may be accrued from time and principle.\r\n // @return Allocated Supply in Stars\r\n function _allocatedSupply()\r\nprivate\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 valuesinto it\r\n // @param PermStake stakeRef reference of values to get\r\n // @param uint256 myStakeId or the globalStakeId\r\n // @paramTempStake 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\ninternal\r\n view\r\n {\r\n //require current stake index is valid\r\n require(myStakeId == stakeRef.stakeId, \"myStakeId notin 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 PrivateFunction for updating the stake\r\n // returns nothing, it just updates the stake passed to it\r\n // @param PermStake stakeRef the referenceto the original mapping of the stake store\r\n // @param TempStake stake the new instance to update from\r\n function _updateStake(PermStakestorage 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 StakeInternal Function\r\n // @param uint256 stakedPrinciple\r\n // @param uint256 stakedDays length of days in the stake\r\n // @param uint256possibleStars allocated total for this stake\r\n function _startStake(\r\n uint256 stakedPrinciple,\r\n uint256 stakedDays,\r\nuint256 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 andcreate the stake\r\n uint256 newStakeId = ++g_latestStakeId;\r\n // push the new stake into the sender\u0027s stake list\r\nStakes[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\nuint256(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 thebasic 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 stakedays 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\nrequire(principle \u003c= MAX_STAKE_AMOUNT, \"Principle is too high\");\r\n }\r\n\r\n // @dev Calculate Interest Function\r\n // @noticeThis calculates the amount of interest for the number of servedDays.\r\n // This divides up served days into buckets of yearly increments basedon 365.25 days\r\n // Then applies the rate of return based on the interestTable.\r\n // @param uint256 principle - the principle toapply\r\n // @param uint256 servedDays - the number of days to calculate.\r\n function _calculateInterest(uint256 principle, uint256servedDays)\r\n internal\r\n pure\r\n returns(\r\n uint256 totalInterest\r\n )\r\n {\r\n // year is 365.25, but weneed to multiply by 100 to keep it integer\u0027istic\r\n uint256 workingDays = servedDays * YEARPRECISION;\r\n // This will fill upbased 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 uint256appliedInterestRate = 0;\r\n uint256 tempInterestAmount = 0;\r\n uint256 current = 0;\r\n\r\n while (workingidx \u003cMAX_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\ncurrent = workingDays; // this will give the days left over\r\n workingDays = 0;\r\n }\r\n // apply thisyears 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\nuint tempInterestAmountNumerator = 0;\r\n tempInterestAmountNumerator = ((current * appliedInterestRate) * principle) /YEARPRECISION;\r\n tempInterestAmount = tempInterestAmountNumerator / (PRECISION * PRECISION); //36\r\n\r\n // apply theprinciple 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 // @devCalculatePenalty\r\n // @notice This calculates the penalty if there is one.\r\n // The rules for penalty:\r\n // - if a stake is lessthan 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 eachday from 100%\r\n // example: Stake is 60% complete. You should receive 60% of your principle back.\r\n // @param TempStake stake thestake to calculate penalties for\r\n function _calculatePenalty(TempStake memory stake)\r\n internal\r\n view\r\n returns(\r\nuint256 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\nuint256 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 orless 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 frompctleft\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 letstest 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 uint256appliedPrinciple = 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 - CurrentDay\r\n // 1 startDay - Start Day\r\n // 2 scrapeDay - The previous day this was scraped - (default to startDay, and is set whenscraped)\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 thanstaked 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\nif (penalty \u003e stake._stakedPrinciple) {\r\n // this should never happen but if it does, then set to 50% of the principle\r\nappliedPrinciple = stake._stakedPrinciple / 2;\r\n } else {\r\n // this should return a \"prorated\" amountof principle from 51% to 99%\r\n appliedPrinciple = (stake._stakedPrinciple - penalty);\r\n }\r\n // A brokenstake will only give you the portion of your principle back, not your interest.\r\n stakeTotal = appliedPrinciple;\r\ncurrentInterest = 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 - CurrentDay\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 toCALCULATE INTEREST\r\n // 5 possibleDays - (endOfStakeDays - currentDay)\r\n // @dev Calculate Days\r\n // @notice This returns an arrayof calculated days of your stake based on the current day.\r\n // @param uint256 startDay\r\n // @param uint256 stakedDays length of days inthe stake\r\n // @param uint256 scrapeDay\r\n function _calculateStakeDays(uint256 startDay, uint256 stakedDays, uint256 scrapeDay)\r\ninternal\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\nrequire(stakedDays \u003e= MIN_STAKE_DAYS, \"stake days must be greater than 1\");\r\n uint256 curDay = _currentDay(); //ex. day 25\r\nuint256 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\nuint256 possibleDays = endOfStakeDay - targetStartDay;\r\n uint256 interestDays = 0;\r\n // if the currentDay is greater than theend stake day, we subtract:\r\n // targetStartDay from the endOfStakeDay giving us the interest days.\r\n // otherwise we take thecurrentDay 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\ninterestDays = 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\npossibleDays\r\n ];\r\n }\r\n\r\n // @dev getDailyInterestTable\r\n // @notice This table has precalculated values for the22 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 willnever 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\n301163586584531143052703627652292, \r\n 410677618069815195071868583162217, \r\n547570157426420260095824777549623, \r\n 711841204654346338124572210814510, \r\n 903490759753593429158110882956878, \r\n1122518822724161533196440793976728, \r\n 1368925393566050650239561943874058, \r\n1642710472279260780287474332648870, \r\n 1943874058863791923340177960301163, \r\n 2272416153319644079397672826830937, \r\n2628336755646817248459958932238193, \r\n 3011635865845311430527036276522929, \r\n3422313483915126625598904859685147, \r\n 3860369609856262833675564681724845, \r\n 4325804243668720054757015742642026, \r\n4818617385352498288843258042436687, \r\n 5338809034907597535934291581108829, \r\n5886379192334017796030116358658453, \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 viewoverride 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 asIERC20-totalsupply\r\n */\r\n function endowmentSupply() public view returns (uint256) {\r\n // The Endowment Supply is the totalamount of token available for staking rewards to the stakers.\r\n // A proper representation of Total Supply is the Endowment Supply + whatis 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 oftoken available for staking rewards to the stakers.\r\n // A proper representation of Total Supply is the Endowment Supply + what is in theERC20 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 withoutpermission.\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 theoriginal Owner Address does NOT hold\r\n // the supply. The Endowment Supply holds 97T stars for available rewards \r\n // and is nolonger held by the OA account. We think this is good for security purposes.\r\n //\r\n // These 3T tokens are for initialcirculation. (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\nrequire(fbfail == 0, string(abi.encodePacked(name(), \": You can not send ETH to this contract!\")));\r\n }\r\n\r\n fallback() external{}\r\n}"}}