Quantum Audit Logo

Is Aave Token Safe?

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

Aave Token AAVE
0xba5d…7196
Arbitrum Not verifiedLast checked 2d ago 1 audit on record
How is this score calculated? → Medium Risk
Executive SummaryAI Copilot

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.

1 Critical1 Medium2 Low1 Informational
Volume 24h
$73.6K
Liquidity
$338.6K
Price
$130.3600
Token Age
3y
Top 10 Holders
58.4%

Security Findings

Critical

Public `bridgeInit` allows disabling ERC20 getters

C-01The `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…
IssueThe `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…
FixRestrict 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.
StatusUnresolved
Medium

`BytesParser.toString` strict 32-byte string check

M-01The `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.
IssueThe `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.
FixReview 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.
StatusUnresolved
Low

`BytesParser.toUint8` requires 32-byte input

L-01The `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.
IssueThe `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.
FixIf 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.
StatusUnresolved
Low

`transferAndCall` reentrancy vector

L-02The `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.
IssueThe `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.
FixImplement 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.
StatusUnresolved
Info

Centralized control of token supply

I-01The `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.
IssueThe `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.
FixEnsure 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.
StatusUnresolved

Category Ratings

TechnicalLow7/10

The 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).

GovernanceMedium4/10

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.

UpgradesHigh1/10

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.

Security Checklist

Contract VerifiedPass
Ownership Renounced?
No Mint FunctionPass
Liquidity LockedFail
Not a ProxyFail
HoneypotNoneBuy Tax0.0%Sell Tax0.0%

Proxy Upgrade Controls

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

Holder Composition

4.5% in wallets53.9% in contracts
Effective Concentration26.0%

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

Show 4 more pairsShow less

The 6 remaining pairs hold $1.4K between them and are not listed.

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 Holder22.1%
Top-3 Unlocked41.8%

Key Addresses

Deployer
0x3fe3…000f
Unlocked LP Held By
0xc5cb…f0700x30bd…23d90x50b5…281b0xf6a6…15470xd1af…3d070x24bb…88660x534d…d1920x0cc5…149c0x085a…5fb00x9630…2020

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

What Raised This Score

  • 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

Related Audits

Wrapped liquid staked Ether 2.0 (WSTETH)Medium RiskRAINMedium RiskChainLink Token (LINK)Medium RiskBoopMedium RiskAutonomi (ANT)High RiskSubsquid (SQD)High Risk

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