Skip to content

Ethena

Connector for Ethena yield protocol (USDe/sUSDe).

almanak.framework.connectors.ethena

Ethena Connector.

This module provides an adapter for interacting with Ethena synthetic dollar protocol.

Ethena is a synthetic dollar protocol supporting: - Stake USDe to receive sUSDe (yield-bearing) - Unstake sUSDe to receive USDe (with cooldown period)

Supported chains: - Ethereum (full staking + unstaking)

sUSDe is an ERC4626 vault token that accrues yield from delta-neutral strategies.

Example

from almanak.framework.connectors.ethena import EthenaAdapter, EthenaConfig

config = EthenaConfig( chain="ethereum", wallet_address="0x...", ) adapter = EthenaAdapter(config)

Stake USDe to receive sUSDe

result = adapter.stake_usde(amount=Decimal("1000.0"))

EthenaAdapter

EthenaAdapter(
    config: EthenaConfig,
    token_resolver: TokenResolver | None = None,
)

Adapter for Ethena synthetic dollar protocol.

This adapter provides methods for interacting with Ethena: - Stake USDe to receive sUSDe (yield-bearing vault token) - Unstake sUSDe to receive USDe (requires cooldown period)

Note: sUSDe is an ERC4626 vault. Unstaking has a cooldown period (typically 7 days) before assets can be withdrawn.

Example

config = EthenaConfig( chain="ethereum", wallet_address="0x...", ) adapter = EthenaAdapter(config)

Stake USDe to get sUSDe

result = adapter.stake_usde(Decimal("1000.0"))

Start cooldown for unstaking

result = adapter.unstake_susde(Decimal("1000.0"))

Initialize the adapter.

Parameters:

Name Type Description Default
config EthenaConfig

Adapter configuration

required
token_resolver TokenResolver | None

Optional TokenResolver instance. If None, uses singleton.

None

approve_usde

approve_usde(amount: Decimal) -> TransactionResult

Build an approval transaction for USDe to sUSDe contract.

This must be called before staking to allow the sUSDe contract to transfer USDe from the user's wallet.

Parameters:

Name Type Description Default
amount Decimal

Amount of USDe to approve

required

Returns:

Type Description
TransactionResult

TransactionResult with approval transaction data

stake_usde

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

Build a stake transaction to deposit USDe and receive sUSDe.

Deposits USDe into the sUSDe ERC4626 vault to receive yield-bearing sUSDe.

Parameters:

Name Type Description Default
amount Decimal

Amount of USDe to stake

required
receiver str | None

Address to receive sUSDe (default: wallet_address)

None

Returns:

Type Description
TransactionResult

TransactionResult with transaction data

unstake_susde

unstake_susde(amount: Decimal) -> TransactionResult

Build a transaction to start cooldown for unstaking sUSDe.

Initiates the cooldown period for unstaking sUSDe. After the cooldown period (typically 7 days), the USDe can be withdrawn.

Parameters:

Name Type Description Default
amount Decimal

Amount of sUSDe assets to unstake (in USDe terms)

required

Returns:

Type Description
TransactionResult

TransactionResult with transaction data

complete_unstake

complete_unstake(
    receiver: str | None = None,
) -> TransactionResult

Build a transaction to complete unstaking after cooldown period.

Completes the unstaking process after the cooldown period (typically 7 days) has elapsed. This withdraws the previously locked USDe to the receiver.

Parameters:

Name Type Description Default
receiver str | None

Address to receive the USDe (default: wallet_address)

None

Returns:

Type Description
TransactionResult

TransactionResult with transaction data

compile_stake_intent

compile_stake_intent(
    intent: StakeIntent, market_snapshot: Any | None = None
) -> ActionBundle

Compile a StakeIntent to an ActionBundle.

This method converts a high-level StakeIntent into executable transaction data. For Ethena, this stakes USDe to receive sUSDe.

Parameters:

Name Type Description Default
intent StakeIntent

The StakeIntent to compile

required
market_snapshot Any | None

Optional market data (not used for Ethena)

None

Returns:

Type Description
ActionBundle

ActionBundle containing transaction(s) for execution

Raises:

Type Description
ValueError

If amount="all" is not resolved before compilation

compile_unstake_intent

compile_unstake_intent(
    intent: UnstakeIntent,
    market_snapshot: Any | None = None,
) -> ActionBundle

Compile an UnstakeIntent to an ActionBundle.

This method converts a high-level UnstakeIntent into executable transaction data. For Ethena, this initiates the cooldown period for unstaking sUSDe.

Note: Ethena unstaking is a two-phase process: 1. Initiate cooldown: Call cooldownAssets() to start the 7-day cooldown 2. Complete unstake: Call unstake() after cooldown expires to receive USDe

This method handles phase 1 (initiate cooldown). Phase 2 requires a separate transaction after the cooldown period has elapsed.

Parameters:

Name Type Description Default
intent UnstakeIntent

The UnstakeIntent to compile

required
market_snapshot Any | None

Optional market data (not used for Ethena)

None

Returns:

Type Description
ActionBundle

ActionBundle containing transaction(s) for execution

Raises:

Type Description
ValueError

If amount="all" is not resolved before compilation

EthenaConfig dataclass

EthenaConfig(chain: str, wallet_address: str)

Configuration for Ethena adapter.

Attributes:

Name Type Description
chain str

Blockchain network (ethereum)

wallet_address str

User wallet address

__post_init__

__post_init__() -> None

Validate configuration.

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

EthenaEventType

Bases: Enum

Ethena event types.

EthenaReceiptParser

EthenaReceiptParser(chain: str = 'ethereum', **kwargs: Any)

Parser for Ethena transaction receipts.

Refactored to use base infrastructure utilities for hex decoding and event registry management.

Initialize the parser.

Parameters:

Name Type Description Default
chain str

Blockchain network (ethereum)

'ethereum'
**kwargs Any

Additional arguments (ignored for compatibility)

{}

parse_receipt

parse_receipt(receipt: dict[str, Any]) -> ParseResult

Parse a transaction receipt.

Parameters:

Name Type Description Default
receipt dict[str, Any]

Transaction receipt dict

required

Returns:

Type Description
ParseResult

ParseResult with extracted events

parse_stake

parse_stake(log: dict[str, Any]) -> StakeEventData | None

Parse a Deposit (stake) event from a single log entry.

parse_withdraw

parse_withdraw(
    log: dict[str, Any],
) -> WithdrawEventData | None

Parse a Withdraw event from a single log entry.

parse_unstake

parse_unstake(
    log: dict[str, Any],
) -> WithdrawEventData | None

Backward compatibility alias for parse_withdraw.

is_ethena_event

is_ethena_event(topic: str | bytes) -> bool

Check if a topic is a known Ethena 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 Ethena event

get_event_type

get_event_type(topic: str | bytes) -> EthenaEventType

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
EthenaEventType

Event type or UNKNOWN

extract_stake_amount

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

Extract stake amount (assets deposited) from transaction receipt.

Parameters:

Name Type Description Default
receipt dict[str, Any]

Transaction receipt dict with 'logs' field

required

Returns:

Type Description
int | None

Stake amount in wei if found, None otherwise

extract_shares_received

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

Extract sUSDe shares received from transaction receipt.

Parameters:

Name Type Description Default
receipt dict[str, Any]

Transaction receipt dict with 'logs' field

required

Returns:

Type Description
int | None

Shares received in wei if found, None otherwise

extract_unstake_amount

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

Extract unstake amount (shares burned) from transaction receipt.

Parameters:

Name Type Description Default
receipt dict[str, Any]

Transaction receipt dict with 'logs' field

required

Returns:

Type Description
int | None

Shares burned in wei if found, None otherwise

extract_underlying_received

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

Extract underlying USDe received from withdrawal.

Parameters:

Name Type Description Default
receipt dict[str, Any]

Transaction receipt dict with 'logs' field

required

Returns:

Type Description
int | None

Assets received in wei if found, None otherwise

ParseResult dataclass

ParseResult(
    success: bool,
    stakes: list[StakeEventData] = list(),
    withdraws: list[WithdrawEventData] = list(),
    error: str | None = None,
    transaction_hash: str = "",
    block_number: int = 0,
)

Result of parsing a receipt.

unstakes property

unstakes: list[WithdrawEventData]

Backward compatibility alias for withdraws.

to_dict

to_dict() -> dict[str, Any]

Convert to dictionary.

StakeEventData dataclass

StakeEventData(
    sender: str,
    owner: str,
    assets: Decimal,
    shares: Decimal,
)

Parsed data from Deposit event (stake operation).

to_dict

to_dict() -> dict[str, Any]

Convert to dictionary.

WithdrawEventData dataclass

WithdrawEventData(
    sender: str,
    receiver: str,
    owner: str,
    assets: Decimal,
    shares: Decimal,
)

Parsed data from Withdraw event (cooldown or final withdrawal).

to_dict

to_dict() -> dict[str, Any]

Convert to dictionary.