-
Notifications
You must be signed in to change notification settings - Fork 125
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b531ad3
commit c1d86ea
Showing
8 changed files
with
307 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<!-- | ||
order: 1 | ||
--> | ||
# Concepts | ||
|
||
## Liquidation | ||
|
||
Users with vesting accounts can make their locked ISLM tokens liquid. If vesting account contains only locked tokens user can use `Liquidate` transaction and next things will happen: | ||
|
||
1. Specified amount amount of locked ISLM token will be transfered from a user vesting account to `x/liquidvesting` module account | ||
2. `x/liquidvesting` module will mint a liquid token which won't be locked and could be freely used in any way. Its amount will be equal to specified amount of locked ISLM token transfered to module account. | ||
3. ERC20 contract of newly created liquid token will be deployed on evm layer and token pair for it will be created with `x/erc20` module | ||
|
||
### Liquid token | ||
|
||
Liquid token represents arbitrary amount of ISLM token locked in vesting. For each liquidate transaction new unique liquid token will be created. | ||
Liquid token has vesting unlock schedule, it derives from original vesting account schedule which liquid token created from. | ||
|
||
## Redeem | ||
Once user has any liquid token on its account, it can be redeemed to locked ISLM token. Once user uses `Redeem` transaction next things will happen: | ||
|
||
1. Liquid token amount specified for redeem will be burnt | ||
2. ISLM token will be transfered to user's account from `x/liquidvesting` module | ||
3. Liquid token unlock schedule will be applied to user's account. If user has a regular account it converts to vesting account. If user already has vesting account liquid token schedule will be merged with already existing schedule. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
<!-- | ||
order: 2 | ||
--> | ||
|
||
# State | ||
|
||
## State Objects | ||
|
||
The `x/liquidvesting` module keeps the following objects in state: | ||
|
||
| State Object | Description | Key | Value | Store | | ||
|--------------|-----------------------|---------------------------------|-----------------| -------- | | ||
| `Denom` | Liquid token bytecode | `[]byte{1} + []byte(baseDenom)` | `[]byte{denom}` | KV | | ||
|
||
### Denom | ||
|
||
Denom aka liquid token representation of locked ISLM with unlock schedule | ||
|
||
```go | ||
type Denom struct { | ||
// base_denom main identifier for the denom, used to query it from store. | ||
BaseDenom string `protobuf:"bytes,1,opt,name=base_denom,json=baseDenom,proto3" json:"base_denom,omitempty"` | ||
// display_denom identifier used for display name for broad audience | ||
DisplayDenom string `protobuf:"bytes,2,opt,name=display_denom,json=displayDenom,proto3" json:"display_denom,omitempty"` | ||
// original_denom which liquid denom derived from | ||
OriginalDenom string `protobuf:"bytes,3,opt,name=original_denom,json=originalDenom,proto3" json:"original_denom,omitempty"` | ||
// start date | ||
StartTime time.Time `protobuf:"bytes,4,opt,name=start_time,json=startTime,proto3,stdtime" json:"start_time"` | ||
// end_date | ||
EndTime time.Time `protobuf:"bytes,5,opt,name=end_time,json=endTime,proto3,stdtime" json:"end_time"` | ||
// lockup periods | ||
LockupPeriods github_com_cosmos_cosmos_sdk_x_auth_vesting_types.Periods `protobuf:"bytes,6,rep,name=lockup_periods,json=lockupPeriods,proto3,castrepeated=github.com/cosmos/cosmos-sdk/x/auth/vesting/types.Periods" json:"lockup_periods"` | ||
} | ||
``` | ||
|
||
### Liquid token base denom | ||
|
||
The unique identifier of a `Denom` is obtained by combining prefix `LIQUID` and numeric id which increments every time new liquid token is created e. g. `LIQUID12` | ||
|
||
### Original denom | ||
|
||
Original denom is keeping track of which denom liquid token derives from. In most of the cases it will be ISLM | ||
|
||
### Start time | ||
|
||
Defines start of unlock schedule bound to luqid token. Always match token creation date | ||
|
||
### End time | ||
|
||
Defines the date when liquid token schedule ends | ||
|
||
### LockupPeriods | ||
|
||
The main part of liquid token schedule consist of sdk vesting periods | ||
|
||
```go | ||
type Period struct { | ||
// Period duration in seconds. | ||
Length int64 `protobuf:"varint,1,opt,name=length,proto3" json:"length,omitempty"` | ||
// Period amount | ||
Amount github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,2,rep,name=amount,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"amount"` | ||
} | ||
``` | ||
|
||
## Genesis State | ||
|
||
The `x/liquidvesting` module's `GenesisState` defines the state necessary for initializing the chain from a previous exported height. It contains the module parameters and the existing liquid token : | ||
|
||
```go | ||
// GenesisState defines the module's genesis state. | ||
type GenesisState struct { | ||
// params defines all the paramaters of the module. | ||
Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` | ||
// keeps track of denom ID | ||
DenomCounter uint64 `protobuf:"varint,2,opt,name=denomCounter,proto3" json:"denomCounter,omitempty"` | ||
// list of liquid denoms | ||
Denoms []Denom `protobuf:"bytes,3,rep,name=denoms,proto3" json:"denoms"` | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
<!-- | ||
order: 3 | ||
--> | ||
|
||
# State Transitions | ||
|
||
## Liquidate | ||
|
||
1. User submits `MsgLiquidate` | ||
2. Checks if liquidation allowed for account and amount | ||
- tokens on target account are fully vested | ||
- specified amount is more than minimum liquidation amount param | ||
- specified amount is less or equal to locked token amount | ||
3. Calculate new schedules for account and for liquid token | ||
4. Update target account with new schedule | ||
5. Escrow locked token to module account | ||
6. Create new liquid token with previously calculated schedule and update token id counter | ||
7. Send newly created liquid token to target account | ||
8. Deploy ERC20 contract for liquid token and register token pair with \`x/erc20\` module | ||
9. Convert all liquid tokens from cosmos to ERC20 | ||
|
||
## Redeem | ||
|
||
1. User submits `MsgRedeem` | ||
2. Checks if redeem possible | ||
- Specified liquid token does exist | ||
- Check user's account has sufficient amount of liquid token to redeem | ||
3. Burn specified liquid token amount | ||
4. Subtract burnt liquid token amount from liquid token schedule | ||
5. Transfer ISLM to target account | ||
6. Apply token unlock schedule to target account. If target account is not vesting account it will be converted to vesting one. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
<!-- | ||
order: 4 | ||
--> | ||
|
||
# Transactions | ||
|
||
This section defines the `sdk.Msg` concrete types that result in the state transitions defined on the previous section. | ||
|
||
## `MsgLiquidate` | ||
|
||
A user broadcasts a `MsgLiquidate` message to liquidate locked ISLM token. | ||
|
||
```go | ||
type MsgLiquidate struct { | ||
// account for liquidation of locked vesting tokens | ||
LiquidateFrom string `protobuf:"bytes,1,opt,name=liquidate_from,json=liquidateFrom,proto3" json:"liquidate_from,omitempty"` | ||
// account to send resulted liquid token | ||
LiquidateTo string `protobuf:"bytes,2,opt,name=liquidate_to,json=liquidateTo,proto3" json:"liquidate_to,omitempty"` | ||
// amount of tokens subject for liquidation | ||
Amount types.Coin `protobuf:"bytes,3,opt,name=amount,proto3" json:"amount"` | ||
} | ||
``` | ||
|
||
Message stateless validation fails if: | ||
|
||
- Amount is not positive | ||
- LiquidateFrom bech32 address is invalid | ||
- LiquidateTo bech32 address is invalid | ||
|
||
## `MsgRedeem` | ||
|
||
A user broadcasts a `MsgRedeem` message to redeem liquid token to locked ISLM. | ||
|
||
```go | ||
type MsgRedeem struct { | ||
RedeemFrom string `protobuf:"bytes,1,opt,name=redeem_from,json=redeemFrom,proto3" json:"redeem_from,omitempty"` | ||
// destination address for vesting tokens | ||
RedeemTo string `protobuf:"bytes,2,opt,name=redeem_to,json=redeemTo,proto3" json:"redeem_to,omitempty"` | ||
// amount of vesting tokens to redeem from liquidation module | ||
Amount types.Coin `protobuf:"bytes,3,opt,name=amount,proto3" json:"amount"` | ||
} | ||
``` | ||
|
||
Message stateless validation fails if: | ||
|
||
- Amount is not positive | ||
- RedeemFrom bech32 address is invalid | ||
- RedeemTo bech32 address is invalid |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<!-- | ||
order: 5 | ||
--> | ||
|
||
# Parameters | ||
|
||
The `x/liquidvesting` module contains the following parameters: | ||
|
||
| Key | Type | Default Value | | ||
|----------------------------|-------------|---------------------| | ||
| `MinimumLiquidationAmount` | sdkmath.Int | `1000*10^18` | | ||
|
||
## Minimum liquidation amount | ||
|
||
The `MinimumLiquidationAmount` parameter defines minimum amount of locked token which can be liquidated at once. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
<!-- | ||
order: 6 | ||
--> | ||
|
||
# Clients | ||
|
||
## CLI | ||
|
||
Find below a list of `haqqd` commands added with the `x/liquidvesting` module. You can obtain the full list by using the `haqqd -h` command. A CLI command can look like this: | ||
|
||
```bash | ||
haqqd query liquidvesting params | ||
``` | ||
|
||
### Queries | ||
|
||
| Command | Subcommand | Description | | ||
|-------------------------|------------|--------------------------------| | ||
| `query` `liquidvesting` | `denom` | Get liquid token | | ||
| `query` `liquidvesting` | `denoms` | Get all existing liquid tokens | | ||
|
||
### Transactions | ||
|
||
| Command | Subcommand | Description | | ||
|----------------------|-------------|---------------------------------------------------| | ||
| `tx` `liquidvesting` | `liquidate` | Liquidates arbitrary amount of locked ISLM tokens | | ||
| `tx` `liquidvesting` | `redeem` | Redeem liquid token to ISLM | | ||
|
||
## gRPC | ||
|
||
### Queries | ||
|
||
| Verb | Method | Description | | ||
| ------ |-------------------------------------| ------------------------------ | | ||
| `gRPC` | `haqq.liquidvesting.v1.Query/Denom` | Get liquid token | | ||
| `gRPC` | `haqq.liquidvesting.v1.Query/Denoms`| Get all existing liquid tokens | | ||
| `GET` | `/haqq/liquidvesting/v1/denom` | Get liquid token | | ||
| `GET` | `/haqq/liquidvesting/v1/denom` | Get all existing liquid tokens | | ||
|
||
### Transactions | ||
|
||
| Verb | Method | Description | | ||
|--------|---------------------------------------| ------------------------------------------------- | | ||
| `gRPC` | `haqq.liquidvesting.v1.Msg/Liquidate` | Liquidates arbitrary amount of locked ISLM tokens | | ||
| `gRPC` | `haqq.liquidvesting.v1.Msg/Redeem` | Redeem liquid token to ISLM | | ||
| `POST` | `/haqq/liquidvesting/v1/tx/liquidate` | Liquidates arbitrary amount of locked ISLM tokens | | ||
| `POST` | `/haqq/liquidvesting/v1/tx/redeem` | Redeem liquid token to ISLM | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# Schedule manipulation | ||
|
||
This section describes in details how `x/liquidvesting` module handles operation with schedule mutation. Examples are provided. | ||
|
||
## Liquidation | ||
|
||
For example we have an account this account has 3 days of vesting so each day represented as a period and has amount which be unlocked once period is passed. | ||
Let's imagine every period has different amount 10,20 and 30 respectively | ||
``` | ||
10,20,30 | ||
``` | ||
|
||
So total amount locked in this schedule is 60. We want to liquidate 20 tokens from this schedule. | ||
We will subtract portion of this amount from every period proportionally to total sum. | ||
For the first period : | ||
- 10 - first period amount | ||
- 20 - liquidation amount | ||
- 60 - total amount | ||
|
||
Formula is 10 - 10*20/60 -> 10 - 200/60 -> 10 - 3 = 7 | ||
|
||
Important note in above calculations. We have step 200/60 and this division has a remainder. We will track this remainder but won't use it to calculate new period. | ||
|
||
If we perform the same operation for every period we will get: | ||
``` | ||
7,14,20 | ||
``` | ||
The sum of new periods is 41 but expected sum is 40 because we were subtracting 20 from periods with sum of 60. | ||
So calculate diff between sum of new periods and expected sum and it is 1. Now having the diff we subtract it from last period. So we get: | ||
``` | ||
7,14,19 | ||
``` | ||
These are our new periods. These new periods will be the new schedule of vesting account targeted by liquidation. | ||
|
||
Now we need to know periods for newly created liquid token. and this is simply a diff between original periods and decreased periods | ||
``` | ||
10,20,30 - original amount in periods | ||
7,14,19 - decreased amount in periods | ||
3,6,11 - liquid token amount in periods | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<!-- | ||
order: 0 | ||
title: "Liquid vesting Overview" | ||
parent: | ||
title: "liquidvesting" | ||
--> | ||
|
||
## Abstract | ||
|
||
This document specifies the internal `x/liquidvesting` module of the Haqq Network. | ||
|
||
With the `x/liquidvesting` users on Haqq Network can make their ISLM locked in vesting liquid. | ||
|
||
## Contents | ||
|
||
1. **[Concepts](01_concepts.md)** | ||
2. **[State](02_state.md)** | ||
3. **[State Transitions](03_state_transitions.md)** | ||
4. **[Transactions](04_transactions.md)** | ||
5. **[Parameters](05_parameters.md)** | ||
6. **[Clients](06_clients.md)** | ||
7. **[Schedule Manipulation](07_schedule_manipulation.md)** |