feat(x/cdp): update begin bloocker to run liquidations every X blocks based off params (#1818)

* (feat) update x/cdp to run every X blocks based off params (#1814)

* add new cdp module param to protonet genesis

* update cdp / cdp related tests for new module param

* update telemetry docs and setup for collecting against local node

* update kvool commit for new cdp param

(cherry picked from commit 4d62f47773)

* add tests for configurable x/cdp begin blocker interval param
add migration for default value of param

* make adjustments based off pr feedback

* fix proto back compat check
This commit is contained in:
Levi Schoen 2024-02-02 08:21:11 -10:00 committed by GitHub
parent 2bccb6deaf
commit c59a491788
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
31 changed files with 682 additions and 956 deletions

View File

@ -39,6 +39,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
### Features ### Features
- (cli) [#1785] Add `shard` CLI command to support creating partitions of data for standalone nodes - (cli) [#1785] Add `shard` CLI command to support creating partitions of data for standalone nodes
- (cdp) [#1818] Add module param and logic for running x/cdp begin blocker every `n` blocks
- (cli) [#1804] Add `rocksdb compact` command for manual DB compaction of state or blockstore. - (cli) [#1804] Add `rocksdb compact` command for manual DB compaction of state or blockstore.
## [v0.25.0] ## [v0.25.0]
@ -69,6 +70,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
## [v0.24.3] ## [v0.24.3]
### Bug Fixes ### Bug Fixes
- (deps) [#1770] Bump ledger-cosmos-go to v0.13.1 to resolve signing error with - (deps) [#1770] Bump ledger-cosmos-go to v0.13.1 to resolve signing error with
- (rocksdb) [#1767] Fix resolution of rocksdb database path introduced in v0.24.2 - (rocksdb) [#1767] Fix resolution of rocksdb database path introduced in v0.24.2
@ -324,7 +326,6 @@ the [changelog](https://github.com/cosmos/cosmos-sdk/blob/v0.38.4/CHANGELOG.md).
[#1804]: https://github.com/Kava-Labs/kava/pull/1804 [#1804]: https://github.com/Kava-Labs/kava/pull/1804
[#1785]: https://github.com/Kava-Labs/kava/pull/1785 [#1785]: https://github.com/Kava-Labs/kava/pull/1785
[#1784]: https://github.com/Kava-Labs/kava/pull/1784 [#1784]: https://github.com/Kava-Labs/kava/pull/1784
[#1776]: https://github.com/Kava-Labs/kava/pull/1776
[#1770]: https://github.com/Kava-Labs/kava/pull/1770 [#1770]: https://github.com/Kava-Labs/kava/pull/1770
[#1755]: https://github.com/Kava-Labs/kava/pull/1755 [#1755]: https://github.com/Kava-Labs/kava/pull/1755
[#1761]: https://github.com/Kava-Labs/kava/pull/1761 [#1761]: https://github.com/Kava-Labs/kava/pull/1761
@ -384,7 +385,6 @@ the [changelog](https://github.com/cosmos/cosmos-sdk/blob/v0.38.4/CHANGELOG.md).
[v0.24.1]: https://github.com/Kava-Labs/kava/compare/v0.24.1...v0.24.0 [v0.24.1]: https://github.com/Kava-Labs/kava/compare/v0.24.1...v0.24.0
[v0.24.0]: https://github.com/Kava-Labs/kava/compare/v0.24.0...v0.23.2 [v0.24.0]: https://github.com/Kava-Labs/kava/compare/v0.24.0...v0.23.2
[v0.23.2]: https://github.com/Kava-Labs/kava/compare/v0.23.1...v0.23.2 [v0.23.2]: https://github.com/Kava-Labs/kava/compare/v0.23.1...v0.23.2
[v0.23.1]: https://github.com/Kava-Labs/kava/compare/v0.23.0...v0.23.1
[v0.23.0]: https://github.com/Kava-Labs/kava/compare/v0.21.1...v0.23.0 [v0.23.0]: https://github.com/Kava-Labs/kava/compare/v0.21.1...v0.23.0
[v0.16.1]: https://github.com/Kava-Labs/kava/compare/v0.16.0...v0.16.1 [v0.16.1]: https://github.com/Kava-Labs/kava/compare/v0.16.0...v0.16.1
[v0.16.0]: https://github.com/Kava-Labs/kava/compare/v0.15.2...v0.16.0 [v0.16.0]: https://github.com/Kava-Labs/kava/compare/v0.15.2...v0.16.0

View File

@ -330,6 +330,7 @@ start-remote-sims:
-—container-override environment=[{SIM_NAME=master-$(VERSION)}] -—container-override environment=[{SIM_NAME=master-$(VERSION)}]
update-kvtool: update-kvtool:
git submodule init || true
git submodule update git submodule update
cd tests/e2e/kvtool && make install cd tests/e2e/kvtool && make install

View File

@ -837,6 +837,7 @@
"gov_denom": "ukava", "gov_denom": "ukava",
"params": { "params": {
"circuit_breaker": false, "circuit_breaker": false,
"liquidation_block_interval": 500,
"collateral_params": [ "collateral_params": [
{ {
"auction_size": "50000000000", "auction_size": "50000000000",

View File

@ -3505,6 +3505,9 @@ paths:
type: string type: string
circuit_breaker: circuit_breaker:
type: boolean type: boolean
liquidation_block_interval:
type: string
format: int64
description: Params defines the parameters for the cdp module. description: Params defines the parameters for the cdp module.
description: >- description: >-
QueryParamsResponse defines the response type for the Query/Params QueryParamsResponse defines the response type for the Query/Params
@ -51628,6 +51631,9 @@ definitions:
type: string type: string
circuit_breaker: circuit_breaker:
type: boolean type: boolean
liquidation_block_interval:
type: string
format: int64
description: Params defines the parameters for the cdp module. description: Params defines the parameters for the cdp module.
kava.cdp.v1beta1.QueryAccountsResponse: kava.cdp.v1beta1.QueryAccountsResponse:
type: object type: object
@ -52161,6 +52167,9 @@ definitions:
type: string type: string
circuit_breaker: circuit_breaker:
type: boolean type: boolean
liquidation_block_interval:
type: string
format: int64
description: Params defines the parameters for the cdp module. description: Params defines the parameters for the cdp module.
description: >- description: >-
QueryParamsResponse defines the response type for the Query/Params RPC QueryParamsResponse defines the response type for the Query/Params RPC

View File

@ -38,10 +38,10 @@ Then restart the service with the updated settings
## Running local prometheus collector and grafana services ## Running local prometheus collector and grafana services
To collect app metrics and visualize them locally, you can run the prometheus collector and grafana services with docker compose from the repo root directory To collect app metrics and visualize them locally, you can run the prometheus collector and grafana services with docker compose from the repo root directory (after updating `config.toml` and `app.toml` as detailed above)
```bash ```bash
docker compose -f prometheus.docker-compose.yml docker compose -f prometheus.docker-compose.yml up
``` ```
Navigate to localhost:3000 to view the grafana unix Navigate to localhost:3000 to view the grafana unix
@ -54,13 +54,13 @@ See [grafana docs](https://grafana.com/docs/grafana/latest/dashboards/) for info
### Collecting from local host ### Collecting from local host
Update [prometheus config](../prometheus.yml) to collect metrics from your local source Update [prometheus config](../prometheus.yml) to collect metrics from your local source, where the port matches the value set for `config.toml/instrumentation.prometheus_listen_addr`
```yaml ```yaml
metrics_path: / metrics_path: /
static_configs: static_configs:
- targets: - targets:
- localhost:8888 - docker-host:8888
``` ```
### Collecting from remote host ### Collecting from remote host

View File

@ -1681,6 +1681,7 @@ Params defines the parameters for the cdp module.
| `debt_auction_threshold` | [string](#string) | | | | `debt_auction_threshold` | [string](#string) | | |
| `debt_auction_lot` | [string](#string) | | | | `debt_auction_lot` | [string](#string) | | |
| `circuit_breaker` | [bool](#bool) | | | | `circuit_breaker` | [bool](#bool) | | |
| `liquidation_block_interval` | [int64](#int64) | | |

View File

@ -34,3 +34,10 @@ services:
- 9090 - 9090
networks: networks:
- monitoring - monitoring
docker-host:
image: qoomon/docker-host
cap_add: [ 'NET_ADMIN', 'NET_RAW' ]
mem_limit: 8M
restart: on-failure
networks:
- monitoring

View File

@ -3,8 +3,7 @@ global:
evaluation_interval: 15s evaluation_interval: 15s
scrape_configs: scrape_configs:
- job_name: proxy - job_name: proxy
scheme: https
metrics_path: / metrics_path: /
static_configs: static_configs:
- targets: - targets:
- 4efb-18-207-102-158.ngrok-free.app - docker-host:8888

View File

@ -66,6 +66,8 @@ message Params {
(gogoproto.nullable) = false (gogoproto.nullable) = false
]; ];
bool circuit_breaker = 8; bool circuit_breaker = 8;
int64 liquidation_block_interval = 9;
} }
// DebtParam defines governance params for debt assets // DebtParam defines governance params for debt assets

@ -1 +1 @@
Subproject commit e1085562d203fd81c5dd8576170b29715b2de9ef Subproject commit 99214e8b5196b9ab16fa9902f956858c178921a5

View File

@ -2,6 +2,7 @@ package cdp
import ( import (
"errors" "errors"
"fmt"
"time" "time"
"github.com/cosmos/cosmos-sdk/telemetry" "github.com/cosmos/cosmos-sdk/telemetry"
@ -20,6 +21,9 @@ func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, k keeper.Keeper)
params := k.GetParams(ctx) params := k.GetParams(ctx)
// only run CDP liquidations every `LiquidationBlockInterval` blocks
skipSyncronizeAndLiquidations := ctx.BlockHeight()%params.LiquidationBlockInterval != 0
for _, cp := range params.CollateralParams { for _, cp := range params.CollateralParams {
ok := k.UpdatePricefeedStatus(ctx, cp.SpotMarketID) ok := k.UpdatePricefeedStatus(ctx, cp.SpotMarketID)
if !ok { if !ok {
@ -36,6 +40,13 @@ func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, k keeper.Keeper)
panic(err) panic(err)
} }
if skipSyncronizeAndLiquidations {
ctx.Logger().Debug(fmt.Sprintf("skipping x/cdp SynchronizeInterestForRiskyCDPs and LiquidateCdps for %s", cp.Type))
return
}
ctx.Logger().Debug(fmt.Sprintf("running x/cdp SynchronizeInterestForRiskyCDPs and LiquidateCdps for %s", cp.Type))
err = k.SynchronizeInterestForRiskyCDPs(ctx, cp.CheckCollateralizationIndexCount, sdk.MaxSortableDec, cp.Type) err = k.SynchronizeInterestForRiskyCDPs(ctx, cp.CheckCollateralizationIndexCount, sdk.MaxSortableDec, cp.Type)
if err != nil { if err != nil {
panic(err) panic(err)

View File

@ -79,10 +79,13 @@ func (suite *ModuleTestSuite) createCdps() {
suite.app = tApp suite.app = tApp
suite.keeper = tApp.GetCDPKeeper() suite.keeper = tApp.GetCDPKeeper()
// create 100 cdps
for j := 0; j < 100; j++ { for j := 0; j < 100; j++ {
// 50 of the cdps will be collateralized with xrp
collateral := "xrp" collateral := "xrp"
amount := 10000000000 amount := 10000000000
debt := simulation.RandIntBetween(rand.New(rand.NewSource(int64(j))), 750000000, 1249000000) debt := simulation.RandIntBetween(rand.New(rand.NewSource(int64(j))), 750000000, 1249000000)
// the other half (50) will be collateralized with btc
if j%2 == 0 { if j%2 == 0 {
collateral = "btc" collateral = "btc"
amount = 100000000 amount = 100000000
@ -122,37 +125,81 @@ func (suite *ModuleTestSuite) setPrice(price sdk.Dec, market string) {
} }
func (suite *ModuleTestSuite) TestBeginBlock() { func (suite *ModuleTestSuite) TestBeginBlock() {
// test setup, creating
// 50 xrp cdps each with
// collateral: 10000000000
// debt: between 750000000 - 1249000000
// if debt above 10000000000,
// cdp added to tracker / liquidation list
// debt total added to trackers debt total
// 50 btc cdps each with
// collateral: 10000000000
// debt: between 2700000000 - 5332000000
// if debt above 4000000000,
// cdp added to tracker / liquidation list
// debt total added to trackers debt total
// naively we expect roughly half of the cdps to be above the debt tracking floor, roughly 25 of them collaterallized with xrp, the other 25 with btcb
// usdx is the principal for all cdps
suite.createCdps() suite.createCdps()
ak := suite.app.GetAccountKeeper() ak := suite.app.GetAccountKeeper()
bk := suite.app.GetBankKeeper() bk := suite.app.GetBankKeeper()
// test case 1 setup
acc := ak.GetModuleAccount(suite.ctx, types.ModuleName) acc := ak.GetModuleAccount(suite.ctx, types.ModuleName)
// track how much xrp collateral exists in the cdp module
originalXrpCollateral := bk.GetBalance(suite.ctx, acc.GetAddress(), "xrp").Amount originalXrpCollateral := bk.GetBalance(suite.ctx, acc.GetAddress(), "xrp").Amount
// set the trading price for xrp:usd pools
suite.setPrice(d("0.2"), "xrp:usd") suite.setPrice(d("0.2"), "xrp:usd")
// test case 1 execution
cdp.BeginBlocker(suite.ctx, abci.RequestBeginBlock{Header: suite.ctx.BlockHeader()}, suite.keeper) cdp.BeginBlocker(suite.ctx, abci.RequestBeginBlock{Header: suite.ctx.BlockHeader()}, suite.keeper)
// test case 1 assert
acc = ak.GetModuleAccount(suite.ctx, types.ModuleName) acc = ak.GetModuleAccount(suite.ctx, types.ModuleName)
// get the current amount of xrp held by the cdp module
finalXrpCollateral := bk.GetBalance(suite.ctx, acc.GetAddress(), "xrp").Amount finalXrpCollateral := bk.GetBalance(suite.ctx, acc.GetAddress(), "xrp").Amount
seizedXrpCollateral := originalXrpCollateral.Sub(finalXrpCollateral) seizedXrpCollateral := originalXrpCollateral.Sub(finalXrpCollateral)
// calculate the number of cdps that were liquidated based on the total
// seized collateral divided by the size of each cdp when it was created
xrpLiquidations := int(seizedXrpCollateral.Quo(i(10000000000)).Int64()) xrpLiquidations := int(seizedXrpCollateral.Quo(i(10000000000)).Int64())
// should be 10 because...?
suite.Equal(10, xrpLiquidations) suite.Equal(10, xrpLiquidations)
// btc collateral test case setup
acc = ak.GetModuleAccount(suite.ctx, types.ModuleName) acc = ak.GetModuleAccount(suite.ctx, types.ModuleName)
originalBtcCollateral := bk.GetBalance(suite.ctx, acc.GetAddress(), "btc").Amount originalBtcCollateral := bk.GetBalance(suite.ctx, acc.GetAddress(), "btc").Amount
// set the trading price for btc:usd pools
suite.setPrice(d("6000"), "btc:usd") suite.setPrice(d("6000"), "btc:usd")
// btc collateral test case execution
cdp.BeginBlocker(suite.ctx, abci.RequestBeginBlock{Header: suite.ctx.BlockHeader()}, suite.keeper) cdp.BeginBlocker(suite.ctx, abci.RequestBeginBlock{Header: suite.ctx.BlockHeader()}, suite.keeper)
// btc collateral test case assertion 1
acc = ak.GetModuleAccount(suite.ctx, types.ModuleName) acc = ak.GetModuleAccount(suite.ctx, types.ModuleName)
finalBtcCollateral := bk.GetBalance(suite.ctx, acc.GetAddress(), "btc").Amount finalBtcCollateral := bk.GetBalance(suite.ctx, acc.GetAddress(), "btc").Amount
seizedBtcCollateral := originalBtcCollateral.Sub(finalBtcCollateral) seizedBtcCollateral := originalBtcCollateral.Sub(finalBtcCollateral)
// calculate the number of btc cdps that were liquidated based on the
// total seized collateral divided by the fixed size of each cdp
// when it was created during test setup
btcLiquidations := int(seizedBtcCollateral.Quo(i(100000000)).Int64()) btcLiquidations := int(seizedBtcCollateral.Quo(i(100000000)).Int64())
suite.Equal(10, btcLiquidations) suite.Equal(10, btcLiquidations)
// btc collateral test case assertion 2
// test that the auction module has a balance equal to the amount of collateral seized
acc = ak.GetModuleAccount(suite.ctx, auctiontypes.ModuleName) acc = ak.GetModuleAccount(suite.ctx, auctiontypes.ModuleName)
// should be this exact value because...?
suite.Equal(int64(71955653865), bk.GetBalance(suite.ctx, acc.GetAddress(), "debt").Amount.Int64()) suite.Equal(int64(71955653865), bk.GetBalance(suite.ctx, acc.GetAddress(), "debt").Amount.Int64())
} }
func (suite *ModuleTestSuite) TestSeizeSingleCdpWithFees() { func (suite *ModuleTestSuite) TestSeizeSingleCdpWithFees() {
// test setup
// starting with zero cdps, add a single cdp of
// xrp backed 1:1 with usdx
err := suite.keeper.AddCdp(suite.ctx, suite.addrs[0], c("xrp", 10000000000), c("usdx", 1000000000), "xrp-a") err := suite.keeper.AddCdp(suite.ctx, suite.addrs[0], c("xrp", 10000000000), c("usdx", 1000000000), "xrp-a")
suite.NoError(err) suite.NoError(err)
// verify the total value of all assets in cdps composed of xrp-a/usdx pair equals the amount of the single cdp we just added above
suite.Equal(i(1000000000), suite.keeper.GetTotalPrincipal(suite.ctx, "xrp-a", "usdx")) suite.Equal(i(1000000000), suite.keeper.GetTotalPrincipal(suite.ctx, "xrp-a", "usdx"))
ak := suite.app.GetAccountKeeper() ak := suite.app.GetAccountKeeper()
bk := suite.app.GetBankKeeper() bk := suite.app.GetBankKeeper()
@ -174,6 +221,73 @@ func (suite *ModuleTestSuite) TestSeizeSingleCdpWithFees() {
suite.False(found) suite.False(found)
} }
func (suite *ModuleTestSuite) TestCDPBeginBlockerRunsOnlyOnConfiguredInterval() {
// test setup, creating
// 50 xrp cdps each with
// collateral: 10000000000
// debt: between 750000000 - 1249000000
// if debt above 10000000000,
// cdp added to tracker / liquidation list
// debt total added to trackers debt total
// 50 btc cdps each with
// collateral: 10000000000
// debt: between 2700000000 - 5332000000
// if debt above 4000000000,
// cdp added to tracker / liquidation list
// debt total added to trackers debt total
// naively we expect roughly half of the cdps to be above the debt tracking floor, roughly 25 of them collaterallized with xrp, the other 25 with btcb
// usdx is the principal for all cdps
suite.createCdps()
ak := suite.app.GetAccountKeeper()
bk := suite.app.GetBankKeeper()
// set the cdp begin blocker to run every other block
params := suite.keeper.GetParams(suite.ctx)
params.LiquidationBlockInterval = 2
suite.keeper.SetParams(suite.ctx, params)
// test case 1 setup
acc := ak.GetModuleAccount(suite.ctx, types.ModuleName)
// track how much xrp collateral exists in the cdp module
originalXrpCollateral := bk.GetBalance(suite.ctx, acc.GetAddress(), "xrp").Amount
// set the trading price for xrp:usd pools
suite.setPrice(d("0.2"), "xrp:usd")
// test case 1 execution
cdp.BeginBlocker(suite.ctx, abci.RequestBeginBlock{Header: suite.ctx.BlockHeader()}, suite.keeper)
// test case 1 assert
acc = ak.GetModuleAccount(suite.ctx, types.ModuleName)
// get the current amount of xrp held by the cdp module
finalXrpCollateral := bk.GetBalance(suite.ctx, acc.GetAddress(), "xrp").Amount
seizedXrpCollateral := originalXrpCollateral.Sub(finalXrpCollateral)
// calculate the number of cdps that were liquidated based on the total
// seized collateral divided by the size of each cdp when it was created
xrpLiquidations := int(seizedXrpCollateral.Quo(i(10000000000)).Int64())
// should be 0 because the cdp begin blocker is configured to
// skip execution every odd numbered block
suite.Equal(0, xrpLiquidations, "expected cdp begin blocker not to run liqudations")
// test case 2 setup
// simulate running the second block of the chain
suite.ctx = suite.ctx.WithBlockHeight(2)
// test case 2 execution
cdp.BeginBlocker(suite.ctx, abci.RequestBeginBlock{Header: suite.ctx.BlockHeader()}, suite.keeper)
// test case 2 assert
acc = ak.GetModuleAccount(suite.ctx, types.ModuleName)
// get the current amount of xrp held by the cdp module
finalXrpCollateral = bk.GetBalance(suite.ctx, acc.GetAddress(), "xrp").Amount
seizedXrpCollateral = originalXrpCollateral.Sub(finalXrpCollateral)
// calculate the number of cdps that were liquidated based on the total
// seized collateral divided by the size of each cdp when it was created
xrpLiquidations = int(seizedXrpCollateral.Quo(i(10000000000)).Int64())
suite.Greater(xrpLiquidations, 0, "expected cdp begin blocker to run liquidations")
}
func TestModuleTestSuite(t *testing.T) { func TestModuleTestSuite(t *testing.T) {
suite.Run(t, new(ModuleTestSuite)) suite.Run(t, new(ModuleTestSuite))
} }

View File

@ -210,6 +210,7 @@ func (suite *GenesisTestSuite) Test_InitExportGenesis() {
SurplusAuctionLot: types.DefaultSurplusLot, SurplusAuctionLot: types.DefaultSurplusLot,
DebtAuctionThreshold: types.DefaultDebtThreshold, DebtAuctionThreshold: types.DefaultDebtThreshold,
DebtAuctionLot: types.DefaultDebtLot, DebtAuctionLot: types.DefaultDebtLot,
LiquidationBlockInterval: types.DefaultBeginBlockerExecutionBlockInterval,
CollateralParams: types.CollateralParams{ CollateralParams: types.CollateralParams{
{ {
Denom: "xrp", Denom: "xrp",

View File

@ -118,6 +118,7 @@ func NewCDPGenStateMulti(cdc codec.JSONCodec) app.GenesisState {
SurplusAuctionLot: types.DefaultSurplusLot, SurplusAuctionLot: types.DefaultSurplusLot,
DebtAuctionThreshold: types.DefaultDebtThreshold, DebtAuctionThreshold: types.DefaultDebtThreshold,
DebtAuctionLot: types.DefaultDebtLot, DebtAuctionLot: types.DefaultDebtLot,
LiquidationBlockInterval: types.DefaultBeginBlockerExecutionBlockInterval,
CollateralParams: types.CollateralParams{ CollateralParams: types.CollateralParams{
{ {
Denom: "xrp", Denom: "xrp",

View File

@ -47,6 +47,7 @@ func NewCDPGenState(cdc codec.JSONCodec, asset string, liquidationRatio sdk.Dec)
SurplusAuctionLot: types.DefaultSurplusLot, SurplusAuctionLot: types.DefaultSurplusLot,
DebtAuctionThreshold: types.DefaultDebtThreshold, DebtAuctionThreshold: types.DefaultDebtThreshold,
DebtAuctionLot: types.DefaultDebtLot, DebtAuctionLot: types.DefaultDebtLot,
LiquidationBlockInterval: types.DefaultBeginBlockerExecutionBlockInterval,
CollateralParams: types.CollateralParams{ CollateralParams: types.CollateralParams{
{ {
Denom: asset, Denom: asset,
@ -160,6 +161,7 @@ func NewCDPGenStateMulti(cdc codec.JSONCodec) app.GenesisState {
SurplusAuctionLot: types.DefaultSurplusLot, SurplusAuctionLot: types.DefaultSurplusLot,
DebtAuctionThreshold: types.DefaultDebtThreshold, DebtAuctionThreshold: types.DefaultDebtThreshold,
DebtAuctionLot: types.DefaultDebtLot, DebtAuctionLot: types.DefaultDebtLot,
LiquidationBlockInterval: types.DefaultBeginBlockerExecutionBlockInterval,
CollateralParams: types.CollateralParams{ CollateralParams: types.CollateralParams{
{ {
Denom: "xrp", Denom: "xrp",
@ -253,6 +255,7 @@ func NewCDPGenStateHighDebtLimit(cdc codec.JSONCodec) app.GenesisState {
SurplusAuctionLot: types.DefaultSurplusLot, SurplusAuctionLot: types.DefaultSurplusLot,
DebtAuctionThreshold: types.DefaultDebtThreshold, DebtAuctionThreshold: types.DefaultDebtThreshold,
DebtAuctionLot: types.DefaultDebtLot, DebtAuctionLot: types.DefaultDebtLot,
LiquidationBlockInterval: types.DefaultBeginBlockerExecutionBlockInterval,
CollateralParams: types.CollateralParams{ CollateralParams: types.CollateralParams{
{ {
Denom: "xrp", Denom: "xrp",

View File

@ -0,0 +1,23 @@
package keeper
import (
sdk "github.com/cosmos/cosmos-sdk/types"
v2 "github.com/kava-labs/kava/x/cdp/migrations/v2"
)
// Migrator is a struct for handling in-place store migrations.
type Migrator struct {
keeper Keeper
}
// NewMigrator returns a new Migrator.
func NewMigrator(keeper Keeper) Migrator {
return Migrator{
keeper: keeper,
}
}
// Migrate1to2 migrates from version 1 to 2.
func (m Migrator) Migrate1to2(ctx sdk.Context) error {
return v2.MigrateStore(ctx, m.keeper.paramSubspace)
}

View File

@ -12,7 +12,7 @@ import (
// GetParams returns the params from the store // GetParams returns the params from the store
func (k Keeper) GetParams(ctx sdk.Context) types.Params { func (k Keeper) GetParams(ctx sdk.Context) types.Params {
var p types.Params var p types.Params
k.paramSubspace.GetParamSet(ctx, &p) k.paramSubspace.GetParamSetIfExists(ctx, &p)
return p return p
} }

View File

@ -1,109 +0,0 @@
package v0_15
import (
"time"
sdkmath "cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
)
const (
// ModuleName The name that will be used throughout the module
ModuleName = "cdp"
)
// GenesisState is the state that must be provided at genesis.
type GenesisState struct {
Params Params `json:"params" yaml:"params"`
CDPs CDPs `json:"cdps" yaml:"cdps"`
Deposits Deposits `json:"deposits" yaml:"deposits"`
StartingCdpID uint64 `json:"starting_cdp_id" yaml:"starting_cdp_id"`
DebtDenom string `json:"debt_denom" yaml:"debt_denom"`
GovDenom string `json:"gov_denom" yaml:"gov_denom"`
PreviousAccumulationTimes GenesisAccumulationTimes `json:"previous_accumulation_times" yaml:"previous_accumulation_times"`
TotalPrincipals GenesisTotalPrincipals `json:"total_principals" yaml:"total_principals"`
}
// Params governance parameters for cdp module
type Params struct {
CollateralParams CollateralParams `json:"collateral_params" yaml:"collateral_params"`
DebtParam DebtParam `json:"debt_param" yaml:"debt_param"`
GlobalDebtLimit sdk.Coin `json:"global_debt_limit" yaml:"global_debt_limit"`
SurplusAuctionThreshold sdkmath.Int `json:"surplus_auction_threshold" yaml:"surplus_auction_threshold"`
SurplusAuctionLot sdkmath.Int `json:"surplus_auction_lot" yaml:"surplus_auction_lot"`
DebtAuctionThreshold sdkmath.Int `json:"debt_auction_threshold" yaml:"debt_auction_threshold"`
DebtAuctionLot sdkmath.Int `json:"debt_auction_lot" yaml:"debt_auction_lot"`
CircuitBreaker bool `json:"circuit_breaker" yaml:"circuit_breaker"`
}
// CollateralParams array of CollateralParam
type CollateralParams []CollateralParam
// CollateralParam governance parameters for each collateral type within the cdp module
type CollateralParam struct {
Denom string `json:"denom" yaml:"denom"` // Coin name of collateral type
Type string `json:"type" yaml:"type"`
LiquidationRatio sdk.Dec `json:"liquidation_ratio" yaml:"liquidation_ratio"` // The ratio (Collateral (priced in stable coin) / Debt) under which a CDP will be liquidated
DebtLimit sdk.Coin `json:"debt_limit" yaml:"debt_limit"` // Maximum amount of debt allowed to be drawn from this collateral type
StabilityFee sdk.Dec `json:"stability_fee" yaml:"stability_fee"` // per second stability fee for loans opened using this collateral
AuctionSize sdkmath.Int `json:"auction_size" yaml:"auction_size"` // Max amount of collateral to sell off in any one auction.
LiquidationPenalty sdk.Dec `json:"liquidation_penalty" yaml:"liquidation_penalty"` // percentage penalty (between [0, 1]) applied to a cdp if it is liquidated
Prefix byte `json:"prefix" yaml:"prefix"`
SpotMarketID string `json:"spot_market_id" yaml:"spot_market_id"` // marketID of the spot price of the asset from the pricefeed - used for opening CDPs, depositing, withdrawing
LiquidationMarketID string `json:"liquidation_market_id" yaml:"liquidation_market_id"` // marketID of the pricefeed used for liquidation
KeeperRewardPercentage sdk.Dec `json:"keeper_reward_percentage" yaml:"keeper_reward_percentage"` // the percentage of a CDPs collateral that gets rewarded to a keeper that liquidates the position
CheckCollateralizationIndexCount sdkmath.Int `json:"check_collateralization_index_count" yaml:"check_collateralization_index_count"` // the number of cdps that will be checked for liquidation in the begin blocker
ConversionFactor sdkmath.Int `json:"conversion_factor" yaml:"conversion_factor"` // factor for converting internal units to one base unit of collateral
}
// CDPs a collection of CDP objects
type CDPs []CDP
// CDP is the state of a single collateralized debt position.
type CDP struct {
ID uint64 `json:"id" yaml:"id"` // unique id for cdp
Owner sdk.AccAddress `json:"owner" yaml:"owner"` // Account that authorizes changes to the CDP
Type string `json:"type" yaml:"type"` // string representing the unique collateral type of the CDP
Collateral sdk.Coin `json:"collateral" yaml:"collateral"` // Amount of collateral stored in this CDP
Principal sdk.Coin `json:"principal" yaml:"principal"` // Amount of debt drawn using the CDP
AccumulatedFees sdk.Coin `json:"accumulated_fees" yaml:"accumulated_fees"` // Fees accumulated since the CDP was opened or debt was last repaid
FeesUpdated time.Time `json:"fees_updated" yaml:"fees_updated"` // The time when fees were last updated
InterestFactor sdk.Dec `json:"interest_factor" yaml:"interest_factor"` // the interest factor when fees were last calculated for this CDP
}
// Deposits a collection of Deposit objects
type Deposits []Deposit
// Deposit defines an amount of coins deposited by an account to a cdp
type Deposit struct {
CdpID uint64 `json:"cdp_id" yaml:"cdp_id"` // cdpID of the cdp
Depositor sdk.AccAddress `json:"depositor" yaml:"depositor"` // Address of the depositor
Amount sdk.Coin `json:"amount" yaml:"amount"` // Deposit amount
}
// GenesisAccumulationTimes slice of GenesisAccumulationTime
type GenesisAccumulationTimes []GenesisAccumulationTime
// GenesisAccumulationTime stores the previous distribution time and its corresponding denom
type GenesisAccumulationTime struct {
CollateralType string `json:"collateral_type" yaml:"collateral_type"`
PreviousAccumulationTime time.Time `json:"previous_accumulation_time" yaml:"previous_accumulation_time"`
InterestFactor sdk.Dec `json:"interest_factor" yaml:"interest_factor"`
}
// GenesisTotalPrincipals slice of GenesisTotalPrincipal
type GenesisTotalPrincipals []GenesisTotalPrincipal
// GenesisTotalPrincipal stores the total principal and its corresponding collateral type
type GenesisTotalPrincipal struct {
CollateralType string `json:"collateral_type" yaml:"collateral_type"`
TotalPrincipal sdkmath.Int `json:"total_principal" yaml:"total_principal"`
}
// DebtParam governance params for debt assets
type DebtParam struct {
Denom string `json:"denom" yaml:"denom"`
ReferenceAsset string `json:"reference_asset" yaml:"reference_asset"`
ConversionFactor sdkmath.Int `json:"conversion_factor" yaml:"conversion_factor"`
DebtFloor sdkmath.Int `json:"debt_floor" yaml:"debt_floor"` // minimum active loan size, used to prevent dust
}

View File

@ -1,109 +0,0 @@
package v0_16
import (
v015cdp "github.com/kava-labs/kava/x/cdp/legacy/v0_15"
v016cdp "github.com/kava-labs/kava/x/cdp/types"
)
func migrateParams(params v015cdp.Params) v016cdp.Params {
// migrate collateral params
collateralParams := make(v016cdp.CollateralParams, len(params.CollateralParams))
for i, cp := range params.CollateralParams {
collateralParams[i] = v016cdp.CollateralParam{
Denom: cp.Denom,
Type: cp.Type,
LiquidationRatio: cp.LiquidationRatio,
DebtLimit: cp.DebtLimit,
StabilityFee: cp.StabilityFee,
AuctionSize: cp.AuctionSize,
LiquidationPenalty: cp.LiquidationPenalty,
SpotMarketID: cp.SpotMarketID,
LiquidationMarketID: cp.LiquidationMarketID,
KeeperRewardPercentage: cp.KeeperRewardPercentage,
CheckCollateralizationIndexCount: cp.CheckCollateralizationIndexCount,
ConversionFactor: cp.ConversionFactor,
}
}
return v016cdp.Params{
CollateralParams: collateralParams,
DebtParam: v016cdp.DebtParam{
Denom: params.DebtParam.Denom,
ReferenceAsset: params.DebtParam.ReferenceAsset,
ConversionFactor: params.DebtParam.ConversionFactor,
DebtFloor: params.DebtParam.DebtFloor,
},
GlobalDebtLimit: params.GlobalDebtLimit,
SurplusAuctionThreshold: params.SurplusAuctionThreshold,
SurplusAuctionLot: params.SurplusAuctionLot,
DebtAuctionThreshold: params.DebtAuctionThreshold,
DebtAuctionLot: params.DebtAuctionLot,
CircuitBreaker: params.CircuitBreaker,
}
}
func migrateCDPs(oldCDPs v015cdp.CDPs) v016cdp.CDPs {
cdps := make(v016cdp.CDPs, len(oldCDPs))
for i, cdp := range oldCDPs {
cdps[i] = v016cdp.CDP{
ID: cdp.ID,
Owner: cdp.Owner,
Type: cdp.Type,
Collateral: cdp.Collateral,
Principal: cdp.Principal,
AccumulatedFees: cdp.AccumulatedFees,
FeesUpdated: cdp.FeesUpdated,
InterestFactor: cdp.InterestFactor,
}
}
return cdps
}
func migrateDeposits(oldDeposits v015cdp.Deposits) v016cdp.Deposits {
deposits := make(v016cdp.Deposits, len(oldDeposits))
for i, deposit := range oldDeposits {
deposits[i] = v016cdp.Deposit{
CdpID: deposit.CdpID,
Depositor: deposit.Depositor,
Amount: deposit.Amount,
}
}
return deposits
}
func migratePrevAccTimes(oldPrevAccTimes v015cdp.GenesisAccumulationTimes) v016cdp.GenesisAccumulationTimes {
prevAccTimes := make(v016cdp.GenesisAccumulationTimes, len(oldPrevAccTimes))
for i, prevAccTime := range oldPrevAccTimes {
prevAccTimes[i] = v016cdp.GenesisAccumulationTime{
CollateralType: prevAccTime.CollateralType,
PreviousAccumulationTime: prevAccTime.PreviousAccumulationTime,
InterestFactor: prevAccTime.InterestFactor,
}
}
return prevAccTimes
}
func migrateTotalPrincipals(oldTotalPrincipals v015cdp.GenesisTotalPrincipals) v016cdp.GenesisTotalPrincipals {
totalPrincipals := make(v016cdp.GenesisTotalPrincipals, len(oldTotalPrincipals))
for i, tp := range oldTotalPrincipals {
totalPrincipals[i] = v016cdp.GenesisTotalPrincipal{
CollateralType: tp.CollateralType,
TotalPrincipal: tp.TotalPrincipal,
}
}
return totalPrincipals
}
// Migrate converts v0.15 cdp state and returns it in v0.16 format
func Migrate(oldState v015cdp.GenesisState) *v016cdp.GenesisState {
return &v016cdp.GenesisState{
Params: migrateParams(oldState.Params),
CDPs: migrateCDPs(oldState.CDPs),
Deposits: migrateDeposits(oldState.Deposits),
StartingCdpID: oldState.StartingCdpID,
DebtDenom: oldState.DebtDenom,
GovDenom: oldState.GovDenom,
PreviousAccumulationTimes: migratePrevAccTimes(oldState.PreviousAccumulationTimes),
TotalPrincipals: migrateTotalPrincipals(oldState.TotalPrincipals),
}
}

View File

@ -1,216 +0,0 @@
package v0_16
import (
"io/ioutil"
"path/filepath"
"testing"
"time"
sdkmath "cosmossdk.io/math"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/suite"
app "github.com/kava-labs/kava/app"
v015cdp "github.com/kava-labs/kava/x/cdp/legacy/v0_15"
v016cdp "github.com/kava-labs/kava/x/cdp/types"
)
type migrateTestSuite struct {
suite.Suite
addresses []sdk.AccAddress
v15genstate v015cdp.GenesisState
cdc codec.Codec
legacyCdc *codec.LegacyAmino
}
func (s *migrateTestSuite) SetupTest() {
app.SetSDKConfig()
s.v15genstate = v015cdp.GenesisState{
Params: v015cdp.Params{},
CDPs: v015cdp.CDPs{},
Deposits: v015cdp.Deposits{},
StartingCdpID: 1,
DebtDenom: "usdx",
GovDenom: "ukava",
PreviousAccumulationTimes: v015cdp.GenesisAccumulationTimes{},
TotalPrincipals: v015cdp.GenesisTotalPrincipals{},
}
config := app.MakeEncodingConfig()
s.cdc = config.Marshaler
legacyCodec := codec.NewLegacyAmino()
s.legacyCdc = legacyCodec
_, accAddresses := app.GeneratePrivKeyAddressPairs(10)
s.addresses = accAddresses
}
func (s *migrateTestSuite) TestMigrate_JSON() {
file := filepath.Join("testdata", "v15-cdp.json")
data, err := ioutil.ReadFile(file)
s.Require().NoError(err)
err = s.legacyCdc.UnmarshalJSON(data, &s.v15genstate)
s.Require().NoError(err)
genstate := Migrate(s.v15genstate)
actual := s.cdc.MustMarshalJSON(genstate)
file = filepath.Join("testdata", "v16-cdp.json")
expected, err := ioutil.ReadFile(file)
s.Require().NoError(err)
s.Require().JSONEq(string(expected), string(actual))
}
func (s *migrateTestSuite) TestMigrate_GenState() {
s.v15genstate = v015cdp.GenesisState{
StartingCdpID: 2,
DebtDenom: "usdx",
GovDenom: "ukava",
Params: v015cdp.Params{
CollateralParams: v015cdp.CollateralParams{
{
Denom: "xrp",
Type: "xrp-a",
LiquidationRatio: sdk.MustNewDecFromStr("2.0"),
DebtLimit: sdk.NewInt64Coin("usdx", 500000000000),
StabilityFee: sdk.MustNewDecFromStr("1.012"),
LiquidationPenalty: sdk.MustNewDecFromStr("0.05"),
AuctionSize: sdkmath.NewInt(70),
SpotMarketID: "xrp:usd",
LiquidationMarketID: "xrp:usd",
KeeperRewardPercentage: sdk.MustNewDecFromStr("0.01"),
CheckCollateralizationIndexCount: sdkmath.NewInt(10),
ConversionFactor: sdkmath.NewInt(6),
},
},
DebtParam: v015cdp.DebtParam{
Denom: "usdx",
ReferenceAsset: "usd",
ConversionFactor: sdkmath.NewInt(6),
DebtFloor: sdkmath.NewInt(100),
},
GlobalDebtLimit: sdk.NewInt64Coin("usdx", 1000000000000),
SurplusAuctionThreshold: sdkmath.NewInt(6),
SurplusAuctionLot: sdkmath.NewInt(7),
DebtAuctionThreshold: sdkmath.NewInt(8),
DebtAuctionLot: sdkmath.NewInt(9),
},
CDPs: v015cdp.CDPs{
{
ID: 2,
Owner: s.addresses[0],
Type: "xrp-a",
Collateral: sdk.NewCoin("xrp", sdkmath.NewInt(2123)),
Principal: sdk.NewCoin("usdx", sdkmath.NewInt(100)),
AccumulatedFees: sdk.NewCoin("usdx", sdk.ZeroInt()),
FeesUpdated: time.Date(2020, time.January, 1, 0, 0, 0, 0, time.UTC),
InterestFactor: sdk.NewDec(1),
},
},
Deposits: v015cdp.Deposits{
{
CdpID: 1,
Depositor: s.addresses[0],
Amount: sdk.NewCoin("usdx", sdkmath.NewInt(100)),
},
{
CdpID: 2,
Depositor: s.addresses[1],
Amount: sdk.NewCoin("ukava", sdkmath.NewInt(1200)),
},
},
PreviousAccumulationTimes: v015cdp.GenesisAccumulationTimes{
{
CollateralType: "usdx",
PreviousAccumulationTime: time.Date(2020, time.January, 1, 0, 0, 0, 0, time.UTC),
InterestFactor: sdk.MustNewDecFromStr("0.02"),
},
},
TotalPrincipals: v015cdp.GenesisTotalPrincipals{
{
CollateralType: "usdx",
TotalPrincipal: sdkmath.NewInt(1200),
},
},
}
expected := v016cdp.GenesisState{
StartingCdpID: 2,
DebtDenom: "usdx",
GovDenom: "ukava",
Params: v016cdp.Params{
CollateralParams: v016cdp.CollateralParams{
{
Denom: "xrp",
Type: "xrp-a",
LiquidationRatio: sdk.MustNewDecFromStr("2.0"),
DebtLimit: sdk.NewInt64Coin("usdx", 500000000000),
StabilityFee: sdk.MustNewDecFromStr("1.012"),
LiquidationPenalty: sdk.MustNewDecFromStr("0.05"),
AuctionSize: sdkmath.NewInt(70),
SpotMarketID: "xrp:usd",
LiquidationMarketID: "xrp:usd",
KeeperRewardPercentage: sdk.MustNewDecFromStr("0.01"),
CheckCollateralizationIndexCount: sdkmath.NewInt(10),
ConversionFactor: sdkmath.NewInt(6),
},
},
DebtParam: v016cdp.DebtParam{
Denom: "usdx",
ReferenceAsset: "usd",
ConversionFactor: sdkmath.NewInt(6),
DebtFloor: sdkmath.NewInt(100),
},
GlobalDebtLimit: sdk.NewInt64Coin("usdx", 1000000000000),
SurplusAuctionThreshold: sdkmath.NewInt(6),
SurplusAuctionLot: sdkmath.NewInt(7),
DebtAuctionThreshold: sdkmath.NewInt(8),
DebtAuctionLot: sdkmath.NewInt(9),
},
CDPs: v016cdp.CDPs{
{
ID: 2,
Owner: s.addresses[0],
Type: "xrp-a",
Collateral: sdk.NewCoin("xrp", sdkmath.NewInt(2123)),
Principal: sdk.NewCoin("usdx", sdkmath.NewInt(100)),
AccumulatedFees: sdk.NewCoin("usdx", sdk.ZeroInt()),
FeesUpdated: time.Date(2020, time.January, 1, 0, 0, 0, 0, time.UTC),
InterestFactor: sdk.NewDec(1),
},
},
Deposits: v016cdp.Deposits{
{
CdpID: 1,
Depositor: s.addresses[0],
Amount: sdk.NewCoin("usdx", sdkmath.NewInt(100)),
},
{
CdpID: 2,
Depositor: s.addresses[1],
Amount: sdk.NewCoin("ukava", sdkmath.NewInt(1200)),
},
},
PreviousAccumulationTimes: v016cdp.GenesisAccumulationTimes{
{
CollateralType: "usdx",
PreviousAccumulationTime: time.Date(2020, time.January, 1, 0, 0, 0, 0, time.UTC),
InterestFactor: sdk.MustNewDecFromStr("0.02"),
},
},
TotalPrincipals: v016cdp.GenesisTotalPrincipals{
{
CollateralType: "usdx",
TotalPrincipal: sdkmath.NewInt(1200),
},
},
}
genState := Migrate(s.v15genstate)
s.Require().Equal(expected, *genState)
}
func TestCdpMigrateTestSuite(t *testing.T) {
suite.Run(t, new(migrateTestSuite))
}

View File

@ -1,135 +0,0 @@
{
"cdps": [
{
"accumulated_fees": {
"amount": "36088",
"denom": "usdx"
},
"collateral": {
"amount": "40911876",
"denom": "bnb"
},
"fees_updated": "2021-11-05T21:13:12.85608847Z",
"id": "19",
"interest_factor": "1.002881426571765716",
"owner": "kava1u4p6a2yse66ewfndw4j7ppsa777vdcex3m4n9s",
"principal": {
"amount": "10016831",
"denom": "usdx"
},
"type": "bnb-a"
},
{
"accumulated_fees": {
"amount": "156662",
"denom": "usdx"
},
"collateral": {
"amount": "88268546",
"denom": "bnb"
},
"fees_updated": "2021-11-05T21:13:12.85608847Z",
"id": "22",
"interest_factor": "1.002881426571765716",
"owner": "kava1e8xjfylam4nvugcmkxwvuxh22uvvad5vknu4yh",
"principal": {
"amount": "10000000",
"denom": "usdx"
},
"type": "bnb-a"
}
],
"debt_denom": "debt",
"deposits": [
{
"amount": {
"amount": "40911876",
"denom": "bnb"
},
"cdp_id": "19",
"depositor": "kava1u4p6a2yse66ewfndw4j7ppsa777vdcex3m4n9s"
},
{
"amount": {
"amount": "88268546",
"denom": "bnb"
},
"cdp_id": "22",
"depositor": "kava1e8xjfylam4nvugcmkxwvuxh22uvvad5vknu4yh"
}
],
"gov_denom": "ukava",
"params": {
"circuit_breaker": false,
"collateral_params": [
{
"auction_size": "50000000000",
"conversion_factor": "8",
"debt_limit": {
"amount": "20000000000000",
"denom": "usdx"
},
"denom": "bnb",
"liquidation_market_id": "bnb:usd:30",
"liquidation_penalty": "0.050000000000000000",
"liquidation_ratio": "1.500000000000000000",
"keeper_reward_percentage": "0.01",
"check_collateralization_index_count": "10",
"prefix": 1,
"spot_market_id": "bnb:usd",
"stability_fee": "1.000000000782997700",
"type": "bnb-a"
},
{
"denom": "hbtc",
"type": "hbtc-a",
"liquidation_ratio": "1.500000000000000000",
"debt_limit": {
"denom": "usdx",
"amount": "10000000000000"
},
"stability_fee": "1.000000001547125958",
"auction_size": "1000000000000",
"liquidation_penalty": "0.075000000000000000",
"check_collateralization_index_count": "10",
"keeper_reward_percentage": "0.01",
"prefix": 8,
"spot_market_id": "btc:usd",
"liquidation_market_id": "btc:usd:30",
"conversion_factor": "8"
}
],
"debt_auction_lot": "10000000000",
"debt_auction_threshold": "100000000000",
"debt_param": {
"conversion_factor": "6",
"debt_floor": "10000000",
"denom": "usdx",
"reference_asset": "usd",
"savings_rate": "0.950000000000000000"
},
"global_debt_limit": {
"amount": "43000000000000",
"denom": "usdx"
},
"savings_distribution_frequency": "43200000000000",
"surplus_auction_lot": "10000000000",
"surplus_auction_threshold": "500000000000"
},
"previous_distribution_time": "1970-01-01T00:00:00Z",
"savings_rate_distributed": "0",
"starting_cdp_id": "1",
"previous_accumulation_times": [
{
"collateral_type": "bnb-a",
"interest_factor": "1.002881426571765716",
"previous_accumulation_time": "2021-11-05T21:13:12.85608847Z"
}
],
"total_principals": [
{
"collateral_type": "bnb-a",
"total_principal": "9285009581820"
}
]
}

View File

@ -1,93 +0,0 @@
{
"params": {
"collateral_params": [
{
"denom": "bnb",
"type": "bnb-a",
"liquidation_ratio": "1.500000000000000000",
"debt_limit": { "denom": "usdx", "amount": "20000000000000" },
"stability_fee": "1.000000000782997700",
"auction_size": "50000000000",
"liquidation_penalty": "0.050000000000000000",
"spot_market_id": "bnb:usd",
"liquidation_market_id": "bnb:usd:30",
"keeper_reward_percentage": "0.010000000000000000",
"check_collateralization_index_count": "10",
"conversion_factor": "8"
},
{
"denom": "hbtc",
"type": "hbtc-a",
"liquidation_ratio": "1.500000000000000000",
"debt_limit": { "denom": "usdx", "amount": "10000000000000" },
"stability_fee": "1.000000001547125958",
"auction_size": "1000000000000",
"liquidation_penalty": "0.075000000000000000",
"spot_market_id": "btc:usd",
"liquidation_market_id": "btc:usd:30",
"keeper_reward_percentage": "0.010000000000000000",
"check_collateralization_index_count": "10",
"conversion_factor": "8"
}
],
"debt_param": {
"denom": "usdx",
"reference_asset": "usd",
"conversion_factor": "6",
"debt_floor": "10000000"
},
"global_debt_limit": { "denom": "usdx", "amount": "43000000000000" },
"surplus_auction_threshold": "500000000000",
"surplus_auction_lot": "10000000000",
"debt_auction_threshold": "100000000000",
"debt_auction_lot": "10000000000",
"circuit_breaker": false
},
"cdps": [
{
"id": "19",
"owner": "kava1u4p6a2yse66ewfndw4j7ppsa777vdcex3m4n9s",
"type": "bnb-a",
"collateral": { "denom": "bnb", "amount": "40911876" },
"principal": { "denom": "usdx", "amount": "10016831" },
"accumulated_fees": { "denom": "usdx", "amount": "36088" },
"fees_updated": "2021-11-05T21:13:12.856088470Z",
"interest_factor": "1.002881426571765716"
},
{
"id": "22",
"owner": "kava1e8xjfylam4nvugcmkxwvuxh22uvvad5vknu4yh",
"type": "bnb-a",
"collateral": { "denom": "bnb", "amount": "88268546" },
"principal": { "denom": "usdx", "amount": "10000000" },
"accumulated_fees": { "denom": "usdx", "amount": "156662" },
"fees_updated": "2021-11-05T21:13:12.856088470Z",
"interest_factor": "1.002881426571765716"
}
],
"deposits": [
{
"cdp_id": "19",
"depositor": "kava1u4p6a2yse66ewfndw4j7ppsa777vdcex3m4n9s",
"amount": { "denom": "bnb", "amount": "40911876" }
},
{
"cdp_id": "22",
"depositor": "kava1e8xjfylam4nvugcmkxwvuxh22uvvad5vknu4yh",
"amount": { "denom": "bnb", "amount": "88268546" }
}
],
"starting_cdp_id": "1",
"debt_denom": "debt",
"gov_denom": "ukava",
"previous_accumulation_times": [
{
"collateral_type": "bnb-a",
"previous_accumulation_time": "2021-11-05T21:13:12.856088470Z",
"interest_factor": "1.002881426571765716"
}
],
"total_principals": [
{ "collateral_type": "bnb-a", "total_principal": "9285009581820" }
]
}

View File

@ -0,0 +1,22 @@
package v2
import (
sdk "github.com/cosmos/cosmos-sdk/types"
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
"github.com/kava-labs/kava/x/cdp/types"
)
// MigrateStore performs in-place store migrations for consensus version 2
// V2 adds the begin_blocker_execution_block_interval param to parameters.
func MigrateStore(ctx sdk.Context, paramstore paramtypes.Subspace) error {
migrateParamsStore(ctx, paramstore)
return nil
}
// migrateParamsStore ensures the param key table exists and has the begin_blocker_execution_block_interval property
func migrateParamsStore(ctx sdk.Context, paramstore paramtypes.Subspace) {
if !paramstore.HasKeyTable() {
paramstore.WithKeyTable(types.ParamKeyTable())
}
paramstore.Set(ctx, types.KeyBeginBlockerExecutionBlockInterval, types.DefaultBeginBlockerExecutionBlockInterval)
}

View File

@ -0,0 +1,63 @@
package v2_test
import (
"testing"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/simapp"
"github.com/cosmos/cosmos-sdk/testutil"
sdk "github.com/cosmos/cosmos-sdk/types"
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
v2cdp "github.com/kava-labs/kava/x/cdp/migrations/v2"
"github.com/kava-labs/kava/x/cdp/types"
)
func TestStoreMigrationAddsKeyTableIncludingNewParam(t *testing.T) {
encCfg := simapp.MakeTestEncodingConfig()
cdpKey := sdk.NewKVStoreKey(types.ModuleName)
tcdpKey := sdk.NewTransientStoreKey("transient_test")
ctx := testutil.DefaultContext(cdpKey, tcdpKey)
paramstore := paramtypes.NewSubspace(encCfg.Codec, encCfg.Amino, cdpKey, tcdpKey, types.ModuleName)
// Check param doesn't exist before
require.False(t, paramstore.Has(ctx, types.KeyBeginBlockerExecutionBlockInterval))
// Run migrations.
err := v2cdp.MigrateStore(ctx, paramstore)
require.NoError(t, err)
// Make sure the new params are set.
require.True(t, paramstore.Has(ctx, types.KeyBeginBlockerExecutionBlockInterval))
// Assert the value is what we expect
result := types.DefaultBeginBlockerExecutionBlockInterval
paramstore.Get(ctx, types.KeyBeginBlockerExecutionBlockInterval, &result)
require.Equal(t, result, types.DefaultBeginBlockerExecutionBlockInterval)
}
func TestStoreMigrationSetsNewParamOnExistingKeyTable(t *testing.T) {
encCfg := simapp.MakeTestEncodingConfig()
cdpKey := sdk.NewKVStoreKey(types.ModuleName)
tcdpKey := sdk.NewTransientStoreKey("transient_test")
ctx := testutil.DefaultContext(cdpKey, tcdpKey)
paramstore := paramtypes.NewSubspace(encCfg.Codec, encCfg.Amino, cdpKey, tcdpKey, types.ModuleName)
paramstore.WithKeyTable(types.ParamKeyTable())
// expect it to have key table
require.True(t, paramstore.HasKeyTable())
// expect it to not have new param
require.False(t, paramstore.Has(ctx, types.KeyBeginBlockerExecutionBlockInterval))
// Run migrations.
err := v2cdp.MigrateStore(ctx, paramstore)
require.NoError(t, err)
// Make sure the new params are set.
require.True(t, paramstore.Has(ctx, types.KeyBeginBlockerExecutionBlockInterval))
// Assert the value is what we expect
result := types.DefaultBeginBlockerExecutionBlockInterval
paramstore.Get(ctx, types.KeyBeginBlockerExecutionBlockInterval, &result)
require.Equal(t, result, types.DefaultBeginBlockerExecutionBlockInterval)
}

View File

@ -3,6 +3,7 @@ package cdp
import ( import (
"context" "context"
"encoding/json" "encoding/json"
"fmt"
"github.com/grpc-ecosystem/grpc-gateway/runtime" "github.com/grpc-ecosystem/grpc-gateway/runtime"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -26,6 +27,9 @@ var (
// _ module.AppModuleSimulation = AppModule{} // _ module.AppModuleSimulation = AppModule{}
) )
// ConsensusVersion defines the current module consensus version.
const ConsensusVersion = 2
// AppModuleBasic app module basics object // AppModuleBasic app module basics object
type AppModuleBasic struct{} type AppModuleBasic struct{}
@ -75,7 +79,7 @@ func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sd
// ConsensusVersion implements AppModule/ConsensusVersion. // ConsensusVersion implements AppModule/ConsensusVersion.
func (AppModule) ConsensusVersion() uint64 { func (AppModule) ConsensusVersion() uint64 {
return 1 return ConsensusVersion
} }
// GetTxCmd returns the root tx command for the cdp module. // GetTxCmd returns the root tx command for the cdp module.
@ -133,6 +137,11 @@ func (AppModule) QuerierRoute() string {
func (am AppModule) RegisterServices(cfg module.Configurator) { func (am AppModule) RegisterServices(cfg module.Configurator) {
types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper)) types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper))
types.RegisterQueryServer(cfg.QueryServer(), keeper.NewQueryServerImpl(am.keeper)) types.RegisterQueryServer(cfg.QueryServer(), keeper.NewQueryServerImpl(am.keeper))
m := keeper.NewMigrator(am.keeper)
if err := cfg.RegisterMigration(types.ModuleName, 1, m.Migrate1to2); err != nil {
panic(fmt.Sprintf("failed to migrate x/cdp from version 1 to 2: %v", err))
}
} }
// InitGenesis module init-genesis // InitGenesis module init-genesis

View File

@ -142,6 +142,7 @@ type Params struct {
DebtAuctionThreshold github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,6,opt,name=debt_auction_threshold,json=debtAuctionThreshold,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"debt_auction_threshold"` DebtAuctionThreshold github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,6,opt,name=debt_auction_threshold,json=debtAuctionThreshold,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"debt_auction_threshold"`
DebtAuctionLot github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,7,opt,name=debt_auction_lot,json=debtAuctionLot,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"debt_auction_lot"` DebtAuctionLot github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,7,opt,name=debt_auction_lot,json=debtAuctionLot,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"debt_auction_lot"`
CircuitBreaker bool `protobuf:"varint,8,opt,name=circuit_breaker,json=circuitBreaker,proto3" json:"circuit_breaker,omitempty"` CircuitBreaker bool `protobuf:"varint,8,opt,name=circuit_breaker,json=circuitBreaker,proto3" json:"circuit_breaker,omitempty"`
LiquidationBlockInterval int64 `protobuf:"varint,9,opt,name=liquidation_block_interval,json=liquidationBlockInterval,proto3" json:"liquidation_block_interval,omitempty"`
} }
func (m *Params) Reset() { *m = Params{} } func (m *Params) Reset() { *m = Params{} }
@ -205,6 +206,13 @@ func (m *Params) GetCircuitBreaker() bool {
return false return false
} }
func (m *Params) GetLiquidationBlockInterval() int64 {
if m != nil {
return m.LiquidationBlockInterval
}
return 0
}
// DebtParam defines governance params for debt assets // DebtParam defines governance params for debt assets
type DebtParam struct { type DebtParam struct {
Denom string `protobuf:"bytes,1,opt,name=denom,proto3" json:"denom,omitempty"` Denom string `protobuf:"bytes,1,opt,name=denom,proto3" json:"denom,omitempty"`
@ -456,81 +464,83 @@ func init() {
func init() { proto.RegisterFile("kava/cdp/v1beta1/genesis.proto", fileDescriptor_e4494a90aaab0034) } func init() { proto.RegisterFile("kava/cdp/v1beta1/genesis.proto", fileDescriptor_e4494a90aaab0034) }
var fileDescriptor_e4494a90aaab0034 = []byte{ var fileDescriptor_e4494a90aaab0034 = []byte{
// 1179 bytes of a gzipped FileDescriptorProto // 1208 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x57, 0xcd, 0x6e, 0x1b, 0x37, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x57, 0xdd, 0x6e, 0x1a, 0xc7,
0x10, 0xf6, 0x3a, 0x8a, 0x23, 0xd1, 0x8a, 0x24, 0x33, 0x4e, 0xb2, 0x76, 0x50, 0x49, 0x75, 0xd1, 0x17, 0xf7, 0xda, 0xc4, 0x81, 0xb1, 0x63, 0xf0, 0xc4, 0x49, 0xd6, 0x8e, 0xfe, 0xc0, 0xdf, 0x55,
0xc6, 0x3d, 0x58, 0x42, 0x52, 0x20, 0x40, 0x81, 0xa2, 0xa9, 0x65, 0xc1, 0x81, 0x11, 0x17, 0x10, 0x1b, 0x7a, 0x11, 0x50, 0x52, 0x29, 0x52, 0xa5, 0xa8, 0x69, 0xd6, 0x28, 0x11, 0x4a, 0x2a, 0xa1,
0xd6, 0x3e, 0xb5, 0x87, 0x05, 0x97, 0x4b, 0xc9, 0x84, 0x56, 0xcb, 0x2d, 0x49, 0xa9, 0xb6, 0x5f, 0xb5, 0xaf, 0xda, 0x8b, 0xd5, 0xec, 0xec, 0x80, 0x47, 0x2c, 0x3b, 0xdb, 0x99, 0x81, 0x26, 0x79,
0xa1, 0x28, 0x1a, 0xf4, 0x25, 0x0a, 0xe4, 0xdc, 0x87, 0x48, 0x6f, 0x41, 0x4f, 0x45, 0x0f, 0x72, 0x85, 0xaa, 0x6a, 0xd4, 0x97, 0xa8, 0x14, 0xf5, 0xb2, 0x0f, 0x91, 0xde, 0x45, 0xbd, 0xaa, 0x7a,
0x21, 0xdf, 0xfb, 0x0c, 0x05, 0x7f, 0xf4, 0x63, 0xc9, 0x02, 0x02, 0x5b, 0xbd, 0x58, 0xcb, 0x19, 0x41, 0x2a, 0xf2, 0x22, 0xd5, 0x7c, 0x00, 0x6b, 0x30, 0x52, 0x64, 0xd3, 0x1b, 0x76, 0xe7, 0x7c,
0xce, 0xf7, 0xcd, 0x90, 0x33, 0xc3, 0x31, 0x28, 0xb6, 0x51, 0x0f, 0x55, 0x71, 0x98, 0x54, 0x7b, 0xfc, 0xce, 0xc7, 0x9c, 0x73, 0xf6, 0x00, 0xca, 0x3d, 0x34, 0x44, 0x0d, 0x1c, 0xa5, 0x8d, 0xe1,
0xcf, 0x02, 0x22, 0xd1, 0xb3, 0x6a, 0x8b, 0xc4, 0x44, 0x50, 0x51, 0x49, 0x38, 0x93, 0x0c, 0x16, 0xbd, 0x90, 0x48, 0x74, 0xaf, 0xd1, 0x25, 0x09, 0x11, 0x54, 0xd4, 0x53, 0xce, 0x24, 0x83, 0x25,
0x94, 0xbe, 0x82, 0xc3, 0xa4, 0x62, 0xf5, 0x9b, 0x45, 0xcc, 0x44, 0x87, 0x89, 0x6a, 0x80, 0x04, 0xc5, 0xaf, 0xe3, 0x28, 0xad, 0x5b, 0xfe, 0x41, 0x19, 0x33, 0xd1, 0x67, 0xa2, 0x11, 0x22, 0x41,
0x19, 0x19, 0x61, 0x46, 0x63, 0x63, 0xb1, 0xb9, 0x61, 0xf4, 0xbe, 0x5e, 0x55, 0xcd, 0xc2, 0xaa, 0xa6, 0x4a, 0x98, 0xd1, 0xc4, 0x68, 0x1c, 0xec, 0x1b, 0x7e, 0xa0, 0x4f, 0x0d, 0x73, 0xb0, 0xac,
0xd6, 0x5b, 0xac, 0xc5, 0x8c, 0x5c, 0x7d, 0x59, 0x69, 0xa9, 0xc5, 0x58, 0x2b, 0x22, 0x55, 0xbd, 0xbd, 0x2e, 0xeb, 0x32, 0x43, 0x57, 0x6f, 0x96, 0x5a, 0xe9, 0x32, 0xd6, 0x8d, 0x49, 0x43, 0x9f,
0x0a, 0xba, 0xcd, 0xaa, 0xa4, 0x1d, 0x22, 0x24, 0xea, 0x24, 0x76, 0xc3, 0xe6, 0x8c, 0x8f, 0xca, 0xc2, 0x41, 0xa7, 0x21, 0x69, 0x9f, 0x08, 0x89, 0xfa, 0xa9, 0x15, 0x38, 0x58, 0xf0, 0x51, 0xf9,
0x1f, 0xad, 0xdb, 0xfa, 0x23, 0x05, 0xb2, 0xaf, 0x8c, 0xc7, 0x47, 0x12, 0x49, 0x02, 0x5f, 0x80, 0xa3, 0x79, 0x87, 0x7f, 0xe4, 0xc0, 0xf6, 0x53, 0xe3, 0xf1, 0xb1, 0x44, 0x92, 0xc0, 0x07, 0x60,
0x95, 0x04, 0x71, 0xd4, 0x11, 0xae, 0x53, 0x76, 0xb6, 0x57, 0x9f, 0xbb, 0x95, 0xe9, 0x08, 0x2a, 0x33, 0x45, 0x1c, 0xf5, 0x85, 0xeb, 0x54, 0x9d, 0xda, 0xd6, 0x7d, 0xb7, 0x3e, 0x1f, 0x41, 0xbd,
0x0d, 0xad, 0xaf, 0xa5, 0xde, 0xf5, 0x4b, 0x4b, 0x9e, 0xdd, 0x0d, 0x5f, 0x82, 0x14, 0x0e, 0x13, 0xad, 0xf9, 0x5e, 0xee, 0xed, 0xa8, 0xb2, 0xe6, 0x5b, 0x69, 0xf8, 0x08, 0xe4, 0x70, 0x94, 0x0a,
0xe1, 0x2e, 0x97, 0xef, 0x6c, 0xaf, 0x3e, 0x7f, 0x38, 0x6b, 0xb5, 0x57, 0x6f, 0xd4, 0xd6, 0x95, 0x77, 0xbd, 0xba, 0x51, 0xdb, 0xba, 0x7f, 0x63, 0x51, 0xeb, 0xa8, 0xd9, 0xf6, 0xf6, 0x94, 0xca,
0xc9, 0xa0, 0x5f, 0x4a, 0xed, 0xd5, 0x1b, 0xe2, 0xed, 0x85, 0xf9, 0xf5, 0xb4, 0x21, 0x7c, 0x05, 0x78, 0x54, 0xc9, 0x1d, 0x35, 0xdb, 0xe2, 0xcd, 0x7b, 0xf3, 0xf4, 0xb5, 0x22, 0x7c, 0x0a, 0xf2,
0xd2, 0x21, 0x49, 0x98, 0xa0, 0x52, 0xb8, 0x77, 0x34, 0xc8, 0xc6, 0x2c, 0x48, 0xdd, 0xec, 0xa8, 0x11, 0x49, 0x99, 0xa0, 0x52, 0xb8, 0x1b, 0x1a, 0x64, 0x7f, 0x11, 0xa4, 0x69, 0x24, 0xbc, 0x92,
0x15, 0x14, 0xd0, 0xdb, 0x8b, 0x52, 0xda, 0x0a, 0x84, 0x37, 0x32, 0x86, 0x5f, 0x82, 0xbc, 0x90, 0x02, 0x7a, 0xf3, 0xbe, 0x92, 0xb7, 0x04, 0xe1, 0x4f, 0x95, 0xe1, 0x97, 0xa0, 0x28, 0x24, 0xe2,
0x88, 0x4b, 0x1a, 0xb7, 0x7c, 0x1c, 0x26, 0x3e, 0x0d, 0xdd, 0x54, 0xd9, 0xd9, 0x4e, 0xd5, 0xd6, 0x92, 0x26, 0xdd, 0x00, 0x47, 0x69, 0x40, 0x23, 0x37, 0x57, 0x75, 0x6a, 0x39, 0x6f, 0x77, 0x3c,
0x06, 0xfd, 0xd2, 0xfd, 0x23, 0xab, 0xda, 0x0b, 0x93, 0x83, 0xba, 0x77, 0x5f, 0x4c, 0x2c, 0x43, 0xaa, 0x5c, 0x3b, 0xb6, 0xac, 0xa3, 0x28, 0x6d, 0x35, 0xfd, 0x6b, 0x22, 0x73, 0x8c, 0xe0, 0xff,
0xf8, 0x11, 0x00, 0x21, 0x09, 0xa4, 0x1f, 0x92, 0x98, 0x75, 0xdc, 0xbb, 0x65, 0x67, 0x3b, 0xe3, 0x00, 0x88, 0x48, 0x28, 0x83, 0x88, 0x24, 0xac, 0xef, 0x5e, 0xa9, 0x3a, 0xb5, 0x82, 0x5f, 0x50,
0x65, 0x94, 0xa4, 0xae, 0x04, 0xf0, 0x09, 0xc8, 0xb4, 0x58, 0xcf, 0x6a, 0x57, 0xb4, 0x36, 0xdd, 0x94, 0xa6, 0x22, 0xc0, 0xdb, 0xa0, 0xd0, 0x65, 0x43, 0xcb, 0xdd, 0xd4, 0xdc, 0x7c, 0x97, 0x0d,
0x62, 0x3d, 0xa3, 0xfc, 0xc9, 0x01, 0x4f, 0x12, 0x4e, 0x7a, 0x94, 0x75, 0x85, 0x8f, 0x30, 0xee, 0x0d, 0xf3, 0x47, 0x07, 0xdc, 0x4e, 0x39, 0x19, 0x52, 0x36, 0x10, 0x01, 0xc2, 0x78, 0xd0, 0x1f,
0x76, 0xba, 0x11, 0x92, 0x94, 0xc5, 0xbe, 0xbe, 0x0f, 0xf7, 0x9e, 0x8e, 0xe9, 0xf3, 0xd9, 0x98, 0xc4, 0x48, 0x52, 0x96, 0x04, 0xfa, 0x3e, 0xdc, 0xab, 0x3a, 0xa6, 0xcf, 0x17, 0x63, 0xb2, 0xe9,
0xec, 0xf1, 0xef, 0x4e, 0x98, 0x1c, 0xd3, 0x0e, 0xa9, 0x95, 0x6d, 0x8c, 0xee, 0x9c, 0x0d, 0xc2, 0x7f, 0x9c, 0x51, 0x39, 0xa1, 0x7d, 0xe2, 0x55, 0x6d, 0x8c, 0xee, 0x12, 0x01, 0xe1, 0xef, 0x4f,
0xdb, 0x18, 0xf2, 0xcd, 0xa8, 0x20, 0x07, 0x05, 0xc9, 0x24, 0x8a, 0xfc, 0x84, 0xd3, 0x18, 0xd3, 0xec, 0x2d, 0xb0, 0x20, 0x07, 0x25, 0xc9, 0x24, 0x8a, 0x83, 0x94, 0xd3, 0x04, 0xd3, 0x14, 0xc5,
0x04, 0x45, 0xc2, 0x4d, 0x6b, 0x0f, 0x9e, 0xce, 0xf5, 0xe0, 0x58, 0x19, 0x34, 0x86, 0xfb, 0x6b, 0xc2, 0xcd, 0x6b, 0x0f, 0xee, 0x2c, 0xf5, 0xe0, 0x44, 0x29, 0xb4, 0x27, 0xf2, 0x5e, 0xd9, 0xda,
0x45, 0xcb, 0xff, 0xe8, 0x5a, 0xb5, 0xf0, 0xf2, 0xf2, 0xaa, 0x60, 0xeb, 0xdf, 0xbb, 0x60, 0xc5, 0xbf, 0x79, 0x2e, 0x5b, 0xf8, 0x45, 0x79, 0x96, 0x70, 0xf8, 0xdb, 0x26, 0xd8, 0x34, 0xb5, 0x01,
0xe4, 0x06, 0x3c, 0x01, 0x6b, 0x98, 0x45, 0x11, 0x92, 0x84, 0x2b, 0x1f, 0x86, 0x09, 0xa5, 0xf8, 0x4f, 0xc1, 0x2e, 0x66, 0x71, 0x8c, 0x24, 0xe1, 0xca, 0x87, 0x49, 0x41, 0x29, 0xfb, 0xff, 0x3f,
0x3f, 0xbe, 0x26, 0x35, 0x46, 0x5b, 0xb5, 0x79, 0xcd, 0xb5, 0xcc, 0x85, 0x29, 0x85, 0xf0, 0x0a, 0xa7, 0x34, 0xa6, 0xa2, 0x5a, 0xdd, 0x73, 0xad, 0xe5, 0xd2, 0x1c, 0x43, 0xf8, 0x25, 0x3c, 0x47,
0x78, 0x4a, 0x02, 0xbf, 0xb1, 0x57, 0xa6, 0x39, 0xdc, 0x65, 0x9d, 0xb3, 0x4f, 0xae, 0x4b, 0x9c, 0x81, 0x5f, 0xdb, 0x2b, 0xd3, 0x36, 0xdc, 0x75, 0x5d, 0xb3, 0xb7, 0xcf, 0x2b, 0x9c, 0x50, 0x1a,
0x40, 0x1a, 0x70, 0x93, 0xb6, 0xfa, 0x56, 0xb5, 0x00, 0xbe, 0x06, 0x6b, 0xad, 0x88, 0x05, 0x28, 0x70, 0x53, 0xb6, 0xfa, 0x56, 0x35, 0x01, 0x3e, 0x03, 0xbb, 0xdd, 0x98, 0x85, 0x28, 0x0e, 0x34,
0xf2, 0x35, 0x50, 0x44, 0x3b, 0x54, 0xba, 0x77, 0x34, 0xd0, 0x46, 0xc5, 0xd6, 0x9f, 0x2a, 0xd6, 0x50, 0x4c, 0xfb, 0x54, 0xba, 0x1b, 0x1a, 0x68, 0xbf, 0x6e, 0xfb, 0x4f, 0x35, 0x6b, 0xc6, 0x5d,
0x09, 0x77, 0x69, 0x6c, 0x61, 0xf2, 0xc6, 0x52, 0xa1, 0x1f, 0x2a, 0x3b, 0x78, 0x0a, 0x36, 0x44, 0x9a, 0x58, 0x98, 0xa2, 0xd1, 0x54, 0xe8, 0xcf, 0x95, 0x1e, 0x7c, 0x01, 0xf6, 0xc5, 0x80, 0xa7,
0x97, 0x27, 0x91, 0xca, 0x81, 0x2e, 0x36, 0xd7, 0x7f, 0xc2, 0x89, 0x38, 0x61, 0x91, 0x49, 0xc3, 0xb1, 0xaa, 0x81, 0x01, 0x36, 0xd7, 0x7f, 0xca, 0x89, 0x38, 0x65, 0xb1, 0x29, 0xc3, 0x82, 0xf7,
0x4c, 0xed, 0x2b, 0x65, 0xf9, 0x77, 0xbf, 0xf4, 0x59, 0x8b, 0xca, 0x93, 0x6e, 0x50, 0xc1, 0xac, 0x50, 0x69, 0xfe, 0x3d, 0xaa, 0x7c, 0xd6, 0xa5, 0xf2, 0x74, 0x10, 0xd6, 0x31, 0xeb, 0xdb, 0x36,
0x63, 0xcb, 0xdc, 0xfe, 0xec, 0x88, 0xb0, 0x5d, 0x95, 0x67, 0x09, 0x11, 0x95, 0x83, 0x58, 0xfe, 0xb7, 0x8f, 0xbb, 0x22, 0xea, 0x35, 0xe4, 0xcb, 0x94, 0x88, 0x7a, 0x2b, 0x91, 0x7f, 0xfe, 0x7e,
0xf9, 0xfb, 0x0e, 0xb0, 0x5e, 0x1c, 0xc4, 0xd2, 0x7b, 0x6c, 0xe1, 0x77, 0x0d, 0xfa, 0xf1, 0x10, 0x17, 0x58, 0x2f, 0x5a, 0x89, 0xf4, 0x6f, 0x59, 0xf8, 0xc7, 0x06, 0xfd, 0x64, 0x02, 0x0e, 0x63,
0x1c, 0x46, 0xe0, 0xc1, 0x34, 0x73, 0xc4, 0xa4, 0x49, 0xe2, 0x5b, 0x72, 0xae, 0x5d, 0xe5, 0x3c, 0x70, 0x7d, 0xde, 0x72, 0xcc, 0xa4, 0x29, 0xe2, 0x4b, 0xda, 0xdc, 0x3d, 0x6b, 0xf3, 0x39, 0x93,
0x64, 0x12, 0x72, 0xf0, 0x48, 0x9f, 0xd6, 0x6c, 0x90, 0x2b, 0x0b, 0x20, 0x5c, 0x57, 0xd8, 0x33, 0x90, 0x83, 0x9b, 0x3a, 0x5b, 0x8b, 0x41, 0x6e, 0xae, 0xc0, 0xe0, 0x9e, 0xc2, 0x5e, 0x88, 0xb0,
0x11, 0x36, 0x41, 0xe1, 0x0a, 0xa7, 0x0a, 0xef, 0xde, 0x02, 0xd8, 0x72, 0x13, 0x6c, 0x2a, 0xb6, 0x03, 0x4a, 0x67, 0x6c, 0xaa, 0xf0, 0xae, 0xae, 0xc0, 0xda, 0x4e, 0xc6, 0x9a, 0x8a, 0xed, 0x0e,
0xa7, 0x20, 0x8f, 0x29, 0xc7, 0x5d, 0x2a, 0xfd, 0x80, 0x13, 0xd4, 0x26, 0xdc, 0x4d, 0x97, 0x9d, 0x28, 0x62, 0xca, 0xf1, 0x80, 0xca, 0x20, 0xe4, 0x04, 0xf5, 0x08, 0x77, 0xf3, 0x55, 0xa7, 0x96,
0xed, 0xb4, 0x97, 0xb3, 0xe2, 0x9a, 0x91, 0x6e, 0xfd, 0xba, 0x0c, 0x32, 0xa3, 0xc4, 0x82, 0xeb, 0xf7, 0x77, 0x2c, 0xd9, 0x33, 0x54, 0xf8, 0x10, 0x1c, 0xc4, 0xf4, 0xfb, 0x01, 0x8d, 0x4c, 0x9f,
0xe0, 0xae, 0xe9, 0x0c, 0x8e, 0xee, 0x0c, 0x66, 0xa1, 0xc0, 0x38, 0x69, 0x12, 0x4e, 0x62, 0x4c, 0x87, 0x31, 0xc3, 0xbd, 0x80, 0x26, 0x92, 0xf0, 0x21, 0x8a, 0xdd, 0x42, 0xd5, 0xa9, 0x6d, 0xf8,
0x7c, 0x24, 0x04, 0x91, 0x3a, 0x49, 0x33, 0x5e, 0x6e, 0x24, 0xde, 0x55, 0x52, 0x48, 0x55, 0xc9, 0x6e, 0x46, 0xc2, 0x53, 0x02, 0x2d, 0xcb, 0x3f, 0xfc, 0x65, 0x1d, 0x14, 0xa6, 0x65, 0x09, 0xf7,
0xc4, 0x3d, 0xc2, 0x85, 0x8a, 0xad, 0x89, 0xb0, 0x64, 0x5c, 0xa7, 0xe1, 0x6d, 0xc3, 0x2b, 0x8c, 0xc0, 0x15, 0x33, 0x57, 0x1c, 0x3d, 0x57, 0xcc, 0x41, 0xb9, 0xc2, 0x49, 0x87, 0x70, 0x92, 0x60,
0x61, 0xf7, 0x35, 0x2a, 0xfc, 0xde, 0xd6, 0x4c, 0x33, 0x62, 0x8c, 0x2f, 0x24, 0x2b, 0x75, 0x39, 0x12, 0x20, 0x21, 0x88, 0xd4, 0x25, 0x5e, 0xf0, 0x77, 0xa6, 0xe4, 0xc7, 0x8a, 0x0a, 0xa9, 0x6a,
0xed, 0x2b, 0xb8, 0xad, 0x5f, 0xd2, 0x20, 0x3f, 0x55, 0xb7, 0x73, 0x8e, 0x06, 0x82, 0x94, 0xc2, 0xb8, 0x64, 0x48, 0xb8, 0x50, 0x9e, 0x74, 0x10, 0x96, 0x8c, 0xeb, 0x22, 0xbe, 0x6c, 0x72, 0x4a,
0xb3, 0xe7, 0xa1, 0xbf, 0xd5, 0x29, 0x44, 0xf4, 0x87, 0x2e, 0x0d, 0x4d, 0xeb, 0xe4, 0xea, 0xe7, 0x33, 0xd8, 0x27, 0x1a, 0x15, 0x7e, 0x67, 0x3b, 0xae, 0x13, 0x33, 0xc6, 0x57, 0x52, 0xd3, 0xba,
0x06, 0xa7, 0x50, 0x27, 0x78, 0xc2, 0xc3, 0x3a, 0xc1, 0x5e, 0x61, 0x02, 0xd6, 0x53, 0x7f, 0xe1, 0x19, 0x9f, 0x28, 0xb8, 0xc3, 0x9f, 0xf3, 0xa0, 0x38, 0xd7, 0xf5, 0x4b, 0x52, 0x03, 0x41, 0x4e,
0xd7, 0xf6, 0x14, 0x4c, 0xc1, 0xa7, 0x3e, 0xac, 0xe0, 0x75, 0xa0, 0xa6, 0xd4, 0x11, 0x50, 0xaf, 0xe1, 0xd9, 0x7c, 0xe8, 0x77, 0x95, 0x85, 0xec, 0x85, 0x70, 0xf5, 0xb8, 0x40, 0x16, 0x9a, 0x04,
0x47, 0x40, 0x23, 0x2a, 0xcf, 0xfc, 0x26, 0x21, 0x37, 0x28, 0xb5, 0x59, 0x37, 0xb3, 0x23, 0xc8, 0x67, 0x3c, 0x6c, 0x12, 0xec, 0x97, 0x32, 0xb0, 0xbe, 0xfa, 0x85, 0x5f, 0xd9, 0x2c, 0x98, 0x71,
0x7d, 0x42, 0xa0, 0x0f, 0xb2, 0xc3, 0x64, 0x17, 0xf4, 0x9c, 0x2c, 0xa4, 0xb6, 0x56, 0x2d, 0xe2, 0x91, 0xfb, 0xb8, 0x71, 0xa1, 0x03, 0x35, 0x83, 0x02, 0x01, 0xf5, 0xed, 0x09, 0x69, 0x4c, 0xe5,
0x11, 0x3d, 0x27, 0xb0, 0x03, 0x1e, 0x4c, 0x1e, 0x77, 0x42, 0x62, 0x14, 0xc9, 0xb3, 0x1b, 0x54, 0xcb, 0xa0, 0x43, 0xc8, 0x05, 0x1a, 0x75, 0xd1, 0xcd, 0xed, 0x29, 0xe4, 0x13, 0x42, 0x60, 0x00,
0xd5, 0x6c, 0x24, 0x70, 0x02, 0xb8, 0x61, 0x70, 0xe1, 0x0b, 0x90, 0x13, 0x09, 0x93, 0x7e, 0x07, 0xb6, 0x27, 0xad, 0x22, 0xe8, 0x2b, 0xb2, 0x92, 0xce, 0xdc, 0xb2, 0x88, 0xc7, 0xf4, 0x15, 0x81,
0xf1, 0x36, 0x91, 0xea, 0x65, 0x4e, 0x6b, 0xa6, 0xc2, 0xa0, 0x5f, 0xca, 0x1e, 0x25, 0x4c, 0x7e, 0x7d, 0x70, 0x3d, 0x9b, 0xee, 0x94, 0x24, 0x28, 0x96, 0x2f, 0x2f, 0xd0, 0x93, 0x8b, 0x91, 0xc0,
0xab, 0x15, 0x07, 0x75, 0x2f, 0x2b, 0xc6, 0xab, 0x10, 0xbe, 0x06, 0x0f, 0x27, 0xdd, 0x1c, 0x9b, 0x0c, 0x70, 0xdb, 0xe0, 0xc2, 0x07, 0x60, 0x47, 0xa4, 0x4c, 0x06, 0x7d, 0xc4, 0x7b, 0x44, 0xaa,
0x67, 0xb4, 0xf9, 0xe3, 0x41, 0xbf, 0xf4, 0xe0, 0x70, 0xbc, 0x61, 0x84, 0x32, 0x19, 0xdc, 0x08, 0xef, 0x7a, 0x5e, 0x5b, 0x2a, 0x8d, 0x47, 0x95, 0xed, 0xe3, 0x94, 0xc9, 0x6f, 0x34, 0xa3, 0xd5,
0xac, 0x07, 0xdc, 0x36, 0x21, 0x09, 0xe1, 0x3e, 0x27, 0x3f, 0x22, 0x1e, 0xfa, 0x09, 0xe1, 0x98, 0xf4, 0xb7, 0xc5, 0xec, 0x14, 0xc1, 0x67, 0xe0, 0x46, 0xd6, 0xcd, 0x99, 0x7a, 0x41, 0xab, 0xdf,
0xc4, 0x12, 0xb5, 0x88, 0x0b, 0x16, 0x10, 0xf8, 0x23, 0x83, 0xee, 0x69, 0xf0, 0xc6, 0x08, 0x5b, 0x1a, 0x8f, 0x2a, 0xd7, 0x9f, 0xcf, 0x04, 0xa6, 0x28, 0xd9, 0xe0, 0xa6, 0x60, 0x43, 0xe0, 0xf6,
0x0d, 0x08, 0x9f, 0xe0, 0x13, 0x82, 0xdb, 0xfe, 0xf8, 0x11, 0xa3, 0xe7, 0x26, 0x22, 0x1a, 0x87, 0x08, 0x49, 0x09, 0x0f, 0x38, 0xf9, 0x01, 0xf1, 0x28, 0x48, 0x09, 0xc7, 0x24, 0x91, 0xa8, 0x4b,
0xe4, 0xd4, 0xc7, 0xac, 0x1b, 0x4b, 0x77, 0x75, 0x01, 0x97, 0x5c, 0xd6, 0x44, 0x7b, 0xd3, 0x3c, 0x5c, 0xb0, 0x82, 0xc0, 0x6f, 0x1a, 0x74, 0x5f, 0x83, 0xb7, 0xa7, 0xd8, 0x6a, 0xbd, 0xf8, 0x04,
0x07, 0x8a, 0x66, 0x4f, 0xb1, 0x5c, 0xdf, 0x6e, 0xb2, 0xff, 0x47, 0xbb, 0xd9, 0xfa, 0x79, 0x19, 0x9f, 0x12, 0xdc, 0x0b, 0x66, 0x9f, 0x40, 0xfa, 0xca, 0x44, 0x44, 0x93, 0x88, 0xbc, 0x08, 0x30,
0x3c, 0x9e, 0x33, 0xc3, 0xe8, 0x5e, 0x3b, 0x1e, 0x14, 0x74, 0x3b, 0x30, 0x3d, 0x22, 0x37, 0x16, 0x1b, 0x24, 0xd2, 0xdd, 0x5a, 0xc1, 0x25, 0x57, 0xb5, 0xa1, 0xa3, 0x79, 0x3b, 0x2d, 0x65, 0xe6,
0x1f, 0xab, 0xc6, 0x10, 0x80, 0xcd, 0xf9, 0xd3, 0x95, 0x7d, 0xf7, 0x37, 0x2b, 0x66, 0x14, 0xae, 0x48, 0x59, 0x39, 0x7f, 0xdc, 0x6c, 0xff, 0x17, 0xe3, 0xe6, 0xf0, 0xa7, 0x75, 0x70, 0x6b, 0xc9,
0x0c, 0x47, 0xe1, 0xca, 0xf1, 0x70, 0x14, 0xae, 0xa5, 0x55, 0x50, 0x6f, 0x2e, 0x4a, 0x8e, 0xe7, 0x06, 0xa4, 0x27, 0xf5, 0x6c, 0xcd, 0xd0, 0xe3, 0xc0, 0xcc, 0x88, 0x9d, 0x19, 0xf9, 0x44, 0x0d,
0xce, 0x9b, 0x9a, 0x20, 0x01, 0x79, 0x1a, 0x4b, 0xc2, 0x89, 0x90, 0x37, 0x6f, 0xc0, 0xb3, 0x09, 0x86, 0x10, 0x1c, 0x2c, 0xdf, 0xcd, 0xec, 0xd6, 0x70, 0x50, 0x37, 0x8b, 0x74, 0x7d, 0xb2, 0x48,
0x91, 0x1b, 0x82, 0xda, 0xf3, 0xf8, 0xcd, 0x01, 0x0f, 0xaf, 0x9d, 0xa9, 0x3e, 0xfc, 0x34, 0x08, 0xd7, 0x4f, 0x26, 0x8b, 0xb4, 0x97, 0x57, 0x41, 0xbd, 0x7e, 0x5f, 0x71, 0x7c, 0x77, 0xd9, 0xce,
0xc8, 0x4f, 0x8d, 0x77, 0xa6, 0x8b, 0xde, 0xf6, 0x25, 0xbc, 0x3a, 0xd2, 0xd5, 0x5e, 0xbe, 0x1b, 0x05, 0x09, 0x28, 0xea, 0xd9, 0x4f, 0x84, 0xbc, 0xf8, 0x00, 0x5e, 0x2c, 0x88, 0x9d, 0x09, 0xa8,
0x14, 0x9d, 0xf7, 0x83, 0xa2, 0xf3, 0xcf, 0xa0, 0xe8, 0xbc, 0xb9, 0x2c, 0x2e, 0xbd, 0xbf, 0x2c, 0xcd, 0xc7, 0xaf, 0x0e, 0xb8, 0x71, 0xee, 0x46, 0xf6, 0xf1, 0xd9, 0x20, 0xa0, 0x38, 0xb7, 0x1c,
0x2e, 0xfd, 0x75, 0x59, 0x5c, 0xfa, 0xee, 0xd3, 0x09, 0x7c, 0x35, 0x6c, 0xed, 0x44, 0x28, 0x10, 0x9a, 0x29, 0x7a, 0xd9, 0xef, 0xe8, 0xd9, 0x85, 0xd0, 0x7b, 0xf4, 0x76, 0x5c, 0x76, 0xde, 0x8d,
0xfa, 0xab, 0x7a, 0xaa, 0xff, 0xd5, 0xd0, 0x14, 0xc1, 0x8a, 0xbe, 0x89, 0x2f, 0xfe, 0x0b, 0x00, 0xcb, 0xce, 0x3f, 0xe3, 0xb2, 0xf3, 0xfa, 0x43, 0x79, 0xed, 0xdd, 0x87, 0xf2, 0xda, 0x5f, 0x1f,
0x00, 0xff, 0xff, 0xe6, 0x31, 0x9b, 0x4e, 0x27, 0x0d, 0x00, 0x00, 0xca, 0x6b, 0xdf, 0x7e, 0x9a, 0xc1, 0x57, 0xab, 0xda, 0xdd, 0x18, 0x85, 0x42, 0xbf, 0x35, 0x5e,
0xe8, 0x3f, 0x2a, 0xda, 0x44, 0xb8, 0xa9, 0x6f, 0xe2, 0x8b, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff,
0x5c, 0xdf, 0x27, 0x18, 0x65, 0x0d, 0x00, 0x00,
} }
func (m *GenesisState) Marshal() (dAtA []byte, err error) { func (m *GenesisState) Marshal() (dAtA []byte, err error) {
@ -661,6 +671,11 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i _ = i
var l int var l int
_ = l _ = l
if m.LiquidationBlockInterval != 0 {
i = encodeVarintGenesis(dAtA, i, uint64(m.LiquidationBlockInterval))
i--
dAtA[i] = 0x48
}
if m.CircuitBreaker { if m.CircuitBreaker {
i-- i--
if m.CircuitBreaker { if m.CircuitBreaker {
@ -1108,6 +1123,9 @@ func (m *Params) Size() (n int) {
if m.CircuitBreaker { if m.CircuitBreaker {
n += 2 n += 2
} }
if m.LiquidationBlockInterval != 0 {
n += 1 + sovGenesis(uint64(m.LiquidationBlockInterval))
}
return n return n
} }
@ -1798,6 +1816,25 @@ func (m *Params) Unmarshal(dAtA []byte) error {
} }
} }
m.CircuitBreaker = bool(v != 0) m.CircuitBreaker = bool(v != 0)
case 9:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field LiquidationBlockInterval", wireType)
}
m.LiquidationBlockInterval = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.LiquidationBlockInterval |= int64(b&0x7F) << shift
if b < 0x80 {
break
}
}
default: default:
iNdEx = preIndex iNdEx = preIndex
skippy, err := skipGenesis(dAtA[iNdEx:]) skippy, err := skipGenesis(dAtA[iNdEx:])

View File

@ -21,6 +21,7 @@ var (
KeyDebtLot = []byte("DebtLot") KeyDebtLot = []byte("DebtLot")
KeySurplusThreshold = []byte("SurplusThreshold") KeySurplusThreshold = []byte("SurplusThreshold")
KeySurplusLot = []byte("SurplusLot") KeySurplusLot = []byte("SurplusLot")
KeyBeginBlockerExecutionBlockInterval = []byte("BeginBlockerExecutionBlockInterval")
DefaultGlobalDebt = sdk.NewCoin(DefaultStableDenom, sdk.ZeroInt()) DefaultGlobalDebt = sdk.NewCoin(DefaultStableDenom, sdk.ZeroInt())
DefaultCircuitBreaker = false DefaultCircuitBreaker = false
DefaultCollateralParams = CollateralParams{} DefaultCollateralParams = CollateralParams{}
@ -39,12 +40,14 @@ var (
DefaultSurplusLot = sdkmath.NewInt(10000000000) DefaultSurplusLot = sdkmath.NewInt(10000000000)
DefaultDebtLot = sdkmath.NewInt(10000000000) DefaultDebtLot = sdkmath.NewInt(10000000000)
stabilityFeeMax = sdk.MustNewDecFromStr("1.000000051034942716") // 500% APR stabilityFeeMax = sdk.MustNewDecFromStr("1.000000051034942716") // 500% APR
// Run every block
DefaultBeginBlockerExecutionBlockInterval = int64(1)
) )
// NewParams returns a new params object // NewParams returns a new params object
func NewParams( func NewParams(
debtLimit sdk.Coin, collateralParams CollateralParams, debtParam DebtParam, surplusThreshold, debtLimit sdk.Coin, collateralParams CollateralParams, debtParam DebtParam, surplusThreshold,
surplusLot, debtThreshold, debtLot sdkmath.Int, breaker bool, surplusLot, debtThreshold, debtLot sdkmath.Int, breaker bool, beginBlockerExecutionBlockInterval int64,
) Params { ) Params {
return Params{ return Params{
GlobalDebtLimit: debtLimit, GlobalDebtLimit: debtLimit,
@ -55,6 +58,7 @@ func NewParams(
DebtAuctionThreshold: debtThreshold, DebtAuctionThreshold: debtThreshold,
DebtAuctionLot: debtLot, DebtAuctionLot: debtLot,
CircuitBreaker: breaker, CircuitBreaker: breaker,
LiquidationBlockInterval: beginBlockerExecutionBlockInterval,
} }
} }
@ -63,7 +67,7 @@ func DefaultParams() Params {
return NewParams( return NewParams(
DefaultGlobalDebt, DefaultCollateralParams, DefaultDebtParam, DefaultSurplusThreshold, DefaultGlobalDebt, DefaultCollateralParams, DefaultDebtParam, DefaultSurplusThreshold,
DefaultSurplusLot, DefaultDebtThreshold, DefaultDebtLot, DefaultSurplusLot, DefaultDebtThreshold, DefaultDebtLot,
DefaultCircuitBreaker, DefaultCircuitBreaker, DefaultBeginBlockerExecutionBlockInterval,
) )
} }
@ -122,6 +126,7 @@ func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs {
paramtypes.NewParamSetPair(KeySurplusLot, &p.SurplusAuctionLot, validateSurplusAuctionLotParam), paramtypes.NewParamSetPair(KeySurplusLot, &p.SurplusAuctionLot, validateSurplusAuctionLotParam),
paramtypes.NewParamSetPair(KeyDebtThreshold, &p.DebtAuctionThreshold, validateDebtAuctionThresholdParam), paramtypes.NewParamSetPair(KeyDebtThreshold, &p.DebtAuctionThreshold, validateDebtAuctionThresholdParam),
paramtypes.NewParamSetPair(KeyDebtLot, &p.DebtAuctionLot, validateDebtAuctionLotParam), paramtypes.NewParamSetPair(KeyDebtLot, &p.DebtAuctionLot, validateDebtAuctionLotParam),
paramtypes.NewParamSetPair(KeyBeginBlockerExecutionBlockInterval, &p.LiquidationBlockInterval, validateBeginBlockerExecutionBlockIntervalParam),
} }
} }
@ -143,6 +148,10 @@ func (p Params) Validate() error {
return err return err
} }
if err := validateBeginBlockerExecutionBlockIntervalParam(p.LiquidationBlockInterval); err != nil {
return err
}
if err := validateSurplusAuctionThresholdParam(p.SurplusAuctionThreshold); err != nil { if err := validateSurplusAuctionThresholdParam(p.SurplusAuctionThreshold); err != nil {
return err return err
} }
@ -346,3 +355,16 @@ func validateDebtAuctionLotParam(i interface{}) error {
return nil return nil
} }
func validateBeginBlockerExecutionBlockIntervalParam(i interface{}) error {
bbebi, ok := i.(int64)
if !ok {
return fmt.Errorf("invalid parameter type: %T", i)
}
if bbebi <= 0 {
return fmt.Errorf("begin blocker execution block interval param should be positive: %d", bbebi)
}
return nil
}

View File

@ -28,6 +28,7 @@ func (suite *ParamsTestSuite) TestParamValidation() {
debtThreshold sdkmath.Int debtThreshold sdkmath.Int
debtLot sdkmath.Int debtLot sdkmath.Int
breaker bool breaker bool
beginBlockerExecutionBlockInterval int64
} }
type errArgs struct { type errArgs struct {
expectPass bool expectPass bool
@ -50,6 +51,7 @@ func (suite *ParamsTestSuite) TestParamValidation() {
debtThreshold: types.DefaultDebtThreshold, debtThreshold: types.DefaultDebtThreshold,
debtLot: types.DefaultDebtLot, debtLot: types.DefaultDebtLot,
breaker: types.DefaultCircuitBreaker, breaker: types.DefaultCircuitBreaker,
beginBlockerExecutionBlockInterval: types.DefaultBeginBlockerExecutionBlockInterval,
}, },
errArgs: errArgs{ errArgs: errArgs{
expectPass: true, expectPass: true,
@ -87,6 +89,7 @@ func (suite *ParamsTestSuite) TestParamValidation() {
debtThreshold: types.DefaultDebtThreshold, debtThreshold: types.DefaultDebtThreshold,
debtLot: types.DefaultDebtLot, debtLot: types.DefaultDebtLot,
breaker: types.DefaultCircuitBreaker, breaker: types.DefaultCircuitBreaker,
beginBlockerExecutionBlockInterval: types.DefaultBeginBlockerExecutionBlockInterval,
}, },
errArgs: errArgs{ errArgs: errArgs{
expectPass: true, expectPass: true,
@ -124,6 +127,7 @@ func (suite *ParamsTestSuite) TestParamValidation() {
debtThreshold: types.DefaultDebtThreshold, debtThreshold: types.DefaultDebtThreshold,
debtLot: types.DefaultDebtLot, debtLot: types.DefaultDebtLot,
breaker: types.DefaultCircuitBreaker, breaker: types.DefaultCircuitBreaker,
beginBlockerExecutionBlockInterval: types.DefaultBeginBlockerExecutionBlockInterval,
}, },
errArgs: errArgs{ errArgs: errArgs{
expectPass: false, expectPass: false,
@ -161,6 +165,7 @@ func (suite *ParamsTestSuite) TestParamValidation() {
debtThreshold: types.DefaultDebtThreshold, debtThreshold: types.DefaultDebtThreshold,
debtLot: types.DefaultDebtLot, debtLot: types.DefaultDebtLot,
breaker: types.DefaultCircuitBreaker, breaker: types.DefaultCircuitBreaker,
beginBlockerExecutionBlockInterval: types.DefaultBeginBlockerExecutionBlockInterval,
}, },
errArgs: errArgs{ errArgs: errArgs{
expectPass: false, expectPass: false,
@ -212,6 +217,7 @@ func (suite *ParamsTestSuite) TestParamValidation() {
debtThreshold: types.DefaultDebtThreshold, debtThreshold: types.DefaultDebtThreshold,
debtLot: types.DefaultDebtLot, debtLot: types.DefaultDebtLot,
breaker: types.DefaultCircuitBreaker, breaker: types.DefaultCircuitBreaker,
beginBlockerExecutionBlockInterval: types.DefaultBeginBlockerExecutionBlockInterval,
}, },
errArgs: errArgs{ errArgs: errArgs{
expectPass: true, expectPass: true,
@ -263,6 +269,7 @@ func (suite *ParamsTestSuite) TestParamValidation() {
debtThreshold: types.DefaultDebtThreshold, debtThreshold: types.DefaultDebtThreshold,
debtLot: types.DefaultDebtLot, debtLot: types.DefaultDebtLot,
breaker: types.DefaultCircuitBreaker, breaker: types.DefaultCircuitBreaker,
beginBlockerExecutionBlockInterval: types.DefaultBeginBlockerExecutionBlockInterval,
}, },
errArgs: errArgs{ errArgs: errArgs{
expectPass: false, expectPass: false,
@ -314,6 +321,7 @@ func (suite *ParamsTestSuite) TestParamValidation() {
debtThreshold: types.DefaultDebtThreshold, debtThreshold: types.DefaultDebtThreshold,
debtLot: types.DefaultDebtLot, debtLot: types.DefaultDebtLot,
breaker: types.DefaultCircuitBreaker, breaker: types.DefaultCircuitBreaker,
beginBlockerExecutionBlockInterval: types.DefaultBeginBlockerExecutionBlockInterval,
}, },
errArgs: errArgs{ errArgs: errArgs{
expectPass: false, expectPass: false,
@ -350,6 +358,7 @@ func (suite *ParamsTestSuite) TestParamValidation() {
debtThreshold: types.DefaultDebtThreshold, debtThreshold: types.DefaultDebtThreshold,
debtLot: types.DefaultDebtLot, debtLot: types.DefaultDebtLot,
breaker: types.DefaultCircuitBreaker, breaker: types.DefaultCircuitBreaker,
beginBlockerExecutionBlockInterval: types.DefaultBeginBlockerExecutionBlockInterval,
}, },
errArgs: errArgs{ errArgs: errArgs{
expectPass: false, expectPass: false,
@ -387,6 +396,7 @@ func (suite *ParamsTestSuite) TestParamValidation() {
debtThreshold: types.DefaultDebtThreshold, debtThreshold: types.DefaultDebtThreshold,
debtLot: types.DefaultDebtLot, debtLot: types.DefaultDebtLot,
breaker: types.DefaultCircuitBreaker, breaker: types.DefaultCircuitBreaker,
beginBlockerExecutionBlockInterval: types.DefaultBeginBlockerExecutionBlockInterval,
}, },
errArgs: errArgs{ errArgs: errArgs{
expectPass: false, expectPass: false,
@ -438,6 +448,7 @@ func (suite *ParamsTestSuite) TestParamValidation() {
debtThreshold: types.DefaultDebtThreshold, debtThreshold: types.DefaultDebtThreshold,
debtLot: types.DefaultDebtLot, debtLot: types.DefaultDebtLot,
breaker: types.DefaultCircuitBreaker, breaker: types.DefaultCircuitBreaker,
beginBlockerExecutionBlockInterval: types.DefaultBeginBlockerExecutionBlockInterval,
}, },
errArgs: errArgs{ errArgs: errArgs{
expectPass: false, expectPass: false,
@ -489,6 +500,7 @@ func (suite *ParamsTestSuite) TestParamValidation() {
debtThreshold: types.DefaultDebtThreshold, debtThreshold: types.DefaultDebtThreshold,
debtLot: types.DefaultDebtLot, debtLot: types.DefaultDebtLot,
breaker: types.DefaultCircuitBreaker, breaker: types.DefaultCircuitBreaker,
beginBlockerExecutionBlockInterval: types.DefaultBeginBlockerExecutionBlockInterval,
}, },
errArgs: errArgs{ errArgs: errArgs{
expectPass: true, expectPass: true,
@ -526,6 +538,7 @@ func (suite *ParamsTestSuite) TestParamValidation() {
debtThreshold: types.DefaultDebtThreshold, debtThreshold: types.DefaultDebtThreshold,
debtLot: types.DefaultDebtLot, debtLot: types.DefaultDebtLot,
breaker: types.DefaultCircuitBreaker, breaker: types.DefaultCircuitBreaker,
beginBlockerExecutionBlockInterval: types.DefaultBeginBlockerExecutionBlockInterval,
}, },
errArgs: errArgs{ errArgs: errArgs{
expectPass: false, expectPass: false,
@ -563,6 +576,7 @@ func (suite *ParamsTestSuite) TestParamValidation() {
debtThreshold: types.DefaultDebtThreshold, debtThreshold: types.DefaultDebtThreshold,
debtLot: types.DefaultDebtLot, debtLot: types.DefaultDebtLot,
breaker: types.DefaultCircuitBreaker, breaker: types.DefaultCircuitBreaker,
beginBlockerExecutionBlockInterval: types.DefaultBeginBlockerExecutionBlockInterval,
}, },
errArgs: errArgs{ errArgs: errArgs{
expectPass: false, expectPass: false,
@ -600,6 +614,7 @@ func (suite *ParamsTestSuite) TestParamValidation() {
debtThreshold: types.DefaultDebtThreshold, debtThreshold: types.DefaultDebtThreshold,
debtLot: types.DefaultDebtLot, debtLot: types.DefaultDebtLot,
breaker: types.DefaultCircuitBreaker, breaker: types.DefaultCircuitBreaker,
beginBlockerExecutionBlockInterval: types.DefaultBeginBlockerExecutionBlockInterval,
}, },
errArgs: errArgs{ errArgs: errArgs{
expectPass: false, expectPass: false,
@ -637,6 +652,7 @@ func (suite *ParamsTestSuite) TestParamValidation() {
debtThreshold: types.DefaultDebtThreshold, debtThreshold: types.DefaultDebtThreshold,
debtLot: types.DefaultDebtLot, debtLot: types.DefaultDebtLot,
breaker: types.DefaultCircuitBreaker, breaker: types.DefaultCircuitBreaker,
beginBlockerExecutionBlockInterval: types.DefaultBeginBlockerExecutionBlockInterval,
}, },
errArgs: errArgs{ errArgs: errArgs{
expectPass: false, expectPass: false,
@ -669,6 +685,7 @@ func (suite *ParamsTestSuite) TestParamValidation() {
debtThreshold: types.DefaultDebtThreshold, debtThreshold: types.DefaultDebtThreshold,
debtLot: types.DefaultDebtLot, debtLot: types.DefaultDebtLot,
breaker: types.DefaultCircuitBreaker, breaker: types.DefaultCircuitBreaker,
beginBlockerExecutionBlockInterval: types.DefaultBeginBlockerExecutionBlockInterval,
}, },
errArgs: errArgs{ errArgs: errArgs{
expectPass: false, expectPass: false,
@ -706,6 +723,7 @@ func (suite *ParamsTestSuite) TestParamValidation() {
debtThreshold: types.DefaultDebtThreshold, debtThreshold: types.DefaultDebtThreshold,
debtLot: types.DefaultDebtLot, debtLot: types.DefaultDebtLot,
breaker: types.DefaultCircuitBreaker, breaker: types.DefaultCircuitBreaker,
beginBlockerExecutionBlockInterval: types.DefaultBeginBlockerExecutionBlockInterval,
}, },
errArgs: errArgs{ errArgs: errArgs{
expectPass: false, expectPass: false,
@ -723,6 +741,7 @@ func (suite *ParamsTestSuite) TestParamValidation() {
debtThreshold: types.DefaultDebtThreshold, debtThreshold: types.DefaultDebtThreshold,
debtLot: types.DefaultDebtLot, debtLot: types.DefaultDebtLot,
breaker: types.DefaultCircuitBreaker, breaker: types.DefaultCircuitBreaker,
beginBlockerExecutionBlockInterval: types.DefaultBeginBlockerExecutionBlockInterval,
}, },
errArgs: errArgs{ errArgs: errArgs{
expectPass: false, expectPass: false,
@ -740,6 +759,7 @@ func (suite *ParamsTestSuite) TestParamValidation() {
debtThreshold: types.DefaultDebtThreshold, debtThreshold: types.DefaultDebtThreshold,
debtLot: types.DefaultDebtLot, debtLot: types.DefaultDebtLot,
breaker: types.DefaultCircuitBreaker, breaker: types.DefaultCircuitBreaker,
beginBlockerExecutionBlockInterval: types.DefaultBeginBlockerExecutionBlockInterval,
}, },
errArgs: errArgs{ errArgs: errArgs{
expectPass: false, expectPass: false,
@ -757,6 +777,7 @@ func (suite *ParamsTestSuite) TestParamValidation() {
debtThreshold: sdk.ZeroInt(), debtThreshold: sdk.ZeroInt(),
debtLot: types.DefaultDebtLot, debtLot: types.DefaultDebtLot,
breaker: types.DefaultCircuitBreaker, breaker: types.DefaultCircuitBreaker,
beginBlockerExecutionBlockInterval: types.DefaultBeginBlockerExecutionBlockInterval,
}, },
errArgs: errArgs{ errArgs: errArgs{
expectPass: false, expectPass: false,
@ -774,6 +795,7 @@ func (suite *ParamsTestSuite) TestParamValidation() {
debtThreshold: types.DefaultDebtThreshold, debtThreshold: types.DefaultDebtThreshold,
debtLot: types.DefaultDebtLot, debtLot: types.DefaultDebtLot,
breaker: types.DefaultCircuitBreaker, breaker: types.DefaultCircuitBreaker,
beginBlockerExecutionBlockInterval: types.DefaultBeginBlockerExecutionBlockInterval,
}, },
errArgs: errArgs{ errArgs: errArgs{
expectPass: false, expectPass: false,
@ -791,16 +813,53 @@ func (suite *ParamsTestSuite) TestParamValidation() {
debtThreshold: types.DefaultDebtThreshold, debtThreshold: types.DefaultDebtThreshold,
debtLot: sdk.ZeroInt(), debtLot: sdk.ZeroInt(),
breaker: types.DefaultCircuitBreaker, breaker: types.DefaultCircuitBreaker,
beginBlockerExecutionBlockInterval: types.DefaultBeginBlockerExecutionBlockInterval,
}, },
errArgs: errArgs{ errArgs: errArgs{
expectPass: false, expectPass: false,
contains: "debt auction lot should be positive", contains: "debt auction lot should be positive",
}, },
}, },
{
name: "zero begin blocker execution interval",
args: args{
globalDebtLimit: types.DefaultGlobalDebt,
collateralParams: types.DefaultCollateralParams,
debtParam: types.DefaultDebtParam,
surplusThreshold: types.DefaultSurplusThreshold,
surplusLot: types.DefaultSurplusLot,
debtThreshold: types.DefaultDebtThreshold,
debtLot: types.DefaultDebtLot,
breaker: types.DefaultCircuitBreaker,
beginBlockerExecutionBlockInterval: 0,
},
errArgs: errArgs{
expectPass: false,
contains: "begin blocker execution block interval param should be positive",
},
},
{
name: "negative begin blocker execution interval",
args: args{
globalDebtLimit: types.DefaultGlobalDebt,
collateralParams: types.DefaultCollateralParams,
debtParam: types.DefaultDebtParam,
surplusThreshold: types.DefaultSurplusThreshold,
surplusLot: types.DefaultSurplusLot,
debtThreshold: types.DefaultDebtThreshold,
debtLot: types.DefaultDebtLot,
breaker: types.DefaultCircuitBreaker,
beginBlockerExecutionBlockInterval: -1,
},
errArgs: errArgs{
expectPass: false,
contains: "begin blocker execution block interval param should be positive",
},
},
} }
for _, tc := range testCases { for _, tc := range testCases {
suite.Run(tc.name, func() { suite.Run(tc.name, func() {
params := types.NewParams(tc.args.globalDebtLimit, tc.args.collateralParams, tc.args.debtParam, tc.args.surplusThreshold, tc.args.surplusLot, tc.args.debtThreshold, tc.args.debtLot, tc.args.breaker) params := types.NewParams(tc.args.globalDebtLimit, tc.args.collateralParams, tc.args.debtParam, tc.args.surplusThreshold, tc.args.surplusLot, tc.args.debtThreshold, tc.args.debtLot, tc.args.breaker, tc.args.beginBlockerExecutionBlockInterval)
err := params.Validate() err := params.Validate()
if tc.errArgs.expectPass { if tc.errArgs.expectPass {
suite.Require().NoError(err) suite.Require().NoError(err)

View File

@ -18,6 +18,7 @@ func NewCDPGenState(cdc codec.JSONCodec, denom, asset string, liquidationRatio s
SurplusAuctionLot: cdptypes.DefaultSurplusLot, SurplusAuctionLot: cdptypes.DefaultSurplusLot,
DebtAuctionThreshold: cdptypes.DefaultDebtThreshold, DebtAuctionThreshold: cdptypes.DefaultDebtThreshold,
DebtAuctionLot: cdptypes.DefaultDebtLot, DebtAuctionLot: cdptypes.DefaultDebtLot,
LiquidationBlockInterval: cdptypes.DefaultBeginBlockerExecutionBlockInterval,
CollateralParams: cdptypes.CollateralParams{ CollateralParams: cdptypes.CollateralParams{
{ {
Denom: denom, Denom: denom,

View File

@ -28,6 +28,7 @@ func NewCDPGenStateMulti(cdc codec.JSONCodec) app.GenesisState {
SurplusAuctionLot: cdptypes.DefaultSurplusLot, SurplusAuctionLot: cdptypes.DefaultSurplusLot,
DebtAuctionThreshold: cdptypes.DefaultDebtThreshold, DebtAuctionThreshold: cdptypes.DefaultDebtThreshold,
DebtAuctionLot: cdptypes.DefaultDebtLot, DebtAuctionLot: cdptypes.DefaultDebtLot,
LiquidationBlockInterval: cdptypes.DefaultBeginBlockerExecutionBlockInterval,
CollateralParams: cdptypes.CollateralParams{ CollateralParams: cdptypes.CollateralParams{
{ {
Denom: "xrp", Denom: "xrp",

View File

@ -34,6 +34,7 @@ func NewCDPGenStateMulti(cdc codec.JSONCodec) app.GenesisState {
SurplusAuctionLot: cdptypes.DefaultSurplusLot, SurplusAuctionLot: cdptypes.DefaultSurplusLot,
DebtAuctionThreshold: cdptypes.DefaultDebtThreshold, DebtAuctionThreshold: cdptypes.DefaultDebtThreshold,
DebtAuctionLot: cdptypes.DefaultDebtLot, DebtAuctionLot: cdptypes.DefaultDebtLot,
LiquidationBlockInterval: cdptypes.DefaultBeginBlockerExecutionBlockInterval,
CollateralParams: cdptypes.CollateralParams{ CollateralParams: cdptypes.CollateralParams{
{ {
Denom: "xrp", Denom: "xrp",