Token Liquidity Foundation

CertiKFiles named in the report

CertiK reviewed Token Liquidity Foundation on 14 Mar 2023: 6 findings, 1 critical; 4 marked fixed, 2 open.

1 critical finding, fixed
Open the reportOpen Token Liquidity Foundation’s security record

Report hosted on skynet.certik.com.

Trustblock does not review code.

Findings6

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

SeverityOpenAcknowledgedFixed
Critical001
High101
Medium000
Low102
CriticalSelf Transfers Allow Users To Arbitrarily IncreasFixed

It is possible for a user to arbitrarily increase their balance by performing self-transfers. The cause is that the function `_transferInternal()` uses a possibly incorrect value for the recipient's balance. ```solidity function _transferInternal(address sender, address recipient, uint256 amount) private returns (bool) { notZeroAddress(recipient); notZeroAddress(sender); uint256 senderBalance = balanceOf[sender]; require(senderBalance >= amount, "ERC20: transfer amount exceeds balance"); if (amount > 0) { if (senderBalance == amount) { // account is now zero so one less holder holders--; } uint256 recipientBalance = balanceOf[recipient]; if (recipientBalance == 0) { // account is has moved from zero one more holder holders++; } unchecked { balanceOf[sender] = senderBalance - amount; // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by // decrementing then incrementing. balanceOf[recipient] = recipientBalance + amount; } } ``` The variable `senderBalance` is assigned to be `balanceOf[sender]` and the variable `recipientBalance` is assigned to be `balanceOf[recipient]` and both values are changed after the assignments. This means that if the sender and recipient are the same address, the change `balanceOf[sender] = senderBalance - amount` will not occur as the change of `balanceOf[recipient] = recipientBalance + amount` will overwrite it. Furthermore, since `sender == recipient`, we have `recipientBalance == senderBalance`, the original starting balance of the user, which gets increased by `amount`. This allows a user to transfer tokens to themselves to increase their token balance. Furthermore, the number of holders can be incorrect with a self-transfer if `amount == senderBalance`. In this situation, `holders` will decrease by one, but will not increase as `recipientBalance` is the balance of the sender before the transfer. This causes the `holders` variable to be lower than expected.

HighPotential Unauthorized `burn()` FunctionFixed

It is possible for a bridge to burn anyone's tokens as the `allowance` check when burning mixes up the token owner and token spender. The linked function allows `msg.sender` to burn a certain amount of tokens from the account associated with `from`. Before calling `_burnInternal()` to burn the token from the `from` account, the function first checks the `allowance` and `amount`. ```solidity=213 function burn(address from, uint256 amount) external bridgingAllowed { address burningAccount = _msgSender(); require(allowance[burningAccount][from] >= amount, "Unauthorized attempt to burn"); require(balanceOf[from] >= amount, "Attempt to burn more than holding"); _burnInternal(amount, from, burningAccount); } ``` The check uses `allowance[burningAccount][from]`, suggesting that the token spender is the first parameter and the token owner is the second parameter. However, in the function `approve()`, the first parameter is actually the token owner and the second parameter is the token spender. Thus, this function can allow a privileged user (approved by calling the `approveBridgeMintBurn()` function) to burn tokens from any account without the permission of the account owners. ```solidity=387 function approve(address spender, uint256 amount) external initialized returns (bool) { notZeroAddress(spender); address account = _msgSender(); allowance[account][spender] = amount; // Announce the change in approval of the spender of liquid tokens emit Approval(account, spender, amount); return true; } ``` Therefore, the privileged user can call `approve(targetAddress, type(uint256).max)` to increase the allowance `allowance[msg.sender][targetAddress]`, and then call `burn(targetAddress, amount)` to burn tokens from the "targetAddress".

LowPotential Integer OverflowFixed

The linked variables are increased when the functions `mint()`, `burn()`, `liquify()`, and `solidify()` are invoked. There is no function to decrease these state variables, forcing an integer overflow can cause a denial-of-service attack.

LowUnused Return ValueFixed

The return value of the internal call is not used. ```solidity=410 _decreaseAllowanceInternal(sender, spender, 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 (22)

  • Contracts/src/lib/Address.sol
  • Contracts/src/interfaces/IERC20-Metadata.sol
  • Contracts/src/interfaces/ILiquidVault.sol
  • Contracts/src/lib/Context.sol
  • Contracts/src/ERC3643-Liquid.sol
  • Contracts/src/interfaces/IAnySwap.sol
  • Contracts/src/interfaces/ICompliance.sol
  • Contracts/src/interfaces/IERC3643.sol
  • Contracts/src/interfaces/IERC20-Token.sol
  • Contracts/src/interfaces/IERC3643-LiquidDeployer.sol
  • Contracts/src/mock/ComplianceShim.sol
  • Contracts/src/interfaces/IERC173-Ownable.sol
  • Contracts/src/interfaces/IERC3643-Liquid.sol
  • Contracts/src/interfaces/IGovernor.sol
  • Contracts/src/ERC3643-LiquidDeployer.sol
  • Contracts/src/lib/Create2.sol
  • Contracts/src/lib/SafeERC20.sol
  • Contracts/src/interfaces/IEnsReverseRegistrar.sol
  • Contracts/src/LiquidVault.sol
  • Contracts/src/lib/ERC173-Ownable.sol
  • Contracts/src/lib/NameRegistrable.sol
  • Contracts/src/lib/VoteProxy.sol

Part of Token Liquidity Foundation’s security record

Token Liquidity Foundation
Audits2 audits by 1 firmLast audit Jul 2023, by CertiK.
Critical findingsNo open critical findingsAcross the 2 reports, 1 critical finding was reported. It is marked fixed by the firm that reported it.
Open Token Liquidity Foundation’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