mamababa (mamababa) security report
Radar by SecureChain AI scanned mamababa on BNB Smart Chain. Material findings include uninitialized-clone takeover risk, tax rates that can exceed 100%, and dividend callback failures that may revert transfers. Slither was not run.
The source does not expose an owner-controlled mint, blacklist, proxy upgrade, or adjustable tax setter after initialization. However, initialization must be performed atomically and with trusted parameters. An uninitialized clone can be taken over and receive the full initial supply, initialization permits tax rates above 100%, and dividend callback failures can make transfers revert when a dividend contract is configured.
Trust score: 48/100. Source verified: Yes. Chain: bsc. Contract: 0x0d634584a421c105d48d9583f0db89d4c31f7777.
This report was last modified on 2026-10-10 and contains 3 material findings.
high finding: Uninitialized clone can be claimed and configured by an arbitrary caller
The external initialize function is protected only by the one-time initializer modifier and does not restrict who may perform the first initialization. The caller becomes the Ownable owner and receives the entire maxSupply through _mint(msg.sender, maxSupply). That caller also selects the tax processor, dividend contract, pools, tax rates, and migration parameters. If a deployed clone is not initialized atomically, the first external caller can take control and receive the initial supply.
Evidence: In FlapTaxTokenV3.initialize, __Ownable_init() assigns ownership to _msgSender(), _mint(msg.sender, maxSupply) assigns the full configured supply to the initializer caller, and all operational parameters are taken directly from the caller-supplied InitParams. The implementation constructor calls _disableInitializers(), so this risk applies to an uninitialized proxy or clone rather than the locked implementation itself.
Recommendation: Initialize every clone atomically during deployment, preferably by passing initialization calldata to the proxy or clone deployment transaction. Verify the owner, pool addresses, tax processor, dividend contract, and all initialization parameters before exposing the instance to external calls.
medium finding: Initialization permits tax rates above 100%, which can lock pool transfers
The initializer accepts buyTax and sellTax as unrestricted uint16 values. The tax calculation divides by 10000, but there is no validation that either rate is at most 10000 basis points. If a configured pool transfer uses a rate above 10000, tax exceeds the transfer amount and _taxedTransfer reverts on amount - tax. This can prevent buys or sells while the relevant tax state is active.
Evidence: initialize stores params.buyTax and params.sellTax directly in poolState without an upper-bound check. _getTaxWithPoolState computes (amount * currentPoolState.buyTaxRate) / 10000 or the equivalent sell calculation, and _taxedTransfer executes uint256 remainingAmount = amount - tax. The GoPlus evidence leaves buy_tax, sell_tax, and transfer_tax blank, so the deployed rates are not established by the supplied evidence.
Recommendation: Require both initialization tax rates to be <= 10000, preferably enforce a lower project-specific cap, and test buy and sell paths for boundary values before deployment. Treat existing instances with unverified initialization parameters as requiring configuration review.
medium finding: Dividend callback failure can block token transfers
When dividendContract is nonzero, every transfer involving a non-exempt address calls the external dividend contract through setShare. Any revert from that callback is caught and immediately rethrown as DividendShareUpdateFailed. A misconfigured, unavailable, or incompatible dividend contract can therefore make ordinary transfers revert, creating a transfer-lock condition for affected addresses.
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. Each failed call executes revert DividendShareUpdateFailed(...). dividendContract is supplied during initialize and is not changeable through an exposed setter.
Recommendation: Use a verified dividend implementation with non-reverting setShare behavior, validate the configured address during initialization, and consider making dividend accounting failure-tolerant or providing a controlled recovery path that cannot permanently block ERC20 transfers.