Convex
The Convex adapter reports an account's Convex-staked Curve LP positions across any configured Convex pool, plus all claimable rewards (CRV, CVX, and extra tokens).
The Convex adapter (ConvexCurveLPStakingMetaBalanceAdapter) reports an account's Convex-staked Curve LP positions across any configured Convex pool, plus all claimable rewards (CRV, CVX, and extra tokens). A single immutable meta-adapter serves every pool; the active set of Convex rewarders lives on NAVCalculator.
Type: Meta-adapter
protocolSubId:
keccak256("convex-curve-lp-staking")Instance key: the Convex
BaseRewardPool(rewarder) address, widened to bytes32. The underlying Curve LP token and pool are resolved on-chain viarewarder.pid()→Booster.poolInfo(pid).lptoken→CurvePoolLib.getPool(lpToken).
Positions returned
Per rewarder instance:
Staked LP coin (one per Curve pool coin)
Staking
false
Pro-rata share of each Curve pool coin backing the staked LP
Staked LP token (fallback)
Staking
false
The LP token itself, emitted instead of the per-coin legs when the Curve pool cannot be resolved structurally — so the principal is reported rather than dropped
CRV reward
Rewards
false
Claimable CRV (main reward token)
CVX reward
Rewards
false
CVX derived from CRV via the cliff schedule (skipped if CVX_TOKEN == address(0))
Extra reward (up to 8)
Rewards
false
Each enumerated extra reward token; stash wrappers unwrapped to the underlying
Legs with zero amount, unregistered assets, or assets excluded by assetFilter are dropped.
Balance calculation
Staking legs — stakedLp = rewarder.balanceOf(account). For each Curve pool coin i:
(CurvePoolLib.proRataAmount, using getPoolBalance, getTotalSupply, getCoins.)
CRV reward:
This is exact and view-safe — Convex accounts for all pending CRV in earned(), so it is not a lower bound.
CVX reward — derived from crvEarned via the Convex cliff emission schedule:
Returns 0 once cliff >= 1000.
Extra reward legs — for each extra rewarder up to 8: amount = extraRewarder.earned(account). The reward token is unwrapped from any stash wrapper (stash.token() → underlying). Tokens equal to CRV are skipped (already reported); CVX via a stash wrapper is skipped (already derived in the CVX leg).
Identity
positionId:
abi.encode(address rewarder)— one positionId per rewarder instance (all legs of an instance share it).positionKind:
Stakingfor LP coins,Rewardsfor CRV / CVX / extra tokens.
There is no labels field on the position. The adapter implements positionLabels(positionId), which returns the 3-segment breadcrumb ["Staking", "Curve LP", "TOKEN0/TOKEN1/…"] — the third segment being the underlying Curve pool's coin symbols, derived on-chain from the rewarder's LP token (collapses to ["Staking", "Curve LP"] if unreadable). It is surfaced only by the verbose reads (getAccountPositionsVerbose / getAccountNavVerbose); the full breadcrumb is [protocolName, ...labels].
Constructor
booster_
Convex Booster contract (resolves lptoken from a pool ID; mainnet 0xF403C135812408BFbE8713b5A23a04b3D48AAE31)
cvxToken_
CVX token address (mainnet 0x4e3FBD56CD56c3e72c1403e103b45Db9da5B9D2B); pass address(0) to skip CVX computation on L2
navCalculator_
NAVCalculator contract for asset-registry access
Registration
Register the adapter once with addMetaBalanceAdapter, then enable each pool with addMetaInstances. The instance coordinate is the Convex BaseRewardPool (rewarder) address widened to bytes32. The adapter holds no instance state — it reads its active set from NAV_CALCULATOR.getMetaInstances(address(this)).
Last updated