Crypto Training
ERC-7540 in Practice: Standards, Implementations, Security Pitfalls, and Alternatives
A code-first analysis of ERC-7540, ERC-7575, and ERC-7887: what the standards require, how production systems actually implement async flows, where designs diverge, recurring vulnerability patterns, and how Mellow compares as an async vault architecture outside strict ERC-7540.
Asynchronous vaults have moved from edge-case design to mainstream infrastructure for RWAs, delayed-liquidity strategies, and controlled redemption systems.
The core standard in this space is ERC-7540, usually paired with ERC-7575, and increasingly extended with ERC-7887.
This post is a code-level comparison of those standards and real implementations, including where teams deviate intentionally.
Primary references:
- EIP-7540
- EIP-7575
- EIP-7887
- ERC-7540 Reference
- OpenZeppelin issue #4761
- Lagoon docs and audits page
- Blockmagnates explainer
- QuillAudits explainer
- Recon: reusable properties for ERC-7540 vaults
Why async vaults exist#
Synchronous ERC-4626 assumes deposits/redeems can clear immediately against currently available liquidity.
Many vaults cannot guarantee that:
- RWA and credit strategies settle on delayed schedules.
- Exit liquidity can be batched or epoch-based.
- External unwind can require multiple transactions and time windows.
- Strategy NAV may be finalized periodically rather than per block.
ERC-7540 formalizes this with request-based state transitions.
Standards map: 4626, 7540, 7575, 7887#
ERC-7540#
ERC-7540 adds request/claim lifecycle for deposits and redeems while still requiring ERC-4626 interfaces.
Core request methods:
requestDeposit(assets, controller, owner)requestRedeem(shares, controller, owner)pending*Request(requestId, controller)claimable*Request(requestId, controller)
Operator model:
setOperator(operator, approved)isOperator(controller, operator)
Key rule from the spec: async flows must use pull-based two-step claim semantics, not push settlement.
ERC-7575#
ERC-7575 externalizes share() and enables multi-asset entry points over a shared vault-share system.
This is why many ERC-7540 implementations also expose share() and ERC-165 interface support.
ERC-7887#
ERC-7887 adds cancellation state machines on top of ERC-7540:
- cancel request
- pending cancel
- claimable cancel
- cancel claim
It also requires blocking new same-side requests while cancellation is pending.
The selector and semantics tension with ERC-4626#
One recurring friction point is that ERC-7540 reuses familiar ERC-4626 function names (deposit, mint, withdraw, redeem) but changes behavior in async contexts.
EIP-7540 explicitly requires reverts in preview paths depending on async mode:
- async deposit vaults:
previewDepositandpreviewMintmust revert. - async redeem vaults:
previewRedeemandpreviewWithdrawmust revert.
That practical friction appears in the OpenZeppelin discussion thread as maintainers and integrators debate how cleanly this composes with a generic ERC-4626 library model: issue #4761.
Reference implementation behavior (ERC-7540-Reference)#
The reference repository is useful for understanding intended behaviors and tradeoffs.
Repository: ERC4626-Alliance/ERC-7540-Reference
Notable contracts:
BaseERC7540.solControlledAsyncDeposit.solControlledAsyncRedeem.solTimelockedAsyncRedeem.solFullyAsyncVault.solIERC7540.sol
Design choices worth noting:
- Request aggregation by
requestId == 0pattern is explicitly supported. - Operator model is first-class.
- Preview reverts are enforced in async modes.
- Multiple variants show how fulfillment logic is implementation-specific.
Real-world implementations: what is standard, what is custom#
A) Code-confirmed implementations in reviewed repos#
| Project | Evidence of 7540 semantics in code | Notes |
|---|---|---|
| Centrifuge | AsyncVault.sol, BaseVaults.sol, IAsyncVault.sol | Full async vault path plus cancellation support pathways aligned with 7887-style interfaces. |
| Lagoon | src/v0.5.0/ERC7540.sol, src/v0.5.0/Vault.sol | Epoch-oriented async flows with additional vault-state and whitelist layers. |
| Superform SuperVault | SuperVault.sol, ISuperVault.sol | Hybrid model: sync deposits, async redeems, explicit cancel-redeem path. |
| Amphor async vault | AsyncSynthVault.sol, IERC7540.sol | Contest-era implementation with multiple high-impact async-state bugs found. |
| NashPoint | Node.sol, IERC7540.sol | Node architecture with router layer and async redeem behavior. |
| UltraYield | BaseControlledAsyncRedeem.sol, IBaseVault.sol | Async redeem-focused design with cancellation variants and custom custody assumptions. |
| maxAPY MetaVault | MetaVault.sol, lib/ERC7540.sol | ERC-7540-oriented interfaces wrapped around cross-chain strategy engine decisions. |
| ERC-7540 Reference | src | Reference, not production by itself, but foundational for many implementations. |
B) Publicly claimed implementations or adjacent designs#
| Project | Public signal | Status from this code review |
|---|---|---|
| Cove | Public mention in OZ issue thread with source links: issue #4761 comments | Claimed ERC-7540 implementation; not deeply audited in this post. |
| MORE Markets | Public docs and external discussions claim ERC-7540 facet style support | Local snapshot did not provide direct 7540 markers in scanned contracts; treat as unverified here. |
The big pattern: almost everyone keeps the high-level request lifecycle, but fulfillment math, batching granularity, cancellation semantics, and custody models diverge significantly.
Lagoon as a concrete epoch-style implementation#
Lagoon is useful as a practical epoch-7540 architecture.
Code and docs:
Lagoon-specific behaviors beyond bare standard:
- Epoch snapshots and explicit close/open workflow.
- Single-request constraints in specific paths (
OnlyOneRequestAllowed) to simplify state transitions. - Whitelisting and role-based controls around who can interact.
- Operational controls to pause/cancel request paths.
Superform as hybrid async design#
Superform's v2 periphery states the SuperVault model as sync deposits plus async redeems.
References:
Interesting implementation detail:
previewWithdrawandpreviewRedeemare explicitly not implemented for async redeem path.requestRedeemmoves shares to escrow, then strategy handles async operations.- Cancellation path is built into vault interfaces.
Centrifuge as full async plus cancellation stack#
Centrifuge's vault module is one of the clearest examples of complete async architecture with manager separation.
References:
Notable architecture decisions:
- Request managers split by responsibilities.
- Explicit cancellation flows.
- Router and manager boundaries for operational and integration clarity.
Common design dimensions where implementations differ#
The standards intentionally leave room for different policy choices.
1) Fulfillment granularity#
- Per-user manual fulfillment
- Batch-based fulfillment
- Time-delay auto-claimable fulfillment
2) Pricing point#
- Price at request
- Price at settlement
- Price at claim
3) State model strictness#
- Strict pending to claimable to claimed
- Partial claimable balances across multiple rounds
4) Cancellation model#
- No cancellation
- Cancellation only for one side
- Full 7887-style cancellation for both sides
Security: recurring vulnerabilities in async vaults#
The highest-value section in async-vault audits is almost always state-machine consistency.
Below are common bug classes observed in judged findings and audited codebases, with examples grounded in real contest findings from the Amphor async vault corpus and related implementations.
1) Claim before valid settlement context#
Pattern:
- Claim path executes while request is still in current unsettled epoch.
- Conversion function reads uninitialized snapshot context.
- User claim clears pending state but receives zero or wrong output.
Observed in judged findings against Amphor async design.
2) Controller-owner-account mismatch#
Pattern:
- Request created on behalf of one account while internal indexes update another.
- Claim lookup uses mismatched key.
- Shares or assets become permanently unclaimable.
3) Async math divergence between sync and async paths#
Pattern:
- Sync path and async path use different fee inclusion or conversion baseline.
- Equal economic action yields different shares/assets depending on route.
- Long-term accounting drifts and unfair allocation emerges.
4) Token behavior assumptions#
Pattern:
- Code assumes strict ERC-20 return behavior.
- Non-standard tokens (USDT-like return patterns, WBTC allowance behavior) break flow or lock value.
5) Partial-fill and zap residue theft#
Pattern:
- Router or zap path permits partial execution.
- Unspent tokens remain in intermediate contract.
- Subsequent caller can drain residual value.
6) Allowance depletion over long horizons#
Pattern:
- "Approve max once" assumed sufficient.
- Token decreases max allowance on each transfer.
- Eventually pulls fail and funds become trapped without a refresh mechanism.
Practical invariant suite for ERC-7540 systems#
A robust test plan should combine unit tests, fuzzing, and invariants around state conservation and phase correctness.
Suggested invariant classes:
-
Request conservation:
pending + claimable + claimedtransitions cannot create or destroy value unexpectedly. -
Phase safety: claim path must revert unless request is actually claimable.
-
Identity consistency: for every request key, same identity tuple used for creation, transition, and claim.
-
Operator safety: operator permissions must only widen access intentionally and revocation must take effect immediately.
-
Pricing consistency: if design requires deterministic batch pricing, all participants in same batch must receive same rate.
-
Cancellation safety: if cancel is pending for a side, new requests for that side must be blocked per design.
Where ERC-7540 is strong#
- Standardized async vocabulary for integrators.
- Shared operator model for delegated request management.
- Cleaner integration target for RWA and delayed-liquidity systems.
- Better composability than ad hoc request APIs.
Where ERC-7540 is hard in production#
- Integrator confusion when 4626 method names retain different runtime semantics.
- Fulfillment logic and pricing remain highly custom and operationally heavy.
- Cancellations and partial fulfillments rapidly increase state complexity.
- Off-chain orchestration quality often dominates user safety in practice.
Alternative async architecture: Mellow#
Mellow flexible-vaults is not a strict ERC-7540 implementation, but it solves similar async vault problems with a different architecture.
References:
- Mellow flexible-vaults repository
src/queues/DepositQueue.solsrc/queues/RedeemQueue.solsrc/oracles/Oracle.solsrc/vaults/Subvault.solsrc/modules/CallModule.solsrc/permissions/Verifier.sol
Mellow architecture highlights:
- Explicit
DepositQueueandRedeemQueuecontracts for request lifecycle. - Oracle-report-driven settlement cadence.
- Subvault isolation for strategy execution.
- Call-level policy enforcement through
Verifierand custom verifier modules.
This is structurally similar to async request systems but with stronger strategy-execution policy tooling inside the protocol stack itself.
ERC-7540 vs Mellow: concise comparison#
| Dimension | Typical ERC-7540 design | Mellow flexible-vaults |
|---|---|---|
| Standard interface | ERC-7540 and often 7575/7887 | Custom queue interfaces, ERC-4626-like user surface |
| Request abstraction | Standardized request and claim methods | Queue modules and report-triggered handling |
| Strategy execution controls | Often external manager policy | Built-in verifier and call-module gating |
| Settlement trigger | Implementation-defined | Explicit oracle report path |
| Integrator familiarity | Better at interface level | Better at policy and modular operations |
What high-quality ERC-7540 designs have in common#
Across strong implementations, the following properties keep reappearing:
- Deterministic and auditable request state transitions.
- Explicit identity model for owner, controller, operator.
- Conversion logic tied to a clearly defined pricing point.
- Guardrails against same-epoch or stale-context claims.
- Cancellation semantics that avoid ambiguous overlapping states.
- Good integration hygiene for non-standard ERC-20 behavior.
Implementation checklist for new deployments#
- Decide whether requests are per-user aggregate (
requestId == 0) or per-batch/per-position. - Pin one precise pricing point and encode it in tests and documentation.
- Add phase-gate checks to every claim and cancel claim path.
- Harden token interactions with safe transfer patterns and allowance refresh strategies.
- Prove identity invariants for owner/controller/operator transitions.
- If using cancellation, enforce request blocking during pending cancel windows.
- Add invariant tests for conservation and no-stuck-value guarantees.
- Document exactly which ERC-7540 subset is implemented if hybrid.
Final perspective#
ERC-7540 is useful because it standardizes the async request vocabulary without forcing one fulfillment engine.
That flexibility is both the strength and the danger:
- it enables adaptation to many real strategies,
- but it shifts safety to implementation correctness and operational discipline.
If you are integrating async vaults, audit the actual settlement engine and identity model first. The interface alone is not enough.
Code index#
Standards and references#
- ERC-7540: eips.ethereum.org/EIPS/eip-7540
- ERC-7575: eips.ethereum.org/EIPS/eip-7575
- ERC-7887: eips.ethereum.org/EIPS/eip-7887
- ERC-7540 Reference
src: github.com/ERC4626-Alliance/ERC-7540-Reference/tree/main/src
Implementations#
- Centrifuge vaults: github.com/centrifuge/protocol/tree/main/src/vaults
- Lagoon v0.5.0: github.com/hopperlabsxyz/lagoon-v0/tree/main/src/v0.5.0
- Superform SuperVault: github.com/superform-xyz/v2-periphery/tree/dev/src/SuperVault
- Amphor async vault: github.com/sherlock-audit/2024-03-amphor/tree/main/asynchronous-vault/src
- NashPoint contracts: github.com/nashpoint/nashpoint-smart-contracts/tree/main/src
- UltraYield contracts: github.com/UltraYield/contracts/tree/main/src
- maxAPY MetaVault: github.com/turingcapitalgroup/metaVault/tree/main/src
Alternatives#
- Mellow flexible-vaults: github.com/mellow-finance/flexible-vaults/tree/main/src
Context and discussion#
- OpenZeppelin issue on ERC-7540 support: github.com/OpenZeppelin/openzeppelin-contracts/issues/4761
- Lagoon docs: docs.lagoon.finance
- Lagoon audits page: docs.lagoon.finance/resources/audits
- Blockmagnates explainer: blog.blockmagnates.com/erc7540-asynchronous-erc4626-vault-0b78c6a56aef
- QuillAudits explainer: quillaudits.com/research/rwa-development/relevant-standards/erc-7540-async-erc-4626-tokenized
- Recon article: getrecon.substack.com/p/reusable-properties-for-erc7540-vaults