> 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/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. 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`](https://github.com/karpatkey/onchain-accounting/blob/main/src/balances/MetaBalanceAdapters/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/onchain-accounting/balance-adapters.md#how-an-adapter-is-built).

***

## Balance calculation

<figure><img src="/files/dmAW8rnnpdnQACl6SdrM" alt="Flowchart of the Compound V3 balance adapter: read calls derive position legs into PositionBalance entries."><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 on-chain 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 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/compound-v3.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.
