Radar by SecureChain AI

Matagi (マタギ) security report

Radar AI scanned Matagi’s verified source on BNB Smart Chain. No post-initialization public mint, blacklist, pause, or proxy behavior was identified in the supplied evidence. Material findings include owner-controlled migration that can keep pool transfers restricted, and external dividend-contract calls that can revert and block transfers. Slither was not run; conclusions are based on independent source review and supplied GoPlus signals.

Matagi is not shown to have a public post-initialization mint, blacklist, or proxy mechanism in the supplied evidence. However, the owner controls migration from the initial BondingCurve state, and configured dividend-contract failures can cause token transfers to revert. These are meaningful operational and centralization risks.

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

This report was last modified on 2026-10-14 and contains 3 material findings.

medium finding: Owner can keep pool transfers disabled in BondingCurve state

The token starts in PoolState.BondingCurve and rejects any transfer where either endpoint is a configured pool. Only the owner can call startMigration(), so the owner can delay migration indefinitely and prevent transfers to or from the configured pools.

Evidence: initialize() sets poolState.state to PoolState.BondingCurve. In _transfer(), the BondingCurve branch executes require(!pools[from] && !pools[to], "Transfers to/from pools are restricted in BondingCurve state"). startMigration() is protected by onlyOwner and is the only source-level transition out of BondingCurve.

Recommendation: Use an enforceable migration deadline or permissionless transition mechanism, and publish the expected migration controls. Consider preventing indefinite owner retention of the BondingCurve state after deployment.

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

When dividendContract is nonzero, every non-excluded sender or recipient triggers an external setShare() call. Any revert from that configured contract is rethrown as DividendShareUpdateFailed, causing the entire token transfer to revert. A broken, incompatible, or unavailable dividend contract can therefore create a transfer-lock condition for affected addresses.

Evidence: _afterTokenTransfer() calls IDividend(dividendContract).setShare(from, balanceOf(from)) and setShare(to, balanceOf(to)) for non-excluded addresses. Each call is wrapped in try/catch, but the catch immediately executes revert DividendShareUpdateFailed(...). dividendContract is assigned during initialize() and has no setter or recovery function in the supplied token source.

Recommendation: Avoid making core transfers depend on a reverting external call. Use a non-blocking update pattern, a trusted and immutable interface, or an emergency bypass/recovery mechanism with narrowly scoped governance.

medium finding: Tax processing is delegated to an externally configured processor

Accumulated transfer tax is approved to taxProcessor with an effectively unlimited allowance and then passed to its processTaxTokens() function. If processing fails, the remaining token balance is transferred directly to taxProcessor. The processor is supplied during initialization and cannot be changed by the token contract, creating material dependency and configuration risk.

Evidence: _processTax() sets allowance(address(this), taxProcessor) to type(uint256).max when needed, calls ITaxProcessor(taxProcessor).processTaxTokens(taxAmount), and on failure executes _plainTransfer(address(this), taxProcessor, remainingBalance). taxProcessor is assigned from params.taxProcessor in initialize().

Recommendation: Validate and tightly control the processor address at deployment, minimize allowance exposure, document processor trust assumptions, and consider a recovery or replacement path for processor failure without automatically forwarding all remaining tax tokens.