Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TRA-617] Integrate PML and Megavault (backport #2331) #2377

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ListingVaultDepositParams, ListingVaultDepositParamsSDKType } from "./params";
import * as _m0 from "protobufjs/minimal";
import { DeepPartial } from "../../helpers";
/** GenesisState defines `x/listing`'s genesis state. */
Expand All @@ -8,6 +9,9 @@ export interface GenesisState {
* listed
*/
hardCapForMarkets: number;
/** listing_vault_deposit_params is the params for PML megavault deposits */

listingVaultDepositParams?: ListingVaultDepositParams;
}
/** GenesisState defines `x/listing`'s genesis state. */

Expand All @@ -17,11 +21,15 @@ export interface GenesisStateSDKType {
* listed
*/
hard_cap_for_markets: number;
/** listing_vault_deposit_params is the params for PML megavault deposits */

listing_vault_deposit_params?: ListingVaultDepositParamsSDKType;
}

function createBaseGenesisState(): GenesisState {
return {
hardCapForMarkets: 0
hardCapForMarkets: 0,
listingVaultDepositParams: undefined
};
}

Expand All @@ -31,6 +39,10 @@ export const GenesisState = {
writer.uint32(8).uint32(message.hardCapForMarkets);
}

if (message.listingVaultDepositParams !== undefined) {
ListingVaultDepositParams.encode(message.listingVaultDepositParams, writer.uint32(18).fork()).ldelim();
}

return writer;
},

Expand All @@ -47,6 +59,10 @@ export const GenesisState = {
message.hardCapForMarkets = reader.uint32();
break;

case 2:
message.listingVaultDepositParams = ListingVaultDepositParams.decode(reader, reader.uint32());
break;

default:
reader.skipType(tag & 7);
break;
Expand All @@ -59,6 +75,7 @@ export const GenesisState = {
fromPartial(object: DeepPartial<GenesisState>): GenesisState {
const message = createBaseGenesisState();
message.hardCapForMarkets = object.hardCapForMarkets ?? 0;
message.listingVaultDepositParams = object.listingVaultDepositParams !== undefined && object.listingVaultDepositParams !== null ? ListingVaultDepositParams.fromPartial(object.listingVaultDepositParams) : undefined;
return message;
}

Expand Down
7 changes: 7 additions & 0 deletions proto/dydxprotocol/listing/genesis.proto
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
syntax = "proto3";
package dydxprotocol.listing;

import "gogoproto/gogo.proto";
import "dydxprotocol/listing/params.proto";

option go_package = "github.com/dydxprotocol/v4-chain/protocol/x/listing/types";

// GenesisState defines `x/listing`'s genesis state.
message GenesisState {
// hard_cap_for_markets is the hard cap for the number of markets that can be
// listed
uint32 hard_cap_for_markets = 1;

// listing_vault_deposit_params is the params for PML megavault deposits
ListingVaultDepositParams listing_vault_deposit_params = 2
[ (gogoproto.nullable) = false ];
}
2 changes: 2 additions & 0 deletions protocol/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -1206,6 +1206,7 @@ func New(
app.ClobKeeper,
&app.MarketMapKeeper,
app.PerpetualsKeeper,
app.VaultKeeper,
)
listingModule := listingmodule.NewAppModule(
appCodec,
Expand All @@ -1214,6 +1215,7 @@ func New(
app.ClobKeeper,
&app.MarketMapKeeper,
app.PerpetualsKeeper,
app.VaultKeeper,
)

// Initialize authenticators
Expand Down
7 changes: 6 additions & 1 deletion protocol/app/testdata/default_genesis_state.json
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,12 @@
}
},
"listing": {
"hard_cap_for_markets": 0
"hard_cap_for_markets": 500,
"listing_vault_deposit_params": {
"new_vault_deposit_amount": "10000000000",
"main_vault_deposit_amount": "0",
"num_blocks_to_lock_shares": 2592000
}
},
"params": null,
"perpetuals": {
Expand Down
7 changes: 6 additions & 1 deletion protocol/scripts/genesis/sample_pregenesis.json
Original file line number Diff line number Diff line change
Expand Up @@ -869,7 +869,12 @@
}
},
"listing": {
"hard_cap_for_markets": 0
"hard_cap_for_markets": 500,
"listing_vault_deposit_params": {
"main_vault_deposit_amount": "0",
"new_vault_deposit_amount": "10000000000",
"num_blocks_to_lock_shares": 2592000
}
},
"marketmap": {
"last_updated": "0",
Expand Down
8 changes: 8 additions & 0 deletions protocol/testing/genesis.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2258,6 +2258,14 @@ function edit_genesis() {
# ICA Controller Params
update_ica_controller_params

# Listing
# Set hard cap for markets
dasel put -t int -f "$GENESIS" ".app_state.listing.hard_cap_for_markets" -v '500'
# Set default listing vault deposit params
dasel put -t string -f "$GENESIS" ".app_state.listing.listing_vault_deposit_params.new_vault_deposit_amount" -v "10000000000" # 10_000 USDC
dasel put -t string -f "$GENESIS" ".app_state.listing.listing_vault_deposit_params.main_vault_deposit_amount" -v "0" # 0 USDC
dasel put -t int -f "$GENESIS" ".app_state.listing.listing_vault_deposit_params.num_blocks_to_lock_shares" -v '2592000' # 30 days

# Vaults
# Set default quoting params.
dasel put -t int -f "$GENESIS" ".app_state.vault.default_quoting_params.spread_min_ppm" -v '3000'
Expand Down
7 changes: 6 additions & 1 deletion protocol/testutil/constants/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -873,7 +873,12 @@ const GenesisState = `{
}
},
"listing": {
"hard_cap_for_markets": 0
"hard_cap_for_markets": 500,
"listing_vault_deposit_params": {
"new_vault_deposit_amount": "10000000000",
"main_vault_deposit_amount": "0",
"num_blocks_to_lock_shares": 2592000
}
},
"perpetuals": {
"liquidity_tiers": [
Expand Down
4 changes: 4 additions & 0 deletions protocol/testutil/keeper/listing.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
clobkeeper "github.com/dydxprotocol/v4-chain/protocol/x/clob/keeper"
perpetualskeeper "github.com/dydxprotocol/v4-chain/protocol/x/perpetuals/keeper"
priceskeeper "github.com/dydxprotocol/v4-chain/protocol/x/prices/keeper"
vaultkeeper "github.com/dydxprotocol/v4-chain/protocol/x/vault/keeper"
marketmapkeeper "github.com/skip-mev/slinky/x/marketmap/keeper"
"github.com/stretchr/testify/mock"

Expand Down Expand Up @@ -165,6 +166,7 @@ func ListingKeepers(
perpetualsKeeper,
clobKeeper,
marketMapKeeper,
vaultKeeper,
)

return []GenesisInitializer{keeper}
Expand All @@ -182,6 +184,7 @@ func createListingKeeper(
perpetualsKeeper *perpetualskeeper.Keeper,
clobKeeper *clobkeeper.Keeper,
marketMapKeeper *marketmapkeeper.Keeper,
vaultkeeper *vaultkeeper.Keeper,
) (
*keeper.Keeper,
storetypes.StoreKey,
Expand All @@ -201,6 +204,7 @@ func createListingKeeper(
clobKeeper,
marketMapKeeper,
perpetualsKeeper,
vaultkeeper,
)

return k, storeKey, mockTimeProvider
Expand Down
30 changes: 11 additions & 19 deletions protocol/x/clob/keeper/clob_pair.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,10 @@ func (k Keeper) CreatePerpetualClobPair(
return clobPair, err
}

err := k.CreateClobPair(ctx, clobPair)
// Write the `ClobPair` to state.
k.SetClobPair(ctx, clobPair)

err := k.CreateClobPairStructures(ctx, clobPair)
if err != nil {
return clobPair, err
}
Expand Down Expand Up @@ -162,22 +165,11 @@ func (k Keeper) createOrderbook(ctx sdk.Context, clobPair types.ClobPair) {
k.MemClob.CreateOrderbook(clobPair)
}

// CreateClobPair creates a new `ClobPair` in the store and creates the corresponding orderbook in the memclob.
// CreateClobPair performs all non stateful operations to create a CLOB pair.
// These include creating the corresponding orderbook in the memclob, the mapping between
// the CLOB pair and the perpetual and the indexer event.
// This function returns an error if a value for the ClobPair's id already exists in state.
func (k Keeper) CreateClobPair(ctx sdk.Context, clobPair types.ClobPair) error {
// Validate the given clob pair id is not already in use.
if _, exists := k.GetClobPair(ctx, clobPair.GetClobPairId()); exists {
panic(
fmt.Sprintf(
"ClobPair with id %+v already exists in state",
clobPair.GetClobPairId(),
),
)
}

// Write the `ClobPair` to state.
k.setClobPair(ctx, clobPair)

func (k Keeper) CreateClobPairStructures(ctx sdk.Context, clobPair types.ClobPair) error {
// Create the corresponding orderbook in the memclob.
k.createOrderbook(ctx, clobPair)

Expand Down Expand Up @@ -217,8 +209,8 @@ func (k Keeper) CreateClobPair(ctx sdk.Context, clobPair types.ClobPair) error {
return nil
}

// setClobPair sets a specific `ClobPair` in the store from its index.
func (k Keeper) setClobPair(ctx sdk.Context, clobPair types.ClobPair) {
// SetClobPair sets a specific `ClobPair` in the store from its index.
func (k Keeper) SetClobPair(ctx sdk.Context, clobPair types.ClobPair) {
store := k.getClobPairStore(ctx)
b := k.cdc.MustMarshal(&clobPair)
store.Set(clobPairKey(clobPair.GetClobPairId()), b)
Expand Down Expand Up @@ -567,7 +559,7 @@ func (k Keeper) UpdateClobPair(
return err
}

k.setClobPair(ctx, clobPair)
k.SetClobPair(ctx, clobPair)

// Send UpdateClobPair to indexer.
k.GetIndexerEventManager().AddTxnEvent(
Expand Down
4 changes: 4 additions & 0 deletions protocol/x/listing/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState)
if err := k.SetMarketsHardCap(ctx, genState.HardCapForMarkets); err != nil {
panic(err)
}

if err := k.SetListingVaultDepositParams(ctx, genState.ListingVaultDepositParams); err != nil {
panic(err)
}
}

// ExportGenesis returns the module's exported genesis.
Expand Down
3 changes: 3 additions & 0 deletions protocol/x/listing/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type (
ClobKeeper types.ClobKeeper
MarketMapKeeper types.MarketMapKeeper
PerpetualsKeeper types.PerpetualsKeeper
VaultKeeper types.VaultKeeper
}
)

Expand All @@ -31,6 +32,7 @@ func NewKeeper(
clobKeeper types.ClobKeeper,
marketMapKeeper types.MarketMapKeeper,
perpetualsKeeper types.PerpetualsKeeper,
vaultKeeper types.VaultKeeper,
) *Keeper {
return &Keeper{
cdc: cdc,
Expand All @@ -40,6 +42,7 @@ func NewKeeper(
ClobKeeper: clobKeeper,
MarketMapKeeper: marketMapKeeper,
PerpetualsKeeper: perpetualsKeeper,
VaultKeeper: vaultKeeper,
}
}

Expand Down
73 changes: 72 additions & 1 deletion protocol/x/listing/keeper/listing.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ package keeper

import (
"math"
"math/big"

vaulttypes "github.com/dydxprotocol/v4-chain/protocol/x/vault/types"

satypes "github.com/dydxprotocol/v4-chain/protocol/x/subaccounts/types"

"github.com/dydxprotocol/v4-chain/protocol/lib"

Expand Down Expand Up @@ -101,10 +106,12 @@ func (k Keeper) CreateClobPair(
return 0, err
}

k.ClobKeeper.SetClobPair(ctx, clobPair)

// Only create the clob pair if we are in deliver tx mode. This is to prevent populating
// in memory data structures in the CLOB during simulation mode.
if lib.IsDeliverTxMode(ctx) {
err := k.ClobKeeper.CreateClobPair(ctx, clobPair)
err := k.ClobKeeper.CreateClobPairStructures(ctx, clobPair)
if err != nil {
return 0, err
}
Expand Down Expand Up @@ -187,3 +194,67 @@ func (k Keeper) GetListingVaultDepositParams(
k.cdc.MustUnmarshal(b, &vaultDepositParams)
return vaultDepositParams
}

// Function to deposit to the megavault for a new PML market
// This function deposits money to the megavault, transfers the new vault
// deposit amount to the new market vault and locks the shares for the deposit
func (k Keeper) DepositToMegavaultforPML(
ctx sdk.Context,
fromSubaccount satypes.SubaccountId,
clobPairId uint32,
) error {
// Get the listing vault deposit params
vaultDepositParams := k.GetListingVaultDepositParams(ctx)

// Deposit to the megavault
totalDepositAmount := new(big.Int).Add(
vaultDepositParams.NewVaultDepositAmount.BigInt(),
vaultDepositParams.MainVaultDepositAmount.BigInt(),
)
mintedShares, err := k.VaultKeeper.DepositToMegavault(
ctx,
fromSubaccount,
totalDepositAmount,
)
if err != nil {
return err
}

vaultId := vaulttypes.VaultId{
Type: vaulttypes.VaultType_VAULT_TYPE_CLOB,
Number: clobPairId,
}

// Transfer the new vault deposit amount to the new market vault
err = k.VaultKeeper.AllocateToVault(
ctx,
vaultId,
vaultDepositParams.NewVaultDepositAmount.BigInt(),
)
if err != nil {
return err
}

// Lock the shares for the new vault deposit amount
err = k.VaultKeeper.LockShares(
ctx,
fromSubaccount.Owner,
vaulttypes.BigIntToNumShares(mintedShares),
uint32(ctx.BlockHeight())+vaultDepositParams.NumBlocksToLockShares,
)
if err != nil {
return err
}

// Activate vault to quoting status
err = k.VaultKeeper.SetVaultStatus(
ctx,
vaultId,
vaulttypes.VaultStatus_VAULT_STATUS_QUOTING,
)
if err != nil {
return err
}

return nil
}
Loading
Loading