BAID (BAID) security report
Radar AI scanned BAID's verified BNB Smart Chain contract and found medium-severity risks involving owner-controlled migration, unchecked tax-rate bounds, dividend callbacks, and external tax processing. Slither was not run.
Material medium-severity control and availability risks were identified. The source does not expose post-deployment minting, blacklist functions, or owner-adjustable tax setters, but migration and external processor configuration remain important trust assumptions.
Trust score: 58/100. Source verified: Yes. Chain: bsc. Contract: 0xe722c77ea3dc022f35314415ca99d69793237777.
This report was last modified on 2026-10-08 and contains 5 material findings.
medium finding: Initializer accepts tax rates above the valid percentage range
The initializer accepts buyTax and sellTax as uint16 values but does not require either value to be at most 10000 basis points. If a value above 10000 is configured, taxed pool transfers calculate tax greater than the transfer amount and revert on remainingAmount = amount - tax, creating a trading lock for the affected direction once tax enforcement begins.
Evidence: initialize() stores params.buyTax and params.sellTax directly in poolState. _taxedTransfer() computes uint256 remainingAmount = amount - tax, while _getTaxWithPoolState() divides by 10000 without an upper-bound check.
Recommendation: Require both tax parameters to be <= 10000 during initialization and validate deployed configuration before enabling tax-enforced states.
medium finding: Owner can indefinitely control migration and pool transfer availability
While the token remains in BondingCurve state, every transfer involving a configured pool reverts. Only the owner can call startMigration() and finalizeMigration(), and no permissionless timeout advances the state. An owner that delays migration can therefore keep pool-based trading transfers unavailable.
Evidence: _transfer() requires !pools[from] && !pools[to] in PoolState.BondingCurve. startMigration() and finalizeMigration() are both external onlyOwner functions, and there is no automatic transition out of BondingCurve.
Recommendation: Use a permissionless or time-bounded migration path, or document and govern the owner-controlled transition with a timelock and operational safeguards.
medium finding: External dividend callback can block ordinary token transfers
When dividendContract is nonzero, transfers involving non-excluded addresses call IDividend.setShare(). Any revert from that external callback is propagated as DividendShareUpdateFailed, causing the token transfer itself to revert. A misconfigured, unavailable, or incompatible dividend contract can therefore create a transfer availability failure.
Evidence: _afterTokenTransfer() calls IDividend(dividendContract).setShare(from, balanceOf(from)) and setShare(to, balanceOf(to)) inside try/catch blocks; each catch executes revert DividendShareUpdateFailed(...).
Recommendation: Avoid making core transfers depend on a synchronous external callback, or add a resilient failure-handling mode, bounded gas strategy, and validated dividend-contract configuration.
medium finding: Tax-processing failure redirects the entire accrued token balance
If TaxProcessor.processTaxTokens() reverts, the catch block transfers balanceOf(address(this)) to taxProcessor, not merely the current taxAmount. This can redirect all tax tokens accumulated by the token contract to the configured processor address, including balances accrued from prior liquidations. The processor address is supplied during initialization and is not changeable through this contract.
Evidence: _processTax() catches processTaxTokens() failure and executes uint256 remainingBalance = balanceOf(address(this)); followed by _plainTransfer(address(this), taxProcessor, remainingBalance).
Recommendation: On processing failure, retain the balance for a controlled retry or transfer only the current batch after explicit validation. Add processor-code and configuration checks, and document the recovery authority.
medium finding: Tax processing relies on a privileged external processor with unlimited allowance
The token grants taxProcessor a maximum uint256 allowance whenever the current allowance is insufficient. The processor can therefore pull the token contract's accrued tax balance through its processTaxTokens implementation. This is an external trust dependency and a compromise or incorrect configuration of the processor can affect accrued tax assets.
Evidence: _processTax() calls _approve(address(this), taxProcessor, type(uint256).max) before invoking ITaxProcessor(taxProcessor).processTaxTokens(taxAmount). taxProcessor is set from initialization and has no setter in FlapTaxTokenV3.
Recommendation: Use narrowly scoped approvals where practical, validate the processor implementation and address, add governance or timelock controls around processor selection, and provide a safe recovery path for failed processing.