币安好物 (币安好物) security report
币安好物 was AI scanned using verified Solidity source and GoPlus evidence. Slither was not run. No Critical exploit was proven, but the audit identified high-risk owner concentration, owner-controlled migration, potentially extreme initialization taxes, and a dividend callback that can block transfers if it fails.
AI source analysis was completed, and GoPlus evidence was reviewed. No Critical vulnerability is proven from the supplied evidence. Slither was not run.
Trust score: 42/100. Source verified: Yes. Chain: bsc. Contract: 0x661b42b4424d2cabe497ab56f0825a5f293a7777.
This report was last modified on 2026-09-24 and contains 4 material findings.
high finding: Initialization permits effectively confiscatory buy and sell taxes
The initializer accepts arbitrary uint16 buyTax and sellTax values, with no upper-bound validation. The maximum value is 65,535 basis points, or 655.35%. During TaxEnforced states, the tax is deducted from every pool trade; a 100% or greater effective tax can make a sell return zero tokens while transferring the tax amount to the token contract.
Evidence: initialize() stores params.buyTax and params.sellTax directly in poolState. _getTaxWithPoolState() computes amount * rate / 10000, and _taxedTransfer() sends the tax to address(this) and only the remainder to the recipient. The owner alone can call startMigration() and finalizeMigration(), which activate the configured tax schedule.
Recommendation: Enforce explicit maximum buy and sell tax limits, reject rates that can make the net transfer zero, publish the initialized values and migration state, and use immutable or timelocked governance for migration transitions.
high finding: Owner-controlled migration can activate transfer restrictions and taxes
The owner has exclusive control over the transition from BondingCurve to Migrating and then to TaxEnforcedAntiFarmer. In BondingCurve, all transfers to or from configured pools revert, while the later state applies the initialization-time taxes. This gives the owner centralized control over when trading is blocked and when taxation begins.
Evidence: startMigration() and finalizeMigration() are both onlyOwner. In _transfer(), BondingCurve requires !pools[from] && !pools[to], and TaxEnforcedAntiFarmer applies buyTaxRate or sellTaxRate to transfers involving any configured pool. GoPlus identifies owner_address as 0xe2ce6ab80874fa9fa2aae65d2776dd6b8e65c9de0.
Recommendation: Use a transparent, time-locked migration mechanism, disclose the exact state and transition schedule, validate pool addresses, and prevent owner-only activation of arbitrary tax or trading conditions after launch.
medium finding: Reverting dividend callback can lock ordinary token transfers
If dividendContract is nonzero and its setShare() call reverts, _afterTokenTransfer() reverts the entire token transfer. This affects transfers involving ordinary users, not only dividend operations, and can create a broad transfer lock if the external dividend contract is unavailable, misconfigured, or deliberately reverting.
Evidence: _afterTokenTransfer() calls IDividend(dividendContract).setShare(from, balanceOf(from)) and setShare(to, balanceOf(to)) without a non-reverting fallback; each failure executes revert DividendShareUpdateFailed(...). dividendContract is set during initialize() and there is no owner function to replace or disable it afterward.
Recommendation: Do not make core ERC20 transfers depend on an external dividend callback. Queue share updates, use a non-blocking try/catch policy, or provide a carefully governed recovery path to disable or replace a failed dividend contract.
medium finding: Tax processing relies on a privileged external processor and forwards the full residual balance on failure
Tax liquidation delegates processing to taxProcessor. If the call fails, the catch block transfers the token contract's entire remaining token balance to taxProcessor rather than preserving or safely recovering the funds. A malicious or misconfigured processor could therefore receive accrued tax balances and disrupt intended distribution.
Evidence: _processTax() approves taxProcessor for an unlimited allowance, calls processTaxTokens(taxAmount), and on failure executes _plainTransfer(address(this), taxProcessor, remainingBalance). taxProcessor is supplied during initialize() and cannot be changed through the exposed contract ABI.
Recommendation: Validate and constrain the processor address, avoid unlimited approvals where possible, transfer only the intended tax amount, add explicit recovery governance, and test failure behavior with an adversarial processor.