CertiK reviewed Hawk on 16 Sep 2024: 8 findings, 0 critical; all acknowledged, none fixed.
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 | 3 | 0 |
| Medium | 0 | 1 | 0 |
| Low | 0 | 4 | 0 |
The function is designed to interact with the PancakeSwap V2 Router to add liquidity to a pool. It takes several parameters, including `marketAddress`, which denotes the recipient address for the liquidity provider (LP) tokens generated by the transaction. The code snippet below illustrates the use of `marketAddress` in the function call: ```solidity function addLiquidityForTokenB() public { // ... (other code) Router.addLiquidity( // ... (other parameters), marketAddress ); // ... (other code) } ``` Over time, the `marketAddress` accumulates a significant portion of LP tokens. If `marketAddress` is an externally owned account (EOA), the security of its private key is critical. Any compromise of this key could lead to a loss of funds and damage to the project's integrity.
In the contract `TransitSwap`, the role `owner` has authority over the function shown in the diagram below. Any compromise to the `owner` account may allow the hacker to take advantage of this authority and withdraw the specified token's balance. It is important to note that in the `HawkToken.sol` file, the `owner` of `TransitSwap` is the `HawkToken` contract. 
All of the Hawk tokens are sent to the contract deployer. This is a centralization risk because the deployer can distribute tokens without obtaining the consensus of the community. Any compromise to the address may allow a hacker to steal and sell tokens on the market, resulting in severe damage to the project.
The `swapAndAddLiquidity()` function in the contract is designed to add liquidity to the pair using the `AmountLiquidityFee`. However, there is a potential issue where fees may not be fully added to the liquidity pair, causing any excess tokens to become permanently locked in the contract.
The contract has a `receive()` function or payable functions, making it able to receive native tokens. However, it does not have a function to withdraw the funds, which can lead to permanently locked tokens within the contract. ```solidity=833 receive() external payable {} ``` ```solidity=835 function withdraw(address token) public payable { ``` ```solidity=707 constructor( ) payable ERC20("Hawk", "Hawk") { ``` ```solidity=726 receive() external payable {} ``` ```solidity=727 fallback() external payable{} ```
A sandwich attack can occur when an attacker notices a transaction involving token swaps or liquidity additions that lacks slippage restrictions or minimum output amount settings. The attacker can exploit this by frontrunning the transaction to purchase one of the assets, thereby manipulating the exchange rate, and then backrunning the transaction to sell the asset for a profit. The referenced functions are invoked without setting slippage restrictions or minimum output amounts, making transactions that trigger these functions particularly vulnerable to sandwich attacks, especially when large input amounts are involved.
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=681 address public tokenB = address(0x55d398326f99059fF775485246999027B3197955); ``` ```solidity=719 IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02(0x10ED43C718714eb63d5aA57B78B54704E256024E); ```
The `swapping` variable in the `_transfer()` function is intended to prevent recursive swap calls, which can cause a `stack overflow` error when interacting with the liquidity pair. However, the variable is not effectively used in the current implementation. Instead, the function relies on the check `from != address(this)` to prevent recursion. ```solidity=741 if(uniswapV2Pair == to &&from != owner() &&to != owner() &&from != address(this)) { swapping = true; if(AmountMarketFee > AmountMarketFeeDoTran){ swapAndSendMarketAddress(); } if(AmountLiquidityFee > AmountLiquidityFeeDoAdd){ swapAndAddLiquidity(); } swapping = false; } ```
| Address | Chain | Source code |
|---|---|---|
| 0xe846…0d2d0xe846d164b88ed2e1209609fea3cf7a3d89d70d2d | Chain: BNB Chain | Source code: Verified source |
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