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
¶
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 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 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 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
¶
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
¶
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 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 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 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
¶
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
¶
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 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
¶
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
¶
Read the vault's total assets (totalAssets()).
Returns:
| Type | Description |
|---|---|
int
|
Total assets in underlying token units (raw integer). |
get_pending_deposits
¶
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
¶
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 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 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
¶
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
¶
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
¶
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
¶
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
¶
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
¶
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
¶
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 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 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 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 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. |