CertiK reviewed EAGLE NFT (EAGLE TOKEN) on 24 Jul 2023: 34 findings, 0 critical; 2 marked fixed, 32 open.
The original report was removed from its address (seen 21 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 | 4 | 0 | 1 |
| Medium | 4 | 0 | 1 |
| Low | 24 | 0 | 0 |
Several privileged roles with special permissions to execute functions are present in the audited contracts. Below we report a description of each of them and of the possible impacts that these roles can have on the project. In the contract `Miniter` in the `PhoenixEagleNFT.sol` and `TigerEagleNFT.sol` files, the role `_owner` has authority over the function `setMiniter` as shown in the diagram below. Any compromise to the `_owner` account may allow the hacker to take advantage of this authority and set arbitrary account addresses as Miniter at his/her will.  In the contract `PhoenixEagleNFT` and `TigerEagleNFT` the role `_minter` has authority over the functions `mint` and `batchMint` as shown in the diagram below. Any compromise to the `_minter` account may allow the hacker to take advantage of this authority and thus giving the power to the hacker to mint new NFTs at his/her will.  In the contract `Eagle` 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 and at his/her will potentially set any buy/sell fee, change the fee addresses, set the arbitrary values for the variables `swapTokensAtAmount`, `setSwapTigerAtAmount`, `setSwapPhoenixAtAmount`, exclude from fees any deserved account, set new automatedMarketMakerPairs and enable and disable the swaps of the `Eagle` token.  In the contract `Wrap` the role `eagle` has authority over the function `withdraw` as shown in the diagram below. Any compromise to the `eagle` account may allow the hacker to take advantage of this authority and withdraw `usdt` at any time he/her desires and every time that the `SwapAndLiquifyFunction` is called.  Important Note: Certain identification and KYC procedures were attempted to be applied to the project team in order to better understand the centralization situation and potential risks of the project. The project team refused to cooperate with the investigation efforts, thus based on the negative signals we concluded that there is potential high risk to the project. We strongly advise end users to conduct further research and exercise due diligence before engaging with the project. It is crucial for end users to independently verify and assess all available information to make informed decisions.
The `TigerEagleNFT` and `PhoenixEagleNFT` contracts (`ERC721`) have the following logic to mint new tokens: 1. Check that minting new tokens don't pass the max supply 2. Get new token id by adding 1 to the previous 3. Mint token 4. Get URI of the token from list of URIs defined in deployment (constructor) 5. If the token id is higher than the length of the list of URIs, use the URI located using mod to get the index like `token_id % length`. It is possible to observe that in the last step, if the length of the list of URIs is less than the max supply there's going to be duplicated URIs. By consequence, the tokens are going to be semi-fungible as they are copies of the same token.
In the contract `Eagle` the line below is granting approval to the `_router` address to transfer an effectively infinite amount of usdt and `Eagle` tokens on its behalf. This is potentially risky because if the `_router` address is malicious or controlled by a malicious actor, they could use the `transferFrom` function of the usdt and/or `Eagle` contract to transfer all usdt and/or `Eagle` tokens from the contract to their own address, effectively stealing the contract's usdt and/or `Eagle` tokens. ```solidity=1266 ERC20(usdt).approve(_router, ~uint256(0)); _approve(address(this), _router, ~uint256(0)); ```
All `EAGLE` tokens are sent to the contract deployer when deploying the contract. This is a potential centralization risk as the deployer can distribute `EAGLE` tokens without the consensus of the community. Important Note: Certain identification and KYC procedures were attempted to be applied to the project team in order to better understand the centralization situation and potential risks of the project. The project team refused to cooperate with the investigation efforts, thus based on the negative signals we concluded that there is potential high risk to the project. We strongly advise end users to conduct further research and exercise due diligence before engaging with the project. It is crucial for end users to independently verify and assess all available information to make informed decisions.
The `PhoenixEagleNFT` and `TigerEagleNFT` contracts define a default max supply hardcoded in the variable `maxSupply` of specific values `688` and `68` respectively. However, in the deployment that value is overwriting for a value input as argument of the constructor. This can be misleading for users reading the contract as they can think the contract has a max supply of the hardcoded values, but the contract could have a different max supply.
In the contract `Eagle`, there are no upper limits restricting parameters of `setBuyFee` and `setSellFee`, potentially enabling up to 100% fees on pair-related transactions.
A reentrancy attack can occur when the contract creates a function that makes an external call to another untrusted contract before resolving any effects. If the attacker can control the untrusted contract, they can make a recursive call back to the original function, repeating interactions that would have otherwise not run after the external call resolved the effects. We report below as an example a partial overview of the possible reentrancy attacks. Note all the vulnerable parts of the codebase that are affected are reported in the finding locations. ### External call(s) ```solidity=1423 swapAndLiquify(swapAmount); ``` * This function call executes the following external call(s). * In `Eagle.addLiquidity`, * `uniswapV2Router.addLiquidity(address(this),usdt,t1Amount,t2Amount,0,0,address(this),block.timestamp)` * In `Eagle.swapTokensForUsdt`, * `uniswapV2Router.swapExactTokensForTokensSupportingFeeOnTransferTokens(tokenAmount,0,path,to,block.timestamp)` * In `Eagle.swapAndLiquify`, * `wrap.withdraw()` ### State variables written after the call(s) ```solidity=1424 swapAmount = 0; ``` --- ### External call(s) ```solidity=1423 swapAndLiquify(swapAmount); ``` * This function call executes the following external call(s). * In `Eagle.addLiquidity`, * `uniswapV2Router.addLiquidity(address(this),usdt,t1Amount,t2Amount,0,0,address(this),block.timestamp)` * In `Eagle.swapTokensForUsdt`, * `uniswapV2Router.swapExactTokensForTokensSupportingFeeOnTransferTokens(tokenAmount,0,path,to,block.timestamp)` * In `Eagle.swapAndLiquify`, * `wrap.withdraw()` ```solidity=1428 swapTokensForUsdt(tigerAmount, _tigerAddress); ``` ### State variables written after the call(s) ```solidity=1429 tigerAmount = 0; ``` --- ### External call(s) ```solidity=1423 swapAndLiquify(swapAmount); ``` * This function call executes the following external call(s). * In `Eagle.addLiquidity`, * `uniswapV2Router.addLiquidity(address(this),usdt,t1Amount,t2Amount,0,0,address(this),block.timestamp)` * In `Eagle.swapTokensForUsdt`, * `uniswapV2Router.swapExactTokensForTokensSupportingFeeOnTransferTokens(tokenAmount,0,path,to,block.timestamp)` * In `Eagle.swapAndLiquify`, * `wrap.withdraw()` ```solidity=1428 swapTokensForUsdt(tigerAmount, _tigerAddress); ``` ```solidity=1433 swapTokensForUsdt(phoenixAmount, _phoenixAddress); ``` ### State variables written after the call(s) ```solidity=1434 phoenixAmount = 0; ``` ```solidity=1437 swapping = false; ``` ```solidity=1449 amount = takeBuyFee(from,amount); ``` * This function call executes the following assignment(s). * In `ERC20._transfer`, * `_balances[sender] = senderBalance - amount` * In `ERC20._transfer`, * `_balances[recipient] += amount`
The `_transfer` function in the `Eagle` contract includes a condition where, if the balance of the from address is equal to the amount to be transferred, the amount is decreased by one before the transfer operation. This behavior is non-standard and can potentially lead to unexpected consequences. For example, if a user tries to transfer their entire balance, one token would always remain in their account.
The linked lines have commented-out code that is redundant and can be deleted.
The `delayTradeTime` of the `Eagle` (ERC20) contract has a default value of `600`. However, the value is overwriting without any validation. This means the value could be any number from 0 (no delay) to the max number in `uint256` (endless delay).
The highlighted error messages use `BABYTOKEN` as the project name, which is a fork leftover.
The `Eagle` token constructor receives the address of the `USDT` token and to create a `Wrap`. When the `Wrap` constructor is called, it pass as argument `address(usdt)`. However, `usdt` is already an address and the usage of the `address()` function in unnecessary.
The `Wrap` contract employs `if` conditions for validation instead of using the `require` function. `Require` statements revert the transaction if the condition is not satisfied, providing a more robust way to validate conditions and ensure the proper functioning of the smart contract.
The codebase contains multiple Solidity versions, which can lead to unexpected behavior, potential vulnerabilities, difficulties in maintaining the code, and inconsistencies in the execution of the smart contract. Using different versions may also result in increased complexity during code auditing, as different security features and bug fixes are present in different versions of the compiler. Versions used: `^0.8.1`, `^0.8.0` `^0.8.0` is used in PhoenixEagleNFT.sol file. ```solidity=2174 pragma solidity ^0.8.0; ``` `^0.8.1` is used in PhoenixEagleNFT.sol file. ```solidity=818 pragma solidity ^0.8.1; ```
The contract has a `receive()` payable function, making it able to receive native tokens such as Ethers. However, it does not have a function to withdraw `ETH` funds, which can lead to permanently locked tokens within the contract.
The current wording of the error message does not accurately reflect the nature of the problem. The phrase, "Account is already the value of excluded", could be misconstrued due to its unclear reference to the input variable `excluded` which can be either `false` or `true`.
The highlighted function affects the status of sensitive variables should emit events as notifications to customers.
Addresses are not validated before assignment or external calls, potentially allowing the use of zero addresses and leading to unexpected behavior or vulnerabilities. For example, transferring tokens to a zero address can result in a permanent loss of those tokens. ```solidity=107 eagle = _eagle; ``` - `_eagle` is not zero-checked before being used. --- ```solidity=1242 usdt = _usdt; ``` - `_usdt` is not zero-checked before being used. --- ```solidity=1256 uniswapV2Pair = _uniswapV2Pair; ``` - `_uniswapV2Pair` is not zero-checked before being used. --- ```solidity=1289 _tigerAddress = tigerAddress; ``` - `tigerAddress` is not zero-checked before being used. --- ```solidity=1290 _phoenixAddress = phoenixAddress; ``` - `phoenixAddress` is not zero-checked before being used. --- ```solidity=1291 _marketAddress = marketAddress; ``` - `marketAddress` is not zero-checked before being used.
A reentrancy attack can occur when the contract creates a function that makes an external call to another untrusted contract before resolving any effects. If the attacker can control the untrusted contract, they can make a recursive call back to the original function, repeating interactions that would have otherwise not run after the external call resolved the effects. ### External call(s) ```solidity=1423 swapAndLiquify(swapAmount); ``` * This function call executes the following external call(s). * In `Eagle.addLiquidity`, * `uniswapV2Router.addLiquidity(address(this),usdt,t1Amount,t2Amount,0,0,address(this),block.timestamp)` * In `Eagle.swapTokensForUsdt`, * `uniswapV2Router.swapExactTokensForTokensSupportingFeeOnTransferTokens(tokenAmount,0,path,to,block.timestamp)` * In `Eagle.swapAndLiquify`, * `wrap.withdraw()` ```solidity=1428 swapTokensForUsdt(tigerAmount, _tigerAddress); ``` ```solidity=1433 swapTokensForUsdt(phoenixAmount, _phoenixAddress); ``` ### Events emitted after the call(s) ```solidity=419 emit Transfer(sender, recipient, amount); ``` * Executed via the following function call(s): * `amount = takeBuyFee(from,amount)` * `super._transfer(from,to,amount)` * `amount = takeSellFee(from,amount)` --- ### External call(s) ```solidity=1521 swapTokensForUsdt(half,address(wrap)); // <- this breaks the ETH -> HATE swap when swap+liquify is triggered ``` * This function call executes the following external call(s). * In `Eagle.swapTokensForUsdt`, * `uniswapV2Router.swapExactTokensForTokensSupportingFeeOnTransferTokens(tokenAmount,0,path,to,block.timestamp)` ```solidity=1523 wrap.withdraw(); ``` ```solidity=1528 addLiquidity(otherHalf, newBalance); ``` * This function call executes the following external call(s). * In `Eagle.addLiquidity`, * `uniswapV2Router.addLiquidity(address(this),usdt,t1Amount,t2Amount,0,0,address(this),block.timestamp)` ### Events emitted after the call(s) ```solidity=1530 emit SwapAndLiquify(half, newBalance, otherHalf); ```
A sandwich attack might happen when an attacker observes a transaction swapping tokens or adding liquidity without setting restrictions on slippage or minimum output amount. The attacker can manipulate the exchange rate by frontrunning (before the transaction being attacked) a transaction to purchase one of the assets and make profits by backrunning (after the transaction being attacked) a transaction to sell the asset. 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: - `uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens()` ```solidity= uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens( tokenAmount, 0, // accept any amount of ETH path, address(this), block.timestamp ); ```
State variables that never change should be declared as `constant` to save gas. ```solidity=1175 uint256 private _basePercent = 10000; ``` - `_basePercent` should be declared `constant`.
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=1157 IUniswapV2Router02 public uniswapV2Router; ``` - The contract `Eagle` interacts with third party contract with `IUniswapV2Router02` interface via `uniswapV2Router`.
There are typo in the codebase or comments.
The return value of the `transfer()` calls in the smart contract is not checked. Some ERC-20 tokens' transfer functions return no values, while others return a bool value, they should be handled with care. If a function returns `false` instead of reverting upon failure, an unchecked failed transfer could be mistakenly considered successful in the contract. ```solidity=115 usdt.transfer(eagle, usdtBalance); ```
The state variables `tradingEnabledTimestamp` and `isCreatePair` are never initialized. The concern is that these variables are used in the function `_transfer` before any explicit value has been assigned to them.
The contracts cited have an unlocked compiler version. An unlocked compiler version in the source code of the contract permits the user to compile it at or above a particular version. This, in turn, leads to differences in the generated bytecode between compilations due to differing compiler version numbers. This can lead to ambiguity when debugging, as compiler specific bugs may occur in the codebase that would be hard to identify over a span of multiple compiler versions rather than a specific one.
In the function `_transfer` of `Eagle` contract if the transfer amount is zero, the function proceeds to call the `_transfer` function from a parent contract with a value of 0 and then returns. This allows for the execution of a transfer operation even when the amount to be transferred is zero.
The `SafeMath` library is used unnecessarily. With Solidity compiler versions 0.8.0 or newer, arithmetic operations will automatically revert in case of integer overflow or underflow. ```solidity=629 library SafeMath { ``` - An implementation of `SafeMath` library is found. --- ```solidity=1154 using SafeMath for uint256; ``` - `SafeMath` library is used for `uint256` type in `Eagle` contract. ```solidity=1464 uint256 tFee = amount.mul(_sellTigerFee).div(_basePercent); ``` - `SafeMath.mul` is called in `takeSellFee` function of `Eagle` contract. *Note: Only a sample of 2 `SafeMath` library usage in this contract (out of 38) are shown above.*
The pointed code is not used, by consequence doesn't add any value to the contracts. It only will increase deployment price.
The smart contract does not check or store the return value of the external calls below in a local or state variable, which may introduce vulnerabilities due to the unhandled outcome. ```solidity=1266 ERC20(usdt).approve(_router, ~uint256(0)); ``` --- ```solidity=1552 uniswapV2Router.addLiquidity(address(this), usdt, t1Amount, t2Amount, 0, 0, address(this), block.timestamp); ```
Different magic numbers are used as-is in code.
The linked variables assigned in the constructor can be declared as `immutable`. Immutable state variables can be assigned during contract creation but will remain constant throughout the lifetime of a deployed contract. A big advantage of immutable variables is that reading them is significantly cheaper than reading from regular state variables since they will not be stored in storage.
| Address | Chain | Source code |
|---|---|---|
| 0x323a…f6660x323ab075d9cc84912d8ec97877f01261e34bf666 | Chain: BNB Chain | Source code: Verified source |
| 0x3d1f…3d960x3d1feca61485f6c356665f832a89ad75bba03d96 | Chain: BNB Chain | Source code: Verified source |
| 0xebe1…ded60xebe1348d7d814306bdda65ce8f980c7f12b2ded6 | 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