> 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/compound-v3.md).

# Compound V3

One immutable meta-adapter that reports an account's position in any Compound V3 (Comet) market, base-token supply or borrow, every collateral leg, and unclaimed COMP rewards.

One immutable meta-adapter that reports an account's position in *any* Compound V3 (Comet) market, base-token supply or borrow, every collateral leg, and unclaimed COMP rewards. Which comets it queries is a governed instance set on the NAV Calculator; the adapter holds no per-comet state. Read math is delegated to `CompoundV3CometLib`.

* **Type:** Meta-adapter
* **protocolSubId:** `keccak256("compound-v3-comets")`
* **Instance key:** the comet (market) address, widened to `bytes32`
* **Source:** `CompoundV3CometsMetaBalanceAdapter.sol`

## Positions returned

| Leg         | PositionKind | isDebt  | Description                                          |
| ----------- | ------------ | ------- | ---------------------------------------------------- |
| Base supply | `Supplied`   | `false` | Positive base position, present value                |
| Base borrow | `Borrowed`   | `true`  | Negative base position, present value                |
| Collateral  | `Collateral` | `false` | One leg per collateral asset with a non-zero balance |
| Rewards     | `Rewards`    | `false` | Unclaimed reward token (COMP)                        |

The base leg is supply or borrow depending on the sign of the net base position (never both). Each leg is dropped if its amount is zero, its asset is unregistered, or it is excluded by `assetFilter`. A multi-role asset (e.g. COMP as both collateral and reward) emits one leg per role.

Where the net base position is a **borrow** and the base asset is unregistered, the comet reports **nothing**, collateral and rewards included, rather than emitting credit legs with no offsetting debt. See [Never report collateral without its debt](/funds/infrastructure/architecture/onchain-accounting/balance-adapters.md#how-an-adapter-is-built).

## Balance calculation

<figure><picture><source srcset="/files/wIY0CZhSnKNun9przEEO" media="(prefers-color-scheme: dark)"><img src="https://1699303810-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FUsQM4bzcmOPSgkWddkeN%2Fuploads%2FxART8yonnoGaLfOtpIxd%2Fmeta-compound-v3.png?alt=media&amp;token=2bd9a8a1-28b5-4ca1-b57e-2aa5d97134ee" alt="Flowchart of the Compound V3 balance adapter: read calls derive position legs into PositionBalance entries."></picture><figcaption><p>Compound V3 adapter: how the underlying balances reported to the NAV Calculator are derived.</p></figcaption></figure>

`CompoundV3CometLib.accountData(comet, rewards, rewardToken, account)` returns the net base, collateral balances, and unclaimed reward, accruing interest and reward indices to `block.timestamp` (it re-derives Comet's accrual rather than mutating state).

```
baseNet = userBasic(account).principal * (principal >= 0 ? baseSupplyIndex : baseBorrowIndex) / BASE_INDEX_SCALE
          (indices first advanced by the elapsed-time accrual)
  baseNet > 0 → Supplied, amount =  baseNet
  baseNet < 0 → Borrowed, amount = -baseNet

collateralBalances[i] = comet.collateralBalanceOf(account, asset[i])   // per collateral asset

rewardOwed = accrued − rewardsClaimed(comet, account), floored at 0
```

Reward accrual mirrors Comet's tracking-index math, handling the optional 4th `multiplier`/`rescaleFactor` field returned by some chains' `rewardConfig` (detected via returndata length). The library is a leg-for-leg, fork-tested port of the per-comet adapter.

## Identity

* **positionId:** `abi.encode(address comet)`; the comet address (all legs of a comet share it)
* **positionKind:** `Supplied` · `Borrowed` · `Collateral` · `Rewards`

There is no `labels` field on the position. The adapter implements `positionLabels(positionId)`, which returns `["Market", "<comet symbol()>"]` (e.g. `"cUSDCv3"`) from the comet's onchain symbol; surfaced only by the verbose reads (`getAccountPositionsVerbose` / `getAccountNavVerbose`); the full breadcrumb is `[protocolName, ...labels]`.

## Constructor

```solidity
constructor(address compoundRewards_, address rewardToken_, address navCalculator_)
```

| Parameter          | Description                                                                                |
| ------------------ | ------------------------------------------------------------------------------------------ |
| `compoundRewards_` | The chain's CometRewards contract (shared by every comet on the chain; must be a contract) |
| `rewardToken_`     | The reward token, COMP or its bridged form (must be non-zero)                              |
| `navCalculator_`   | NAV Calculator contract (asset registry + instance set)                                    |

`compoundRewards_` and `rewardToken_` are chain-level constants pinned once here, so they apply across every comet in the instance set.

## Registration

Meta-adapter. Register once and seed its comets with `addMetaBalanceAdapter(adapter, instances)`, then adjust with `addMetaInstances(adapter, instances)` / `removeMetaInstances(adapter, instances)` (MANAGER-gated). Each instance coordinate is a **comet address widened to `bytes32`** (decoded via `_toAddress`). Adding a new comet is a config call, no new deploy.


---

# 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/compound-v3.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.
