The audit of the StandardArbERC20 contract, an implementation for an Arbitrum L2 ERC20 token deployed via a beacon proxy, reveals a well-structured and robust design. The contract correctly handles L1 token metadata parsing and integrates with the Cloneable pattern for proxy compatibility. Identified issues are primarily related to design choices and best practices, with no critical or high-severity vulnerabilities found. The overall risk level is assessed as Low.
On-chain security analysis — is it a scam or legit?
Is Pendle 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 audit of the StandardArbERC20 contract, an implementation for an Arbitrum L2 ERC20 token deployed via a beacon proxy, reveals a well-structured and robust design.
Read the full analysis- Ownership status UNKNOWN
- Proxy contract
- Complex proxy pattern
- Top-10 concentration > 30%
- Liquidity not locked, but no owner/deployer address holds LP — market-depth risk, not rug risk
- 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 > 30% (41.8% total → 33.3% effective; 27.5% in EOAs, 14.3% in contracts — moderate)
- Liquidity not locked, but no owner/deployer address holds LP — market-depth risk, not rug risk
- 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, staking14.3%
- Walletsanonymous holders, free to sell27.5%
- Everyone elsethe rest of the supply58.2%
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- CamelotWETHAnalysed$2.12M46.3%
- UniswapWETH$1.08M23.5%
- UniswapUSD₮0$630.5K13.8%
- UniswapUSDC$299.4K6.5%
- UniswapWETH$158.8K3.5%
- Camelot v3WETH$135.8K3.0%
Show 4 more pairs
The 11 remaining pairs hold $7.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.
0xbfe6…d71b0xaa56…74620x68d6…126a0x75df…97790xdec1…63760xda7c…da3f0x2832…9f4c0xaf41…a32d0xc044…f44c0x9d3c…b090No privileged address appears among these holders: the unlocked liquidity sits with independent providers, not with the deployer.
Security Findings
MediumRevert on Missing ERC20 Metadata
The decimals(), name(), and symbol() functions explicitly revert if the corresponding ignore flag (e.g., availableGetters.ignoreDecimals) is set, indicating that the metadata was not successfully parsed from the L1 token. While this behavior is intended to mimic L1 contracts where such functions might not exist, it deviates from standard ERC20 implementations which typically return a value (e.g., 0 for decimals, empty string for name/symbol) rather than reverting. This could cause issues for dApps or integrations that expect these standard ERC20 getters to always return a value and do not handle reverts gracefully.M-01
Issue
The decimals(), name(), and symbol() functions explicitly revert if the corresponding ignore flag (e.g., availableGetters.ignoreDecimals) is set, indicating that the metadata was not successfully parsed from the L1 token. While this behavior is intended to mimic L1 contracts where such functions might not exist, it deviates from standard ERC20 implementations which typically return a value (e.g., 0 for decimals, empty string for name/symbol) rather than reverting. This could cause issues for dApps or integrations that expect these standard ERC20 getters to always return a value and do not handle reverts gracefully.
Fix
Clearly document this specific behavior for integrators. Consider if returning a default value (e.g., 0 for decimals, empty string for name/symbol) is a more compatible approach for a broader range of ERC20 integrations, even if it deviates from the L1 mimicry. If reverting is critical for the design, ensure comprehensive testing of integrations under these conditions.
Status
Unresolved
LowImplicit Trust in L2GatewayToken Initialization Logic
The bridgeInit function calls L2GatewayToken._initialize to perform the core initialization logic. The security of preventing multiple initializations (a critical aspect for proxy contracts) relies entirely on L2GatewayToken._initialize correctly implementing an initializer pattern (e.g., using an initialized flag or initializer modifier). Without the source code for L2GatewayToken, this crucial protection is an assumption, introducing a dependency risk.L-01
L2GatewayToken Initialization LogicIssue
The bridgeInit function calls L2GatewayToken._initialize to perform the core initialization logic. The security of preventing multiple initializations (a critical aspect for proxy contracts) relies entirely on L2GatewayToken._initialize correctly implementing an initializer pattern (e.g., using an initialized flag or initializer modifier). Without the source code for L2GatewayToken, this crucial protection is an assumption, introducing a dependency risk.
Fix
Verify that the L2GatewayToken._initialize function rigorously enforces a single-call initialization to prevent re-initialization attacks. If possible, consider adding an explicit initializer modifier directly to StandardArbERC20.bridgeInit for defense in depth, even if L2GatewayToken provides its own protection.
Status
Unresolved
LowInline Assembly Usage in BytesLib
The BytesLib library, used by BytesParser for decoding _data, extensively utilizes inline assembly (assembly { ... }) for byte manipulation. While assembly can be highly efficient for low-level operations, it is inherently more complex, error-prone, and harder to audit than high-level Solidity. Although the library includes require statements for bounds checking, subtle errors in assembly logic could lead to unexpected behavior or vulnerabilities.L-02
BytesLibIssue
The BytesLib library, used by BytesParser for decoding _data, extensively utilizes inline assembly (assembly { ... }) for byte manipulation. While assembly can be highly efficient for low-level operations, it is inherently more complex, error-prone, and harder to audit than high-level Solidity. Although the library includes require statements for bounds checking, subtle errors in assembly logic could lead to unexpected behavior or vulnerabilities.
Fix
Ensure that BytesLib has undergone thorough and independent security review, specifically focusing on its assembly code. Maintain comprehensive test coverage for all functions within BytesLib to validate correct behavior across various input scenarios.
Status
Unresolved
InfobridgeInit Visibility and Explicit Initializer Pattern
The bridgeInit function is declared as public virtual. While L2GatewayToken._initialize is expected to handle the single-call initialization, making bridgeInit public rather than external means it can be called internally, which is not strictly necessary for an initializer. Additionally, an explicit initializer modifier (e.g., from OpenZeppelin's Initializable pattern) is not directly applied to bridgeInit in StandardArbERC20 itself, relying solely on the base contract.I-01
bridgeInit Visibility and Explicit Initializer PatternIssue
The bridgeInit function is declared as public virtual. While L2GatewayToken._initialize is expected to handle the single-call initialization, making bridgeInit public rather than external means it can be called internally, which is not strictly necessary for an initializer. Additionally, an explicit initializer modifier (e.g., from OpenZeppelin's Initializable pattern) is not directly applied to bridgeInit in StandardArbERC20 itself, relying solely on the base contract.
Fix
Consider changing bridgeInit to external if it's not intended for internal calls. For clarity and robustness, explicitly apply an initializer modifier to bridgeInit within StandardArbERC20 if L2GatewayToken does not already provide a sufficiently robust and explicit mechanism, or if StandardArbERC20 needs its own initialization state.
Status
Unresolved
InfoCloneable isMasterCopy Storage Behavior in Proxy Context
The Cloneable base contract initializes isMasterCopy to true in its constructor. In a proxy deployment, the constructor of the implementation contract (StandardArbERC20) is only called once when the implementation itself is deployed, not when proxy instances are initialized. Consequently, isMasterCopy will always be true in the implementation's storage slot. For proxy instances, this storage slot will be initialized to its default value (false) unless explicitly set during initialization. This is the intended behavior for the Cloneable pattern, where the implementation serves as the 'master copy' and clones are distinct.I-02
Cloneable isMasterCopy Storage Behavior in Proxy ContextIssue
The Cloneable base contract initializes isMasterCopy to true in its constructor. In a proxy deployment, the constructor of the implementation contract (StandardArbERC20) is only called once when the implementation itself is deployed, not when proxy instances are initialized. Consequently, isMasterCopy will always be true in the implementation's storage slot. For proxy instances, this storage slot will be initialized to its default value (false) unless explicitly set during initialization. This is the intended behavior for the Cloneable pattern, where the implementation serves as the 'master copy' and clones are distinct.
Fix
No direct action is required as this is the designed behavior of the Cloneable pattern. However, it's important for developers and auditors to understand this distinction to avoid misinterpreting the state of isMasterCopy when analyzing proxy instances versus the master implementation.
Status
Unresolved
Analysis
AI Copilotas of audit · Sep 4The StandardArbERC20 contract implements an L2 ERC20 token, leveraging L2GatewayToken for core functionality and Cloneable for proxy compatibility. The bridgeInit function correctly decodes L1 token metadata using BytesParser and BytesLib, with robust bounds checks in assembly-level operations (7.2 Code Security). A notable design choice is the explicit revert in decimals(), name(), and symbol() if L1 metadata is unavailable, which deviates from typical ERC20 behavior and could impact integrations (7.6 External). The reliance on L2GatewayToken for proper initialization handling is a key architectural assumption (7.1 Architecture, 7.3 Access Control).
The contract primarily functions as a standard ERC20 token on Arbitrum, with no complex governance mechanisms or unique economic incentives defined within its scope (7.5 Governance, 7.4 Economic). The design allows for flexible handling of L1 token metadata, enabling the L2 token to adapt to varying L1 ERC20 implementations (7.4 Economic). There are no apparent economic attack vectors or governance vulnerabilities in the provided code, maintaining a simple and predictable economic model.
The StandardArbERC20 contract is designed as an implementation for a beacon proxy, inheriting from Cloneable which correctly distinguishes between master copy and clone instances (7.7 Upgrades). The bridgeInit function serves as the initializer, and its single-call execution is assumed to be enforced by the L2GatewayToken base contract, ensuring safe initialization for proxy instances (7.7 Upgrades, 7.8 Operations). Storage layout appears straightforward with ERC20Getters and isMasterCopy occupying distinct slots, minimizing upgrade risks related to storage collisions, assuming L2GatewayToken also follows best practices (7.7 Upgrades).
Ensure that the L2GatewayToken base contract strictly enforces a single-call initialization pattern for _initialize to prevent re-initialization attacks on proxy instances.
Document the expected behavior of decimals(), name(), and symbol() reverting when L1 metadata is unavailable to inform integrators and prevent unexpected failures. Consider making bridgeInit external and explicitly adding an initializer modifier for clearer access control and to reinforce the one-time setup expectation.
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 6, 202626Low
Score changes are recorded as dated snapshots — history is append-only and cannot be edited.
Would You Like a More Detailed Audit of Pendle?
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