BNB Agent Center (BAC) security report
Radar AI scanned BNB Agent Center's verified contract on BNB Smart Chain. Findings include external tax-processing loss exposure, transfer blocking through dividend callbacks, owner-controlled migration restrictions, and unsafe initializer tax bounds.
The contract is not free of material risks. A configured tax processor can receive the token contract's entire accumulated token balance when tax processing fails, and a configured dividend contract can make ordinary transfers revert. The owner can also delay migration while pool transfers remain restricted.
Trust score: 52/100. Source verified: Yes. Chain: bsc. Contract: 0xc75059bf5b767a8b1fc7846950b24864dac47777.
This report was last modified on 2026-10-14 and contains 4 material findings.
medium finding: Initialization parameters can impose confiscatory pool taxes
The initializer accepts arbitrary uint16 buy and sell tax rates without enforcing a maximum of 10000 basis points. Rates above 10000 make the calculated tax exceed the transfer amount, causing the taxed transfer to revert; a rate of 10000 can also leave no amount for the recipient. This is a deployment-time configuration risk rather than an identified post-initialization rate setter.
Evidence: initialize() stores params.buyTax and params.sellTax directly in poolState without a bounds check. _getTaxWithPoolState computes amount * taxRate / 10000, and _taxedTransfer then computes amount - tax.
Recommendation: Enforce buy and sell rates at or below 10000 basis points, document effective tax limits, and verify initializer parameters before deployment. If higher rates are intentionally supported, define explicit transfer behavior instead of relying on arithmetic underflow reverts.
medium finding: Tax-processing failure forwards the entire contract token balance
When the external tax processor call fails, the fallback transfers the full token balance held by this token contract to taxProcessor, rather than only the tax amount being processed. A faulty, compromised, or incompatible processor can therefore receive previously accumulated tax tokens in addition to the current batch.
Evidence: In _processTax(uint256 taxAmount), the catch block reads balanceOf(address(this)) into remainingBalance and calls _plainTransfer(address(this), taxProcessor, remainingBalance). The external call is ITaxProcessor(taxProcessor).processTaxTokens(taxAmount), and taxProcessor is configured during initialize().
Recommendation: Restrict the processor to a reviewed immutable or governed address, transfer only the intended taxAmount on failure, and add an explicit recovery or pause procedure that cannot redirect all accumulated tax tokens to an external dependency.
medium finding: Dividend callback can block token transfers
Every transfer involving a non-excluded address invokes the configured dividend contract's setShare callback. If that external call reverts, the token transfer reverts through DividendShareUpdateFailed, creating a transfer denial-of-service condition dependent on the dividend contract's availability and behavior.
Evidence: _afterTokenTransfer calls IDividend(dividendContract).setShare(from, balanceOf(from)) and setShare(to, balanceOf(to)) for addresses not equal to the token contract, zero address, dead address, dividend contract, or a configured pool. Each call is wrapped in try/catch that reverts with DividendShareUpdateFailed on failure.
Recommendation: Use a trusted, resilient dividend contract and consider making share updates non-blocking, queue-based, or separately callable. Add an emergency mechanism to disable the callback if the dependency becomes unavailable.
medium finding: Owner-controlled migration can keep pool transfers restricted
While the token remains in BondingCurve state, all transfers to or from configured pools revert. Only the owner can call startMigration and finalizeMigration to advance the state, so an owner that delays or refuses these calls can prevent pool-based trading from progressing.
Evidence: _transfer requires !pools[from] && !pools[to] in PoolState.BondingCurve and reverts with "Transfers to/from pools are restricted in BondingCurve state". startMigration() and finalizeMigration() are both external onlyOwner functions, and no permissionless timeout or forced transition exists.
Recommendation: Use a transparent, timelocked migration process or a permissionless transition after defined conditions are met. Publish the state-transition authority and ensure users are not dependent on an unbounded owner action for pool transfers.