Quantum Audit Logo

Is Wrapped liquid staked Ether 2.0 Safe?

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

Wrapped liquid staked Ether 2.0 WSTETH
0x5979…0529
Arbitrum Not verifiedLast checked 3d ago 1 audit on record
How is this score calculated? → Medium Risk
Executive SummaryAI Copilot

The audit of the ERC20Bridged token implementation, deployed behind an OssifiableProxy, revealed critical vulnerabilities primarily stemming from incorrect handling of immutable variables and an unprotected initialization function within a proxy context. These issues lead to a complete bypass of the bridge's access control, allowing unauthorized minting/burning, and enable anyone to set the token's metadata. Additionally, significant centralization risk exists with the bridge address, and potential storage collision concerns were identified. The overall risk level is Critical.

2 Critical1 High1 Medium
Volume 24h
$963.4K
Liquidity
$1.05M
Price
$3132.7400
Token Age
3y
Top 10 Holders
76.6%

Security Findings

Critical

Critical: Immutable Variables Incompatible with Proxy Pattern

C-01The `ERC20Bridged` contract declares `bridge` as an `immutable` variable, and `ERC20Metadata` declares `decimals` as `immutable`. When an implementation contract with `immutable` variables is deployed behind a proxy, these variables are set during the implementation's constructor execution and are stored in the implementation's bytecode or a special storage area, not in the proxy's delegated storage. Consequently, when calls are made through the proxy, `bridge` will always evaluate to `address(0)` and `decimals` will always evaluate to `0`. This renders the `onlyBridge` modifier ineffective, allowing any non-zero address to call `bridgeMint` and `bridgeBurn`, and causes the `decimals()` fun…
IssueThe `ERC20Bridged` contract declares `bridge` as an `immutable` variable, and `ERC20Metadata` declares `decimals` as `immutable`. When an implementation contract with `immutable` variables is deployed behind a proxy, these variables are set during the implementation's constructor execution and are stored in the implementation's bytecode or a special storage area, not in the proxy's delegated storage. Consequently, when calls are made through the proxy, `bridge` will always evaluate to `address(0)` and `decimals` will always evaluate to `0`. This renders the `onlyBridge` modifier ineffective, allowing any non-zero address to call `bridgeMint` and `bridgeBurn`, and causes the `decimals()` fun…
FixRemove the `immutable` keyword from `bridge` and `decimals`. These variables should be declared as regular state variables and initialized via an access-controlled initializer function (e.g., `initialize(..., address bridge_, uint8 decimals_)`) that is called only once through the proxy. Ensure the initializer function is properly protected to prevent re-initialization.
StatusUnresolved
Critical

Critical: Unprotected Initialization Function

C-02The `initialize` function in `ERC20Bridged` allows setting the token's `name` and `symbol` via `_setERC20MetadataName` and `_setERC20MetadataSymbol`. This function lacks any access control (e.g., `onlyOwner` or `initializer` modifier). When the contract is deployed as an implementation behind a proxy, the proxy's storage for `name` and `symbol` will initially be empty. This allows any external caller to invoke `initialize` through the proxy and set arbitrary `name` and `symbol` values for the token, leading to potential manipulation of the token's identity.
IssueThe `initialize` function in `ERC20Bridged` allows setting the token's `name` and `symbol` via `_setERC20MetadataName` and `_setERC20MetadataSymbol`. This function lacks any access control (e.g., `onlyOwner` or `initializer` modifier). When the contract is deployed as an implementation behind a proxy, the proxy's storage for `name` and `symbol` will initially be empty. This allows any external caller to invoke `initialize` through the proxy and set arbitrary `name` and `symbol` values for the token, leading to potential manipulation of the token's identity.
FixImplement robust access control for the `initialize` function. It should be callable only once by a trusted entity (e.g., the contract owner or a dedicated deployer address) during the proxy's initialization. Consider using OpenZeppelin's `Initializable` base contract and its `initializer` modifier for secure proxy initialization.
StatusUnresolved
High

High: Centralization Risk with Bridge Address

H-01The `bridge` address has absolute control over the token's supply through the `bridgeMint` and `bridgeBurn` functions. If this address is compromised, an attacker could mint an arbitrary amount of tokens or burn existing tokens, leading to severe economic instability and loss of user funds. While this is a common design for bridged tokens, the single point of failure represents a significant centralization risk.
IssueThe `bridge` address has absolute control over the token's supply through the `bridgeMint` and `bridgeBurn` functions. If this address is compromised, an attacker could mint an arbitrary amount of tokens or burn existing tokens, leading to severe economic instability and loss of user funds. While this is a common design for bridged tokens, the single point of failure represents a significant centralization risk.
FixConsider implementing a multi-signature wallet (e.g., Gnosis Safe) for the `bridge` address to distribute control and require multiple approvals for critical operations. Alternatively, explore time-locks or governance mechanisms to introduce delays or community oversight for `bridgeMint` and `bridgeBurn` operations.
StatusUnresolved
Medium

Medium: Potential for Storage Collisions with Custom Metadata Slot

M-01The `ERC20Metadata` contract uses a custom storage slot (`DYNAMIC_METADATA_SLOT = keccak256("ERC20Metdata.dynamicMetadata")`) for storing the token's `name` and `symbol`. While using a `keccak256` hash for a storage slot is a common technique to avoid collisions with standard storage variables, it introduces a potential risk in future upgrades. If a new version of the contract or a base contract introduces a state variable that happens to occupy this specific storage slot, it could lead to a storage collision, corrupting data or causing unexpected behavior.
IssueThe `ERC20Metadata` contract uses a custom storage slot (`DYNAMIC_METADATA_SLOT = keccak256("ERC20Metdata.dynamicMetadata")`) for storing the token's `name` and `symbol`. While using a `keccak256` hash for a storage slot is a common technique to avoid collisions with standard storage variables, it introduces a potential risk in future upgrades. If a new version of the contract or a base contract introduces a state variable that happens to occupy this specific storage slot, it could lead to a storage collision, corrupting data or causing unexpected behavior.
FixEnsure that any future upgrades or modifications to the contract's storage layout are meticulously reviewed for potential collisions with this custom slot. Document this custom slot clearly in the contract's design specifications. Consider using a more explicit 'gap' array or OpenZeppelin's `ERC1967Storage` pattern for proxy-safe storage management, although the current approach is generally considered safer than direct slot assignment for custom data.
StatusUnresolved

Category Ratings

TechnicalMedium4/10

The ERC20Bridged token implements standard ERC-20 functionality with custom mint/burn capabilities controlled by a 'bridge' address. The core ERC-20 logic in ERC20Core is generally well-structured and uses Solidity 0.8+ safe math, preventing common integer overflow/underflow issues (7.2 Code Security). However, critical technical flaws arise from its deployment as a proxy implementation. Specifically, immutable variables like 'bridge' and 'decimals' are not correctly handled in the proxy's storage, leading to a complete bypass of the 'onlyBridge' access control (7.3 Access Control). Furthermore, the 'initialize' function, intended for setting metadata, lacks any access control and can be called by any external address, allowing arbitrary modification of the token's name and symbol (7.3 Access Control).

GovernanceHigh1/10

The economic model of the ERC20Bridged token relies heavily on the security and integrity of the designated 'bridge' address. This address holds absolute power over the token's supply through the 'bridgeMint' and 'bridgeBurn' functions (7.4 Economic). While this is a common design for bridged tokens, it introduces a significant centralization risk; compromise of this single address would lead to complete loss of control over the token's supply and severe economic consequences for holders. The current implementation exacerbates this risk by rendering the 'onlyBridge' modifier ineffective due to proxy storage issues, effectively decentralizing mint/burn control to any caller (7.3 Access Control, 7.4 Economic).

UpgradesHigh1/10

The contract is designed as an implementation for an OssifiableProxy (Transparent Proxy), which is a standard upgradeability pattern (7.7 Upgrades). However, the use of 'immutable' variables ('bridge' and 'decimals') in the implementation contract is fundamentally incompatible with proxy patterns. These variables are not stored in the proxy's delegated storage, causing them to always resolve to their default zero values when accessed through the proxy, breaking core functionality and access control (7.7 Upgrades). Additionally, the ERC20Metadata contract uses a custom storage slot for dynamic metadata, which, while using a keccak256 hash, could still pose a risk of storage collision in future upgrades if not carefully managed (7.1 Architecture, 7.7 Upgrades).

Security Checklist

Contract VerifiedPass
Ownership RenouncedFail
No Mint FunctionPass
Liquidity LockedFail
Not a ProxyFail

Proxy Upgrade Controls

Proxy TypeEip1967 Transparent
AdminOther-Contract
ImplementationVerified source
Upgrades (30d)0 · stable

Holder Composition

3.4% in wallets73.1% in contracts
Effective Concentration32.7%

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 4 remaining pairs hold $49 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 Holder46.0%
Top-3 Unlocked76.4%

Key Addresses

Deployer
0x1824…6321
Unlocked LP Held By
0xb884…722c0x9e3f…b72f0x6f99…6ae50x642f…f2610x241a…e4880x185a…1d0f0xfafe…89f40xdd70…6eb50x7e6b…d4c10x8b5f…c98d

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 (admin/mint authority retained)
  • Proxy contract (upgradeable — admin can replace logic)
  • Admin is unclassified contract
  • Top-10 concentration > 30% (76.6% total → 32.7% effective; 3.4% in EOAs, 73.1% in contracts — moderate)
  • Liquidity not locked, but no owner/deployer address holds LP — market-depth risk, not rug risk
  • 2 Critical finding(s) from audit
  • 1 High finding(s) from audit
  • 1 Medium 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

Aave Token (AAVE)Medium RiskRAINMedium RiskChainLink Token (LINK)Medium RiskBoopMedium RiskAutonomi (ANT)High RiskSubsquid (SQD)High Risk

Would You Like a More Detailed Audit of Wrapped liquid staked Ether 2.0?

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

Get Detailed Audit