Radar by SecureChain AI

契约精神 (Pact) security report

Radar AI scanned Pact’s verified contract source and reviewed GoPlus evidence. No minting, blacklist, proxy, self-destruct, or honeypot signal was reported.

The source does not show an unrestricted mint, blacklist, upgrade proxy, or obvious honeypot tax setter.

Trust score: 61/100. Source verified: Yes. Chain: bsc. Contract: 0x4842e458af07c5d88040ef7a616a841ad3f87777.

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

high finding: Dividend callback can freeze ordinary wallet transfers

The token calls the configured dividend contract during transfers involving non-excluded addresses and reverts the entire token transfer if setShare fails. A reverting, unavailable, or incompatible dividend contract can therefore block transfers between ordinary holders.

Evidence: In _afterTokenTransfer, IDividend(dividendContract).setShare(...) is wrapped in try/catch, but the catch executes revert DividendShareUpdateFailed(...). The callback is skipped only for the token contract, zero/dead addresses, dividendContract, and configured pools; ordinary wallet-to-wallet transfers remain dependent on the external contract.

Recommendation: Make dividend-share updates non-blocking, queue failed updates, or add a controlled emergency bypass. Validate the dividend contract interface and liveness during initialization, and use a circuit breaker that cannot permanently disable ERC-20 transfers.

medium finding: Owner-controlled migration states impose transfer and trading restrictions

The owner controls transitions from BondingCurve to Migrating and then to TaxEnforcedAntiFarmer. While in BondingCurve, all transfers to or from configured pools revert; while in Migrating, pool transfers are allowed without tax. This creates centralized control over when pool interaction is enabled and when tax enforcement begins.

Evidence: startMigration() and finalizeMigration() are both onlyOwner. In _transfer, BondingCurve requires !pools[from] && !pools[to], while Migrating calls _plainTransfer without tax. GoPlus identifies an owner address but does not attest to decentralized control.

Recommendation: Publish and enforce explicit migration conditions, timelocks, and administrative monitoring. Consider permissionless or objectively triggered state transitions and document the exact pool-state behavior for users and integrators.

medium finding: Tax expiration is triggered only by a transfer to the main pool

The contract does not independently transition out of tax-enforced states when the expiration timestamp passes. Expiration logic runs inside _liquidateTax only when the current transfer recipient is mainPool. If users continue buying or interacting with another configured pool without a main-pool sell, the configured tax state can persist beyond its nominal duration.

Evidence: _liquidateTax requires to == mainPool before checking block.timestamp against taxExpirationTime and antiFarmerExpirationTime. _transfer invokes _liquidateTax(to) for every transfer, but transfers whose recipient is not mainPool do not execute the expiration branch.

Recommendation: Evaluate and apply time-based state transitions independently of transfer direction, or ensure every taxed path checks expiration before calculating tax. Add tests covering buys, secondary pools, wallet transfers, and periods with no main-pool sells.

medium finding: Tax processing depends on trusted external contracts and can redirect accrued tax tokens

Tax liquidation delegates processing to taxProcessor. If processing fails, the contract transfers its entire accumulated token balance directly to taxProcessor. A misconfigured or compromised processor can therefore receive accrued tax tokens and can also affect the liquidation-threshold direction when processing succeeds.

Evidence: _processTax approves taxProcessor for up to type(uint256).max. On catch, it executes _plainTransfer(address(this), taxProcessor, remainingBalance). On success, it trusts the int8 direction returned by ITaxProcessor.processTaxTokens and passes it to _adjustLiquidationThreshold. taxProcessor is supplied during initialize and is not changeable afterward.

Recommendation: Use a verified, immutable or governance-controlled processor, minimize approvals, constrain fallback transfers, and add accounting and event checks for failed processing. Test processor failure and malicious-return scenarios before deployment.