Skip to content

Compound V3

Connector for Compound V3 lending protocol.

almanak.framework.connectors.compound_v3

Compound V3 (Comet) Connector.

This module provides adapters and utilities for interacting with Compound V3, a lending protocol with single borrowable assets and multiple collateral options.

Compound V3 Features: - Single borrowable asset (base) per market (USDC, WETH, USDT) - Multiple collateral assets per market - No cTokens for collateral (only base asset is tokenized) - Simplified interest rate model - Efficient liquidation mechanism

Supported Chains: - Ethereum - Arbitrum

Example

from almanak.framework.connectors.compound_v3 import ( CompoundV3Adapter, CompoundV3Config, CompoundV3ReceiptParser, )

Initialize adapter

config = CompoundV3Config( chain="ethereum", wallet_address="0x...", market="usdc", ) adapter = CompoundV3Adapter(config)

Get market info

market_info = adapter.get_market_info() print(f"Market: {market_info.name}")

Build a supply transaction

result = adapter.supply( amount=Decimal("1000"), )

Parse transaction receipts

parser = CompoundV3ReceiptParser() events = parser.parse_receipt(receipt)

CompoundV3Adapter

CompoundV3Adapter(
    config: CompoundV3Config,
    price_oracle: PriceOracle | None = None,
    token_resolver: TokenResolver | None = None,
)

Adapter for Compound V3 (Comet) lending protocol.

This adapter provides methods for interacting with Compound V3: - Supply/withdraw base assets (lending) - Supply/withdraw collateral assets - Borrow/repay base assets - Health factor calculations

Compound V3 uses a single borrowable asset (base) per market with multiple collateral options. Unlike traditional Compound, collateral does not earn interest - only base asset suppliers earn yield.

Example

config = CompoundV3Config( chain="ethereum", wallet_address="0x...", market="usdc", ) adapter = CompoundV3Adapter(config)

Supply base asset to earn interest

result = adapter.supply(amount=Decimal("1000"))

Supply collateral for borrowing

result = adapter.supply_collateral(asset="WETH", amount=Decimal("1.0"))

Borrow against collateral

result = adapter.borrow(amount=Decimal("500"))

Initialize the adapter.

Parameters:

Name Type Description Default
config CompoundV3Config

Adapter configuration

required
price_oracle PriceOracle | None

Optional price oracle callback

None
token_resolver TokenResolver | None

Optional TokenResolver instance (defaults to singleton)

None

supply

supply(
    amount: Decimal, on_behalf_of: str | None = None
) -> TransactionResult

Build a supply transaction for the base asset.

Supplies the base asset (e.g., USDC) to earn interest.

Parameters:

Name Type Description Default
amount Decimal

Amount of base token to supply

required
on_behalf_of str | None

Address to credit (defaults to wallet_address)

None

Returns:

Type Description
TransactionResult

TransactionResult with transaction data

withdraw

withdraw(
    amount: Decimal,
    receiver: str | None = None,
    withdraw_all: bool = False,
) -> TransactionResult

Build a withdraw transaction for the base asset.

Withdraws supplied base asset from the market.

Parameters:

Name Type Description Default
amount Decimal

Amount of base token to withdraw

required
receiver str | None

Address to receive tokens (defaults to wallet_address)

None
withdraw_all bool

If True, withdraws all supplied base asset

False

Returns:

Type Description
TransactionResult

TransactionResult with transaction data

supply_collateral

supply_collateral(
    asset: str,
    amount: Decimal,
    on_behalf_of: str | None = None,
) -> TransactionResult

Build a supply collateral transaction.

Supplies collateral to enable borrowing.

Parameters:

Name Type Description Default
asset str

Collateral asset symbol (e.g., "WETH")

required
amount Decimal

Amount of collateral to supply

required
on_behalf_of str | None

Address to credit (defaults to wallet_address)

None

Returns:

Type Description
TransactionResult

TransactionResult with transaction data

withdraw_collateral

withdraw_collateral(
    asset: str,
    amount: Decimal,
    receiver: str | None = None,
    withdraw_all: bool = False,
) -> TransactionResult

Build a withdraw collateral transaction.

Withdraws collateral from the market.

Parameters:

Name Type Description Default
asset str

Collateral asset symbol (e.g., "WETH")

required
amount Decimal

Amount of collateral to withdraw

required
receiver str | None

Address to receive tokens (defaults to wallet_address)

None
withdraw_all bool

If True, withdraws all collateral for this asset

False

Returns:

Type Description
TransactionResult

TransactionResult with transaction data

borrow

borrow(
    amount: Decimal, receiver: str | None = None
) -> TransactionResult

Build a borrow transaction.

Borrows the base asset against supplied collateral.

Parameters:

Name Type Description Default
amount Decimal

Amount of base token to borrow

required
receiver str | None

Address to receive borrowed tokens (defaults to wallet_address)

None

Returns:

Type Description
TransactionResult

TransactionResult with transaction data

repay

repay(
    amount: Decimal,
    on_behalf_of: str | None = None,
    repay_all: bool = False,
) -> TransactionResult

Build a repay transaction.

Repays borrowed base asset.

Parameters:

Name Type Description Default
amount Decimal

Amount of base token to repay

required
on_behalf_of str | None

Address with debt (defaults to wallet_address)

None
repay_all bool

If True, repays full debt

False

Returns:

Type Description
TransactionResult

TransactionResult with transaction data

get_market_info

get_market_info() -> CompoundV3MarketInfo

Get information about the current market.

Returns:

Type Description
CompoundV3MarketInfo

CompoundV3MarketInfo with market details

get_supported_collaterals

get_supported_collaterals() -> list[str]

Get list of supported collateral assets for the current market.

Returns:

Type Description
list[str]

List of collateral asset symbols

get_collateral_info

get_collateral_info(asset: str) -> dict[str, Any] | None

Get information about a collateral asset.

Parameters:

Name Type Description Default
asset str

Collateral asset symbol

required

Returns:

Type Description
dict[str, Any] | None

Collateral info dictionary or None if not supported

calculate_health_factor

calculate_health_factor(
    collateral_balances: dict[str, Decimal],
    borrow_balance: Decimal,
) -> CompoundV3HealthFactor

Calculate health factor for a position.

Parameters:

Name Type Description Default
collateral_balances dict[str, Decimal]

Dictionary of collateral asset balances

required
borrow_balance Decimal

Amount of borrowed base asset

required

Returns:

Type Description
CompoundV3HealthFactor

CompoundV3HealthFactor with health calculation

build_approve_transaction

build_approve_transaction(
    token: str, amount: Decimal | None = None
) -> TransactionResult

Build an ERC20 approval transaction for the Comet contract.

Parameters:

Name Type Description Default
token str

Token symbol to approve

required
amount Decimal | None

Amount to approve (None for max approval)

None

Returns:

Type Description
TransactionResult

TransactionResult with transaction data

CompoundV3Config dataclass

CompoundV3Config(
    chain: str,
    wallet_address: str,
    market: str = "usdc",
    default_slippage_bps: int = 50,
)

Configuration for Compound V3 adapter.

Attributes:

Name Type Description
chain str

Blockchain network (ethereum, arbitrum)

wallet_address str

User wallet address

market str

Market identifier (usdc, weth, usdt, etc.)

default_slippage_bps int

Default slippage tolerance in basis points

__post_init__

__post_init__() -> None

Validate configuration.

CompoundV3HealthFactor dataclass

CompoundV3HealthFactor(
    collateral_value_usd: Decimal,
    borrow_value_usd: Decimal,
    borrow_capacity_usd: Decimal,
    liquidation_threshold_usd: Decimal,
    health_factor: Decimal,
    is_liquidatable: bool = False,
)

Health factor calculation for a Compound V3 position.

Attributes:

Name Type Description
collateral_value_usd Decimal

Total value of collateral in USD

borrow_value_usd Decimal

Total value of borrowed assets in USD

borrow_capacity_usd Decimal

Maximum borrowable amount based on collateral

liquidation_threshold_usd Decimal

USD debt level at which liquidation occurs

health_factor Decimal

Calculated health factor (liquidation_threshold / borrow)

is_liquidatable bool

Whether the position can be liquidated

is_healthy property

is_healthy: bool

Check if position is healthy (HF >= 1).

available_borrow_usd property

available_borrow_usd: Decimal

Get remaining borrowable amount in USD.

to_dict

to_dict() -> dict[str, Any]

Convert to dictionary.

CompoundV3MarketInfo dataclass

CompoundV3MarketInfo(
    market_id: str,
    name: str,
    base_token: str,
    base_token_address: str,
    comet_address: str,
    collaterals: dict[str, dict[str, Any]],
)

Information about a Compound V3 market.

Attributes:

Name Type Description
market_id str

Market identifier (e.g., "usdc")

name str

Human-readable market name

base_token str

Symbol of the base token (borrowable asset)

base_token_address str

Address of the base token

comet_address str

Address of the Comet contract

collaterals dict[str, dict[str, Any]]

Dictionary of supported collateral assets

to_dict

to_dict() -> dict[str, Any]

Convert to dictionary.

CompoundV3Position dataclass

CompoundV3Position(
    market_id: str,
    base_balance: Decimal = Decimal("0"),
    collateral_balances: dict[str, Decimal] = dict(),
)

User position in a Compound V3 market.

Attributes:

Name Type Description
market_id str

Market identifier

base_balance Decimal

Balance of base token (positive = supply, negative = borrow)

collateral_balances dict[str, Decimal]

Balances of collateral tokens

is_supplier property

is_supplier: bool

Check if user is a net supplier.

is_borrower property

is_borrower: bool

Check if user is a net borrower.

borrow_balance property

borrow_balance: Decimal

Get the borrow balance (positive value).

supply_balance property

supply_balance: Decimal

Get the supply balance.

has_collateral property

has_collateral: bool

Check if user has any collateral.

to_dict

to_dict() -> dict[str, Any]

Convert to dictionary.

TransactionResult dataclass

TransactionResult(
    success: bool,
    tx_data: dict[str, Any] | None = None,
    gas_estimate: int = 0,
    description: str = "",
    error: str | None = None,
)

Result of a transaction build operation.

Attributes:

Name Type Description
success bool

Whether operation succeeded

tx_data dict[str, Any] | None

Transaction data (to, value, data)

gas_estimate int

Estimated gas

description str

Human-readable description

error str | None

Error message if failed

to_dict

to_dict() -> dict[str, Any]

Convert to dictionary.

CompoundV3Event dataclass

CompoundV3Event(
    event_type: CompoundV3EventType,
    event_name: str,
    log_index: int,
    transaction_hash: str,
    block_number: int,
    contract_address: str,
    data: dict[str, Any],
    raw_topics: list[str] = list(),
    raw_data: str = "",
    timestamp: datetime = (lambda: datetime.now(tz=None))(),
)

Parsed Compound V3 event.

to_dict

to_dict() -> dict[str, Any]

Convert to dictionary.

from_dict classmethod

from_dict(data: dict[str, Any]) -> CompoundV3Event

Create from dictionary.

CompoundV3EventType

Bases: Enum

Compound V3 event types.

CompoundV3ReceiptParser

CompoundV3ReceiptParser(
    base_decimals: int = 6, **kwargs: Any
)

Parser for Compound V3 transaction receipts.

Refactored to use base infrastructure utilities for hex decoding and event registry management. Maintains all event parsing and aggregation logic.

Initialize the parser.

Parameters:

Name Type Description Default
base_decimals int

Decimals for the base token (default 6 for USDC)

6
**kwargs Any

Additional arguments (ignored for compatibility)

{}

parse_receipt

parse_receipt(
    receipt: dict[str, Any],
    comet_address: str | None = None,
) -> ParseResult

Parse a transaction receipt.

Parameters:

Name Type Description Default
receipt dict[str, Any]

Transaction receipt dictionary

required
comet_address str | None

Optional Comet contract address to filter events

None

Returns:

Type Description
ParseResult

ParseResult with parsed events and aggregated data

parse_logs

parse_logs(
    logs: list[dict[str, Any]],
    tx_hash: str = "",
    block_number: int = 0,
) -> list[CompoundV3Event]

Parse a list of logs.

is_compound_v3_event

is_compound_v3_event(topic: str | bytes) -> bool

Check if a topic is a known Compound V3 event.

Parameters:

Name Type Description Default
topic str | bytes

Event topic (supports bytes, hex string with/without 0x, any case)

required

Returns:

Type Description
bool

True if topic is a known Compound V3 event

get_event_type

get_event_type(topic: str | bytes) -> CompoundV3EventType

Get the event type for a topic.

Parameters:

Name Type Description Default
topic str | bytes

Event topic (supports bytes, hex string with/without 0x, any case)

required

Returns:

Type Description
CompoundV3EventType

Event type enum or UNKNOWN if not recognized

extract_supply_amount

extract_supply_amount(
    receipt: dict[str, Any],
) -> int | None

Extract supply amount from transaction receipt.

In Compound V3, supplying the base asset increases lending position and can also repay borrowed debt.

Parameters:

Name Type Description Default
receipt dict[str, Any]

Transaction receipt dict with 'logs' field

required

Returns:

Type Description
int | None

Supply amount in token units if found, None otherwise

extract_withdraw_amount

extract_withdraw_amount(
    receipt: dict[str, Any],
) -> int | None

Extract withdraw amount from transaction receipt.

In Compound V3, withdrawing the base asset decreases lending position and can create a borrow if withdrawn amount exceeds supplied amount.

Parameters:

Name Type Description Default
receipt dict[str, Any]

Transaction receipt dict with 'logs' field

required

Returns:

Type Description
int | None

Withdraw amount in token units if found, None otherwise

extract_borrow_amount

extract_borrow_amount(
    receipt: dict[str, Any],
) -> int | None

Extract borrow amount from transaction receipt.

In Compound V3, borrowing is done via the Withdraw event when the user withdraws more than their supplied balance. This method returns the withdraw amount which represents the borrowed amount in that case.

Parameters:

Name Type Description Default
receipt dict[str, Any]

Transaction receipt dict with 'logs' field

required

Returns:

Type Description
int | None

Borrow (withdraw) amount in token units if found, None otherwise

extract_repay_amount

extract_repay_amount(receipt: dict[str, Any]) -> int | None

Extract repay amount from transaction receipt.

In Compound V3, repaying is done via the Supply event when the user has outstanding debt. This method returns the supply amount which represents the repaid amount in that case.

Parameters:

Name Type Description Default
receipt dict[str, Any]

Transaction receipt dict with 'logs' field

required

Returns:

Type Description
int | None

Repay (supply) amount in token units if found, None otherwise

ParseResult dataclass

ParseResult(
    success: bool,
    events: list[CompoundV3Event] = list(),
    supply_amount: Decimal = Decimal("0"),
    withdraw_amount: Decimal = Decimal("0"),
    collateral_supplied: dict[str, Decimal] = dict(),
    collateral_withdrawn: dict[str, Decimal] = dict(),
    error: str | None = None,
)

Result of parsing a transaction receipt.

to_dict

to_dict() -> dict[str, Any]

Convert to dictionary.