CertiK reviewed TEXAN TOKEN (Texan Endowment Token) on 21 Dec 2022: 20 findings, 0 critical; 17 marked fixed, 3 open.
Report hosted on skynet.certik.com.
Trustblock does not review code.
Statuses are the security firm’s own, from its report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 0 | 0 | 0 |
| High | 0 | 0 | 0 |
| Medium | 1 | 0 | 2 |
| Low | 2 | 0 | 15 |
The tokens are originally sent to the contract creator at mint. However the difference in the amount of tokens held by the Origin Address and the amount of tokens outside can cause issues with creating a new stake by calling the function `startStake`.
In the function `endStake()`, `g_stakedStars` needs to have the `stakeTotal` subtracted as it will be minted to the user. This can be done by subtracting `stakeTotal` instead of subtracting `interestAccrued` and then `stake._stakedPrinciple`. In addition, `g_stakedStars` can not be less than the interest or principle as it is the total sum of these variables for all stakes.
In the function `scrapeStake()`, it is checked if `previousPossibleStars > currentInterest`. However, this is always true as the `previousPossibleStars` is always the principle plus the total amount of accrued interest possible for the stake up to the `endOfStakeDay`. Opposed to the `currentInterest`, which is the amount of accrued interest up to the current day, where the current day must be less than the `endOfStakeDay` because of a `require()` statement earlier in the function. --- In the function `endStake()`, there is the following check: ```solidity=368 if(g_stakedStars >= (stake._possibleStars)){ ``` However, `g_stakedStars` is always updated with `stake._possibleStars`, so that it will always be the sum off all staked possible stars. Thus the check will always pass. --- In the function `endStake()`, there is the following check: ```solidity=373 if(g_stakedPrincipleStars >= stake._stakedPrinciple){ ``` However, `g_stakedPrincipleStars` is always updated with `stake._stakedPrinciple`, so that it will always be the sum off all stakes principle stars. Thus the check will always pass. --- In the function `endStake()`, there is the following check: ```solidity=396 if(g_stakedPrincipleStars >= stake._stakedPrinciple){ ``` However, `g_stakedPrincipleStars` is always updated with the `stake._stakedPrinciple`, so that it will always be the sum off all stakes principle stars. Thus the check will always pass. --- In the function `endStake()`, there is the following check: ```solidity=403 if (stakeTotal != 0) { ``` However, this the `stakeTotal` is either the `principle + accruedInterest` or `principle - penalty`. The maximum `penalty` is only 50 percent of the `principle` and the `principle` is at least `10000` so that the `stakeTotal` can never be `0`. --- In the function `_calculatePenalty()`, there is the following check: ```solidity=760 if (totalStakeDays <= 0) { totalStakeDays = 1 * pctprecision; //sets minimum amt for calculation } ``` However, this is only called in `endStake()` so that the `totalStakeDays` must be at least `MIN_STAKE_DAYS * pctprecision`, thus it is always greater than `0`. --- In the function `_calculatePenalty()`, there is the following check: ```solidity=763 if (calcDays[0] < calcDays[1]) { // should never happen... condition handled in parent } else ``` However, this is only called in `endStake()` in the else block after the if block with the condition that `calcDays[0] < calcDays[1]`. Thus this will never be true. --- In the function `_calculatePenalty()`, there is the following check: ```solidity=784 if (penaltyAmount <= 0) { penaltyAmount = 0; } ``` However, `penaltyAmount` is a `uint256`, thus if it is less than or equal to `0`, then it is already `0` and does not need to be assigned. --- In the function `_calculatePenalty()`, there is the following check: ```solidity=788 if (penaltyAmount > stake._stakedPrinciple) { penaltyAmount = stake._stakedPrinciple; } ``` The `penaltyAmount` is calculated as `(stake._stakedPrinciple * pctleft) / 100`, however the `pctLeft` can only be in the range `[0,50]`. This ensures the maximum `penaltyAmount` is equal to `stake._stakedPrinciple` so that it is impossible for the `penaltyAmount` to be greater than `stake._stakedPrinciple`. --- In the function `calculateStakeTotal()`, there is the following check: ```solidity=824 if (penalty > stake._stakedPrinciple) { // this should never happen but if it does, then set to 50% of the principle appliedPrinciple = stake._stakedPrinciple / 2; } ``` However, the `penalty` amount is always at most 50 percent of the principle so that it can never be greater than `stake._stakedPrinciple`.
The report names a repository or files. Open the report to see its scope.
Repository and files the report names (6)
1,044 projects reviewed · 1,375 reports · latest May 2025
See CertiK’s auditsSomething 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