liquidvesting

package
v10.1.0 Latest Latest
Warning

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

Go to latest
Published: Mar 14, 2025 License: Apache-2.0 Imports: 24 Imported by: 0

README

x/liquidvesting

Abstract

The following document specify the liquid vesting module.

This module allows the creation of synthetic tokens that represent tokens that have been locked elsewhere.

Contents

Concepts

User insurance fund

A user insurance fund is the amount of tokens that a user has accrued in the liquid vesting module as an insurance for future slashing operations. This fund is accumulated by sending over tokens to the liquid vesting module and specifying the user that should receive the insurance.

https://github.com/milkyway-labs/milkyway/blob/v8.1.0/proto/milkyway/liquidvesting/v1/models.proto#L12-L19

When trying to restake some locked tokens, the following formula is applied:

restakable_quantity = insurance_fund / insurance_percentage

Where insurance_percentage is the percentage of the insurance fund that is used to cover for the slashing of the restaked and is determined by the module's params.

This means that the minimum amount of tokens that a user always has to have in their insurance fund is:

min_insurance_amount = restaked_tokens * insurance_percentage
Depositing into an insurance fund

In order to deposit into an insurance fund, a user must send over tokens to the liquid vesting module though an IBC transfer message, and specify themselves as the receiver of those funds. This can be done using the following command:

<app-name> tx ibc-transfer transfer transfer [channel-id] milk102lq49sg6lmw2e0mw740tjldzq68v0yfgtazz5 [amount] \
  --memo '{"liquidvesting":{"amounts":[{"depositor":"[user-address]","amount":"[amount]"}]}}'

Note that the memo has to be parsable inside the following object structure:

{
  "liquidvesting": {
    "amounts": [
      {
        "depositor": "[user-address]",
        "amount": "[amount]"
      }
    ]
  }
}

Where the [amount] has to be only the amount of tokens to be deposited, and does not have to contain the denomination. For example, if you want to deposit 1 token to two users, you would have to use the following memo:

{
  "liquidvesting": {
    "amounts": [
      {
        "depositor": "[user-1-address]",
        "amount": "1000000"
      },
      {
        "depositor": "[user-2-address]",
        "amount": "1000000"
      }
    ]
  }
}

Another thing to note is that only specific IBC channels are allowed when depositing funds into a user insurance fund. The list of channels is specific inside the module's on-chain parameters and can be changed by the chain's governance.

Withdrawing from an insurance fund

A user can always withdraw excessive funds from their insurance fund by sending a message to the liquid vesting module. The only condition to be able to properly withdraw funds is that after the withdrawal there have to be enough funds to cover for slashing of tokens that have been restaked based on the insurance percentage amount set in the module params.

To give an example, let's consider the following scenario:

  • Alice has an insurance fund of 50 tokens
  • The insurance percentage is set to 10%
  • Alice has restaked 20 tokens

Considering the insurance percentage at 10%, this means that Alice only needs to have 2 tokens in her insurance fund to cover for the slashing of the 20 tokens that have been restaked. This means that Alice can withdraw 48 tokens from her insurance fund without any issues. However, if she was to withdraw 49 tokens, the transaction would fail as that would leave her with only 1 token in her insurance fund, which is not enough to cover for the slashing of the 20 tokens that have been restaked.

Locked tokens

Locked tokens are native tokens that have been created with the usage of the x/tokenfactory module. These tokens can only be created by specific users that have been granted the "minter" role in the module.

Once minted, locked tokens can only be restaked and cannot be transferred to other users or modules.

Minting locked tokens

The minting of locked tokens can be performed by sending a MsgMintLockedRepresentation from users that have been accredited with the "minter" role using the module's params.

Burning locked tokens

The burning of locked tokens can be performed by sending a MsgBurnLockedRepresentation from users that have been accredited with the "burner" role using the module's params.

If a burner sends a burn message for a user who has their tokens restaked, the restaking positions will automatically be undelegated to cover the burn. Once the undelegations complete, then the undelegated tokens will be burned as soon as the next block is produced.

Burn coins list

The BurnCoinsList contains a list of BurnCoins object, each one containing the information about the coins to burn once the unbonding period of the tokens ends.

https://github.com/milkyway-labs/milkyway/blob/v8.1.0/proto/milkyway/liquidvesting/v1/models.proto#L21-L50

State

Params

The module params are stored using the 0x01 key:

  • Params: 0x01 -> ProtocolBuffer(Params)
User insurance funds

The user insurance funds are stored using the 0x10 key:

  • User insurance fund: 0x10 | UserAddress -> ProtocolBuffer(UserInsuranceFund)
Burn coins queue

The amount of tokens that are automatically undelegated and queued to be burned are stored using the 0x20 key:

  • Burn coins queue: 0x20 -> ProtocolBuffer(BurnCoinsList)

Messages

MsgMintLockedRepresentation

The MsgMintLockedRepresentation can be sent by authorized minters to mint new locked tokens.

https://github.com/milkyway-labs/milkyway/blob/v8.1.0/proto/milkyway/liquidvesting/v1/messages.proto#L39-L59

The message will fail under the following conditions:

  • The user is not an authorized minter
MsgBurnLockedRepresentation

The MsgBurnLockedRepresentation can be sent by authorized burners to burn locked tokens.

https://github.com/milkyway-labs/milkyway/blob/v8.1.0/proto/milkyway/liquidvesting/v1/messages.proto#L65-L84

The message will fail under the following conditions:

  • The user is not an authorized burner
  • The amount to be burned is not composed of locked tokens
  • The user does not have any liquid nor restaked locked tokens
MsgWithdrawInsuranceFund

The MsgWithdrawInsuranceFund can be sent by users to withdraw tokens from their insurance fund.

https://github.com/milkyway-labs/milkyway/blob/v8.1.0/proto/milkyway/liquidvesting/v1/messages.proto#L90-L105

The message will fail under the following conditions:

  • The user does not have enough funds in their insurance fund to be withdrawn
  • The remaining insurance fund amount would not cover for the restaked tokens amount

Events

EndBlocker
Type Attribute Key Attribute Value
burn_locked_representation amount {burnedTokensAmount}
burn_locked_representation user {burnedTokensOwnerAddress}
Handlers
MsgMintLockedRepresentation
Type Attribute Key Attribute Value
mint_locked_representation sender {minterAddress}
mint_locked_representation amount {mintedAmount}
mint_locked_representation receiver {receiverAddress}
MsgBurnLockedRepresentation
Type Attribute Key Attribute Value
burn_locked_representation sender {burnerAddress}
burn_locked_representation amount {burnedAmount}
burn_locked_representation user {tokenOwnerAddress}
MsgWithdrawInsuranceFund
Type Attribute Key Attribute Value
withdraw_insurance_fund sender {userAddress}
withdraw_insurance_fund amount {withdrawnAmount}

Parameters

The liquid vesting module contains the following parameters:

https://github.com/milkyway-labs/milkyway/blob/v8.1.0/proto/milkyway/liquidvesting/v1/params.proto#L9-L35

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func EndBlocker

func EndBlocker(ctx sdk.Context, k *keeper.Keeper) error

EndBlocker is called every block and is responsible for maturing unbonding delegations

Types

type AppModule

type AppModule struct {
	AppModuleBasic
	// contains filtered or unexported fields
}

AppModule implements the AppModule interface for the liquidvesting module.

func NewAppModule

func NewAppModule(cdc codec.Codec, keeper *keeper.Keeper) AppModule

func (AppModule) AutoCLIOptions

func (a AppModule) AutoCLIOptions() *autocliv1.ModuleOptions

AutoCLIOptions implements the autocli.HasAutoCLIConfig interface.

func (AppModule) ConsensusVersion

func (AppModule) ConsensusVersion() uint64

ConsensusVersion implements ConsensusVersion.

func (AppModule) EndBlock

func (a AppModule) EndBlock(ctx context.Context) error

EndBlock executes all ABCI EndBlock logic respective to the restaking module.

func (AppModule) ExportGenesis

func (a AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage

ExportGenesis returns the module's exported genesis state as raw JSON bytes.

func (AppModule) InitGenesis

func (a AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, gs json.RawMessage)

InitGenesis performs the module's genesis initialization It returns no validator updates.

func (AppModule) IsAppModule

func (a AppModule) IsAppModule()

IsAppModule implements appmodule.AppModule.

func (AppModule) IsOnePerModuleType

func (a AppModule) IsOnePerModuleType()

IsOnePerModuleType implements appmodule.AppModule.

func (AppModule) Name

func (a AppModule) Name() string

Name returns the module's name.

func (AppModule) RegisterServices

func (a AppModule) RegisterServices(cfg module.Configurator)

RegisterServices registers a GRPC query service to respond to the module-specific GRPC queries.

type AppModuleBasic

type AppModuleBasic struct {
	// contains filtered or unexported fields
}

AppModuleBasic implements the AppModuleBasic interface for the liquidvesting module.

func NewAppModuleBasic

func NewAppModuleBasic(cdc codec.BinaryCodec) AppModuleBasic

func (AppModuleBasic) DefaultGenesis

func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage

DefaultGenesis returns the module's default genesis state.

func (AppModuleBasic) Name

func (a AppModuleBasic) Name() string

Name implements module.AppModuleBasic.

func (AppModuleBasic) RegisterGRPCGatewayRoutes

func (a AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux)

RegisterGRPCGatewayRoutes implements module.AppModuleBasic.

func (AppModuleBasic) RegisterInterfaces

func (a AppModuleBasic) RegisterInterfaces(reg cdctypes.InterfaceRegistry)

RegisterInterfaces implements module.AppModuleBasic.

func (AppModuleBasic) RegisterLegacyAminoCodec

func (a AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino)

RegisterLegacyAminoCodec implements module.AppModuleBasic.

func (AppModuleBasic) ValidateGenesis

func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error

ValidateGenesis performs genesis state validation for the module.

type IBCModule

type IBCModule struct {
	// contains filtered or unexported fields
}

func NewIBCMiddleware

func NewIBCMiddleware(app porttypes.IBCModule, k *keeper.Keeper) IBCModule

NewIBCMiddleware creates a new IBCModule given the keeper

func (IBCModule) GetAppVersion

func (im IBCModule) GetAppVersion(ctx sdk.Context, portID, channelID string) (string, bool)

GetAppVersion implements the IBCModule interface

func (IBCModule) OnAcknowledgementPacket

func (im IBCModule) OnAcknowledgementPacket(
	ctx sdk.Context,
	packet channeltypes.Packet,
	acknowledgement []byte,
	relayer sdk.AccAddress,
) error

OnAcknowledgementPacket implements the IBCModule interface

func (IBCModule) OnChanCloseConfirm

func (im IBCModule) OnChanCloseConfirm(
	ctx sdk.Context,
	portID,
	channelID string,
) error

OnChanCloseConfirm implements the IBCModule interface

func (IBCModule) OnChanCloseInit

func (im IBCModule) OnChanCloseInit(
	ctx sdk.Context,
	portID,
	channelID string,
) error

OnChanCloseInit implements the IBCModule interface

func (IBCModule) OnChanOpenAck

func (im IBCModule) OnChanOpenAck(
	ctx sdk.Context,
	portID,
	channelID string,
	counterpartyChannelID string,
	counterpartyVersion string,
) error

OnChanOpenAck implements the IBCModule interface

func (IBCModule) OnChanOpenConfirm

func (im IBCModule) OnChanOpenConfirm(
	ctx sdk.Context,
	portID,
	channelID string,
) error

OnChanOpenConfirm implements the IBCModule interface

func (IBCModule) OnChanOpenInit

func (im IBCModule) OnChanOpenInit(
	ctx sdk.Context,
	order channeltypes.Order,
	connectionHops []string,
	portID string,
	channelID string,
	channelCap *capabilitytypes.Capability,
	counterparty channeltypes.Counterparty,
	version string,
) (string, error)

OnChanOpenInit implements the IBCModule interface

func (IBCModule) OnChanOpenTry

func (im IBCModule) OnChanOpenTry(
	ctx sdk.Context,
	order channeltypes.Order,
	connectionHops []string,
	portID,
	channelID string,
	chanCap *capabilitytypes.Capability,
	counterparty channeltypes.Counterparty,
	counterpartyVersion string,
) (string, error)

OnChanOpenTry implements the IBCModule interface.

func (IBCModule) OnRecvPacket

func (im IBCModule) OnRecvPacket(
	ctx sdk.Context,
	packet channeltypes.Packet,
	relayer sdk.AccAddress,
) ibcexported.Acknowledgement

OnRecvPacket implements the IBCModule interface. A successful acknowledgement is returned if the packet data is successfully decoded and the receive application logic returns without error.

func (IBCModule) OnTimeoutPacket

func (im IBCModule) OnTimeoutPacket(
	ctx sdk.Context,
	packet channeltypes.Packet,
	relayer sdk.AccAddress,
) error

OnTimeoutPacket implements the IBCModule interface

Directories

Path Synopsis
Package types is a reverse proxy.
Package types is a reverse proxy.

Jump to

Keyboard shortcuts

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