NFAi

CertiK1 address on Ethereum

CertiK reviewed nsurance (NFAi) on 3 Mar 2023: 16 findings, 0 critical; none marked fixed.

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

Report hosted on skynet.certik.com.

Trustblock does not review code.

Findings16

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

SeverityOpenAcknowledgedFixed
Critical000
High200
Medium200
Low1200
HighCentralization Risks in NFAi.solOpen

In the contract `NFAi` 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. ![](https://accelerator-tasks-prod.acc.corp.certik.com/0af19168f9f54748b4ba9e2c76319386/diagrams/centralization_NFAi-NFAi-_owner.svg) In the contract `Ownable` 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. ![](https://accelerator-tasks-prod.acc.corp.certik.com/0af19168f9f54748b4ba9e2c76319386/diagrams/centralization_NFAi-Ownable-_owner.svg)

HighInitial Token DistributionOpen

All **NFAi** tokens are sent to the contract address and the two EOA addresses when deploying the contract. This is a potential centralization risk as these privileged addresses can distribute **NFAi** tokens without the consensus of the community. - The 75% of token supply is sent to contract address, and the contract owner will use them to add liquidity. - The 15% of token supply is sent to `0xCE14646cEBc61f9b9d92B40fA9acec18F5c06661`. - The 10% of token supply is sent to `0x114AF948c4fc58E6AB41E412a8711b54f0639CCa`.

MediumPotential Loss of PrecisionOpen

Division operations may result in loss of precision. There maybe a small amount of `NFAi` loss based on the fee formulas. ```solidity=920 fees = (amount * 99) / 100; tokensForLiquidity += (fees * buyLiquidityFee) / buyTotalFees; tokensForOperations += (fees * buyOperationsFee) / buyTotalFees; tokensForTreasury += (fees * buyTreasuryFee) / buyTotalFees; } // on sell else if (automatedMarketMakerPairs[to] && sellTotalFees > 0) { fees = (amount * sellTotalFees) / 100; tokensForLiquidity += (fees * sellLiquidityFee) / sellTotalFees; tokensForOperations += (fees * sellOperationsFee) / sellTotalFees; tokensForTreasury += (fees * sellTreasuryFee) / sellTotalFees; } // on buy else if (automatedMarketMakerPairs[from] && buyTotalFees > 0) { fees = (amount * buyTotalFees) / 100; tokensForLiquidity += (fees * buyLiquidityFee) / buyTotalFees; tokensForOperations += (fees * buyOperationsFee) / buyTotalFees; tokensForTreasury += (fees * buyTreasuryFee) / buyTotalFees; } ```

MediumSpenders With Infinite Allowance Handled IncorrecOpen

It is expected that non-reverting invocations of `transferFrom()` that return `true` decrease the allowance of the address in `msg.sender` for the address in `from` by the value in `amount`. An allowance that equals `type(uint256).max` is treated as an exception and interpreted as an unlimited allowance that does not need to be reduced in order for this check to pass. The `transferFrom` function in this contract violates this property.

LowERC20 Approval Race ConditionOpen

The approval function of the ERC20 standard possesses a well-known vulnerability whereby two consecutive approvals can be exploited to instead “reset” the approval by consuming the approval that is meant to be replaced with a new one.

LowIncorrect Error MessageOpen

The error message in #L661 is incorrect since the function `updateMaxBuyAmount()` is only used to update max buy amount. ```solidity=654 function updateMaxBuyAmount(uint256 newNum) external onlyOwner { require( newNum >= ((totalSupply() * 5) / 1000) / 1e18, "Cannot set max buy amount lower than 0.5%" ); require( newNum <= ((totalSupply() * 2) / 100) / 1e18, "Cannot set buy sell amount higher than 2%" ); maxBuyAmount = newNum * (10**18); emit UpdatedMaxBuyAmount(maxBuyAmount); } ``` The error message in #L1074 is incorrect since the function `setTreasuryAddress()` is only used to update treasury address. ```solidity=1071 function setTreasuryAddress(address _treasuryAddress) external onlyOwner { require( _treasuryAddress != address(0), "_operationsAddress address cannot be 0" ); treasuryAddress = payable(_treasuryAddress); emit UpdatedTreasuryAddress(_treasuryAddress); } ```

LowMiscalculation of Max HoldingOpen

The transaction may be charged fees, so the max holding of the receiver should be the sum of the held tokens and the amount received from the transfer. The fees should not be included in the max holding. ```solidity=869 require( amount + balanceOf(to) <= maxWallet, "Max Wallet Exceeded" ); ``` - Max holding is checked. ```solidity=946 amount -= fees; ``` - Receiving amount is adjusted. ```solidity=276 _balances[recipient] += amount; ``` - Balance is increased by the adjusted amount.

LowMissing Emit EventsOpen

There should always be events emitted in the sensitive functions that are controlled by centralization roles.

LowPotential Sandwich AttacksOpen

A sandwich attack may 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 front running (before the transaction being attacked) a transaction to purchase one of the assets and make profits by back running (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: - `swapExactTokensForETHSupportingFeeOnTransferTokens()`

LowPull-Over-Push Pattern In `transferOwnership()` FOpen

The change of `_owner` by function `transferOwnership()` overrides the previously set `_owner` with the new one without guaranteeing the new `_owner` is able to actuate transactions on-chain.

Show 6 more
LowThird Party DependencyOpen

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 assume 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=414 IDexRouter public dexRouter; ``` - The contract `NFAi` interacts with third party contract with `IDexRouter` interface via `dexRouter`.

LowUnused EventOpen

```solidity=490 event SwapAndLiquify( uint256 tokensSwapped, uint256 ethReceived, uint256 tokensIntoLiquidity ); ``` ```solidity=498 event UpdatedPrivateMaxSell(uint256 amount); ```

LowUnused Return ValueOpen

The return value of an external call is not stored in a local or state variable. ```solidity=979 dexRouter.addLiquidityETH{value: ethAmount}( address(this), tokenAmount, 0, // slippage is unavoidable 0, // slippage is unavoidable address(0xdead), block.timestamp ); ``` --- ```solidity=1140 dexRouter.addLiquidityETH{value: address(this).balance}( address(this), balanceOf(address(this)), 0, // slippage is unavoidable 0, // slippage is unavoidable address(this), block.timestamp ); ``` --- ```solidity=1158 IERC20(lpPair).approve(address(dexRouter), lpAmount); ``` --- ```solidity=1161 dexRouter.removeLiquidityETH( address(this), lpAmount, 1, // slippage is unavoidable 1, // slippage is unavoidable msg.sender, block.timestamp ); ``` --- ```solidity=1197 dexRouter.addLiquidityETH{value: address(this).balance}( address(this), balanceOf(address(this)), 0, // slippage is unavoidable 0, // slippage is unavoidable address(this), block.timestamp ); ```

LowUsage of `tx.origin`Open

Contracts that authorize users using the `tx.origin` variable are typically vulnerable to phishing attacks which can trick users into performing authenticated actions on the vulnerable contract. There are multiple reasons why using `tx.origin` is not safe from the security perspective. Refer to : * [Solidity Documentation on `tx.origin`](https://docs.soliditylang.org/en/latest/security-considerations.html#tx-origin) * <https://github.com/ethereum/solidity/issues/683> ```solidity=832 require( _holderLastTransferTimestamp[tx.origin] < block.number - 2 && _holderLastTransferTimestamp[to] < block.number - 2, "_transfer:: Transfer Delay enabled. Try again later." ); ```

LowUseless Variable `sellingEnabled`Open

The initial value of `sellingEnabled` is `true`, and the only function that can update it - `setSellingEnabled()` - requires its value to be equal to `false` first. In short, there is no way to update `sellingEnabled`, it will always be true. Therefore, the variable `sellingEnabled` is useless. There is even less need to check it. ```solidity=454 bool public sellingEnabled = true; ``` ```solidity=863 require(sellingEnabled, "Selling is disabled"); ``` ```solidity=1101 function setSellingEnabled() external onlyOwner { require(!sellingEnabled, "Selling already enabled!"); sellingEnabled = true; emit EnabledSelling(); } ```

LowVariables That Could Be Declared as ImmutableOpen

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.

Contracts in scope1

AddressChainSource code
0x8eecaad83a1ea77bd88a818d4628fafc4cad7969Chain: EthereumSource code: Verified source

Part of nsurance’s security record

nsurance
Audits4 audits by 2 firmsLast audit Feb 2024, by CertiK.
Critical findingsNo open critical findingsAcross the 4 reports, 1 critical finding was reported. It is marked fixed by the firm that reported it.
Open nsurance’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