mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-27 08:45:19 +00:00
ed9991d44a
* Add vault and vault shares to genesis * Fix error and denoms * Update init and export genesis with correct data * Fix total supply genesis check, remove legacy test for enum errors * Add vault slice validate tests * Update denom validation, add additional test
256 lines
7.5 KiB
Go
256 lines
7.5 KiB
Go
package keeper
|
|
|
|
import (
|
|
"github.com/cosmos/cosmos-sdk/store/prefix"
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
"github.com/kava-labs/kava/x/earn/types"
|
|
)
|
|
|
|
// GetVaultTotalSupplied returns the total balance supplied to the vault. This
|
|
// may not necessarily be the current value of the vault, as it is the sum
|
|
// of the supplied denom and the value may be higher due to accumulated APYs.
|
|
func (k *Keeper) GetVaultTotalSupplied(
|
|
ctx sdk.Context,
|
|
denom string,
|
|
) (sdk.Coin, error) {
|
|
vault, found := k.GetVaultRecord(ctx, denom)
|
|
if !found {
|
|
return sdk.Coin{}, types.ErrVaultRecordNotFound
|
|
}
|
|
|
|
return vault.TotalSupply, nil
|
|
}
|
|
|
|
// GetTotalValue returns the total **value** of all coins in this vault,
|
|
// i.e. the realizable total value denominated by GetDenom() if the vault
|
|
// were to liquidate its entire strategies.
|
|
//
|
|
// **Note:** This does not include the tokens held in bank by the module
|
|
// account. If it were to be included, also note that the module account is
|
|
// unblocked and can receive funds from bank sends.
|
|
func (k *Keeper) GetVaultTotalValue(
|
|
ctx sdk.Context,
|
|
denom string,
|
|
) (sdk.Coin, error) {
|
|
enabledVault, found := k.GetAllowedVault(ctx, denom)
|
|
if !found {
|
|
return sdk.Coin{}, types.ErrVaultRecordNotFound
|
|
}
|
|
|
|
strategy, err := k.GetStrategy(enabledVault.VaultStrategy)
|
|
if err != nil {
|
|
return sdk.Coin{}, types.ErrInvalidVaultStrategy
|
|
}
|
|
|
|
return strategy.GetEstimatedTotalAssets(ctx, enabledVault.Denom)
|
|
}
|
|
|
|
// GetVaultAccountSupplied returns the supplied amount for a single address
|
|
// within a vault.
|
|
func (k *Keeper) GetVaultAccountSupplied(
|
|
ctx sdk.Context,
|
|
acc sdk.AccAddress,
|
|
) (sdk.Coins, error) {
|
|
vaultShareRecord, found := k.GetVaultShareRecord(ctx, acc)
|
|
if !found {
|
|
return sdk.Coins{}, types.ErrVaultShareRecordNotFound
|
|
}
|
|
|
|
return vaultShareRecord.AmountSupplied, nil
|
|
}
|
|
|
|
// GetVaultAccountValue returns the value of a single address within a vault
|
|
// if the account were to withdraw their entire balance.
|
|
func (k *Keeper) GetVaultAccountValue(
|
|
ctx sdk.Context,
|
|
denom string,
|
|
acc sdk.AccAddress,
|
|
) (sdk.Coin, error) {
|
|
totalSupplied, err := k.GetVaultTotalSupplied(ctx, denom)
|
|
if err != nil {
|
|
return sdk.Coin{}, err
|
|
}
|
|
|
|
accSupplied, err := k.GetVaultAccountSupplied(ctx, acc)
|
|
if err != nil {
|
|
return sdk.Coin{}, err
|
|
}
|
|
|
|
vaultTotalValue, err := k.GetVaultTotalValue(ctx, denom)
|
|
if err != nil {
|
|
return sdk.Coin{}, err
|
|
}
|
|
|
|
// Percent of vault account ownership = accountSupply / totalSupply
|
|
// Value of vault account ownership = percentOwned * totalValue
|
|
vaultShare := accSupplied.AmountOf(denom).ToDec().Quo(totalSupplied.Amount.ToDec())
|
|
shareValueDec := vaultTotalValue.Amount.ToDec().Mul(vaultShare)
|
|
|
|
return sdk.NewCoin(denom, shareValueDec.TruncateInt()), nil
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// VaultRecord -- vault total supplies
|
|
|
|
// GetVaultRecord returns the vault record for a given denom.
|
|
func (k *Keeper) GetVaultRecord(
|
|
ctx sdk.Context,
|
|
vaultDenom string,
|
|
) (types.VaultRecord, bool) {
|
|
store := prefix.NewStore(ctx.KVStore(k.key), types.VaultRecordKeyPrefix)
|
|
|
|
bz := store.Get(types.VaultKey(vaultDenom))
|
|
if bz == nil {
|
|
return types.VaultRecord{}, false
|
|
}
|
|
|
|
var record types.VaultRecord
|
|
k.cdc.MustUnmarshal(bz, &record)
|
|
|
|
return record, true
|
|
}
|
|
|
|
// UpdateVaultRecord updates the vault record in state for a given denom. This
|
|
// deletes it if the supply is zero and updates the state if supply is non-zero.
|
|
func (k *Keeper) UpdateVaultRecord(
|
|
ctx sdk.Context,
|
|
vaultRecord types.VaultRecord,
|
|
) {
|
|
if vaultRecord.TotalSupply.IsZero() {
|
|
k.DeleteVaultRecord(ctx, vaultRecord.Denom)
|
|
} else {
|
|
k.SetVaultRecord(ctx, vaultRecord)
|
|
}
|
|
}
|
|
|
|
// DeleteVaultRecord deletes the vault record for a given denom.
|
|
func (k *Keeper) DeleteVaultRecord(ctx sdk.Context, vaultDenom string) {
|
|
store := prefix.NewStore(ctx.KVStore(k.key), types.VaultRecordKeyPrefix)
|
|
store.Delete(types.VaultKey(vaultDenom))
|
|
}
|
|
|
|
// SetVaultRecord sets the vault record for a given denom.
|
|
func (k *Keeper) SetVaultRecord(ctx sdk.Context, record types.VaultRecord) {
|
|
store := prefix.NewStore(ctx.KVStore(k.key), types.VaultRecordKeyPrefix)
|
|
bz := k.cdc.MustMarshal(&record)
|
|
store.Set(types.VaultKey(record.Denom), bz)
|
|
}
|
|
|
|
// IterateVaultRecords iterates over all vault objects in the store and performs
|
|
// a callback function.
|
|
func (k Keeper) IterateVaultRecords(
|
|
ctx sdk.Context,
|
|
cb func(record types.VaultRecord) (stop bool),
|
|
) {
|
|
store := prefix.NewStore(ctx.KVStore(k.key), types.VaultRecordKeyPrefix)
|
|
iterator := sdk.KVStorePrefixIterator(store, []byte{})
|
|
defer iterator.Close()
|
|
|
|
for ; iterator.Valid(); iterator.Next() {
|
|
var record types.VaultRecord
|
|
k.cdc.MustUnmarshal(iterator.Value(), &record)
|
|
if cb(record) {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
// GetAllVaultRecords returns all vault records from the store.
|
|
func (k Keeper) GetAllVaultRecords(ctx sdk.Context) types.VaultRecords {
|
|
var records types.VaultRecords
|
|
|
|
k.IterateVaultRecords(ctx, func(record types.VaultRecord) bool {
|
|
records = append(records, record)
|
|
return false
|
|
})
|
|
|
|
return records
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// VaultShare -- user shares per vault
|
|
|
|
// GetVaultShareRecord returns the vault share record for a given denom and
|
|
// account.
|
|
func (k *Keeper) GetVaultShareRecord(
|
|
ctx sdk.Context,
|
|
acc sdk.AccAddress,
|
|
) (types.VaultShareRecord, bool) {
|
|
store := prefix.NewStore(ctx.KVStore(k.key), types.VaultShareRecordKeyPrefix)
|
|
|
|
bz := store.Get(types.DepositorVaultSharesKey(acc))
|
|
if bz == nil {
|
|
return types.VaultShareRecord{}, false
|
|
}
|
|
|
|
var record types.VaultShareRecord
|
|
k.cdc.MustUnmarshal(bz, &record)
|
|
|
|
return record, true
|
|
}
|
|
|
|
// UpdateVaultShareRecord updates the vault share record in state for a given
|
|
// denom and account. This deletes it if the supply is zero and updates the
|
|
// state if supply is non-zero.
|
|
func (k *Keeper) UpdateVaultShareRecord(
|
|
ctx sdk.Context,
|
|
record types.VaultShareRecord,
|
|
) {
|
|
if record.AmountSupplied.IsZero() {
|
|
k.DeleteVaultShareRecord(ctx, record.Depositor)
|
|
} else {
|
|
k.SetVaultShareRecord(ctx, record)
|
|
}
|
|
}
|
|
|
|
// DeleteVaultShareRecord deletes the vault share record for a given denom and
|
|
// account.
|
|
func (k *Keeper) DeleteVaultShareRecord(
|
|
ctx sdk.Context,
|
|
acc sdk.AccAddress,
|
|
) {
|
|
store := prefix.NewStore(ctx.KVStore(k.key), types.VaultShareRecordKeyPrefix)
|
|
store.Delete(types.DepositorVaultSharesKey(acc))
|
|
}
|
|
|
|
// SetVaultShareRecord sets the vault share record for a given denom and account.
|
|
func (k *Keeper) SetVaultShareRecord(
|
|
ctx sdk.Context,
|
|
record types.VaultShareRecord,
|
|
) {
|
|
store := prefix.NewStore(ctx.KVStore(k.key), types.VaultShareRecordKeyPrefix)
|
|
bz := k.cdc.MustMarshal(&record)
|
|
store.Set(types.DepositorVaultSharesKey(record.Depositor), bz)
|
|
}
|
|
|
|
// IterateVaultShareRecords iterates over all vault share objects in the store
|
|
// and performs a callback function.
|
|
func (k Keeper) IterateVaultShareRecords(
|
|
ctx sdk.Context,
|
|
cb func(record types.VaultShareRecord) (stop bool),
|
|
) {
|
|
store := prefix.NewStore(ctx.KVStore(k.key), types.VaultShareRecordKeyPrefix)
|
|
iterator := sdk.KVStorePrefixIterator(store, []byte{})
|
|
defer iterator.Close()
|
|
|
|
for ; iterator.Valid(); iterator.Next() {
|
|
var record types.VaultShareRecord
|
|
k.cdc.MustUnmarshal(iterator.Value(), &record)
|
|
if cb(record) {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
// GetAllVaultShareRecords returns all vault share records from the store.
|
|
func (k Keeper) GetAllVaultShareRecords(ctx sdk.Context) types.VaultShareRecords {
|
|
var records types.VaultShareRecords
|
|
|
|
k.IterateVaultShareRecords(ctx, func(record types.VaultShareRecord) bool {
|
|
records = append(records, record)
|
|
return false
|
|
})
|
|
|
|
return records
|
|
}
|