Skip to content

Commit

Permalink
add events for logging purposes
Browse files Browse the repository at this point in the history
  • Loading branch information
Unique-Divine committed Nov 28, 2023
1 parent b081818 commit 1b5c836
Show file tree
Hide file tree
Showing 8 changed files with 700 additions and 121 deletions.
24 changes: 24 additions & 0 deletions proto/nibiru/perp/v2/event.proto
Original file line number Diff line number Diff line change
Expand Up @@ -234,3 +234,27 @@ message MarketUpdatedEvent {
// the final state of the market
nibiru.perp.v2.Market final_market = 1 [ (gogoproto.nullable) = false ];
}

message EventShiftPegMultiplier {
string old_peg_multiplier = 1 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
string new_peg_multiplier = 2 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
cosmos.base.v1beta1.Coin cost_paid = 3 [ (gogoproto.nullable) = false ];
}

message EventShiftSwapInvariant {
string old_swap_invariant = 1 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
string new_swap_invariant = 2 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
cosmos.base.v1beta1.Coin cost_paid = 3 [ (gogoproto.nullable) = false ];
}
4 changes: 2 additions & 2 deletions x/perp/v2/integration/action/market.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,15 +153,15 @@ func EditPriceMultiplier(pair asset.Pair, newValue sdk.Dec) action.Action {

type editSwapInvariant struct {
pair asset.Pair
newValue sdk.Dec
newValue sdk.Int
}

func (e editSwapInvariant) Do(app *app.NibiruApp, ctx sdk.Context) (sdk.Context, error, bool) {
err := app.PerpKeeperV2.UnsafeShiftSwapInvariant(ctx, e.pair, e.newValue)
return ctx, err, true
}

func EditSwapInvariant(pair asset.Pair, newValue sdk.Dec) action.Action {
func EditSwapInvariant(pair asset.Pair, newValue sdk.Int) action.Action {
return editSwapInvariant{
pair: pair,
newValue: newValue,
Expand Down
2 changes: 1 addition & 1 deletion x/perp/v2/keeper/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ func (k admin) ShiftPegMultiplier(
func (k admin) ShiftSwapInvariant(
ctx sdk.Context,
pair asset.Pair,
newSwapInvariant sdk.Dec,
newSwapInvariant sdk.Int,
sender sdk.AccAddress,
) error {
if err := k.SudoKeeper.CheckPermissions(sender, ctx); err != nil {
Expand Down
49 changes: 32 additions & 17 deletions x/perp/v2/keeper/amm.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ func (k Keeper) UnsafeShiftPegMultiplier(
if err != nil {
return err
}
oldPriceMult := amm.PriceMultiplier

if newPriceMultiplier.Equal(amm.PriceMultiplier) {
if newPriceMultiplier.Equal(oldPriceMult) {
// same price multiplier, no-op
return nil
}
Expand All @@ -36,7 +37,7 @@ func (k Keeper) UnsafeShiftPegMultiplier(
return err
}

err = k.handleMarketUpdateCost(ctx, pair, cost)
costPaid, err := k.handleMarketUpdateCost(ctx, pair, cost)
if err != nil {
return err
}
Expand All @@ -45,49 +46,56 @@ func (k Keeper) UnsafeShiftPegMultiplier(
amm.PriceMultiplier = newPriceMultiplier
k.SaveAMM(ctx, amm)

return nil
return ctx.EventManager().EmitTypedEvent(&types.EventShiftPegMultiplier{
OldPegMultiplier: oldPriceMult,
NewPegMultiplier: newPriceMultiplier,
CostPaid: costPaid,
})
}

// UnsafeShiftSwapInvariant: [Without checking x/sudo permissions] Edit the swap
// invariant of an amm pool after making sure there's enough money in the perp
// fund to pay for the operation. These funds get send to the vault to pay for
// trader's new net margin.
func (k Keeper) UnsafeShiftSwapInvariant(
ctx sdk.Context, pair asset.Pair, newSwapInvariant sdk.Dec,
ctx sdk.Context, pair asset.Pair, newSwapInvariant sdk.Int,
) (err error) {
// Get the pool
amm, err := k.GetAMM(ctx, pair)
if err != nil {
return err
}

// Compute cost of re-pegging the pool
cost, err := amm.CalcUpdateSwapInvariantCost(newSwapInvariant)
cost, err := amm.CalcUpdateSwapInvariantCost(newSwapInvariant.ToLegacyDec())
if err != nil {
return err
}

err = k.handleMarketUpdateCost(ctx, pair, cost)
costPaid, err := k.handleMarketUpdateCost(ctx, pair, cost)
if err != nil {
return err
}

err = amm.UpdateSwapInvariant(newSwapInvariant)
err = amm.UpdateSwapInvariant(newSwapInvariant.ToLegacyDec())
if err != nil {
return err
}

k.SaveAMM(ctx, amm)

return nil
return ctx.EventManager().EmitTypedEvent(&types.EventShiftSwapInvariant{
OldSwapInvariant: amm.BaseReserve.Mul(amm.QuoteReserve).RoundInt(),
NewSwapInvariant: newSwapInvariant,
CostPaid: costPaid,
})
}

func (k Keeper) handleMarketUpdateCost(
ctx sdk.Context, pair asset.Pair, costAmt sdkmath.Int,
) (err error) {
) (costPaid sdk.Coin, err error) {
collateral, err := k.Collateral.Get(ctx)
if err != nil {
return err
return costPaid, err
}

if costAmt.IsPositive() {
Expand All @@ -102,11 +110,13 @@ func (k Keeper) handleMarketUpdateCost(
cost,
)
if err != nil {
return types.ErrNotEnoughFundToPayAction.Wrapf(
return costPaid, types.ErrNotEnoughFundToPayAction.Wrapf(
"not enough fund in perp ef to pay for repeg, need %s got %s",
cost.String(),
k.BankKeeper.GetBalance(ctx, k.AccountKeeper.GetModuleAddress(types.PerpEFModuleAccount), collateral).String(),
)
} else {
costPaid = cost[0]
}
} else if costAmt.IsNegative() {
// Negative cost, send from margin vault to perp ef.
Expand All @@ -119,13 +129,18 @@ func (k Keeper) handleMarketUpdateCost(
),
)
if err != nil { // nolint:staticcheck
// if there's no money in margin to pay for the repeg, we still repeg. It's surprising if it's
// happening on mainnet, but it's not a problem.
// It means there's bad debt in the system, and it's preventing to pay for the repeg down. But the bad debt
// end up being paid up by the perp EF anyway.
costPaid = sdk.NewInt64Coin(collateral, 0)
// Explanation: If there's no money in the vault to pay for the
// operation, the execution should still be successful. It's
// surprising if it's happening on mainnet, but it's not a problem.
// It means there's bad debt in the system, and it's preventing to
// pay for the repeg down. But the bad debt end up being paid up by
// the perp EF anyway.
} else {
costPaid = sdk.NewCoin(collateral, costAmt.Abs())
}
}
return nil
return costPaid, nil
}

// GetMarket returns the market that is enabled. It is the last version of the market.
Expand Down
22 changes: 11 additions & 11 deletions x/perp/v2/keeper/amm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,11 +255,11 @@ func TestUnsafeShiftSwapInvariant_Fail(t *testing.T) {
require.NoError(t, err)

// Error because of invalid price multiplier
err = app.PerpKeeperV2.Admin.UnsafeShiftSwapInvariant(ctx, asset.MustNewPair("luna:usdt"), sdk.NewDec(-1))
err = app.PerpKeeperV2.Admin.UnsafeShiftSwapInvariant(ctx, asset.MustNewPair("luna:usdt"), sdk.NewInt(-1))
require.ErrorContains(t, err, "market luna:usdt not found")

// Error because of invalid price multiplier
err = app.PerpKeeperV2.Admin.UnsafeShiftSwapInvariant(ctx, pair, sdk.NewDec(-1))
err = app.PerpKeeperV2.Admin.UnsafeShiftSwapInvariant(ctx, pair, sdk.NewInt(-1))
require.ErrorIs(t, err, types.ErrNonPositiveSwapInvariant)

// Add market activity
Expand All @@ -281,15 +281,15 @@ func TestUnsafeShiftSwapInvariant_Fail(t *testing.T) {
require.NoError(t, err)

// Error because no money in perp ef fund
err = app.PerpKeeperV2.Admin.UnsafeShiftSwapInvariant(ctx, pair, sdk.NewDec(2_000_000))
err = app.PerpKeeperV2.Admin.UnsafeShiftSwapInvariant(ctx, pair, sdk.NewInt(2_000_000))
require.ErrorContains(t, err, "not enough fund in perp ef to pay for repeg")

// Fail at validate
err = app.PerpKeeperV2.Admin.UnsafeShiftSwapInvariant(ctx, pair, sdk.NewDec(0))
err = app.PerpKeeperV2.Admin.UnsafeShiftSwapInvariant(ctx, pair, sdk.NewInt(0))
require.ErrorContains(t, err, "swap multiplier must be > 0")

// Works because it goes in the other way
err = app.PerpKeeperV2.Admin.UnsafeShiftSwapInvariant(ctx, pair, sdk.NewDec(500_000))
err = app.PerpKeeperV2.Admin.UnsafeShiftSwapInvariant(ctx, pair, sdk.NewInt(500_000))
require.NoError(t, err)
}

Expand All @@ -308,7 +308,7 @@ func TestUnsafeShiftSwapInvariant(t *testing.T) {
FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)))),
).
When(
EditSwapInvariant(pair, sdk.NewDec(1e12)),
EditSwapInvariant(pair, sdk.NewInt(1e12)),
).
Then(
ModuleBalanceEqual(types.VaultModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)),
Expand All @@ -332,7 +332,7 @@ func TestUnsafeShiftSwapInvariant(t *testing.T) {
FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)))),
).
When(
EditSwapInvariant(pair, sdk.NewDec(1e18)),
EditSwapInvariant(pair, sdk.NewInt(1e18)),
).
Then(
ModuleBalanceEqual(types.VaultModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)),
Expand All @@ -352,7 +352,7 @@ func TestUnsafeShiftSwapInvariant(t *testing.T) {
FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)))),
).
When(
EditSwapInvariant(pair, sdk.NewDec(1e14)),
EditSwapInvariant(pair, sdk.NewInt(1e14)),
).
Then(
ModuleBalanceEqual(types.VaultModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(1008101)),
Expand All @@ -372,7 +372,7 @@ func TestUnsafeShiftSwapInvariant(t *testing.T) {
FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)))),
).
When(
EditSwapInvariant(pair, sdk.NewDec(1e6)),
EditSwapInvariant(pair, sdk.NewInt(1e6)),
).
Then(
ModuleBalanceEqual(types.VaultModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(999991)),
Expand All @@ -392,7 +392,7 @@ func TestUnsafeShiftSwapInvariant(t *testing.T) {
FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)))),
).
When(
EditSwapInvariant(pair, sdk.NewDec(1e14)),
EditSwapInvariant(pair, sdk.NewInt(1e14)),
).
Then(
ModuleBalanceEqual(types.VaultModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(1010102)),
Expand All @@ -412,7 +412,7 @@ func TestUnsafeShiftSwapInvariant(t *testing.T) {
FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)))),
).
When(
EditSwapInvariant(pair, sdk.NewDec(1e6)),
EditSwapInvariant(pair, sdk.NewInt(1e6)),
).
Then(
ModuleBalanceEqual(types.VaultModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(999989)),
Expand Down
23 changes: 14 additions & 9 deletions x/perp/v2/keeper/clearing_house_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func TestMarketOrder(t *testing.T) {
MarketOrder(alice, pairBtcNusd, types.Direction_SHORT, sdk.NewInt(10_000), sdk.OneDec(), sdk.ZeroDec()),
MarketOrder(bob, pairBtcNusd, types.Direction_LONG, sdk.NewInt(10_000), sdk.OneDec(), sdk.ZeroDec()),

EditSwapInvariant(pairBtcNusd, sdk.OneDec()),
EditSwapInvariant(pairBtcNusd, sdk.NewInt(1)),
).
When(
PartialCloseFails(alice, pairBtcNusd, sdk.NewDec(5_000), types.ErrBaseReserveAtZero),
Expand Down Expand Up @@ -264,7 +264,7 @@ func TestMarketOrder(t *testing.T) {
FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(10_000)))),
MarketOrder(alice, pairBtcNusd, types.Direction_LONG, sdk.NewInt(9_000), sdk.NewDec(10), sdk.ZeroDec()),
FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(100_000_000)))),
EditSwapInvariant(pairBtcNusd, sdk.OneDec()),
EditSwapInvariant(pairBtcNusd, sdk.NewInt(1)),
).
When(
ClosePosition(alice, pairBtcNusd),
Expand Down Expand Up @@ -1956,7 +1956,7 @@ func TestUpdateSwapInvariant(t *testing.T) {
pairBtcNusd := asset.Registry.Pair(denoms.BTC, denoms.NUSD)
startBlockTime := time.Now()

startingSwapInvariant := sdk.NewDec(1_000_000_000_000).Mul(sdk.NewDec(1_000_000_000_000))
startingSwapInvariant := sdk.NewInt(1e12).Mul(sdk.NewInt(1e12))

tc := TestCases{
TC("only long position - no change to swap invariant").
Expand Down Expand Up @@ -1999,7 +1999,7 @@ func TestUpdateSwapInvariant(t *testing.T) {
).
When(
MarketOrder(alice, pairBtcNusd, types.Direction_LONG, sdk.NewInt(10_000_000_000), sdk.OneDec(), sdk.ZeroDec()),
EditSwapInvariant(pairBtcNusd, startingSwapInvariant.MulInt64(100)),
EditSwapInvariant(pairBtcNusd, startingSwapInvariant.MulRaw(100)),
AMMShouldBeEqual(
pairBtcNusd,
AMM_SwapInvariantShouldBeEqual(sdk.MustNewDecFromStr("99999999999999999999999999.999999000000000000"))),
Expand All @@ -2019,7 +2019,7 @@ func TestUpdateSwapInvariant(t *testing.T) {
).
When(
MarketOrder(alice, pairBtcNusd, types.Direction_SHORT, sdk.NewInt(10_000_000_000), sdk.OneDec(), sdk.ZeroDec()),
EditSwapInvariant(pairBtcNusd, startingSwapInvariant.MulInt64(100)),
EditSwapInvariant(pairBtcNusd, startingSwapInvariant.MulRaw(100)),
AMMShouldBeEqual(
pairBtcNusd,
AMM_SwapInvariantShouldBeEqual(sdk.MustNewDecFromStr("99999999999999999999999999.999999000000000000"))),
Expand All @@ -2040,7 +2040,9 @@ func TestUpdateSwapInvariant(t *testing.T) {
).
When(
MarketOrder(alice, pairBtcNusd, types.Direction_LONG, sdk.NewInt(10_000_000_000), sdk.OneDec(), sdk.ZeroDec()),
EditSwapInvariant(pairBtcNusd, startingSwapInvariant.Mul(sdk.MustNewDecFromStr("0.1"))),
EditSwapInvariant(
pairBtcNusd,
startingSwapInvariant.QuoRaw(10)),
AMMShouldBeEqual(
pairBtcNusd,
AMM_SwapInvariantShouldBeEqual(sdk.MustNewDecFromStr("99999999999999999873578.871987715651277660"))),
Expand All @@ -2060,7 +2062,8 @@ func TestUpdateSwapInvariant(t *testing.T) {
).
When(
MarketOrder(alice, pairBtcNusd, types.Direction_SHORT, sdk.NewInt(10_000_000_000), sdk.OneDec(), sdk.ZeroDec()),
EditSwapInvariant(pairBtcNusd, startingSwapInvariant.Mul(sdk.MustNewDecFromStr("0.1"))),
EditSwapInvariant(pairBtcNusd,
startingSwapInvariant.QuoRaw(10)),
AMMShouldBeEqual(
pairBtcNusd,
AMM_SwapInvariantShouldBeEqual(sdk.MustNewDecFromStr("99999999999999999873578.871987801032774485"))),
Expand All @@ -2083,7 +2086,8 @@ func TestUpdateSwapInvariant(t *testing.T) {
MarketOrder(alice, pairBtcNusd, types.Direction_LONG, sdk.NewInt(10_000_000_000), sdk.OneDec(), sdk.ZeroDec()),
MarketOrder(bob, pairBtcNusd, types.Direction_SHORT, sdk.NewInt(10_000_000_000), sdk.OneDec(), sdk.NewDec(10_000_000_000_000)),

EditSwapInvariant(pairBtcNusd, startingSwapInvariant.MulInt64(100)),
EditSwapInvariant(pairBtcNusd,
startingSwapInvariant.MulRaw(100)),
AMMShouldBeEqual(
pairBtcNusd,
AMM_BiasShouldBeEqual(sdk.ZeroDec()),
Expand Down Expand Up @@ -2114,7 +2118,8 @@ func TestUpdateSwapInvariant(t *testing.T) {
MarketOrder(alice, pairBtcNusd, types.Direction_LONG, sdk.NewInt(10_000_000_000), sdk.OneDec(), sdk.ZeroDec()),
MarketOrder(bob, pairBtcNusd, types.Direction_SHORT, sdk.NewInt(10_000_000_000), sdk.OneDec(), sdk.NewDec(10_000_000_000_000)),

EditSwapInvariant(pairBtcNusd, startingSwapInvariant.Mul(sdk.MustNewDecFromStr("0.1"))),
EditSwapInvariant(pairBtcNusd,
startingSwapInvariant.QuoRaw(10)),
AMMShouldBeEqual(
pairBtcNusd,
AMM_BiasShouldBeEqual(sdk.ZeroDec()),
Expand Down
16 changes: 6 additions & 10 deletions x/perp/v2/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,12 +194,10 @@ func (m msgServer) WithdrawEpochRebates(ctx context.Context, msg *types.MsgWithd
func (m msgServer) ShiftPegMultiplier(
goCtx context.Context, msg *types.MsgShiftPegMultiplier,
) (*types.MsgShiftPegMultiplierResponse, error) {
sender, err := sdk.AccAddressFromBech32(msg.Sender)
if err != nil {
return nil, err
}
// The `msg` here is checked with ValidateBasic before this fn is called.
sender, _ := sdk.AccAddressFromBech32(msg.Sender)
ctx := sdk.UnwrapSDKContext(goCtx)
err = m.k.Admin.ShiftPegMultiplier(ctx, msg.Pair, msg.NewPegMult, sender)
err := m.k.Admin.ShiftPegMultiplier(ctx, msg.Pair, msg.NewPegMult, sender)
return &types.MsgShiftPegMultiplierResponse{}, err
}

Expand All @@ -208,11 +206,9 @@ func (m msgServer) ShiftPegMultiplier(
func (m msgServer) ShiftSwapInvariant(
goCtx context.Context, msg *types.MsgShiftSwapInvariant,
) (*types.MsgShiftSwapInvariantResponse, error) {
sender, err := sdk.AccAddressFromBech32(msg.Sender)
if err != nil {
return nil, err
}
// The `msg` here is checked with ValidateBasic before this fn is called.
sender, _ := sdk.AccAddressFromBech32(msg.Sender)
ctx := sdk.UnwrapSDKContext(goCtx)
err = m.k.Admin.ShiftSwapInvariant(ctx, msg.Pair, msg.NewSwapInvariant.ToLegacyDec(), sender)
err := m.k.Admin.ShiftSwapInvariant(ctx, msg.Pair, msg.NewSwapInvariant, sender)
return &types.MsgShiftSwapInvariantResponse{}, err
}
Loading

0 comments on commit 1b5c836

Please sign in to comment.