The StandardArbERC20 contract serves as an L2 token implementation for Arbitrum, designed to be deployed via a ClonableBeaconProxy. It leverages OpenZeppelin's upgradeable ERC20 standard and custom libraries for cross-chain functionality. A critical vulnerability exists in the bridgeInit function, allowing anyone to disable the token's name, symbol, or decimals getters after initial deployment. The contract also exhibits centralized control over token supply via the l2Gateway address.
On-chain security analysis — is it a scam or legit?
Is Aave Token Safe?
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 →The StandardArbERC20 contract serves as an L2 token implementation for Arbitrum, designed to be deployed via a ClonableBeaconProxy.
- Ownership status UNKNOWN
- Proxy contract
- Complex proxy pattern
- Top-10 concentration > 20%
- Liquidity not locked, but no owner/deployer address holds LP — market-depth risk, not rug risk
- 1 Critical finding(s) from audit
- 1 Medium finding(s) from audit
- 2 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 > 20% (58.4% total → 26.0% effective; 4.5% in EOAs, 53.9% in contracts — mild)
- Liquidity not locked, but no owner/deployer address holds LP — market-depth risk, not rug risk
- 1 Critical finding(s) from audit
- 1 Medium finding(s) from audit
- 2 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 4Holders
as of audit · Sep 4, 2026- Contractstreasury, vesting, bridge, staking53.9%
- Walletsanonymous holders, free to sell4.5%
- Everyone elsethe rest of the supply41.6%
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- UniswapWETHAnalysed$338.6K52.1%
- UniswapUSDC$161.3K24.8%
- PancakeswapWETH$97.2K15.0%
- UniswapARB$16.3K2.5%
- UniswapUSD₮0$14.2K2.2%
- UniswapWETH$6.9K1.1%
Show 4 more pairs
The 6 remaining pairs hold $1.4K between them and are not listed. The risk score reads depth across every pair.
The LP tokens of the analysed pool are not locked or burned, so whoever holds them can withdraw that liquidity.
0xc5cb…f0700x30bd…23d90x50b5…281b0xf6a6…15470xd1af…3d070x24bb…88660x534d…d1920x0cc5…149c0x085a…5fb00x9630…2020No privileged address appears among these holders: the unlocked liquidity sits with independent providers, not with the deployer.
Security Findings
CriticalPublic bridgeInit allows disabling ERC20 getters
The bridgeInit function is public virtual and can be called by any external address. While L2GatewayToken._initialize prevents re-initialization of l2Gateway and l1Address with an ALREADY_INIT check, the availableGetters struct, which controls whether name(), symbol(), and decimals() functions revert, can be re-initialized. An attacker could call bridgeInit with specially crafted _data (e.g., abi.encode(bytes(""), bytes(""), bytes(""))) to cause parseNameSuccess, parseSymbolSuccess, parseDecimalSuccess to be false, subsequently setting ignoreName, ignoreSymbol, ignoreDecimals to true. This would make the standard ERC20 getter functions (name(), `s…C-01
bridgeInit allows disabling ERC20 gettersIssue
The bridgeInit function is public virtual and can be called by any external address. While L2GatewayToken._initialize prevents re-initialization of l2Gateway and l1Address with an ALREADY_INIT check, the availableGetters struct, which controls whether name(), symbol(), and decimals() functions revert, can be re-initialized. An attacker could call bridgeInit with specially crafted _data (e.g., abi.encode(bytes(""), bytes(""), bytes(""))) to cause parseNameSuccess, parseSymbolSuccess, parseDecimalSuccess to be false, subsequently setting ignoreName, ignoreSymbol, ignoreDecimals to true. This would make the standard ERC20 getter functions (name(), `s…
Fix
Restrict access to the bridgeInit function. It should either be callable only once by a trusted initializer (e.g., onlyOwner or a dedicated initializer role) or be made internal and called only during the proxy's initial setup. Given it's a beacon proxy implementation, it should ideally be called only once per clone during its deployment.
Status
Unresolved
MediumBytesParser.toString strict 32-byte string check
The BytesParser.toString function contains specific logic for input.length == 32. It checks input[31] != bytes1(0x00) and returns (false, res) if true. This implies that a 32-byte string *must* be null-terminated at the 31st index to be considered valid. If a valid 32-byte string is provided that is not null-terminated at input[31], it will be incorrectly rejected. This strict requirement might lead to unexpected failures or misinterpretation of token metadata if the L1 bridge sends data that doesn't perfectly conform to this specific null-termination expectation.M-01
BytesParser.toString strict 32-byte string checkIssue
The BytesParser.toString function contains specific logic for input.length == 32. It checks input[31] != bytes1(0x00) and returns (false, res) if true. This implies that a 32-byte string *must* be null-terminated at the 31st index to be considered valid. If a valid 32-byte string is provided that is not null-terminated at input[31], it will be incorrectly rejected. This strict requirement might lead to unexpected failures or misinterpretation of token metadata if the L1 bridge sends data that doesn't perfectly conform to this specific null-termination expectation.
Fix
Review the intended behavior for 32-byte string parsing. If non-null-terminated 32-byte strings are valid, adjust the logic to correctly parse them. Consider if abi.decode(input, (string)) should be used for all non-zero length inputs, as it handles string encoding more robustly.
Status
Unresolved
LowBytesParser.toUint8 requires 32-byte input
The BytesParser.toUint8 function explicitly requires input.length == 32. While abi.decode(input, (uint256)) can handle a uint8 encoded as a uint256 (which would be 32 bytes), this strict length requirement is unusual for a uint8 which only occupies 1 byte. If the L1 bridge were to send decimals as a single byte or a shorter byte array, this function would fail, even if the value is valid. This creates an unnecessary constraint on the input format.L-01
BytesParser.toUint8 requires 32-byte inputIssue
The BytesParser.toUint8 function explicitly requires input.length == 32. While abi.decode(input, (uint256)) can handle a uint8 encoded as a uint256 (which would be 32 bytes), this strict length requirement is unusual for a uint8 which only occupies 1 byte. If the L1 bridge were to send decimals as a single byte or a shorter byte array, this function would fail, even if the value is valid. This creates an unnecessary constraint on the input format.
Fix
If the intention is to always receive uint8 values padded to 32 bytes (e.g., from abi.encode of a uint256), then the current implementation is consistent. However, if flexibility for shorter byte inputs representing uint8 is desired, the function should be modified to handle variable-length inputs more gracefully, potentially using BytesLib.toUint8 directly if the input is guaranteed to be a single byte.
Status
Unresolved
LowtransferAndCall reentrancy vector
The TransferAndCallToken contract (inherited by aeERC20) implements transferAndCall, which performs an external call to receiver.onTokenTransfer after transferring tokens (super.transfer). This pattern, where an external call is made after a state-changing operation, is a classic reentrancy vector. While the StandardArbERC20 contract itself does not hold significant funds that could be directly drained by a reentrant call, a malicious _to contract could re-enter other functions in the system or exploit vulnerabilities in the onTokenTransfer logic if not carefully implemented by the receiver.L-02
transferAndCall reentrancy vectorIssue
The TransferAndCallToken contract (inherited by aeERC20) implements transferAndCall, which performs an external call to receiver.onTokenTransfer after transferring tokens (super.transfer). This pattern, where an external call is made after a state-changing operation, is a classic reentrancy vector. While the StandardArbERC20 contract itself does not hold significant funds that could be directly drained by a reentrant call, a malicious _to contract could re-enter other functions in the system or exploit vulnerabilities in the onTokenTransfer logic if not carefully implemented by the receiver.
Fix
Implement a reentrancy guard (e.g., OpenZeppelin's ReentrancyGuard) on the transferAndCall function if the contract were to hold significant funds or interact with untrusted external contracts in a way that could be exploited. For receiving contracts implementing onTokenTransfer, ensure they follow the Checks-Effects-Interactions pattern and are not vulnerable to reentrancy.
Status
Unresolved
InfoCentralized control of token supply
The bridgeMint and bridgeBurn functions, which control the total supply of the StandardArbERC20 token, are protected by the onlyGateway modifier. This means that only the l2Gateway address has the authority to mint or burn tokens. The l2Gateway address is set during initialization and cannot be changed. This design centralizes control over the token's supply to a single address.I-01
Issue
The bridgeMint and bridgeBurn functions, which control the total supply of the StandardArbERC20 token, are protected by the onlyGateway modifier. This means that only the l2Gateway address has the authority to mint or burn tokens. The l2Gateway address is set during initialization and cannot be changed. This design centralizes control over the token's supply to a single address.
Fix
Ensure that the l2Gateway address is secured with robust multi-signature wallets, time-locks, or other appropriate governance mechanisms to mitigate the risks associated with centralized control. Clearly document the operational procedures and security measures for managing this critical address.
Status
Unresolved
Analysis
AI Copilotas of audit · Sep 4The technical architecture is sound, utilizing OpenZeppelin's upgradeable ERC20 and a beacon proxy pattern for efficient deployment and upgrades (7.1 Architecture, 7.7 Upgrades). Custom BytesParser and BytesLib handle cross-chain data. However, a critical flaw exists in bridgeInit (7.3 Access Control, 7.2 Code Security), allowing unauthorized modification of token metadata getters. The BytesParser.toString logic is also overly strict for 32-byte strings (7.2 Code Security). The transferAndCall function introduces a reentrancy vector, though the direct impact on this contract is limited (7.2 Code Security).
The contract design centralizes control of token minting and burning to the l2Gateway address, which is typical for a bridged token (7.4 Economic). This address is set during initialization and cannot be changed, making its security paramount. There is no explicit governance mechanism within the contract itself (7.5 Governance). The l2Gateway acts as the sole authority for supply management.
The contract is designed as an implementation for a ClonableBeaconProxy, enabling efficient upgrades and multiple token instances (7.7 Upgrades). The Cloneable library correctly distinguishes between the master copy and its clones, preventing accidental self-destruction of the master. This standard pattern ensures a robust upgrade path for all deployed token proxies.
Address the critical access control vulnerability in bridgeInit by restricting its execution to a trusted entity or ensuring it can only be called once.
Review the BytesParser.toString logic to ensure it robustly handles various string encodings from the L1 bridge. While transferAndCall reentrancy risk is primarily on receivers, consider adding reentrancy guards if the contract were to hold significant funds or interact with untrusted external contracts in a way that could be exploited. Ensure the l2Gateway address is secured with robust multi-signature or time-lock mechanisms.
Contract & Record
Free for any token on the record. It links to this page and always shows the current score and the date it was checked.
- Aug 30, 202642Medium
Score changes are recorded as dated snapshots — history is append-only and cannot be edited.
Frequently Asked Questions
What is the AAVE contract address?
The Aave Token (AAVE) contract on Arbitrum is 0xba5ddd1f9d7f570dc94a51479a000e3bce967196. Compare it with the address the project itself publishes before trading: other contracts can carry the same name and ticker.
Is Aave Token a scam?
Quantum Audit's risk score for Aave Token is 42/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 AAVE liquidity locked?
Liquidity lock: Not locked (as of Sep 4, 2026). Total DEX liquidity: $650.2K.
Who holds AAVE?
As of Sep 4, 2026, the 10 largest holders own 58.4% of the supply. The Holders section on this page shows who they are by holder type.
Would You Like a More Detailed Audit of Aave Token?
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