Quantum Audit Logo
Launch App

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

Is MAGIC Safe?

Arbitrum
Not verified This 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.Own this token? Put it under verification →
Last checked Sep 4, 2026 · 1 audit on record
SummaryAI Copilot

The audit of the StandardArbERC20 implementation contract, used via a ClonableBeaconProxy, identified a High-severity access control vulnerability related to the initialization of cloned token instances.

Read the full analysis
What raised the score
  • Ownership status UNKNOWN
  • Proxy contract
  • Complex proxy pattern
  • Top-10 concentration > 50%
  • Liquidity not locked, but no owner/deployer address holds LP — market-depth risk, not rug risk
  • LP top1 unlocked holder = 55.2%
  • LP top3 unlocked holders = 82.9%
  • 1 High finding(s) from audit
  • 1 Medium finding(s) from audit
  • 1 Low finding(s) from audit
Exact factors
  • Ownership status UNKNOWN (owner could not be resolved)
  • Proxy contract (upgradeable — admin can replace logic)
  • Complex proxy pattern (BEACON)
  • Top-10 concentration > 50% (66.3% total → 66.3% effective; 66.3% in EOAs, 0.0% in contracts — heavy)
  • Liquidity not locked, but no owner/deployer address holds LP — market-depth risk, not rug risk
  • LP top1 unlocked holder = 55.2% (independent LP — depth risk, pool = 79% of DEX liquidity)
  • LP top3 unlocked holders = 82.9% (independent LP — depth risk, pool = 79% of DEX liquidity)
  • 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

Security Checklist

as of audit · Sep 44 of 7 checks passed
Contract verifiedVerified
OwnershipUnknown
MintNo mint
Liquidity lockNot locked
UpgradeabilityUpgradeable
HoneypotNone found
Buy / sell tax0% / 0%

Holders

as of audit · Sep 4, 2026
66.3%Wallets33.7%Everyone else
66.3%Wallets33.7%Everyone else
WalletsEveryone elseBubble area = share of supply
66.3%of supply sits with the top 10 holders
  • Walletsanonymous holders, free to sell66.3%
  • Everyone elsethe rest of the supply33.7%
Effective concentrationwhat the score reads66.3%
How holder types affect the score

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.

Holder balances as recorded by the audit of Sep 4, 2026

Liquidity

as of audit · Sep 4$223.4K across 14 pairs
LP tokensNot locked

The LP tokens of the analysed pool are not locked or burned, so whoever holds them can withdraw that liquidity.

Analysed pool$177.4KShare of depth79.4%
Top-1 Unlocked Holder55.2%
Top-3 Unlocked82.9%
Unlocked LP held by
0x3887…7f1c0xdb6a…e2330x8f28…514e0x4e3b…d42e0x7c2d…d4370xf2e1…048e0x0856…0af80x378f…ec920xd510…20e40x84d9…39ca

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

Security Findings

1 High1 Medium1 Low2 Info
High

Unprotected bridgeInit Allows Malicious Initialization of Clones

The bridgeInit function, which serves as the initializer for each cloned token instance, is declared as public without any access control. While L2GatewayToken._initialize prevents re-initialization of state variables within a single clone, the *first* caller to bridgeInit on a newly deployed clone can set the l2Gateway and l1Address. A malicious actor could front-run the legitimate gateway deployment or initialization, setting themselves as the l2Gateway, thereby gaining unauthorized control over bridgeMint and bridgeBurn functions for that specific token instance. This compromises the integrity of the token supply for affected clones (7.3 Access Control, 7.2 Code Securit…H-01

Issue

The bridgeInit function, which serves as the initializer for each cloned token instance, is declared as public without any access control. While L2GatewayToken._initialize prevents re-initialization of state variables within a single clone, the *first* caller to bridgeInit on a newly deployed clone can set the l2Gateway and l1Address. A malicious actor could front-run the legitimate gateway deployment or initialization, setting themselves as the l2Gateway, thereby gaining unauthorized control over bridgeMint and bridgeBurn functions for that specific token instance. This compromises the integrity of the token supply for affected clones (7.3 Access Control, 7.2 Code Securit…

Fix

Implement an onlyInitializing or similar modifier to restrict calls to bridgeInit to a trusted entity (e.g., the deployer, a factory contract, or a designated initializer role). This ensures that only the intended party can configure the critical l2Gateway and l1Address for new token clones.

Status

Unresolved

Medium

ERC20 Standard Functions (name, symbol, decimals) Can Revert

The name(), symbol(), and decimals() functions can revert if the corresponding ignore flags (ignoreName, ignoreSymbol, ignoreDecimals) are set to true during bridgeInit. These flags are set if the BytesParser fails to parse the provided _data for name, symbol, or decimals. This behavior deviates from the standard ERC20 interface, where these functions are expected to always return a value. Integrations relying on these functions might break if they do not handle reverts gracefully, leading to a denial of service for metadata retrieval (7.2 Code Security).M-01

Issue

The name(), symbol(), and decimals() functions can revert if the corresponding ignore flags (ignoreName, ignoreSymbol, ignoreDecimals) are set to true during bridgeInit. These flags are set if the BytesParser fails to parse the provided _data for name, symbol, or decimals. This behavior deviates from the standard ERC20 interface, where these functions are expected to always return a value. Integrations relying on these functions might break if they do not handle reverts gracefully, leading to a denial of service for metadata retrieval (7.2 Code Security).

Fix

Consider returning default or empty values (e.g., empty string for name/symbol, 0 for decimals) instead of reverting when parsing fails. Alternatively, ensure robust validation of _data during bridgeInit to prevent these flags from being set unnecessarily, or provide a mechanism for a privileged role to correct the metadata if parsing initially fails.

Status

Unresolved

Low

BytesParser.toString Edge Case for 32-Byte Strings

The BytesParser.toString function has specific logic for input.length == 32. If input[31] is not bytes1(0x00), it returns (false, res), indicating a parsing failure. This means a valid 32-byte string that happens to have a non-zero last byte (e.g., 'ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF') would be considered a parsing failure, leading to ignoreName or ignoreSymbol being set to true. This could cause the name() or symbol() functions to revert unnecessarily, even for valid inputs (7.2 Code Security).L-01

Issue

The BytesParser.toString function has specific logic for input.length == 32. If input[31] is not bytes1(0x00), it returns (false, res), indicating a parsing failure. This means a valid 32-byte string that happens to have a non-zero last byte (e.g., 'ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF') would be considered a parsing failure, leading to ignoreName or ignoreSymbol being set to true. This could cause the name() or symbol() functions to revert unnecessarily, even for valid inputs (7.2 Code Security).

Fix

Review the BytesParser.toString logic for 32-byte strings to ensure it correctly handles all valid string representations. If the intent is to treat 32-byte inputs as bytes32 and only convert if they are null-padded, this should be clearly documented or handled differently to avoid false negatives for valid strings.

Status

Unresolved

Info

Indirect abi.decode for String/Uint8 Parsing

In bridgeInit, the _data is first abi.decoded into three bytes variables, which are then passed to BytesParser.toString and BytesParser.toUint8. If the _data is consistently encoded as abi.encode(name, symbol, decimals), directly decoding to (string, string, uint8) might simplify the code. The current approach adds an extra parsing layer that handles specific byte representations (7.2 Code Security).I-01

Issue

In bridgeInit, the _data is first abi.decoded into three bytes variables, which are then passed to BytesParser.toString and BytesParser.toUint8. If the _data is consistently encoded as abi.encode(name, symbol, decimals), directly decoding to (string, string, uint8) might simplify the code. The current approach adds an extra parsing layer that handles specific byte representations (7.2 Code Security).

Fix

Document the expected encoding format for _data. If the _data is always abi.encode(name, symbol, decimals), consider direct abi.decode(_data, (string, string, uint8)) for simplicity. If the bytes inputs are expected to be arbitrary byte sequences requiring specific parsing logic (e.g., 32-byte fixed-length strings), the current approach is justified, but the parsing logic should be robust and well-documented.

Status

Unresolved

Info

TransferAndCallToken Uses extcodesize for isContract Check

The isContract function in TransferAndCallToken uses extcodesize to determine if an address is a contract. A known edge case with extcodesize is that it returns 0 during a contract's constructor execution. This means if transferAndCall is called to an address that is currently in its constructor, isContract would return false, and the onTokenTransfer callback would not be invoked (7.2 Code Security).I-02

Issue

The isContract function in TransferAndCallToken uses extcodesize to determine if an address is a contract. A known edge case with extcodesize is that it returns 0 during a contract's constructor execution. This means if transferAndCall is called to an address that is currently in its constructor, isContract would return false, and the onTokenTransfer callback would not be invoked (7.2 Code Security).

Fix

Be aware of this EVM quirk. For most scenarios, this is not an issue as transferAndCall is typically used with already deployed contracts. If interaction with contracts during their construction phase is a critical use case, alternative checks or design patterns might be necessary.

Status

Unresolved

Analysis

AI Copilotas of audit · Sep 4
Executive SummaryWhat the contract is and what the review found

The audit of the StandardArbERC20 implementation contract, used via a ClonableBeaconProxy, identified a High-severity access control vulnerability related to the initialization of cloned token instances. Additionally, Medium and Low severity issues were found concerning ERC20 standard compliance and parsing logic. The contract generally demonstrates good architectural patterns for an L2 bridged token, leveraging OpenZeppelin libraries and a beacon proxy for upgradeability. However, critical attention is required for the initialization process of new token clones to prevent unauthorized control.

Technical8/10Low risk

The StandardArbERC20 contract implements an L2 bridged ERC20 token, utilizing OpenZeppelin's upgradeable ERC20 standard and a Cloneable pattern for efficient deployment. Key strengths include the onlyGateway modifier for bridgeMint and bridgeBurn functions, ensuring controlled token supply management (7.3 Access Control). However, a significant vulnerability exists in the bridgeInit function, which is public and unprotected, allowing any caller to initialize a new clone and potentially set a malicious l2Gateway (7.3 Access Control, 7.2 Code Security). Furthermore, the name(), symbol(), and decimals() functions can revert if parsing fails during initialization, deviating from standard ERC20 behavior and potentially breaking integrations (7.2 Code Security).

Governance1/10High risk

This contract primarily functions as an L2 token implementation and does not contain direct governance mechanisms or complex economic models. Its economic security is largely tied to the integrity of the Arbitrum bridge and the L2 Gateway, which are external components. The bridgeMint and bridgeBurn functions are appropriately restricted to the l2Gateway, mitigating direct economic manipulation within the token contract itself (7.4 Economic, 7.5 Governance).

Upgrades1/10High risk

The contract is designed as an implementation for a ClonableBeaconProxy, enabling efficient deployment of multiple token instances and facilitating future upgrades via the beacon. The _initialize function includes a check (ALREADY_INIT) to prevent re-initialization of critical state variables within a single clone (7.7 Upgrades). However, the bridgeInit function, which triggers this initialization, lacks access control, creating a window for malicious actors to front-run the legitimate initializer for new clones (7.7 Upgrades, 7.3 Access Control).

Final RecommendationWhat to do about this score

Prioritize implementing robust access control for the bridgeInit function to ensure only authorized entities can initialize new token clones.

This is crucial for preventing unauthorized control over token minting and burning capabilities. Additionally, review the behavior of name(), symbol(), and decimals() to align with ERC20 standards, potentially by returning default values instead of reverting on parsing failures. Finally, refine the BytesParser.toString logic to handle edge cases more gracefully, ensuring consistent token metadata availability.

Contract & Record

1 audit on record
TypeClonableBeaconProxy
NetworkArbitrum
Token age4y
Contract0x539b…0342
Deployer0x3fe3…000f
Proxy Upgrade Controls
Proxy TypeBeacon
ImplementationVerified source
Upgrades (30d)0 · stable
Badge for your website
MAGIC security record badge

Free for any token on the record. It links to this page and always shows the current score and the date it was checked.

Audit History
  1. Aug 31, 202658Medium

Score changes are recorded as dated snapshots — history is append-only and cannot be edited.

Frequently Asked Questions

What is the MAGIC contract address?

The MAGIC contract on Arbitrum is 0x539bde0d7dbd336b79148aa742883198bbf60342. Compare it with the address the project itself publishes before trading: other contracts can carry the same name and ticker.

Is MAGIC a scam?

Quantum Audit's risk score for MAGIC is 58/100 (Medium risk) as of Sep 4, 2026, computed by a deterministic function from on-chain facts — Contract verified: Verified; Mint: No mint; Liquidity lock: Not locked; Upgradeability: Upgradeable; Honeypot: None found; Buy / sell tax: 0% / 0%. A score is a dated snapshot of those facts, not a guarantee; each one is listed on this page.

Is MAGIC liquidity locked?

Liquidity lock: Not locked (as of Sep 4, 2026). Total DEX liquidity: $223.4K.

Who holds MAGIC?

As of Sep 4, 2026, the 10 largest holders own 66.3% of the supply. The Holders section on this page shows who they are by holder type.

Would You Like a More Detailed Audit of MAGIC?

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

Get Detailed Audit Is this your token? Publish your own audit on this page