CertiK reviewed Fastex (Bahamut Execution and Consensus) on 13 Aug 2023: 30 findings, 0 critical; 25 marked fixed, 5 acknowledged.
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 | 1 | 0 |
| Medium | 0 | 0 | 5 |
| Low | 0 | 4 | 20 |
In the contract **FTNVault**, the role **owner** has authority over the functions shown in the diagram below.  - **updateLimit(address minterAddress_, uint256 limit_)** to update the maximum amount of the native FTN token that an `minterAddress_` is able to withdraw. According to the project design, the native FTN tokens will be initialized to the FTNVault contact in the genesis. In this case, any compromise to the **owner** account may allow a hacker to take advantage of this authority and drain the FTN tokens from the contract **FTNVault**. If the hacker controls the **owner** role, the hacker is able to call the function `updateLimit()` to set the maximum amount of the native FTN token to the hacker's account, then invokes `processBurnTransaction()` to withdraw the native FTN tokens, resulting in severe damage to the project.
Files: - `bahamut/FTNVault.sol` Commit: - [`1f2392be6927c2227a0061a5c7c9f7c937545971`](https://github.com/fasttoken1/fasttoken-distribution-eth-contracts/tree/1f2392be6927c2227a0061a5c7c9f7c937545971) The contract `FTNVault` serves as a vault of native FTN tokens to redeem the same amount of FTN tokens that the user has burnt on Ethereum. By design, the user burns the FTN token on Ethereum and redeems the same amount of the burnt FTN token from the contract `FTNVault` through the function `processBurnTransaction()` with the burn transaction: ```solidity=64 function processBurnTransaction(bytes32 burnTxHash_, address recipient_, uint256 amount_) external { require(initialized, 'Contract has not been initialized'); require(amount_ <= limits[msg.sender], 'Limit exceeded'); limits[msg.sender] -= amount_; _processBurnTransaction(burnTxHash_, recipient_, amount_); } ``` However, the current implementation seems to miss some logic to validate the burner and amount that is burnt on Ethereum. 1. There is no validation to ensure the passed amount is the amount burnt in the transaction; 2. Similarly, no validation to make sure the user is related to the burner that burns the FTN tokens. The only way is to set the limits to a user via the function `updateLimit()` in a centralized manner; 3. No validation to ensure the passed `burnTxHash_` is actually a burn transaction that happened on Ethereum; Any user that has the limit is able to withdraw all the allowed balance by passing an unused `bytes32`.
Files: - `beacon-chain/core/helpers/validators.go` Commit: - [`3226f8330911cb8df77e775f0155b335ba771bd8`](https://github.com/fastexlabs/bahamut-consensus/tree/3226f8330911cb8df77e775f0155b335ba771bd8) According to the Fasttoken consensus whitepaper, the $i$-th validator's (denoted as $V_i$) power is defined as: $$ P^e_i = T_e \cdot \frac{s_i}{S} + A^e_{V_i},$$ where - $T_e$ is the sum of all transaction constant gas usage components, that is, $T_e = 21000 ∗ N$ where N is the number of all transactions which have been executed during the epoch $e$. - $s_i$ is the staked amount of the $i$-th validator; - $S$ is the sum of all validators' staked balances; - $A^e_{V_i}$ is the activity score assigned to the validator $V_i$ for the epoch $e$. In the implementation, the $\frac{s_i}{S}$ is assumed that the staked amounts of all the validators are the equal, so it is $\frac{1}{n}$ (n is the number of active validators): ```go transactionsGas := sharedActivity.TransactionsGasPerPeriod / length ``` Moreover, the $T_e$ and $A^e_{V_i}$ is the rolling sum of window size `period` given by the formula ```go effectiveActivity := ((val.EffectiveActivity+activity)*period - val.EffectiveActivity) / period ``` and ```go sharedActivity.TransactionsGasPerPeriod = ((gasPerPeriod+gasPerEpoch)*period - gasPerPeriod) / period ``` , which are not the values in the current epoch $e$.
Files: - `bahamut/FTNVault.sol` Commit: - [`1f2392be6927c2227a0061a5c7c9f7c937545971`](https://github.com/fasttoken1/fasttoken-distribution-eth-contracts/tree/1f2392be6927c2227a0061a5c7c9f7c937545971) The contract `FTNVault.sol` serves as a vault of native FTN tokens to redeem the same amount of FTN tokens that the user has burnt on Ethereum. However, no receive, fallback, or any payable function is implemented in the contract to accept the native FTN tokens. In this case, there is no FTN token in the vault except for tokens obtained from the self-destruct of other contracts or before the deployment. Both methods do not align with the current design because the amount of native FTN tokens is determined by the burnt amount on Ethereum.
Files: - `bahamut/FTNVault.sol` Commit: - [`1f2392be6927c2227a0061a5c7c9f7c937545971`](https://github.com/fasttoken1/fasttoken-distribution-eth-contracts/tree/1f2392be6927c2227a0061a5c7c9f7c937545971) In the contract `FTNVault`, the function `initialize()` can be called by anyone due to no access restriction, which enables anyone to initialize the contract, and gain ownership of the contract. Malicious users could observe the pending transaction which will execute the `initialize()` function in the mempool, and launch a similar transaction to front-run the pending transaction. ```solidity=43 function initialize(bytes32 burnTxHash_) public { require(!initialized, 'Contract has already been initialized'); initialized = true; _transferOwnership(msg.sender); burnTransactionHashes[burnTxHash_] = true; uint256 amount = 1000 * 10**18; emit BurnTransactionProcessed(burnTxHash_, msg.sender, amount); } ``` In the case that the contract has some native FTN tokens after the deployment, then the malicious users that control the contract will be able to drain the contract via the functions `updateLimit()` and `processBurnTransaction()`.
The report names a repository or files. Open the report to see its scope.
Repository and files the report names (174)
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