Alibaba Cat (猫天天) security report
Alibaba Cat was AI scanned from verified Solidity source with GoPlus evidence. No confirmed critical or high vulnerability was found. Medium risks include owner-controlled migration, potentially excessive initialization taxes, trusted tax processing, arbitrary pool restrictions, and dividend-contract transfer failures. Slither was not run.
The contract was AI scanned using the verified Solidity source and supplied GoPlus signals; Slither was skipped. No confirmed critical or high finding was identified, but the deployment configuration and privileged migration flow create medium business-logic and availability risks that should be verified on-chain.
Trust score: 64/100. Source verified: Yes. Chain: bsc. Contract: 0xaf856ca8f0a241032f27a4dd533f6696e4a57777.
This report was last modified on 2026-09-29 and contains 5 material findings.
medium finding: Owner can control migration timing and pool-transfer availability
The owner controls startMigration() and finalizeMigration(). While the pool remains in BondingCurve state, every transfer to or from any configured pool reverts. An owner who delays migration can therefore prevent configured-pool trading and liquidity interaction.
Evidence: startMigration() and finalizeMigration() are both onlyOwner. In _transfer(), PoolState.BondingCurve requires !pools[from] && !pools[to], otherwise it reverts with "Transfers to/from pools are restricted in BondingCurve state".
Recommendation: Verify the current state(), mainPool(), and pools configuration on-chain. Publish a clear migration policy, use timelocked or multisig ownership, and avoid relying on a single owner for trading activation.
medium finding: Initialization permits tax rates above 100%, potentially blocking buys and sells
initialize() accepts uint16 buyTax and sellTax values without enforcing a maximum of 10000 basis points. If either configured rate exceeds 100%, _taxedTransfer() computes remainingAmount = amount - tax and reverts, creating a honeypot-like transfer restriction for the affected direction once taxation is active.
Evidence: initialize() stores params.buyTax and params.sellTax directly in poolState. _getTaxWithPoolState() calculates amount * taxRate / 10000, while _taxedTransfer() performs uint256 remainingAmount = amount - tax. The supplied ABI and GoPlus evidence do not include the deployed buy/sell tax values.
Recommendation: Check buyTaxRate() and sellTaxRate() on-chain. Enforce buyTax and sellTax <= 10000 during initialization, and use an immutable or governance-controlled maximum tax policy.
medium finding: Trusted tax processor can receive and control accumulated tax tokens
The configured taxProcessor receives an effectively unlimited ERC20 allowance and is called to process all accumulated tax tokens. If processing fails, the contract transfers its entire remaining token balance to taxProcessor. This creates material centralized custody and dependency risk even though it is not an arbitrary public drain in the token contract.
Evidence: _processTax() approves taxProcessor for type(uint256).max when needed and calls processTaxTokens(taxAmount). Its catch branch executes _plainTransfer(address(this), taxProcessor, remainingBalance), transferring all tokens held by the token contract. taxProcessor is set during initialize() and has no public setter.
Recommendation: Verify the deployed taxProcessor code, ownership, fee receivers, and emergency withdrawal permissions. Use audited immutable processors, bounded approvals where practical, and transparent governance for processor selection.
medium finding: Dividend contract failure can make ordinary transfers revert
When dividendContract is nonzero, transfers involving ordinary addresses synchronously call setShare() for the sender and recipient. Any revert from that external contract causes the entire token transfer to revert, creating a transfer-availability dependency and possible lock if the configured dividend contract is broken or intentionally rejects updates.
Evidence: _afterTokenTransfer() calls IDividend(dividendContract).setShare(...) for non-excluded from and to addresses. The catch blocks explicitly revert with DividendShareUpdateFailed. dividendContract is supplied during initialize() and cannot be changed through the exposed token ABI.
Recommendation: Verify the configured dividend contract and its authorization logic. Consider non-blocking share updates, bounded failure handling, or a governance-controlled recovery mechanism for a malfunctioning dividend module.
medium finding: Configured pool list can impose transfer restrictions beyond the main market
The initializer can mark any number of arbitrary addresses as pools. In anti-farmer mode, transfers involving any marked pool are taxed, and in bonding-curve mode transfers involving any marked pool revert. Because pools are not removable through the exposed ABI, an incorrect or malicious initialization list can affect unrelated addresses permanently.
Evidence: initialize() loops through params.pools and sets pools[params.pools[i]] = true. _getTaxWithPoolState() applies tax when pools[from] or pools[to] is true in TaxEnforcedAntiFarmer, while _transfer() blocks all such transfers in BondingCurve state.
Recommendation: Validate every configured pool against canonical DEX contracts before deployment and publish the complete list. Add governance-controlled pool management or enforce strict pool validation in the factory.