Quantum Audit Logo

Is BOB Safe?

On-chain security analysis — is it a scam or legit?

Is this your token? Publish your own audit on this page →

BOB BOB
0x52b5…b7e7
BNB Chain Not verifiedLast checked 3d ago 1 audit on record
How is this score calculated? → Critical Risk
Executive SummaryAI Copilot

The BobToken contract is an upgradeable ERC-20 token utilizing OpenZeppelin's UUPS, Ownable, ERC20Permit, ERC20Burnable, and AccessControl standards. The audit identified a High severity issue related to broken custom role management functions, which are unusable as implemented. Additionally, a Medium severity concern was noted regarding the centralized control over critical roles by the DEFAULT_ADMIN_ROLE, although mitigated by a multisig owner. Overall, the contract demonstrates good adherence to OpenZeppelin best practices for upgradeability and token functionality, but requires attention to the identified access control and role management issues.

1 High1 Medium1 Low1 Informational
Volume 24h
$84.9K
Liquidity
$449.5K
Price
$0.004826
Token Age
9mo
Top 10 Holders
94.9%

Security Findings

High

Broken Role Management Functions (`grantMintAndBurnRoles`, `revokeMintAndBurnRoles`)

H-01The `grantMintAndBurnRoles` and `revokeMintAndBurnRoles` functions are intended to manage `MINTER_ROLE` and `BURNER_ROLE`. However, they lack explicit access control (e.g., `onlyRole(DEFAULT_ADMIN_ROLE)`). When these functions are called, they internally invoke `grantRole` or `revokeRole`. Since `grantRole` and `revokeRole` are protected by `onlyRole(getRoleAdmin(role))`, and the `msg.sender` for the internal call is the contract itself (`address(this)`), which does not hold `DEFAULT_ADMIN_ROLE`, these functions will always revert. This renders the custom role management functions unusable, requiring `DEFAULT_ADMIN_ROLE` holders to directly interact with `AccessControlUpgradeable`'s `grantR…
IssueThe `grantMintAndBurnRoles` and `revokeMintAndBurnRoles` functions are intended to manage `MINTER_ROLE` and `BURNER_ROLE`. However, they lack explicit access control (e.g., `onlyRole(DEFAULT_ADMIN_ROLE)`). When these functions are called, they internally invoke `grantRole` or `revokeRole`. Since `grantRole` and `revokeRole` are protected by `onlyRole(getRoleAdmin(role))`, and the `msg.sender` for the internal call is the contract itself (`address(this)`), which does not hold `DEFAULT_ADMIN_ROLE`, these functions will always revert. This renders the custom role management functions unusable, requiring `DEFAULT_ADMIN_ROLE` holders to directly interact with `AccessControlUpgradeable`'s `grantR…
FixAdd `onlyRole(DEFAULT_ADMIN_ROLE)` to both `grantMintAndBurnRoles` and `revokeMintAndBurnRoles` functions. This will ensure that only authorized administrators can call these functions, and the internal calls to `grantRole`/`revokeRole` will then be correctly executed with the `msg.sender` being the authorized administrator.
StatusUnresolved
Medium

Centralized Control over Minting/Burning and CCIP Admin

M-01The `DEFAULT_ADMIN_ROLE` holds significant power within the contract. This role can grant/revoke `MINTER_ROLE` and `BURNER_ROLE`, effectively controlling the token's supply dynamics (up to `i_maxSupply`), and can also set the `s_ccipAdmin` address. While the `initialOwner` (assigned `DEFAULT_ADMIN_ROLE`) is a multisig, this still represents a single point of control for these critical functions. A compromise of the multisig could lead to unauthorized token inflation or manipulation of the CCIP admin address.
IssueThe `DEFAULT_ADMIN_ROLE` holds significant power within the contract. This role can grant/revoke `MINTER_ROLE` and `BURNER_ROLE`, effectively controlling the token's supply dynamics (up to `i_maxSupply`), and can also set the `s_ccipAdmin` address. While the `initialOwner` (assigned `DEFAULT_ADMIN_ROLE`) is a multisig, this still represents a single point of control for these critical functions. A compromise of the multisig could lead to unauthorized token inflation or manipulation of the CCIP admin address.
FixConsider implementing further decentralization or introducing a timelock mechanism for critical operations such as granting/revoking `MINTER_ROLE` or `BURNER_ROLE`, or changing the `s_ccipAdmin`. This would provide a delay for users to react to malicious actions and reduce the immediate impact of a multisig compromise.
StatusUnresolved
Low

Fixed Max Supply Value

L-01The `i_maxSupply` is hardcoded in the `initialize` function to `10,000,000,000 * 10**decimals()`. While this provides a clear and immutable supply cap, it means the maximum supply cannot be adjusted without a contract upgrade. If future protocol needs or market conditions require a different supply cap, an upgrade would be necessary, which might not always be desirable or feasible.
IssueThe `i_maxSupply` is hardcoded in the `initialize` function to `10,000,000,000 * 10**decimals()`. While this provides a clear and immutable supply cap, it means the maximum supply cannot be adjusted without a contract upgrade. If future protocol needs or market conditions require a different supply cap, an upgrade would be necessary, which might not always be desirable or feasible.
FixIf flexibility in the maximum supply is desired, consider making `i_maxSupply` configurable by a privileged role (e.g., `DEFAULT_ADMIN_ROLE`) or through a governance mechanism. If the intention is for the maximum supply to be permanently fixed, no change is strictly necessary, but this design choice should be explicitly documented.
StatusUnresolved
Info

External `useNonce` Function Exposure

I-01The `useNonce()` function is an external wrapper around `_useNonce(msg.sender)`. While it doesn't pose a direct vulnerability, `_useNonce` is typically an internal function used by `ERC20Permit`'s `_permit` and `_approve` functions to prevent replay attacks. Exposing this internal mechanism directly via an external function might lead to confusion or unintended usage if its purpose is not clearly understood or documented.
IssueThe `useNonce()` function is an external wrapper around `_useNonce(msg.sender)`. While it doesn't pose a direct vulnerability, `_useNonce` is typically an internal function used by `ERC20Permit`'s `_permit` and `_approve` functions to prevent replay attacks. Exposing this internal mechanism directly via an external function might lead to confusion or unintended usage if its purpose is not clearly understood or documented.
FixReview if the `useNonce()` function is truly necessary for external calls. If its functionality is only required internally by the `ERC20Permit` mechanism, consider removing the external wrapper. If it serves a specific external purpose, ensure its functionality and intended use cases are thoroughly documented.
StatusUnresolved

Category Ratings

TechnicalMedium6/10

The contract leverages well-vetted OpenZeppelin upgradeable libraries for its ERC-20, burnable, permit, and access control functionalities (7.2 Code Security). The architecture is standard for an upgradeable token (7.1 Architecture). However, a significant issue was found in the custom `grantMintAndBurnRoles` and `revokeMintAndBurnRoles` functions, which are currently non-functional due to incorrect access control implementation, rendering them unusable (7.3 Access Control). This requires direct interaction with `AccessControlUpgradeable` functions for role management.

GovernanceHigh2/10

The economic model includes a fixed maximum supply (`i_maxSupply`) for the token, which provides predictability but limits flexibility without an upgrade (7.4 Economic). Governance relies on `OwnableUpgradeable` for upgrades and `AccessControlUpgradeable` for managing `MINTER_ROLE`, `BURNER_ROLE`, and `s_ccipAdmin` (7.5 Governance). The `initialOwner` (and thus `DEFAULT_ADMIN_ROLE`) holds significant power, though this is mitigated by the use of a multisig for the owner address (7.8 Operations).

UpgradesHigh1/10

The contract correctly implements the UUPS upgradeability pattern using OpenZeppelin's `UUPSUpgradeable` (7.7 Upgrades). The `_authorizeUpgrade` function is restricted to `onlyOwner`, ensuring that only the designated owner can initiate upgrades. The `Initializable` pattern is correctly used, and the constructor disables initializers to prevent re-initialization.

Security Checklist

Contract VerifiedPass
Ownership RenouncedFail
No Mint FunctionFail
Liquidity LockedFail
Not a ProxyFail
HoneypotNoneBuy Tax0.0%Sell Tax0.0%

Proxy Upgrade Controls

Proxy TypeEip1967 Uups
ImplementationVerified source

Holder Composition

43.6% in wallets51.3% in contracts
Effective Concentration64.1%

Share held by contracts — treasury, vesting, bridge or staking — is discounted against share held by wallets when the score is computed: a contract cannot decide to sell the way an anonymous holder can, though it can still be drained or voted to sell. Effective concentration is the figure the risk score is actually calculated from.

Liquidity Depth

The risk score reads depth across every pair. The volume figure and the volume-to-liquidity ratio elsewhere on this page describe only the pair this audit analysed, so the two are not directly comparable.

LP Distribution

Top-1 Unlocked Holder100.0%
Top-3 Unlocked100.0%

Key Addresses

Deployer
0x3c30…93ab
Unlocked LP Held By
0x9ead…ef92

No privileged address appears among these holders: the unlocked liquidity sits with independent providers, not with the deployer.

What Raised This Score

  • Ownership NOT renounced — Multisig (2-of-4)
  • Mintable supply — no cap found, dilution unbounded
  • Proxy contract (upgradeable — admin can replace logic)
  • Top-10 concentration > 50% (94.9% total → 64.1% effective; 43.6% in EOAs, 51.3% in contracts — heavy)
  • Liquidity not locked, but no owner/deployer address holds LP — market-depth risk, not rug risk
  • LP top1 unlocked holder = 100.0% (independent LP — depth risk)
  • LP top3 unlocked holders = 100.0% (independent LP — depth risk)
  • 1 High finding(s) from audit
  • 1 Medium finding(s) from audit
  • 1 Low finding(s) from audit

Each factor is an on-chain fact recorded at the time of this analysis. The score is computed from them by a deterministic function, so the same contract returns the same score for anyone who runs the audit. How scores are computed

Related Audits

PancakeSwap Token (CAKE)Critical RiskSubsquid (SQD)Critical RiskAnoma (XAN)Critical RiskelizaOSCritical RiskPlasma (XPL)Critical RiskMirex (MRX)Critical Risk

Would You Like a More Detailed Audit of BOB?

Our AI-powered scanner gives you a deeper, real-time smart contract analysis — free, with every scoring factor shown.

Get Detailed Audit