For the complete documentation index, see llms.txt. This page is also available as Markdown.

Curve Gauges

Reports an account's gauge-staked Curve LP position across any configured gauge, plus all claimable rewards (CRV and extra reward tokens).

Reports an account's gauge-staked Curve LP position across any configured gauge, plus all claimable rewards (CRV and extra reward tokens). The staked LP is decomposed pro-rata into the pool's underlying coins using the same logic as the Pools adapter. Wallet-held (unstaked) LP is the separate Curve Pools adapter.

  • Type: Meta-adapter

  • protocolSubId: keccak256("curve-gauges")

  • Instance key: the gauge address, widened to bytes32.

  • Source: CurveGaugesMetaBalanceAdapter.sol


Positions returned

Leg
PositionKind
isDebt
Description

Staking

Staking

false

Pro-rata share of one pool coin, from the account's staked LP

Rewards (CRV)

Rewards

false

Claimable CRV (lower-bound estimate); only when CURVE_MINTER is set

Rewards (extra)

Rewards

false

Claimable amount of each extra reward token (V2+ gauges)

Unregistered, zero-amount, and asset-filtered tokens are skipped.


Balance calculation

Flowchart of the Curve Gauges balance adapter: read calls derive position legs into PositionBalance entries.
Curve Gauges adapter — how the underlying balances reported to the NAV Calculator are derived.

Staking legs: with stakedLp = gauge.balanceOf(account), the gauge's lp_token() resolves the pool (CurvePoolLib.getPool: self-LP if it has coins(), else minter(), else Curve's own registry). Each coin amount is:

Legacy StableSwap pools resolve via Curve's registry, and the answer is validated rather than trusted. The two heuristics above both miss the oldest generation — on 3Crv, coins(), coins(int128) and minter() all revert — so the pool is looked up through Curve's AddressProvider → registry. The reply must then answer coins() and round-trip (the registry's LP token for that pool must be the LP token asked about), because a wrong or hostile answer would decompose the position against another pool's balances — an over-report, the one direction this family must never take. Every hop is a bounded, guarded staticcall, so a chain without an AddressProvider degrades to the previous behaviour instead of reverting.

If the pool still cannot be resolved, the adapter reports the staked LP token itself as one leg rather than dropping the principal. Reverting would not help: the meta base absorbs a non-gas revert and substitutes empty legs, producing the same silent zero by another route — so the visibility has to live in the returned data. Only structural failure triggers this; a filtered or unregistered coin does not.

CRV rewards use a view-safe lower bound:

This is stale between checkpoints (deposit / withdraw / claim) and reads 0 for recently-transferred gauge tokens — for an exact value, gauge.claimable_tokens(account) must be called as a state mutation (eth_call). The CRV leg is emitted only when CURVE_MINTER != address(0) (mainnet) and CRV is registered.

Extra rewards come from claimable_reward(account, token) for each reward_tokens(i) up to MAX_COINS = 8 (CRV is skipped here, since it is handled via the Minter). V3+ gauges update these at most hourly, so values may be stale.


Identity

  • positionId: abi.encode(address gauge)

  • positionKind: Staking · Rewards

There is no labels field on the position. The adapter implements positionLabels(positionId), which returns ["Staking Gauge", "TOKEN0/TOKEN1/…"] from the on-chain coin symbols — surfaced only by the verbose reads (getAccountPositionsVerbose / getAccountNavVerbose); the full breadcrumb is [protocolName, ...labels].


Constructor

Parameter
Description

minter_

Curve Minter for CRV emission; pass address(0) to disable CRV tracking (L2 / non-mainnet)

crvToken_

CRV token address; address(0) to skip CRV

navCalculator_

NAVCalculator address (must be a contract); source of the asset registry and the instance set

On L2 chains (Arbitrum, Optimism, Base, Polygon) pass minter_ = address(0); LP decomposition is always attempted regardless of the minter.


Registration

Registered as a meta-adapter via addMetaBalanceAdapter(adapter), then per-gauge instances are added with addMetaInstances. Each instance coordinate is the gauge address widened to bytes32.

Last updated