Bunker Mode (BUNKER) security report
Radar AI scanned Bunker Mode on BNB Smart Chain. Findings include an unlimited tax-processor allowance, owner-controlled pool-state transitions, and transfer dependence on an external dividend contract.
The contract is not free of material control and operational risks. The owner can control whether pool transfers remain restricted or whether migration remains tax-free, while the configured tax processor receives an unlimited allowance over accrued tax tokens. Transfers can also revert globally if the configured dividend contract fails. No verified source path allows arbitrary minting after initialization, and GoPlus reports no mintable flag or proxy flag.
Trust score: 55/100. Source verified: Yes. Chain: bsc. Contract: 0xc6d3c8a98dc4613ce010c8b0210d906ffc937777.
This report was last modified on 2026-10-08 and contains 4 material findings.
high finding: Configured tax processor can withdraw accrued tax tokens
The tax processor is granted an effectively unlimited allowance over the token balance held by the token contract. A compromised or malicious configured processor can use that allowance to pull accrued tax tokens, creating a powerful centralized custody risk over collected fees.
Evidence: In _processTax(), the contract calls _approve(address(this), taxProcessor, type(uint256).max) whenever the allowance is insufficient, then calls ITaxProcessor(taxProcessor).processTaxTokens(taxAmount). The processor address is supplied during initialize() and has no setter or validation beyond taxProcessor != address(0).
Recommendation: Use a narrowly scoped allowance for each liquidation, validate the processor against a trusted registry, and document or enforce governance controls for the processor address. Consider resetting allowances after processing and add monitoring for unexpected allowance consumption.
medium finding: Owner controls pool restrictions and can prolong migration behavior
The owner controls transitions into and out of migration. Leaving the contract in BondingCurve keeps transfers to or from configured pools blocked, while leaving it in Migrating permits pool transfers without tax. This creates a material administrative risk affecting trading availability and tax behavior.
Evidence: startMigration() and finalizeMigration() are both onlyOwner. In _transfer(), BondingCurve requires !pools[from] && !pools[to], while Migrating directly performs _plainTransfer(from, to, amount) without tax calculation.
Recommendation: Use a timelocked or independently authorized migration process, enforce state-transition deadlines, and publish the expected transition conditions. Consider preventing indefinite residence in Migrating and adding invariant tests for tax and pool-transfer behavior.
medium finding: Dividend callback can block ordinary token transfers
When dividendContract is configured, every transfer involving a non-excluded address calls the external dividend contract. Any revert from setShare() is propagated as DividendShareUpdateFailed, so a broken, incompatible, or intentionally reverting dividend contract can prevent ordinary user-to-user transfers.
Evidence: _afterTokenTransfer() calls IDividend(dividendContract).setShare(from, balanceOf(from)) and setShare(to, balanceOf(to)) inside try/catch blocks. Each catch explicitly reverts with DividendShareUpdateFailed. dividendContract is set during initialize() and cannot be changed afterward.
Recommendation: Avoid making core ERC20 transfers depend on an external callback, or isolate share updates from transfer success. If synchronous updates are required, add a controlled fallback, circuit breaker, or validated dividend implementation with failure testing.
medium finding: Uninitialized proxy could assign the entire initial supply to the initializer
The initializer is externally callable once and mints the complete maxSupply to msg.sender. If a proxy or clone is deployed without atomic initialization, the first caller can configure the token and receive the entire initial supply.
Evidence: initialize(InitParams memory params) is external and protected only by initializer. It executes _mint(msg.sender, maxSupply). The implementation constructor disables initialization of the implementation itself, but that does not initialize a separate proxy storage context.
Recommendation: Atomically initialize every proxy or clone during deployment, verify initialization transactions, and add deployment checks that reject uninitialized instances. Document the expected factory and initializer authority.