tweety.fun (TWEETY) security report
Radar AI-scanned the verified tweety.fun TWEETY contract on BNB Smart Chain. Findings include dividend callback transfer blocking, tax processor dependency, lazy tax expiry, and owner-dependent migration.
The contract does not expose owner-controlled minting, blacklist logic, or post-initialization tax setters. However, transfers can depend on an external dividend contract, tax tokens are delegated to an externally configured tax processor, and time-based tax removal is evaluated only during sells to the main pool. These conditions warrant operational and integration review before relying on the token.
Trust score: 48/100. Source verified: Yes. Chain: bsc. Contract: 0xe44830f789e3230a6e5abb47c374599f3bc17777.
This report was last modified on 2026-10-08 and contains 5 material findings.
medium finding: External dividend callback can block token transfers
Every transfer involving a non-excluded address invokes dividendContract.setShare. If the configured dividend contract reverts, the token transfer also reverts through DividendShareUpdateFailed. This can prevent ordinary transfers, including buys, sells, and wallet-to-wallet movements, while the callback remains reverting.
Evidence: In _afterTokenTransfer, setShare(from, balanceOf(from)) and setShare(to, balanceOf(to)) are called unless the address is the token contract, zero address, burn address, dividend contract, or a configured pool. Each call is wrapped in try/catch, but the catch explicitly reverts with DividendShareUpdateFailed.
Recommendation: Use a fail-open or bounded dividend-share update design, or provide a controlled recovery path to disable the callback if the dividend contract becomes unavailable. Validate the configured dividend implementation and test transfer behavior when it reverts or consumes excessive gas.
medium finding: Tax processor can receive the token contract's entire balance on processing failure
The token grants the taxProcessor an unlimited allowance and, if processTaxTokens fails, transfers the entire token balance held by the token contract to taxProcessor. This balance can exceed the tax amount currently being processed, so a faulty or untrusted processor can receive accumulated tax reserves or other tokens sent to the contract.
Evidence: _processTax approves taxProcessor for type(uint256).max when needed. In the catch branch after processTaxTokens reverts, it reads balanceOf(address(this)) and calls _plainTransfer(address(this), taxProcessor, remainingBalance), rather than limiting the transfer to taxAmount.
Recommendation: Limit fallback transfers to the amount being processed, avoid unlimited approvals where possible, and use a vetted immutable processor with explicit recovery controls. Add tests for processor reverts, reentrancy, and unexpected token balances.
medium finding: Tax expiration is enforced lazily and can remain active after its deadline
The contract describes taxes as time-dependent, but expiration is checked only inside _liquidateTax, which runs only when a transfer is directed to mainPool. A buy from a pool or a wallet transfer occurring after taxExpirationTime can therefore continue using the prior tax-enforced state until a sell to mainPool triggers the state transition.
Evidence: _transfer calls _liquidateTax(to), and _liquidateTax immediately requires to == mainPool. The expiration check then changes the state to TaxFree and zeroes tax rates. Transfers with other destinations do not execute this expiration transition before calculating tax.
Recommendation: Evaluate expiration before tax calculation on every transfer, or add a permissionless state-update function that can be called independently of a sell. Test buys, wallet transfers, and alternate-pool transfers after both tax and anti-farmer deadlines.
medium finding: Bonding-curve state restricts transfers involving configured pools until owner migration
While poolState is BondingCurve, every transfer whose sender or recipient is a configured pool reverts. Only the owner can advance the state through startMigration and finalizeMigration, so trading through a configured pool depends on owner-controlled migration actions.
Evidence: The BondingCurve branch in _transfer requires !pools[from] && !pools[to]. startMigration and finalizeMigration are both protected by onlyOwner and are the only exposed functions that advance the pool state toward tax-enforced trading.
Recommendation: Document the required migration sequence, monitor ownership and migration status, and use an operational safeguard or permissionless timeout if trading must not depend indefinitely on one owner account.
medium finding: Tax processing and liquidation behavior depend on an externally configured contract
Tax liquidation calls taxProcessor.processTaxTokens and accepts its signed direction output to adjust the liquidation threshold. The processor is configured during initialization and is not changeable through this contract, making processor correctness and availability material to tax handling and threshold behavior.
Evidence: _processTax performs an external ITaxProcessor(taxProcessor).processTaxTokens(taxAmount) call and passes the returned int8 to _adjustLiquidationThreshold. A positive or negative direction changes the threshold by one percent toward its configured bound; a revert triggers the fallback transfer path.
Recommendation: Verify the deployed processor implementation and its access controls, constrain accepted direction semantics, and add monitoring for failed processing and unexpected threshold changes. Include the processor and dividend dependencies in the security review.