Radar by SecureChain AI

HushCause (HUSH) security report

HushCause was AI scanned by Radar on BNB Smart Chain. The review found conditional initialization takeover, dividend-linked transfer blocking, owner-controlled migration restrictions, and external tax-processor dependency risks.

The source does not show owner-controlled minting, blacklist logic, selfdestruct, or a proxy upgrade entry point after initialization. However, an uninitialized instance could be claimed by the first caller, who would become owner and receive the full minted supply. In addition, configured dividend-contract failures can revert ordinary transfers, creating a conditional transfer-lock risk.

Trust score: 58/100. Source verified: Yes. Chain: bsc. Contract: 0x52ceb7d3e4a47ec1685d20ab00986e7650c07777.

This report was last modified on 2026-10-07 and contains 4 material findings.

high finding: Uninitialized instance can be claimed and receive the full token supply

If the deployed instance has not been initialized, any caller can invoke initialize once. The caller becomes owner through __Ownable_init(), receives the entire maxSupply through _mint(msg.sender, maxSupply), and controls the initial external tax, dividend, quote-token, router, pool, and tax-duration configuration.

Evidence: initialize(InitParams) is external and protected only by the one-time initializer modifier. It calls __Ownable_init(), then executes _mint(msg.sender, maxSupply), where maxSupply is 1e9 ether. The supplied GoPlus evidence reports owner_address as the zero address, but that does not by itself prove whether initialization was safely performed and ownership was later renounced or whether the instance remains uninitialized.

Recommendation: Verify the target address's initialization state and historical Initialized and OwnershipTransferred events. Deploy or initialize through an atomic factory transaction, ensure the intended owner and trusted external contracts are supplied, and prevent any public deployment window before initialization completes.

medium finding: Dividend-contract failure can block ordinary token transfers

When dividendContract is nonzero, transfers involving ordinary accounts call the external dividend contract's setShare function. Any revert from that call is propagated as DividendShareUpdateFailed, causing the entire token transfer to revert. A nonresponsive, incompatible, or misconfigured dividend contract can therefore prevent transfers for affected accounts.

Evidence: _afterTokenTransfer calls IDividend(dividendContract).setShare(from, balanceOf(from)) and setShare(to, balanceOf(to)) unless the address is the token contract, zero address, dead address, dividend contract, or a configured pool. Both calls are wrapped in try/catch, but the catch block reverts with DividendShareUpdateFailed.

Recommendation: Use a verified dividend implementation with reliable setShare behavior, test initialization and all transfer paths against it, and consider making dividend-share updates non-blocking or adding a guarded recovery mechanism that can disable the integration without freezing token transfers.

medium finding: Owner-controlled pool-state transitions can restrict pool transfers

The token begins in BondingCurve state, where all transfers to or from configured pools revert. Only the owner can call startMigration and finalizeMigration to move the token through migration and tax-enforced states. If the owner does not complete the required sequence, or if pools are configured incorrectly during initialization, pool trading transfers remain restricted.

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 the pools mapping is populated during initialize.

Recommendation: Document and test the migration sequence before deployment, validate every pool address, monitor PoolStateChanged events, and use a controlled multisignature owner with an operational runbook for migration completion.

medium finding: Tax processing depends on a privileged external processor and can redirect accrued taxes

The initialized taxProcessor receives approval to pull accrued tax tokens. If processTaxTokens reverts, the contract catches the failure and transfers its remaining token balance directly to taxProcessor. The processor address cannot be changed through the shown contract interface, so an incorrect or malicious initialization value can redirect accrued tax tokens or disrupt tax processing.

Evidence: _processTax approves taxProcessor for type(uint256).max when needed and calls ITaxProcessor(taxProcessor).processTaxTokens(taxAmount). In the catch branch, it executes _plainTransfer(address(this), taxProcessor, remainingBalance). taxProcessor is assigned during initialize and there is no setter in FlapTaxTokenV3.

Recommendation: Validate the processor bytecode, configuration, and authorization before initialization; use an audited processor address; monitor TaxLiquidationError events; and add an operator-controlled but tightly governed processor rotation or recovery mechanism in a reviewed upgrade.