Quantum Audit Logo

Is Ninja Squad Token Safe?

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

Ninja Squad Token NST
0x88a2…0cfb
Arbitrum
Not verifiedThis record has not gone through deep verification and is not being monitored. The score is a dated snapshot — the token’s risk can change at any time.
Last checked 4d ago 1 audit on record
How is this score calculated? → Critical Risk
Executive SummaryAI Copilot

The audit of the BridgeToken (TokenImplementation) contract, intended for use as a Beacon proxy implementation, identified a critical vulnerability related to uninitialized proxy state, which could allow unauthorized ownership transfer. Further high-risk concerns involve potential storage collisions during future upgrades due to the custom storage layout. The contract utilizes standard libraries like OpenZeppelin's `Ownable` and `Counters`, but the proxy-specific initialization requires careful attention.

1 Critical1 High1 Medium1 Low
Volume 24h
$73.9K
Liquidity
$176.3K
Price
$1.2700
Token Age
2y
Top 10 Holders
50.0%

Security Findings

Critical

Uninitialized Proxy State / Missing `initialize` Function

C-01The `Ownable` contract's constructor sets the `_owner` variable to `_msgSender()` upon deployment. In the context of an upgradeable proxy, this constructor is called only when the implementation contract itself is deployed, not when the proxy is initialized. Consequently, the `_owner` variable in the proxy's storage slot will remain uninitialized (zero address) unless an explicit `initialize()` function is called on the proxy. If such an `initialize()` function is missing or not properly invoked, any user could call `transferOwnership()` or other `onlyOwner` functions and claim ownership of the contract, leading to complete administrative control.
IssueThe `Ownable` contract's constructor sets the `_owner` variable to `_msgSender()` upon deployment. In the context of an upgradeable proxy, this constructor is called only when the implementation contract itself is deployed, not when the proxy is initialized. Consequently, the `_owner` variable in the proxy's storage slot will remain uninitialized (zero address) unless an explicit `initialize()` function is called on the proxy. If such an `initialize()` function is missing or not properly invoked, any user could call `transferOwnership()` or other `onlyOwner` functions and claim ownership of the contract, leading to complete administrative control.
FixImplement a dedicated `initialize()` function in the implementation contract, protected by an `initialized` flag, which sets the `owner` and other initial state variables. This function must be called exactly once on the proxy after deployment. Ensure the `Ownable` constructor is either removed or modified to be proxy-aware, or that the `initialize()` function explicitly overrides the owner set by the constructor in the proxy's storage. Consider using OpenZeppelin's `Initializable` pattern.
StatusUnresolved
High

Potential Storage Collisions in Upgrades

H-01The contract uses a custom storage layout with `TokenStorage.State _state;` to encapsulate all state variables. While this pattern helps prevent storage collisions when adding new variables to the end of the struct, any modification to the internal structure of the `State` struct itself (e.g., reordering existing variables, changing their types, or inserting new variables in the middle) in a future upgrade could lead to storage collisions. This would corrupt existing state data, potentially rendering the contract unusable or leading to unexpected behavior.
IssueThe contract uses a custom storage layout with `TokenStorage.State _state;` to encapsulate all state variables. While this pattern helps prevent storage collisions when adding new variables to the end of the struct, any modification to the internal structure of the `State` struct itself (e.g., reordering existing variables, changing their types, or inserting new variables in the middle) in a future upgrade could lead to storage collisions. This would corrupt existing state data, potentially rendering the contract unusable or leading to unexpected behavior.
FixStrictly adhere to storage layout guidelines for upgradeable contracts. When upgrading, only append new variables to the end of the `TokenStorage.State` struct. Never reorder, remove, or change the type of existing variables within the struct. Thoroughly test all upgrade scenarios in a development environment before deploying to production.
StatusUnresolved
Medium

`_setOwner` is Private in `Ownable`

M-01The `_setOwner` function within the `Ownable` contract is declared as `private`. This prevents derived contracts from directly calling it to set the owner during their `initialize()` function. While the `Ownable` constructor calls it, this is problematic for proxies as the constructor's effect is on the implementation's storage, not the proxy's. This design forces reliance on the constructor for initial owner assignment, which is a common source of proxy initialization vulnerabilities.
IssueThe `_setOwner` function within the `Ownable` contract is declared as `private`. This prevents derived contracts from directly calling it to set the owner during their `initialize()` function. While the `Ownable` constructor calls it, this is problematic for proxies as the constructor's effect is on the implementation's storage, not the proxy's. This design forces reliance on the constructor for initial owner assignment, which is a common source of proxy initialization vulnerabilities.
FixConsider making `_setOwner` `internal` or providing an `internal` `__Ownable_init()` function that calls `_setOwner`. This would allow the `initialize()` function of the derived contract to explicitly set the owner in the proxy's storage, aligning with best practices for upgradeable contracts and reducing the risk of uninitialized state.
StatusUnresolved
Low

Truncated Code for Upgrade Logic

L-01The provided source code for the `ERC1967Upgrade` contract is truncated. This prevents a full review of the complete upgrade mechanism, including how the beacon address is managed, who has the authority to update the implementation address within the beacon, and any associated access control or timelock mechanisms. While the prefill indicates a Beacon proxy, the full context of its management is not available for audit.
IssueThe provided source code for the `ERC1967Upgrade` contract is truncated. This prevents a full review of the complete upgrade mechanism, including how the beacon address is managed, who has the authority to update the implementation address within the beacon, and any associated access control or timelock mechanisms. While the prefill indicates a Beacon proxy, the full context of its management is not available for audit.
FixProvide the complete source code for all contracts involved in the upgrade mechanism, including the Beacon contract and any associated governance or administrative contracts. This ensures a comprehensive security review of the entire upgrade process (7.7 Upgrades, 7.3 Access Control, 7.5 Governance).
StatusUnresolved

Category Ratings

TechnicalMedium4/10

The contract leverages standard and well-tested libraries such as `Counters` and `Address`, demonstrating good practices for common utilities (7.2 Code Security). The use of `TokenStorage.State` for all state variables is a robust pattern for upgradeability, minimizing storage collision risks for new variables (7.1 Architecture). However, a critical issue exists where the `Ownable` constructor sets the owner for the implementation, not the proxy's storage, leading to an uninitialized owner if `initialize()` is not properly called on the proxy (7.3 Access Control). Additionally, while the `TokenStorage.State` struct helps, direct modifications to its internal structure in future upgrades could still lead to storage collisions (7.2 Code Security).

GovernanceHigh1/10

The contract implements `Ownable` for access control, centralizing administrative functions under a single owner (7.3 Access Control). This provides a clear governance structure for critical operations. However, the critical uninitialized proxy state vulnerability directly impacts the integrity of this ownership, potentially allowing an attacker to seize control of the token's administrative functions (7.5 Governance). The economic model of the token (e.g., minting, burning, fees) is not fully visible in the provided snippet, limiting a comprehensive economic risk assessment (7.4 Economic).

UpgradesHigh1/10

The contract is designed as an implementation for a Beacon proxy, utilizing the `TokenStorage` struct to manage state, which is a good practice for upgrade safety by isolating state variables (7.7 Upgrades). The `ERC1967Upgrade` abstract contract is included, indicating adherence to a standard proxy pattern. However, the critical issue of uninitialized proxy state means that the owner of the proxy's state might not be correctly set, potentially allowing unauthorized parties to control future upgrades or critical parameters (7.7 Upgrades). Furthermore, while the `TokenStorage` struct helps, any structural changes to it in future upgrades could lead to storage collisions, corrupting existing data (7.7 Upgrades).

Security Checklist

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

Proxy Upgrade Controls

Proxy TypeBeacon
ImplementationVerified source
Upgrades (30d)0 · stable

Holder Composition

48.2% in wallets1.9% in contracts
Effective Concentration48.9%

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 Holder99.8%
Top-3 Unlocked100.0%

Key Addresses

Deployer
0xab91…9716
Unlocked LP Held By
0xab91…97160x682f…6c080xfe06…9c41

A privileged address — the deployer, the owner, or the token contract itself — is among these holders, so that party can withdraw liquidity.

What Raised This Score

  • Ownership NOT renounced — owner is a contract (governance/executor, not an EOA)
  • Mintable supply — no cap found, dilution unbounded
  • Proxy contract (upgradeable — admin can replace logic)
  • Complex proxy pattern (BEACON)
  • Top-10 concentration > 30% (50.0% total → 48.9% effective; 48.2% in EOAs, 1.9% in contracts — moderate)
  • Liquidity NOT locked (owner can withdraw — rug-pull risk)
  • LP top1 unlocked holder = 99.8% (exit-liquidity risk, pool = 98% of DEX liquidity)
  • LP top3 unlocked holders = 100.0% (exit-liquidity risk, pool = 98% of DEX liquidity)
  • 1 Critical finding(s) from audit
  • 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

Axelar Wrapped LAVA (LAVA)Critical RiskGU Factory (GU)Critical RiskGUBERTOCritical RiskVangrid (VAN)Critical RiskMORCritical RiskDGrid AI (DGAI)Critical Risk

Would You Like a More Detailed Audit of Ninja Squad Token?

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

Get Detailed Audit