> For the complete documentation index, see [llms.txt](https://docs.kpk.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.kpk.io/funds/infrastructure/architecture/onchain-accounting/meta-balance-adapters/curve-pools.md).

# Curve Pools

Reports an account's wallet-held (unstaked) Curve LP position across any configured pool, decomposed pro-rata into the pool's underlying coins.

Reports an account's **wallet-held (unstaked)** Curve LP position across any configured pool, decomposed pro-rata into the pool's underlying coins. Gauge-staked LP and rewards are the separate [Curve Gauges](/funds/infrastructure/architecture/onchain-accounting/meta-balance-adapters/curve-gauges.md) adapter.

* **Type:** Meta-adapter
* **protocolSubId:** `keccak256("curve-pools")`
* **Instance key:** the pool address, widened to bytes32.
* **Source:** `CurvePoolsMetaBalanceAdapter.sol`

## Positions returned

One leg per registered pool coin with a non-zero wallet share:

| Leg    | PositionKind | isDebt  | Description                                                   |
| ------ | ------------ | ------- | ------------------------------------------------------------- |
| Supply | `Supplied`   | `false` | Pro-rata share of one pool coin, from the account's wallet LP |

Unregistered, zero-amount, and asset-filtered coins are skipped. For metapools, `coins()` enumerates only the meta-coins; base-pool coins are not recursed into (the base LP token has its own price feed). Lending pools report wrapped-token balances.

## Balance calculation

<figure><picture><source srcset="/files/ezsbK9iXOHQwqOXieRMQ" media="(prefers-color-scheme: dark)"><img src="https://1699303810-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FUsQM4bzcmOPSgkWddkeN%2Fuploads%2FqghJPvz6XBtBsIzspF5e%2Fmeta-curve-pools.png?alt=media&amp;token=9541a3fc-c87a-4375-ac6a-01f3482d5f7d" alt="Flowchart of the Curve Pools balance adapter: read calls derive position legs into PositionBalance entries."></picture><figcaption><p>Curve Pools adapter: how the underlying balances reported to the NAV Calculator are derived.</p></figcaption></figure>

The LP token is resolved from the pool by `CurvePoolLib.getLpToken`, the pool itself for classic StableSwap / TriCryptoNG (self-LP), or a separate ERC20 via `lp_token()` for StableSwap-NG factory / TwoCryptoNG pools.

{% hint style="warning" %}
**Legacy StableSwap pools are not decomposed here, deliberately.** On the oldest generation (3pool, whose LP is the separate 3Crv) `lp_token()` reverts, so resolution falls through to "the pool is its own LP token", which is false for these pools, and `balanceOf` on the pool itself reverts. Wallet-held LP for such a pool therefore reports **nothing**.

Unlike the [gauge](/funds/infrastructure/architecture/onchain-accounting/meta-balance-adapters/curve-gauges.md) and [Convex](/funds/infrastructure/architecture/onchain-accounting/meta-balance-adapters/convex.md) staking paths, this is **not** resolved through Curve's registry, and the gap is intentional. Resolving it would flip this adapter from emitting nothing to emitting full `Supplied` coin legs, which double-counts for any operator who worked around the under-report the obvious way, by registering the LP token as an asset so the [default adapter](/funds/infrastructure/architecture/onchain-accounting/balance-adapters/erc20-default.md) reports it. That would be an over-report, the one direction this family must never take, so the under-report is held until all three consumers can be changed together.
{% endhint %}

With \`walletLp = lpToken.balanceOf(account)\` and \`totalSupply\` (ERC20 \`totalSupply()\`, falling back to the StableSwap-NG \`total\_supply()\` storage variant), each coin amount is:

```
amount[i] = poolBalance[i] * walletLp / totalSupply
```

`poolBalance[i]` is read via `balances(uint256)`, falling back to `balances(int128)` for Vyper 0.1.x pools. Coin enumeration similarly tries `coins(uint256)` then `coins(int128)`, up to `MAX_COINS = 8`.

## Identity

* **positionId:** `abi.encode(address pool)`
* **positionKind:** `Supplied`

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

## Constructor

```solidity
constructor(address navCalculator_)
```

| Parameter        | Description                                                                                   |
| ---------------- | --------------------------------------------------------------------------------------------- |
| `navCalculator_` | NAVCalculator address (must be a contract); source of the asset registry and the instance set |

## Registration

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


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.kpk.io/funds/infrastructure/architecture/onchain-accounting/meta-balance-adapters/curve-pools.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
