Radar by SecureChain.ai

FOMO (FOMO) security report

FOMO was AI scanned using the verified Solidity source and supplied GoPlus evidence. Slither was not run. GoPlus reports no proxy, minting, blacklist, honeypot, or active owner. Source review found a high-risk deployer-controlled LP destination, a medium-risk native-currency trapping path, and a conditional buy-reversion bug that should be tested against the deployed configuration.

The supplied GoPlus signals report zero buy and sell tax, no honeypot, no proxy, no minting, no blacklist, and a renounced owner. However, source review identifies a high-severity liquidity-control risk because auto-added LP tokens are sent to the deployer, plus medium business-logic risks involving permanently trapped native currency and a conditional buy-reversion path. Slither was not run.

Trust score: 65/100. Source verified: Yes. Chain: bsc. Contract: 0x23ad60eba2a670b2385d9fce63de7ab67b1e31f6.

This report was last modified on 2026-09-20 and contains 4 material findings.

high finding: Auto-added liquidity tokens are sent to the deployer without a lock

Whenever fee processing adds liquidity, the resulting LP tokens are sent to the constructor-supplied deployer address rather than a timelock, burn address, or locked-liquidity contract. The deployer can therefore potentially remove that liquidity and materially reduce market backing.

Evidence: In _executeSwapAndLiquify(), IUniswapV2Router02(router).addLiquidity(..., _deployer, ... ) sends the LP tokens to _deployer. No LP lock, vesting, or withdrawal restriction is implemented in the verified source. The constructor sets _deployer = deployFeeReceiver.

Recommendation: Verify the deployer address, LP-token balance, and any external lock contract on-chain. Lock or burn LP tokens through a verifiable timelock, or route LP ownership to a governed multisig with published withdrawal controls.

medium finding: Native currency sent to deposits() or receive() cannot be withdrawn

The contract accepts native BNB through deposits() and the receive fallback, but the verified source contains no function that transfers the accumulated native currency out. Any accidental or intentional native-currency deposit is therefore permanently trapped unless another inherited or undocumented mechanism exists.

Evidence: deposits() is external payable and only emits RealLogs(msg.sender, msg.value). receive() external payable has an empty body. No withdrawal function is defined in Token, ERC20, or Ownable.

Recommendation: Remove the payable entry points if they are unnecessary, or add a restricted withdrawal/refund mechanism with clear accounting and tests. Treat the current native-currency balance as unrecoverable until independently verified otherwise.

medium finding: Buy transactions can be conditionally blocked by the liquidity-removal check

When buy fees are configured above zero, every ordinary buy can enter isRemoveLiquidity(). Under normal pool conditions, the USDT balance is commonly equal to the recorded reserve, satisfying balanceOther <= rOther. The function then returns a positive value for ordinary buy amounts, causing the buy to revert with TDP3. The supplied GoPlus evidence reports buy_tax 0, so this path may not be active in the deployed configuration.

Evidence: In _transfer(), buys execute if (!tradingEnabled || isRemoveLiquidity(amount)) revert("TDP3") when buyTotal > 0. isRemoveLiquidity() enters its calculation when balanceOther <= rOther and returns a positive liquidity value for normal positive amounts. GoPlus reports buy_tax="0", making active exploitation/configuration uncertain.

Recommendation: Confirm the deployed getTokenInfo() values and test small and large buys against the live pair. Replace the reserve comparison with a proven liquidity-removal detector that cannot classify normal swaps as removals, and ensure trading state is independently validated.

medium finding: Fee-processing logic can misallocate accumulated token fees

The swap routine derives totalToSwap from the entire token balance held by the contract, but derives the liquidity half only from collectedLpTokens. If the contract holds additional token balances or both marketing and liquidity fees accumulate, the swap and liquidity proportions can differ from the configured fee split. The routine also transfers the entire post-swap USDT balance calculation to the fund receiver before adding liquidity.

Evidence: _executeSwapAndLiquify() sets totalToSwap = balanceOf(address(this)), half = collectedLpTokens / 2, and swaps totalToSwap - half. It calculates lpPortion = (swapped * half) / totalToSwap and fundPortion = afterBal - lpPortion, where afterBal includes the contract's post-transfer USDT balance. This is not based directly on collectedFundTokens and collectedLpTokens.

Recommendation: Track and process only the fee balances intended for the current operation. Calculate marketing and liquidity portions from explicit fee amounts, exclude unrelated token or USDT balances, and add invariant tests for mixed fee configurations and repeated swaps.