> 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/onchain-accounting/meta-balance-adapters/balancer-v3-pools.md).

# Balancer V3 Pools

Reports an account's **wallet-held (unstaked)** Balancer V3 pool liquidity across any pool. It decomposes the account's BPT (pool token) balance pro-rata into the pool's underlying tokens — the AMM-supplied LP only. Gauge-staked LP and rewards are the separate [Balancer V3 Gauges](/funds/infrastructure/onchain-accounting/meta-balance-adapters/balancer-v3-gauges.md) adapter.

* **Type:** Meta-adapter
* **protocolSubId:** `keccak256("balancer-v3-pools")`
* **Instance key:** the pool (BPT) address, widened to bytes32.
* **Source:** [`BalancerV3PoolsMetaBalanceAdapter.sol`](https://github.com/karpatkey/onchain-accounting/blob/main/src/balances/MetaBalanceAdapters/balancer/BalancerV3PoolsMetaBalanceAdapter.sol)

***

## Positions returned

One leg per registered underlying pool token with a non-zero share:

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

Tokens not registered in NAVCalculator are skipped, as are zero-amount and asset-filtered tokens. ERC4626 pool tokens are unwrapped to their `asset()` so the underlying is reported.

***

## Balance calculation

<figure><img src="/files/AMUbOXD7ybMxniqPWkAn" alt="Flowchart of the Balancer V3 Pools balance adapter: read calls derive position legs into PositionBalance entries."><figcaption><p>Balancer V3 Pools adapter — how the underlying balances reported to the NAV Calculator are derived.</p></figcaption></figure>

For BPT balance `walletBpt = pool.balanceOf(account)` (returns nothing if zero), the adapter iterates the pool tokens in index order and computes each one's amount with `BalancerV3PoolLib.poolBalanceOfIndexed(pool, walletBpt, i)`. Keying on the pool-token **index** (rather than resolving by underlying address) ensures every index contributes exactly one leg, so a pool holding the same underlying at two indices (e.g. two distinct ERC4626 wrappers of the same asset) is decomposed correctly rather than double-counting one index and dropping the duplicate:

```
tokenBalance = balancesLiveScaled18[i] * walletBpt / pool.totalSupply()
```

The 18-decimal live-scaled share is then converted back to raw token units:

```
raw = tokenBalance * 1e18 / (decimalScalingFactors[i] * tokenRates[i])
```

A transiently-zero scaling factor or token rate yields a `0` leg (rather than a divide-by-zero that would revert the whole instance). If the pool token is an ERC4626 wrapper, `raw` is treated as wrapped-token shares and unwrapped via `previewRedeem(shares)` to the underlying asset.

***

## 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", "<sym0>/<sym1>/…"]` from the pool's underlying token 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 (BPT) 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 dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

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

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
