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.
Last updated
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
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.
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).
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.
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].
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.
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.
Last updated
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 0constructor(address compoundRewards_, address rewardToken_, address navCalculator_)