F-2025-0003·cross-chain-share-price-mismatch

Users may lose value when transferring ERC-4626 vault shares cross-chain

Fixedvaultetfstrategyd2-contracts
TL;DR

D2OFT bridges vault shares across chains via LayerZero, but the cross-chain accounting does not synchronize the price-per-share between source and destination. When the share price has diverged across chains, the receiver gains or loses value relative to the underlying asset depending on which side appreciated more.

Severity
HIGH
Impact
HIGH
Likelihood
MEDIUM
Method
MManual review
CAT.
Complexity
MEDIUM
Exploitability
MEDIUM
02Section · Description

Description

D2OFT is the cross-chain transport layer for the D2 vault, allowing a user to hold and move ERC-4626 vault shares across the supported chains. Internally, bridging burns vault shares on the source chain and mints the same number of shares on the destination chain.

The bug is that the bridge operates on raw share amounts, not on the underlying asset value those shares represent. When the same vault is deployed on multiple chains, each chain has its own share-to-asset exchange rate that drifts over time as strategies accrue fees and PnL.

Chain A: 1 share = 1.05 USDC Chain B: 1 share = 1.10 USDC User bridges 100 shares from A → B: burns 100 shares worth 105 USDC on A mints 100 shares worth 110 USDC on B user gained 5 USDC of value at the expense of chain B's other depositors

The opposite direction loses value for the bridging user. Either way, value is transferred between sets of LPs without consent.

03Section · Impact

Impact

  • A user transferring shares from a lower-PPS chain to a higher-PPS chain mints themselves more value than they burned, diluting holders on the destination chain.
  • A user transferring in the opposite direction loses value to holders on the destination chain.
  • MEV searchers can scan PPS across chains and arbitrage the price difference through the bridge until the bridging cost equals the divergence, capturing value at the protocol's expense.
04Section · Recommendation

Recommendation

Normalize the cross-chain transfer to underlying asset value rather than raw share count:

  1. On the source chain, burn the user's shares and serialize the equivalent asset amount into the OFT payload (shares * pricePerShare_source).
  2. On the destination chain, decode the asset amount and mint shares equal to assetAmount / pricePerShare_destination.

This requires both chains to expose a convertToAssets view and pricing to be tolerant of small block-time discrepancies (handled either by a TWAP or by accepting the slight slippage as a known cost of bridging).

05Section · Resolution

Resolution

D2: Fixed in 8d8a5a.

Cyfrin: Verified.

Status
Fixed
Fix commit
8d8a5a
F-2025-0003