keeper

package
v1.0.0-beta1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 22, 2025 License: Apache-2.0 Imports: 24 Imported by: 1

Documentation

Index

Constants

View Source
const (
	Supply          = 0
	NoFixedSupply   = false
	NoForceTransfer = false
	NoGovControl    = false
)
View Source
const (
	// AutoReconcilePayoutDuration is the time period (in seconds) used to forecast if a vault has
	// sufficient funds to cover future interest payments.
	AutoReconcilePayoutDuration = 24 * interest.SecondsPerHour
)
View Source
const (
	// AutoReconcileTimeout is the duration (in seconds) that a vault is considered
	// recently reconciled and is exempt from automatic interest checks.
	AutoReconcileTimeout = 20 * interest.SecondsPerHour
)

Variables

This section is empty.

Functions

func NewMsgServer

func NewMsgServer(keeper *Keeper) types.MsgServer

NewMsgServer creates a new MsgServer for the module.

func NewQueryServer

func NewQueryServer(keeper *Keeper) types.QueryServer

Types

type Keeper

type Keeper struct {
	AuthKeeper   types.AccountKeeper
	MarkerKeeper types.MarkerKeeper
	BankKeeper   types.BankKeeper

	Vaults                collections.Map[sdk.AccAddress, []byte]
	PayoutVerificationSet collections.KeySet[sdk.AccAddress]
	PayoutTimeoutQueue    *queue.PayoutTimeoutQueue
	PendingSwapOutQueue   *queue.PendingSwapOutQueue
	// contains filtered or unexported fields
}

func NewKeeper

func NewKeeper(
	cdc codec.Codec,
	storeService store.KVStoreService,
	eventService event.Service,
	addressCodec address.Codec,
	authority []byte,
	authKeeper types.AccountKeeper,
	markerkeeper types.MarkerKeeper,
	bankkeeper types.BankKeeper,
) *Keeper

NewMsgServer creates a new Keeper for the module.

func (*Keeper) BeginBlocker

func (k *Keeper) BeginBlocker(ctx context.Context) error

BeginBlocker is a hook that is called at the beginning of every block.

func (Keeper) CalculateVaultTotalAssets

func (k Keeper) CalculateVaultTotalAssets(ctx sdk.Context, vault *types.VaultAccount, principal sdk.Coin) (sdkmath.Int, error)

CalculateVaultTotalAssets returns the total value of the vault's assets, including the interest that would have accrued from PeriodStart to the current block time, without mutating state.

If no rate is set or accrual has not started, it returns the provided principal unchanged.

func (*Keeper) CanPayoutDuration

func (k *Keeper) CanPayoutDuration(ctx sdk.Context, vault *types.VaultAccount, duration int64) (bool, error)

CanPayoutDuration determines whether the vault can fulfill the interest payment or refund over the given duration based on current reserves and principal.

It returns true when duration <= 0, when accrued interest is zero, when positive interest can be paid from reserves, or when negative interest can be refunded from nonzero principal. Otherwise it returns false.

func (Keeper) ConvertDepositToSharesInUnderlyingAsset

func (k Keeper) ConvertDepositToSharesInUnderlyingAsset(ctx sdk.Context, vault types.VaultAccount, in sdk.Coin) (sdk.Coin, error)

ConvertSharesToRedeemCoin converts a share amount into a payout coin in redeemDenom using the current TVV and total share supply (pro-rata, single-floor arithmetic).

Steps:

  1. Look up the unit price fraction for redeemDenom → underlying via UnitPriceFraction.
  2. Compute the payout in one step using CalculateRedeemProRataFraction(shares, totalShares, TVV, priceNum, priceDen) where TVV is from principal (marker) balances.

Returns a coin in redeemDenom. This function performs calculation only; callers must enforce liquidity/policy. If shares <= 0, returns a zero-amount coin.

func (Keeper) ConvertSharesToRedeemCoin

func (k Keeper) ConvertSharesToRedeemCoin(ctx sdk.Context, vault types.VaultAccount, shares math.Int, redeemDenom string) (sdk.Coin, error)

ConvertSharesToRedeemCoin converts a share amount into a payout coin in redeemDenom using the current TVV and total share supply (both pro-rata, floor arithmetic).

Steps:

  1. Convert shares → underlying via CalculateAssetsFromShares(shares, totalShares, TVV) where TVV is from principal (marker) balances.
  2. Convert the resulting underlying amount to redeemDenom via FromUnderlyingAssetAmount (identity fast-path if redeemDenom == vault.UnderlyingAsset).

Returns a coin in redeemDenom. This function performs calculation only; callers must enforce liquidity/policy. If shares <= 0, returns a zero-amount coin.

func (*Keeper) CreateVault

func (k *Keeper) CreateVault(ctx sdk.Context, attributes VaultAttributer) (*types.VaultAccount, error)

CreateVault creates the vault based on the provided attributes.

func (*Keeper) EndBlocker

func (k *Keeper) EndBlocker(ctx context.Context) error

EndBlocker is a hook that is called at the end of every block.

func (Keeper) ExportGenesis

func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState

ExportGenesis exports the current state of the vault module.

func (*Keeper) FindVaultAccount

func (k *Keeper) FindVaultAccount(ctx sdk.Context, id string) (*types.VaultAccount, error)

FindVault retrieves a vault by its address or share denomination.

func (Keeper) GetAuthority

func (k Keeper) GetAuthority() []byte

GetAuthority returns the module's authority.

func (Keeper) GetNAVPerShareInUnderlyingAsset

func (k Keeper) GetNAVPerShareInUnderlyingAsset(ctx sdk.Context, vault types.VaultAccount) (math.Int, error)

GetNAVPerShareInUnderlyingAsset returns the floor NAV-per-share in units of vault.UnderlyingAsset.

Paused fast-path:

  • If vault.Paused is true, this function short-circuits and returns vault.PausedBalance.Amount (ignores live TVV and share supply).

Computation (when not paused):

  • TVV(underlying) is obtained from GetTVVInUnderlyingAsset (principal/marker balances only).
  • totalShareSupply is fetched from BankKeeper.GetSupply(vault.ShareDenom) (the live supply).
  • If total shares == 0, returns 0. Otherwise returns TVV / totalShareSupply (floor).

func (Keeper) GetTVVInUnderlyingAsset

func (k Keeper) GetTVVInUnderlyingAsset(ctx sdk.Context, vault types.VaultAccount) (math.Int, error)

GetTVVInUnderlyingAsset returns the Total Vault Value (TVV) expressed in vault.UnderlyingAsset using floor arithmetic.

Paused fast-path:

  • If vault.Paused is true, this function short-circuits and returns vault.PausedBalance.Amount (no balance iteration or NAV conversion).

Source of truth (when not paused):

  • TVV sums the balances held at the vault’s *principal* account, i.e. the marker address for vault.PrincipalMarkerAddress().
  • The vault account’s own balances are treated as *reserves* and are not included here.

Computation (when not paused):

  • Iterate all non-share-denom balances at the marker (principal) account.
  • Convert each balance to underlying units via ToUnderlyingAssetAmount.
  • Sum the converted amounts (floor at each multiplication/division step).

func (Keeper) GetVault

func (k Keeper) GetVault(ctx sdk.Context, address sdk.AccAddress) (*types.VaultAccount, error)

GetVault finds a vault by a given address.

This function will return nil if nothing exists at this address.

func (*Keeper) GetVaults

func (k *Keeper) GetVaults(ctx context.Context) ([]sdk.AccAddress, error)

GetVaults is a helper function for retrieving all vaults from state.

func (Keeper) InitGenesis

func (k Keeper) InitGenesis(ctx sdk.Context, genState *types.GenesisState)

InitGenesis initializes the vault module state from genesis.

func (*Keeper) PerformVaultInterestTransfer

func (k *Keeper) PerformVaultInterestTransfer(ctx sdk.Context, vault *types.VaultAccount) error

PerformVaultInterestTransfer applies accrued interest between the vault and the marker account if the current block time is beyond PeriodStart.

Positive interest is paid from vault reserves to the marker. Negative interest is refunded from marker principal back to the vault (bounded by available principal). An EventVaultReconcile is emitted. This method does not modify PeriodStart.

func (*Keeper) ProcessPendingSwapOuts

func (k *Keeper) ProcessPendingSwapOuts(ctx context.Context) error

ProcessPendingSwapOuts processes the queue of pending swap-out requests. Called from the EndBlocker, it iterates through requests due for payout at the current block time. It uses a safe "collect-then-mutate" pattern to comply with the SDK iterator contract. It first collects all due requests, then passes them to `processSwapOutJobs` for execution. Critical, unrecoverable errors during job processing will cause the associated vault to be automatically paused.

func (*Keeper) ReconcileVaultInterest

func (k *Keeper) ReconcileVaultInterest(ctx sdk.Context, vault *types.VaultAccount) error

ReconcileVaultInterest updates interest accounting for a vault if a new interest period has started.

If this is the first time the vault accrues interest, it triggers the start of a new period. If the current block time is after PeriodStart, it applies the interest transfer. If the current time has not advanced past PeriodStart, it is a no-op. This function will do nothing if the vault is paused.

This should be called before any transaction that changes vault principal/reserves or depends on the current interest state.

func (Keeper) SafeAddVerification

func (k Keeper) SafeAddVerification(ctx context.Context, vault *types.VaultAccount) error

SafeAddVerification clears any existing timeout entry for the given vault (if any), sets the vault's period start to the current block time, clears the period timeout, persists the vault, and stores the vault in the PayoutVerificationSet.

This ensures a vault is not present in both the verification set and timeout queues at the same time. Typically called after enabling interest or completing a reconciliation so the next accrual cycle begins cleanly.

func (Keeper) SafeEnqueueTimeout

func (k Keeper) SafeEnqueueTimeout(ctx context.Context, vault *types.VaultAccount) error

SafeEnqueueTimeout clears any existing timeout entry for the given vault (if any), sets the vault's period start to the current block time, sets a new period timeout at (now + AutoReconcileTimeout), persists the vault, and enqueues the timeout entry in the PayoutTimeoutQueue.

This ensures a vault is not present in both the timeout and verification queues at the same time. Typically called after a vault has been marked as payable so it will be revisited after the auto-reconcile window.

func (*Keeper) SetMaxInterestRate

func (k *Keeper) SetMaxInterestRate(ctx sdk.Context, vault *types.VaultAccount, maxRate string) error

SetMaxInterestRate sets the maximum interest rate for a vault. An empty string disables the maximum rate check.

func (*Keeper) SetMinInterestRate

func (k *Keeper) SetMinInterestRate(ctx sdk.Context, vault *types.VaultAccount, minRate string) error

SetMinInterestRate sets the minimum interest rate for a vault. An empty string disables the minimum rate check.

func (*Keeper) SetSwapInEnable

func (k *Keeper) SetSwapInEnable(ctx context.Context, vault *types.VaultAccount, enabled bool)

SetSwapInEnable updates the SwapInEnabled flag for a given vault. It updates the vault account in the state and emits an EventToggleSwapIn event.

func (*Keeper) SetSwapOutEnable

func (k *Keeper) SetSwapOutEnable(ctx context.Context, vault *types.VaultAccount, enabled bool)

SetSwapOutEnable updates the SwapOutEnabled flag for a given vault. It updates the vault account in the state and emits an EventToggleSwapOut event.

func (*Keeper) SetVaultAccount

func (k *Keeper) SetVaultAccount(ctx sdk.Context, vault *types.VaultAccount) error

SetVaultAccount validates and persists a VaultAccount using the auth keeper. Returns an error if validation fails.

func (*Keeper) SetVaultLookup

func (k *Keeper) SetVaultLookup(ctx context.Context, vault *types.VaultAccount) error

SetVaultLookup stores a vault in the Vaults collection, keyed by its bech32 address. NOTE: should only be called by genesis and at vault creation. Returns an error if the vault is nil or the address cannot be parsed.

func (*Keeper) SwapIn

func (k *Keeper) SwapIn(ctx sdk.Context, vaultAddr, recipient sdk.AccAddress, asset sdk.Coin) (*sdk.Coin, error)

SwapIn handles the process of depositing underlying assets into a vault in exchange for newly minted vault shares.

It performs the following steps:

  1. Retrieves the vault configuration for the given vault address.
  2. Verifies that swap-in is enabled for the vault.
  3. Reconciles any accrued interest from the vault to the marker module (if due).
  4. Resolves the vault share marker address.
  5. Validates that the provided underlying asset matches the vault’s configured underlying denom.
  6. Calculates the number of shares to mint based on the deposit, current supply, and vault balance.
  7. Mints the computed amount of shares under the vault’s admin authority.
  8. Withdraws the minted shares from the vault to the recipient address.
  9. Sends the underlying asset from the recipient to the vault’s marker account.

10. Emits a SwapIn event with metadata for indexing and audit.

Returns the minted share amount on success, or an error if any step fails.

func (*Keeper) SwapOut

func (k *Keeper) SwapOut(ctx sdk.Context, vaultAddr, owner sdk.AccAddress, shares sdk.Coin, redeemDenom string) (uint64, error)

SwapOut validates a swap-out request, calculates the resulting assets, escrows the user's shares, and enqueues a pending withdrawal request to be processed by the EndBlocker. It returns the unique ID of the newly queued request.

func (Keeper) ToUnderlyingAssetAmount

func (k Keeper) ToUnderlyingAssetAmount(ctx sdk.Context, vault types.VaultAccount, in sdk.Coin) (math.Int, error)

ToUnderlyingAssetAmount converts an input coin into its value expressed in vault.UnderlyingAsset using integer floor arithmetic.

Formula:

value_in_underlying = in.Amount * priceNumerator / priceDenominator

where (priceNumerator, priceDenominator) are from UnitPriceFraction(in.Denom → underlying). This performs a pure conversion based on NAV (or identity if denom==underlying). It does not enforce whether the denom is accepted by the vault; such policy checks are handled elsewhere.

func (Keeper) UnitPriceFraction

func (k Keeper) UnitPriceFraction(ctx sdk.Context, srcDenom, underlyingAsset string) (num, den math.Int, err error)

UnitPriceFraction returns the unit price of srcDenom expressed in vault.UnderlyingAsset as an integer fraction (priceNumerator, priceDenominator), derived from the NAV.

Semantics:

  • NAV.Price is the total value (in underlyingAsset units) for NAV.Volume units of srcDenom.
  • Therefore, 1 srcDenom = (NAV.Price.Amount / NAV.Volume) underlying units.
  • This function returns (NAV.Price.Amount, NAV.Volume) so callers can apply floor arithmetic.

Special cases and errors:

  • If srcDenom == underlyingAsset, returns (1, 1).
  • Errors if no NAV exists for (srcDenom → underlyingAsset).
  • Errors if NAV.Volume == 0.

func (*Keeper) UpdateInterestRates

func (k *Keeper) UpdateInterestRates(ctx context.Context, vault *types.VaultAccount, currentRate, desiredRate string)

UpdateInterestRates sets the vault's current and desired interest rates and emits an EventVaultInterestChange. The modified account is persisted via the auth keeper.

func (Keeper) ValidateInterestRateLimits

func (k Keeper) ValidateInterestRateLimits(minRateStr, maxRateStr string) error

ValidateInterestRateLimits checks that the provided minimum and maximum interest rates are valid decimal values and that the minimum rate is not greater than the maximum rate. Empty values are treated as unset and pass validation.

type VaultAttributer

type VaultAttributer interface {
	GetAdmin() string
	GetShareDenom() string
	GetUnderlyingAsset() string
	GetPaymentDenom() string
	GetWithdrawalDelaySeconds() uint64
}

VaultAttributer provides the attributes for creating a new vault.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL