跳转至

Lagoon

Connector for Lagoon protocol.

almanak.framework.connectors.lagoon

Lagoon Vault Connector.

This module provides a low-level SDK and adapter for interacting with Lagoon vault contracts (ERC-7540) through the gateway's RPC service.

Supported operations: - Read vault state (total assets, pending deposits/redemptions, share price) - Read storage slots (proposed total assets, silo address) - Verify vault contract version - Build ActionBundles for vault write operations (propose, settle) - Deploy new Lagoon vaults via factory contracts

Example

from almanak.framework.connectors.lagoon import LagoonVaultSDK, LagoonVaultAdapter

sdk = LagoonVaultSDK(gateway_client, chain="ethereum") adapter = LagoonVaultAdapter(sdk)

from almanak.framework.connectors.lagoon import LagoonVaultDeployer, VaultDeployParams

deployer = LagoonVaultDeployer()

LagoonVaultAdapter

LagoonVaultAdapter(
    sdk: LagoonVaultSDK, token_resolver=None
)

Adapter that converts vault params into ActionBundles.

The adapter builds ActionBundles from vault operation params using the LagoonVaultSDK to construct unsigned transactions. It does NOT execute transactions -- the VaultLifecycleManager passes bundles to the ExecutionOrchestrator for execution.

Parameters:

Name Type Description Default
sdk LagoonVaultSDK

A LagoonVaultSDK instance for building transactions.

required

build_propose_valuation_bundle

build_propose_valuation_bundle(
    params: UpdateTotalAssetsParams,
) -> ActionBundle

Build an ActionBundle for proposing a new vault valuation.

Parameters:

Name Type Description Default
params UpdateTotalAssetsParams

Parameters containing vault address, valuator address, and the proposed total assets value.

required

Returns:

Type Description
ActionBundle

ActionBundle with a single propose transaction.

build_settle_deposit_bundle

build_settle_deposit_bundle(
    params: SettleDepositParams,
) -> ActionBundle

Build an ActionBundle for settling pending deposits.

Parameters:

Name Type Description Default
params SettleDepositParams

Parameters containing vault address, safe address, and the total assets value for settlement.

required

Returns:

Type Description
ActionBundle

ActionBundle with a single settle deposit transaction.

build_settle_redeem_bundle

build_settle_redeem_bundle(
    params: SettleRedeemParams,
) -> ActionBundle

Build an ActionBundle for settling pending redemptions.

Parameters:

Name Type Description Default
params SettleRedeemParams

Parameters containing vault address, safe address, and the total assets value for settlement.

required

Returns:

Type Description
ActionBundle

ActionBundle with a single settle redeem transaction.

LagoonVaultDeployer

LagoonVaultDeployer(gateway_client=None)

Deploys new Lagoon vaults via factory contracts.

Uses the Lagoon OptinProxyFactory with proper ABI-encoded calldata. The factory function signature is: createVaultProxy(address logic, address owner, uint256 delay, InitStruct init, bytes32 salt)

Where InitStruct is

(address underlying, string name, string symbol, address admin, address safe, address feeReceiver, address valuationManager, address whitelistManager, uint16 managementRate, uint16 performanceRate, bool enableWhitelist, uint256 rateUpdateCooldown)

Parameters:

Name Type Description Default
gateway_client

Gateway client for RPC calls (needed to read vault logic from registry).

None

get_factory_address staticmethod

get_factory_address(chain: str) -> str

Look up the factory address for a chain.

Returns:

Type Description
str

Factory contract address.

Raises:

Type Description
ValueError

If chain has no known factory.

build_deploy_vault_tx

build_deploy_vault_tx(
    params: VaultDeployParams,
) -> dict[str, Any]

Build an unsigned transaction to deploy a new vault proxy.

Uses eth_abi for proper ABI encoding of the createVaultProxy call.

Parameters:

Name Type Description Default
params VaultDeployParams

Vault deployment parameters.

required

Returns:

Type Description
dict[str, Any]

Unsigned transaction dict with keys: to, from, data, value, gas_estimate.

Raises:

Type Description
ValueError

If chain is unsupported or parameters are invalid.

build_deploy_vault_bundle

build_deploy_vault_bundle(
    params: VaultDeployParams,
) -> ActionBundle

Build an ActionBundle for vault deployment.

Parameters:

Name Type Description Default
params VaultDeployParams

Vault deployment parameters.

required

Returns:

Type Description
ActionBundle

ActionBundle wrapping the deploy transaction.

parse_deploy_receipt staticmethod

parse_deploy_receipt(
    receipt: dict[str, Any],
) -> VaultDeployResult

Parse a deployment transaction receipt to extract the vault address.

Looks for ProxyDeployed event in logs. The vault address is in the event data (first 32 bytes), not in topics.

Parameters:

Name Type Description Default
receipt dict[str, Any]

Transaction receipt dict with 'logs', 'transactionHash', 'status'.

required

Returns:

Type Description
VaultDeployResult

VaultDeployResult with extracted vault address.

build_approve_underlying_tx staticmethod

build_approve_underlying_tx(
    underlying_token_address: str,
    vault_address: str,
    safe_address: str,
    *,
    approval_amount: int | None = None,
) -> dict[str, Any]

Build an ERC20 approve transaction for the Safe to allow vault redemptions.

Post-deployment: the Safe calls underlying.approve(vault, amount) so the vault can pull tokens during redemption settlement.

Security rationale for MAX_UINT256 default: This is the standard ERC-4626 vault approval pattern. The vault contract is the trust boundary -- if it is compromised, the approval amount is moot because the vault already has custody of deposited funds. A scoped approval would require re-approving before every settlement cycle, adding gas cost and operational complexity with no meaningful security improvement. Callers who want a tighter bound can pass approval_amount to cap the approval.

Parameters:

Name Type Description Default
underlying_token_address str

The ERC20 token the vault manages.

required
vault_address str

The newly deployed vault address (spender).

required
safe_address str

The Safe wallet address (token holder / tx sender).

required
approval_amount int | None

Optional cap on the approval amount. Defaults to MAX_UINT256 (standard ERC-4626 pattern).

None

Returns:

Type Description
dict[str, Any]

Unsigned transaction dict.

build_post_deploy_bundle staticmethod

build_post_deploy_bundle(
    underlying_token_address: str,
    vault_address: str,
    safe_address: str,
) -> ActionBundle

Build an ActionBundle for post-deployment approval.

Parameters:

Name Type Description Default
underlying_token_address str

The ERC20 token the vault manages.

required
vault_address str

The newly deployed vault address.

required
safe_address str

The Safe wallet address.

required

Returns:

Type Description
ActionBundle

ActionBundle wrapping the approve transaction.

get_default_logic

get_default_logic(
    chain: str, factory_address: str | None = None
) -> str

Read the default vault logic address from the factory's registry.

Calls registry() on the factory, then defaultLogic() on the registry.

Parameters:

Name Type Description Default
chain str

Chain identifier.

required
factory_address str | None

Override factory address (uses chain default if None).

None

Returns:

Type Description
str

Default vault implementation address.

Raises:

Type Description
RuntimeError

If gateway client is not configured or RPC call fails.

VaultDeployParams dataclass

VaultDeployParams(
    chain: str,
    underlying_token_address: str,
    name: str,
    symbol: str,
    safe_address: str,
    admin_address: str,
    fee_receiver_address: str,
    deployer_address: str,
    logic_address: str | None = None,
    valuation_manager_address: str | None = None,
    whitelist_manager_address: str | None = None,
    management_rate_bps: int = 200,
    performance_rate_bps: int = 2000,
    enable_whitelist: bool = False,
    rate_update_cooldown: int = 86400,
    deploy_delay: int = 86400,
    salt: bytes | None = None,
)

Parameters for deploying a new Lagoon vault.

VaultDeployResult dataclass

VaultDeployResult(
    success: bool,
    vault_address: str | None = None,
    transaction_hash: str | None = None,
    error: str | None = None,
)

Result of parsing a vault deployment receipt.

LagoonReceiptParser

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

Parser for Lagoon vault transaction receipts.

Handles three vault settlement event types: - SettleDeposit: deposit settlement with epoch, assets, and shares data - SettleRedeem: redemption settlement with epoch, assets, and shares data - NewTotalAssets: valuation update with new total assets value

parse_receipt

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

Parse a transaction receipt for Lagoon vault events.

Parameters:

Name Type Description Default
receipt dict[str, Any]

Transaction receipt dict with 'logs', 'transactionHash', etc.

required

Returns:

Type Description
LagoonParseResult

LagoonParseResult with extracted events

parse_event

parse_event(
    log: dict[str, Any],
) -> (
    SettleDepositEventData
    | SettleRedeemEventData
    | NewTotalAssetsEventData
    | None
)

Parse a single log entry for Lagoon vault events.

LagoonVaultSDK

LagoonVaultSDK(gateway_client, chain: str)

Low-level SDK for reading Lagoon vault state via gateway RPC calls.

All RPC calls are routed through the gateway client's RPC service. This SDK handles ABI encoding/decoding and provides typed return values.

Parameters:

Name Type Description Default
gateway_client

Connected gateway client with RPC service

required
chain str

Chain identifier (e.g., "ethereum", "base")

required

get_total_assets

get_total_assets(vault_address: str) -> int

Read the vault's total assets (totalAssets()).

Returns:

Type Description
int

Total assets in underlying token units (raw integer).

get_pending_deposits

get_pending_deposits(
    vault_address: str, request_id_num: int = 0
) -> int

Read pending deposit requests for the vault.

Uses ERC-7540 pendingDepositRequest(uint256,address) with requestId=0 and the vault address as the controller.

Returns:

Type Description
int

Pending deposits in underlying token units (raw integer).

get_pending_redemptions

get_pending_redemptions(
    vault_address: str, request_id_num: int = 0
) -> int

Read pending redemption requests for the vault.

Uses ERC-7540 pendingRedeemRequest(uint256,address) with requestId=0 and the vault address as the controller.

Returns:

Type Description
int

Pending redemptions in share units (raw integer).

get_share_price

get_share_price(vault_address: str) -> Decimal

Get the current share price by converting 1 share to assets.

Uses convertToAssets(1e18) to get the value of one full share in underlying token units.

Returns:

Type Description
Decimal

Share price as a Decimal (assets per share, normalized to 18 decimals).

convert_to_assets

convert_to_assets(vault_address: str, shares: int) -> int

Convert a share amount to underlying asset units via on-chain call.

Uses the ERC-4626 convertToAssets(uint256) function directly with the given share amount, avoiding precision loss from intermediate division.

Parameters:

Name Type Description Default
vault_address str

Vault contract address.

required
shares int

Share amount in raw units (18 decimals).

required

Returns:

Type Description
int

Equivalent underlying asset amount in raw units (underlying decimals).

get_underlying_balance

get_underlying_balance(
    vault_address: str, wallet_address: str
) -> int

Read the underlying token balance of a wallet in the vault context.

Uses balanceOf(address) on the vault to read share balance, then could be converted to underlying. Returns raw share balance.

Returns:

Type Description
int

Share balance (raw integer).

get_proposed_total_assets

get_proposed_total_assets(vault_address: str) -> int

Read the proposed total assets via direct storage slot read.

This value is set during the propose phase of settlement and represents the valuator's proposed total asset value.

Returns:

Type Description
int

Proposed total assets in underlying token units (raw integer).

get_silo_address

get_silo_address(vault_address: str) -> str

Read the silo contract address via direct storage slot read.

The silo is a helper contract that holds deposited assets during the settlement process.

Returns:

Type Description
str

Silo contract address as a checksummed hex string.

get_underlying_token_address

get_underlying_token_address(vault_address: str) -> str

Read the vault's underlying token address (ERC-4626 asset()).

Returns:

Type Description
str

Underlying token contract address as a hex string.

get_roles_storage

get_roles_storage(vault_address: str) -> dict

Read the vault's RolesStorage via getRolesStorage().

Returns a dict with the vault's role addresses, matching Lagoon v0.5.0: whitelistManager, feeReceiver, safe, feeRegistry, valuationManager

Returns:

Type Description
dict

Dict with keys: whitelistManager, feeReceiver, safe, feeRegistry, valuationManager.

get_valuation_manager

get_valuation_manager(vault_address: str) -> str

Read the vault's valuation manager address.

Convenience method that calls getRolesStorage() and extracts the valuationManager. This is the address authorized to call updateNewTotalAssets().

Returns:

Type Description
str

Valuation manager address as a hex string.

get_curator

get_curator(vault_address: str) -> str

Read the vault's curator (Safe) address.

Convenience method that calls getRolesStorage() and extracts the Safe address. This is the address that owns the vault and can call settleDeposit/settleRedeem.

Returns:

Type Description
str

Curator (Safe) address as a hex string.

verify_version

verify_version(
    vault_address: str, expected_version: VaultVersion
) -> None

Verify the on-chain vault version matches the expected version.

Reads the version() string from the vault contract and compares it to the expected VaultVersion. Raises ValueError on mismatch.

Parameters:

Name Type Description Default
vault_address str

The vault contract address.

required
expected_version VaultVersion

The expected VaultVersion enum value.

required

Raises:

Type Description
ValueError

If the on-chain version does not match.

build_update_total_assets_tx

build_update_total_assets_tx(
    vault_address: str,
    valuator_address: str,
    new_total_assets: int,
) -> dict

Build an unsigned transaction for updateNewTotalAssets(uint256).

This is called by the valuator to propose a new total asset valuation during the settlement process.

Parameters:

Name Type Description Default
vault_address str

The vault contract address.

required
valuator_address str

The valuator's address (tx sender).

required
new_total_assets int

The proposed total assets in underlying token units.

required

Returns:

Type Description
dict

Unsigned transaction dict with keys: to, from, data, value, gas_estimate.

build_settle_deposit_tx

build_settle_deposit_tx(
    vault_address: str, safe_address: str, total_assets: int
) -> dict

Build an unsigned transaction for settleDeposit(uint256).

This is called by the safe (vault owner) to settle pending deposits after the valuator has proposed a new total asset value.

Parameters:

Name Type Description Default
vault_address str

The vault contract address.

required
safe_address str

The safe wallet address (tx sender).

required
total_assets int

The total assets value for settlement.

required

Returns:

Type Description
dict

Unsigned transaction dict with keys: to, from, data, value, gas_estimate.

build_settle_redeem_tx

build_settle_redeem_tx(
    vault_address: str, safe_address: str, total_assets: int
) -> dict

Build an unsigned transaction for settleRedeem(uint256).

This is called by the safe (vault owner) to settle pending redemptions after deposits have been settled.

Parameters:

Name Type Description Default
vault_address str

The vault contract address.

required
safe_address str

The safe wallet address (tx sender).

required
total_assets int

The total assets value for settlement.

required

Returns:

Type Description
dict

Unsigned transaction dict with keys: to, from, data, value, gas_estimate.

build_approve_deposit_tx

build_approve_deposit_tx(
    underlying_token: str,
    vault_address: str,
    depositor: str,
    amount: int,
) -> dict

Build an ERC20 approve tx so the vault can pull underlying tokens.

The depositor must approve the vault to spend amount of the underlying token before calling requestDeposit.

Parameters:

Name Type Description Default
underlying_token str

Address of the underlying ERC20 token.

required
vault_address str

The vault contract address (spender).

required
depositor str

The depositor address (tx sender / token owner).

required
amount int

Amount in raw underlying units to approve.

required

Returns:

Type Description
dict

Unsigned transaction dict.

build_request_deposit_tx

build_request_deposit_tx(
    vault_address: str, depositor: str, amount: int
) -> dict

Build an ERC-7540 requestDeposit(uint256,address,address) tx.

Calls vault.requestDeposit(assets, controller=depositor, owner=depositor). The depositor must have approved the vault for amount of underlying first.

Parameters:

Name Type Description Default
vault_address str

The vault contract address.

required
depositor str

The depositor address (controller and owner).

required
amount int

Amount of underlying tokens to deposit (raw units).

required

Returns:

Type Description
dict

Unsigned transaction dict.