TokenFi

CertiKFiles named in the report

CertiK reviewed TokenFi on 31 Oct 2023: 10 findings, 0 critical; 2 marked fixed, 8 open.

No open critical findings
Open the reportOpen TokenFi’s security record

Report hosted on skynet.certik.com.

Trustblock does not review code.

Findings10

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

SeverityOpenAcknowledgedFixed
Critical000
High300
Medium100
Low402
HighCentralization RisksOpen

In the contract `FLOKI` the role `_owner` has authority over the functions shown in the diagram below. Any compromise to the `_owner` account may allow the hacker to take advantage of this authority. - The function `setTreasuryHandler` to set the `treasuryHandler`. - The function `setTaxHandler` to set the `taxHandler`. Note that the token transfer functions may revert if these addresses are incorrectly set. ![](https://accelerator-tasks-prod.acc.corp.certik.com/11ee-6f57-e47e89c0-a867-19816d82264d/diagrams/centralization_Floki-FLOKI-_owner.svg) In the contract `Tokenfi` the role `_owner` has authority over the functions shown in the diagram below. Any compromise to the `_owner` account may allow the hacker to take advantage of this authority. - The function `withdraw` to send any tokens or ETH stuck in the token contract to the treasury handler. - The function `setTreasuryHandler` to set `treasuryHandler`. - The function `setTaxHandler` to set `taxHandler`. Note that the token transfer functions may revert if these addresses are incorrectly set. ![](https://accelerator-tasks-prod.acc.corp.certik.com/11ee-6f57-e47e89c0-a867-19816d82264d/diagrams/centralization_Tokenfi-Tokenfi-_owner.svg) In the contract `ExponentialTaxHandler` the role `_owner` has authority over the functions shown in the diagram below. Any compromise to the `_owner` account may allow the hacker to take advantage of this authority. The functions addExemption/removeExemption can be used to add/remove addresses from the `_exempted` address set. ![](https://accelerator-tasks-prod.acc.corp.certik.com/11ee-6f57-e47e89c0-a867-19816d82264d/diagrams/centralization_ExponentialTaxHandler-ExponentialTaxHandler-_owner.svg) In the contract `StaticTaxHandler` the role `_owner` has authority over the functions shown in the diagram below. Any compromise to the `_owner` account may allow the hacker to take advantage of this authority. - The function `setTaxBasisPoints` can be used to set `taxBasisPoints`. - The functions `addExemption/removeExemption` can be used to add/remove addresses from the `_exempted` address set. ![](https://accelerator-tasks-prod.acc.corp.certik.com/11ee-6f57-e47e89c0-a867-19816d82264d/diagrams/centralization_StaticTaxHandler-StaticTaxHandler-_owner.svg) In the contract `ExchangePoolProcessor` the role `_owner` has authority over the functions shown in the diagram below. Any compromise to the `_owner` account may allow the hacker to take advantage of this authority. - The functions `addExchangePool/removeExchangePool` can be used to add/remove pool addresses from the `_exchangePools` address set. - The function `setPrimaryPool` can be used to set `primaryPool`. ![](https://accelerator-tasks-prod.acc.corp.certik.com/11ee-6f57-e47e89c0-a867-19816d82264d/diagrams/centralization_ExchangePoolProcessor-ExchangePoolProcessor-_owner.svg) In the contract `TreasuryHandlerAlpha` the role `_owner` has authority over the functions shown in the diagram below. Any compromise to the `_owner` account may allow the hacker to take advantage of this authority. - The function `withdraw` can be used to withdraw any tokens or ETH in the treasury handler to the treasury EOA address. - The function `setPriceImpactBasisPoints` can be used to set `priceImpactBasisPoints`. - The function `setTreasury` can be used to set `treasury`. - The function `setLiquidityBasisPoints` can be used to set `liquidityBasisPoints`. ![](https://accelerator-tasks-prod.acc.corp.certik.com/11ee-6f57-e47e89c0-a867-19816d82264d/diagrams/centralization_TreasuryHandlerAlpha-TreasuryHandlerAlpha-_owner.svg)

HighCentralized LP Token Holding Position RiskOpen

In the contracts `FLOCKI` and `Tokenfi`, taxes collected by the `treasuryHandler` are partially used to add liquidity, resulting in the LP tokens being transferred to the `treasury` address. Over time, this design will lead to an increasing centralization of LP tokens within the `treasury` address. Any compromise to the private key of the `treasury` address may allow a hacker to take advantage of the EOA address authority and remove the liquidity from the pool. This could have devastating consequences for the entire project.

HighInitial Token DistributionOpen

All of the FLOKI tokens and Tokenfi tokens are sent to the contract deployers. This is a centralization risk because the deployers can distribute tokens without obtaining the consensus of the community. Any compromise to these addresses may allow a hacker to steal and sell tokens on the market, resulting in severe damage to the project.

MediumUnreasonable Boundary for Fee RateOpen

The `setTaxBasisPoints()` function allows the `_owner` to modify the `taxBasisPoints`, which determines the fee percentage. While there is a cap set at 4,000 basis points (equivalent to 40%), such a high fee rate could be unreasonably high for users. ```solidity function setTaxBasisPoints(uint256 newBasisPoints) external onlyOwner { require( newBasisPoints <= 4000, "StaticTaxHandler:setTaxBasisPoints:HIGHER_VALUE: Basis points cannot exceed 4,000." ); uint256 oldBasisPoints = taxBasisPoints; taxBasisPoints = newBasisPoints; emit TaxBasisPointsUpdated(oldBasisPoints, newBasisPoints); } ```

LowFunction `transferFrom()` Not RecommendedOpen

The function `transferFrom()` in an ERC20 contract is used in the above-mentioned contracts to receive the user payments to the contract. When the contract needs to transfer assets out, it is better to use the function `transfer()/safeTransfer()` because it is possible that the target `tokenAddress` does not support transfer from the user itself. ```solidity=343 function withdraw(address tokenAddress, uint256 amount) external onlyOwner { if (tokenAddress == address(0)) { payable(address(treasuryHandler)).sendValue(amount); } else { IERC20(tokenAddress).transferFrom(address(this), address(treasuryHandler), amount); } } ``` If the contract uses `transferFrom()` to transfer the ERC20 token from itself, and it has no approvals, it may revert transactions.

LowPotential Sandwich AttacksOpen

In a front-running attack, an attacker identifies a pending transaction on the public blockchain and jumps ahead of it (typically by paying higher gas fees). A sandwich attack is a specialized form of front-running. In this scenario, attackers identify users making token swaps or adding liquidity without appropriate slippage limits. The attacker then profits by buying the asset before the victim's transaction and selling it immediately afterwards. The following functions are called without setting restrictions on slippage or minimum output amount, so transactions triggering these functions are vulnerable to sandwich attacks, especially when the input amount is large: ```solidity=234 router.swapExactTokensForETHSupportingFeeOnTransferTokens(tokenAmount, 0, path, address(this), block.timestamp); ``` ```solidity=247 router.addLiquidityETH{ value: weiAmount }( address(token), tokenAmount, 0, 0, address(treasury), block.timestamp ); ```

LowThird-Party Dependency UsageOpen

The contract is serving as the underlying entity to interact with one or more third party protocols. The scope of the audit treats third party entities as black boxes and assumes their functional correctness. However, in the real world, third parties can be compromised and this may lead to lost or stolen assets. In addition, upgrades of third parties can possibly create severe impacts, such as increasing fees of third parties, migrating to new LP pools, etc. ```solidity=35 IUniswapV2Router02 public router; ``` - The contract `TreasuryHandlerAlpha` interacts with third party contract with `IUniswapV2Router02` interface via `router`.

LowUnable to Receive ETHOpen

The `withdraw()` function is designed to allow the `_owner` to withdraw locked Ether or ERC20 tokens. However, the contract lacks any `payable` or `receive()` function, making it incapable of holding or receiving Ether. ```solidity=339 function withdraw(address tokenAddress, uint256 amount) external onlyOwner { if (tokenAddress == address(0)) { payable(address(treasuryHandler)).sendValue(amount); } else { IERC20(tokenAddress).transferFrom(address(this), address(treasuryHandler), amount); } } ```

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 (12)

  • contracts/utils/LenientReentrancyGuard.sol
  • contracts/tax/ZeroTaxHandler.sol
  • contracts/treasury/TreasuryHandlerAlpha.sol
  • contracts/Floki.sol
  • contracts/treasury/ITreasuryHandler.sol
  • contracts/treasury/ZeroTreasuryHandler.sol
  • contracts/tax/ExponentialTaxHandler.sol
  • contracts/tax/StaticTaxHandler.sol
  • contracts/Tokenfi.sol
  • contracts/tax/ITaxHandler.sol
  • contracts/governance/IGovernanceToken.sol
  • contracts/utils/ExchangePoolProcessor.sol

Part of TokenFi’s security record

TokenFi
Audits2 audits by 1 firmLast audit Feb 2024, by CertiK.
Critical findingsNo open critical findingsAcross 2 reports.
Open TokenFi’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