Texan Endowment Token

CertiKFiles named in the report

CertiK reviewed TEXAN TOKEN (Texan Endowment Token) on 21 Dec 2022: 20 findings, 0 critical; 17 marked fixed, 3 open.

No open critical findings
Open the reportOpen TEXAN TOKEN’s security record

Report hosted on skynet.certik.com.

Trustblock does not review code.

Findings20

Statuses are the security firm’s own, from its report.

SeverityOpenAcknowledgedFixed
Critical000
High000
Medium102
Low2015
MediumIncorrect mathematical operationFixed

In the function `startStake()`, it is checked if `_endowmentSupply > possibleStars`. However, only the possible interest is taken from the `_endowmentSupply`. In the function `endStake()`, if a user calls `endStake()` before the `startDay`, then they are refunded the principal. However, this principal is then counted twice in the total supply as the `_endowmentSupply` is increased by the `_possibleStars` which includes the principal and also the `_StakedPrinciple` is minted to the user.

MediumPotential loss of rewardsFixed

The function `stakeScrape` allows an external address to update the stake status of another user. This behavior can lead to a denial of service attack for a given time period. For example suppose that user Bob wanted to call the function `stakeScrape`. However, Alice called this function before with Bob's address in the parameter `stakerAddr` then Bob would no longer be able to call `stakeScrape` on himself as Alice has updated his respective `scrapeDay`.

Low`LAUNCH_TIME` should be in the futureFixed

The `LAUNCH_TIME` should be changed to a date in the future if the project has not already been deployed and launched.

Low`scrapeStake()` should revert if called more thanFixed

The function `scrapeStake()` should only be called once per day and this is ensured by the if statement `if (curDay > calcDays[2])`. In this case it will not revert if a user calls the function multiple times in one day, which can cause confusion.

Low`totalSupply()` value can be misleadingFixed

The `totalSupply` of a token is supposed to return the total amount of tokens in circulation, including those that are locked or in reserve. While the principle amount of tokens is burned from the user and the total possible interest is removed from the `endowmentSupply`, these can be considered as locked or reserved tokens as they are scheduled to be distributed. This can cause confusion if a user stakes or unstakes a large amount of tokens that can make a dramatic change in the `totalSupply`.

LowDivide Before MultiplyFixed

Performing integer division before multiplication truncates the low bits, losing the precision of calculation. ```solidity=726 tempInterestAmount = (((current * appliedInterestRate) / YEARPRECISION) * principle) / (PRECISION * PRECISION); //36 decimals ```

LowFirst `newStakeId` will be 2Fixed

When starting a new stake the global stake id is incremented before the `newStakeId` is set equal to it. Since, `g_latestStakeId` is initialized to 1, it will cause the first `newStakeId` to be 2, which could cause confusion.

LowFunction Should Be Declared ExternalFixed

The following public functions are never called internally. Public functions cost more gas to call then external functions. ```solidity function reportGlobals() ``` --- ```solidity function calculateStakeDays(uint256 tempStartDay, uint256 tempStakedDays, uint256 tempScrapeDay) ``` --- ```solidity function calculateInterest(uint256 stakedPrinciple, uint256 stakedDays) ```

LowHardcoded VariablesFixed

The variable `YEARDIVIDER` is defined at Line 34. The value it refers to is the same value given to the variable `day_divisor`. However the variable `day_divisor` is hardcoded. A similar pattern is also done by the variable 'YEARPRECISION' and `workingDays`. ```solidity uint256 day_divisor = 36525; ``` --- ```solidity uint256 workingDays = servedDays * 100; ```

LowInput Validation OrderFixed

In the function `_calculateStakeDays`, the function performs the following mathematical operations. ```solidity function _calculateStakeDays(uint256 startDay, uint256 stakedDays, uint256 scrapeDay) internal view returns (uint[6] memory) { uint256 curDay = _currentDay(); //ex. day 25 uint256 endOfStakeDay = startDay + stakedDays; //ex. Day 52 // find the higher of the two days ( startDay or a more recent scrapeDay ) uint256 targetStartDay = scrapeDay >= startDay ? scrapeDay : startDay; // the possible interest bearing days uint256 possibleDays = endOfStakeDay - targetStartDay; uint256 interestDays = 0; // if the stakedDays is less than the minimum, throw an error require(stakedDays >= MIN_STAKE_DAYS, "scrape days must be greater than 1"); ``` Then performs the following check. ```solidity require(stakedDays >= MIN_STAKE_DAYS, "scrape days must be greater than 1"); ``` If the function reverts then the operations are also reverted.

Show 7 more
LowMisspelling in Error MessageFixed

In the following code, the error statement declares that the `scrape days must be greater than 1`. However, the error message is with respect to stakeDays. ```solidity require(stakedDays >= MIN_STAKE_DAYS, "scrape days must be greater than 1"); ```

LowRedundant ComparisonFixed

In the function `calculateInterest`, the following check is potentially redundant. ```solidity if (stakedPrinciple <= 0 || stakedDays <= 0) { return (0); } ``` This occurs because the function "_assurePrincipleAndStakedDaysAreValid" checks the minimum amount of `stakedPrinciple` and `stakedDays` required which is larger then zero.

LowToo Many DigitsFixed

The following literals contain a large amount of digits. This is difficult to read. ```solidity uint256 internal constant MAX_STAKE_AMOUNT = 100000000000000000000000000000; // 100B Stake is the max ``` --- ```solidity uint256 constant PRECISION = 1000000000000000000; // 18 decimals ``` --- ```solidity uint intitialTotalSupply = 100000000000000000000000000000000; //100 Trillion Tokens ```

LowTyposFixed

The following typos where found: - In the comments of `_startStake`, "form" is used instead of "from". - In the comment when minting the `lostInterest`, "origin address" is used instead of "endowmentSupply".

LowUninitialized Local VariableFixed

The local variable `stake` is not initialized in the functions `scrapeStake()` and `endStake()`. Explicitly initializing the variables to zero in this case results in a small amount of gas savings.

LowUnrecoverable event dataFixed

The non-indexed parameters of the events `StakeStart`, `StakeScrape` and `StakeEnd` are encoded with a bitwise OR operation. This disallows the recovery of information since the bitwise OR operation is destructive. ```solidity emit StakeStart( // (auto-generated event) uint256(uint40(block.timestamp)) | stakedPrinciple | startDay | stakedDays, msg.sender, stakeId ); ``` ```solidity emit StakeScrape( // (auto-generated event) uint256(block.timestamp) | uint256(stakedPrinciple) | uint256(currentInterest), uint256(lostInterest) | uint256(servedDays), msg.sender, stakeId ); ``` ```solidity emit StakeEnd( // (auto-generated event) uint256(block.timestamp) | uint256(stakedPrinciple) | uint256(payout), uint256(penalty) | uint256(servedDays), msg.sender, stakeId ); ```

LowUnused State VariableFixed

The following state variables are never used in the codebase. ```solidity uint256 g_currentDay = 1; //default sets the inital current day to 1 ``` --- ```solidity uint256 g_currentEpoch = block.timestamp; //start off with this default value of now ```

Contracts in scope

No deployed address is recorded for this audit.

The report names a repository or files. Open the report to see its scope.

Repository and files the report names (6)

  • contracts/TEXAN.sol
  • contracts/ERC20.sol
  • contracts/IERC20.sol
  • contracts/Context.sol
  • contracts/StakableEndowmentToken.sol
  • contracts/IERC20Metadata.sol

Part of TEXAN TOKEN’s security record

TEXAN TOKEN
Audits1 audit by 1 firmLast audit Dec 2022, by CertiK.
Critical findingsNo open critical findingsIn 1 report.
Open TEXAN TOKEN’s security record

Security firm

CertiK

1,044 projects reviewed · 1,375 reports · latest May 2025

See CertiK’s audits

Something wrong on this page? A missing report, a wrong date, a finding that was fixed since. Tell us and we check it against its source.

Tell us