CertiK reviewed Alliance of 314 (Alliance of 314 - Audit) on 29 May 2024: 14 findings, 0 critical; none marked fixed.
The original report was removed from its address (seen 17 Oct 2026).
Trustblock does not review code.
Statuses are the security firm’s own, from its report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 0 | 0 | 0 |
| High | 5 | 0 | 0 |
| Medium | 3 | 0 | 0 |
| Low | 6 | 0 | 0 |
In the contract `ERC314` the role `liquidityProvider` has authority over the functions shown in the diagram below. Any compromise to the `liquidityProvider` account may allow the hacker to take advantage of this authority and withdraw ETH from the contract once `block.number` exceeds the `blockToUnlockLiquidity`; and set `blockToUnlockLiquidity` to a larger value. Note that the `liquidityProvider` becomes the `owner` after the `addLiquidity()` function is called.  In the contract `ERC314` the role `owner` has authority over the functions shown in the diagram below. Any compromise to the `owner` account may allow a hacker to take advantage of this authority and set the transfer cooldown period, set cooldown whitelist accounts, pause/unpause trading, enable/disable the max wallet check, set the max wallet value, renounce ownership, add liquidity, set fee rates, configure auto burn settings, and transfer \$314 tokens in/out of the contract before adding liquidity. 
The `enableTrading()` function is designed to allow the `owner` to control the buy and sell operations of the contract. However, if the `owner` account is compromised, the attacker could disable the sell function. This action would prevent users from exchanging the \$314 token for ETH, rendering the \$314 token valueless if this contract is the only liquidity pool. Additionally, the attacker could exploit the `removeLiquidity()` function to withdraw ETH from the contract once `block.number` exceeds the `blockToUnlockLiquidity`. ```solidity=224 function enableTrading(bool _tradingEnable) external onlyOwner { tradingEnable = _tradingEnable; } ```
The function `initLiquidityAmount` allows the owner to set the contract's token balance to any arbitrary value. After setting the balance, the function transfers the difference between the new and the previous balance to the owner's account. This function introduces a centralization risk, as it does not require community consensus. Such a design could lead to abuse of power or, in the case of a security breach of the owner's account, could allow an attacker to steal a significant amount of tokens, thereby causing severe damage to the project's operations.
The liquidity of the contract could be completely drained by the `liquidityProvider`. The function `removeLiquidity` allows the `liquidityProvider` to withdraw all Ether tokens from the contract. Once this action is performed, the contract will no longer have any liquidity to support transactions. This results in the `BEP314` token holders being unable to sell their tokens, effectively rendering the contract non-functional.
All of the \$314 tokens are sent to the contract and `receiver`(0x9C6F4dDb50e67ad009FDDeE00D9f1544E886Da88). An amount of 16,800,000 \$314 tokens are sent to the contract and an amount of 4,200,000 are sent to the `receiver`. Any compromise to these addresses may allow a hacker to steal and sell tokens, resulting in severe damage to the project.
The `setFee()` and `setBurnFee()` functions in the contract lack upper limits for setting the fee rate and burn rate for buy and sell operations. Consequently, it is possible to set the total fee rate to any arbitrary amount. This could result in scenarios where users receive no tokens in return for their buy or sell transactions.
The `_transfer()` function is designed to prevent the `msg.sender` from making two transactions within the same block. However, if a user controls two accounts, they can bypass this restriction by using the first account to perform a transfer and then approving the second account to transfer tokens from the first account. ```solidity function _transfer(address from, address to, uint256 value) internal virtual { if (to != address(0) && !excludeCoolingOf[msg.sender]) { require(lastTransaction[msg.sender] != block.number, "You can't make two transactions in the same block"); lastTransaction[msg.sender] = uint32(block.number); require(block.timestamp >= _lastTxTime[msg.sender] + cooldownSec, 'Sender must wait for cooldown'); _lastTxTime[msg.sender] = block.timestamp; } ```
The `BEP314` contract implements a trading mechanism without relying on external DEX or SWAP functionalities. However, it calculates the received amount using the constant product formula `x*y=k` which is typically used in Automated Market Makers (AMMs) to determine the price based on the reserves of two assets. A reserve check is lacking to ensure the trade does not leave the trading pair with fewer reserves than it should have. Additionally, a sandwich attack may happen when an attacker observes a transaction swapping tokens via `buy()` or `sell()` functions. The attacker can manipulate the exchange rate by frontrunning (executing before the target) a transaction to purchase one of the assets and make profits by backrunning (executing after the target) a transaction to sell the asset. Although the contract prevents `msg.sender` from being a contract and disallows two transfers within the same block, an attacker can still perform sandwich attacks using two Externally Owned Accounts (EOAs) with different gas fees for reverse direction transactions.
The general syntax for using the require statement in Solidity is: `require(condition, errorMessage);`. Even though Solidity supports using single quotes and double quotes to define strings. It's recommend to use double quotes to enclose the error message for require statements.
The function `autoBurnLiquidityPairTokens` is designed to automatically burn a portion of the contract's balance of `BEP314` tokens. The amount to be burnt is calculated as `(percentForLPBurn) / 10000` of the contract's balance and this burn event occurs every `lpBurnFrequency` seconds. After the execution of this function, the variable `_totalSupply`, which is intended to maintain a record of the total supply of `BEP314` tokens, is not updated to reflect the reduced supply following the token burn. Instead, the burned tokens are sent to the `0xdead` address. However, in both the `buy` and `sell` functions of the contract, `_totalSupply` is correctly decreased in accordance with the `buyBurnFee` and `sellBurnFee` that are burnt during transactions. The inconsistency in updating `_totalSupply` after token burns can lead to discrepancies in the total supply, potentially affecting the integrity of the token economics and functions relying on the accurate total supply value.
The `_maxWallet` parameter represents the maximum token holding limit for an account. This limit is enforced only in the `buy()` function but not in the `_transfer()` function. As a result, the token receiver's balance can exceed the maximum holding limit through transfers. Additionally, in the `buy()` function, transaction fees may be charged, which affects the calculation of the receiver's max holding. The max holding should be based on the sum of the tokens held and the amount received from the transfer, excluding any fees. #### Code Snippets: 1. **Max Holding Check in `buy()` Function:** ```solidity require(token_amount + _balances[msg.sender] <= _maxWallet, 'Max wallet exceeded'); ``` 2. **Adjustment of Receiving Amount:** ```solidity uint256 burn_amount = token_amount - user_amount; ``` 3. **Balance Update in `_transfer()` Function:** ```solidity _balances[to] += value; ```
It is expected that calls of the form `transfer(recipient, amount)` fail if the recipient address is the zero address. And it is expected that calls of the form `transferFrom(from, dest, amount)` fail for transfers from or to the zero address. However, the `transfer()` and `transferFrom()` functions in `ERC314` can transfer tokens from or to the zero address.
Type casting refers to changing an variable of one data type into another. The code contains an unsafe cast between integer types, which may result in unexpected truncation or sign flipping of the value. ```solidity=195 lastTransaction[msg.sender] = uint32(block.number); ``` Casted expression `block.number` has estimated range [0, 700800000000] but target type `uint32` has range [0, 4294967295].
It is not recommended to use Solidity's `transfer()` and `send()` functions for transferring native tokens, since some contracts may not be able to receive the funds. Those functions forward only a fixed amount of gas (2300 specifically) and the receiving contracts may run out of gas before finishing the transfer. Also, EVM instructions' gas costs may increase in the future. Thus, some contracts that can receive now may stop working in the future due to the gas limitation.
The report names a repository or files. Open the report to see its scope.
Repository and files the report names (1)
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