Skip to content

Commit

Permalink
merge conflict
Browse files Browse the repository at this point in the history
  • Loading branch information
teddyding committed Jun 27, 2024
1 parent a12e54c commit dacd0da
Showing 1 changed file with 0 additions and 321 deletions.
321 changes: 0 additions & 321 deletions protocol/x/perpetuals/keeper/perpetual_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -674,328 +674,7 @@ func TestModifyOpenInterest_Mixed(t *testing.T) {
}
}

<<<<<<< HEAD
func TestGetMarginRequirements_Success(t *testing.T) {
oneBip := math.Pow10(2)
tests := map[string]struct {
price uint64
exponent int32
baseCurrencyAtomicResolution int32
bigBaseQuantums *big.Int
initialMarginPpm uint32
maintenanceFractionPpm uint32
openInterest *big.Int
openInterestLowerCap uint64
openInterestUpperCap uint64
bigExpectedInitialMarginPpm *big.Int
bigExpectedMaintenanceMarginPpm *big.Int
}{
"InitialMargin 2 BIPs, MaintenanceMargin 1 BIP, positive exponent, atomic resolution 8": {
price: 5_555,
exponent: 2,
baseCurrencyAtomicResolution: -8,
bigBaseQuantums: big.NewInt(7_000),
initialMarginPpm: uint32(oneBip * 2),
maintenanceFractionPpm: uint32(500_000), // 50% of IM
bigExpectedInitialMarginPpm: big.NewInt(7_777),
bigExpectedMaintenanceMarginPpm: big.NewInt(3_889),
},
"InitialMargin 100 BIPs, MaintenanceMargin 50 BIPs, atomic resolution 4": {
price: 5_555,
exponent: 0,
baseCurrencyAtomicResolution: -4,
bigBaseQuantums: big.NewInt(7_000),
initialMarginPpm: uint32(oneBip * 100),
maintenanceFractionPpm: uint32(500_000), // 50% of IM
bigExpectedInitialMarginPpm: big.NewInt(38_885_000),
bigExpectedMaintenanceMarginPpm: big.NewInt(19_442_500),
},
"InitialMargin 100 BIPs, MaintenanceMargin 50 BIPs, positive exponent, atomic resolution 0": {
price: 42,
exponent: 5,
baseCurrencyAtomicResolution: -0,
bigBaseQuantums: big.NewInt(88),
initialMarginPpm: uint32(oneBip * 100),
maintenanceFractionPpm: uint32(500_000), // 50% of IM
bigExpectedInitialMarginPpm: big.NewInt(3_696_000_000_000),
bigExpectedMaintenanceMarginPpm: big.NewInt(1_848_000_000_000),
},
"InitialMargin 100 BIPs, MaintenanceMargin 50 BIPs, negative exponent, atomic resolution 6": {
price: 42_000_000,
exponent: -2,
baseCurrencyAtomicResolution: -6,
bigBaseQuantums: big.NewInt(-5_000),
initialMarginPpm: uint32(oneBip * 100),
maintenanceFractionPpm: uint32(500_000), // 50% of IM
bigExpectedInitialMarginPpm: big.NewInt(21_000_000),
bigExpectedMaintenanceMarginPpm: big.NewInt(10_500_000),
},
"InitialMargin 10_000 BIPs (max), MaintenanceMargin 10_000 BIPs (max), atomic resolution 6": {
price: 5_555,
exponent: 0,
baseCurrencyAtomicResolution: -6,
bigBaseQuantums: big.NewInt(7_000),
initialMarginPpm: uint32(oneBip * 10_000),
maintenanceFractionPpm: uint32(1_000_000), // 100% of IM
bigExpectedInitialMarginPpm: big.NewInt(38_885_000),
bigExpectedMaintenanceMarginPpm: big.NewInt(38_885_000),
},
"InitialMargin 100 BIPs, MaintenanceMargin 100 BIPs, atomic resolution 6": {
price: 5_555,
exponent: 0,
baseCurrencyAtomicResolution: -6,
bigBaseQuantums: big.NewInt(7_000),
initialMarginPpm: uint32(oneBip * 100),
maintenanceFractionPpm: uint32(1_000_000), // 100% of IM
bigExpectedInitialMarginPpm: big.NewInt(388_850),
bigExpectedMaintenanceMarginPpm: big.NewInt(388_850),
},
"InitialMargin 0.02 BIPs, MaintenanceMargin 0.01 BIPs, positive exponent, atomic resolution 6": {
price: 5_555,
exponent: 3,
baseCurrencyAtomicResolution: -6,
bigBaseQuantums: big.NewInt(-7_000),
initialMarginPpm: uint32(oneBip * 0.02),
maintenanceFractionPpm: uint32(500_000), // 50% of IM
bigExpectedInitialMarginPpm: big.NewInt(77_770),
bigExpectedMaintenanceMarginPpm: big.NewInt(38_885),
},
"InitialMargin 0 BIPs (min), MaintenanceMargin 0 BIPs (min), atomic resolution 6": {
price: 5_555,
exponent: 0,
baseCurrencyAtomicResolution: -6,
bigBaseQuantums: big.NewInt(7_000),
initialMarginPpm: uint32(oneBip * 0),
maintenanceFractionPpm: uint32(1_000_000), // 100% of IM,
bigExpectedInitialMarginPpm: big.NewInt(0),
bigExpectedMaintenanceMarginPpm: big.NewInt(0),
},
"Price is zero, atomic resolution 6": {
price: 0,
exponent: 1,
baseCurrencyAtomicResolution: -6,
bigBaseQuantums: big.NewInt(-7_000),
initialMarginPpm: uint32(oneBip * 1),
maintenanceFractionPpm: uint32(1_000_000), // 100% of IM,
bigExpectedInitialMarginPpm: big.NewInt(0),
bigExpectedMaintenanceMarginPpm: big.NewInt(0),
},
"Price and quantums are max uints": {
price: math.MaxUint64,
exponent: 1,
baseCurrencyAtomicResolution: -6,
bigBaseQuantums: new(big.Int).SetUint64(math.MaxUint64),
initialMarginPpm: uint32(oneBip * 1),
maintenanceFractionPpm: uint32(1_000_000), // 100% of IM,
bigExpectedInitialMarginPpm: big_testutil.MustFirst(
new(big.Int).SetString("340282366920938463426481119284349109", 10),
),
bigExpectedMaintenanceMarginPpm: big_testutil.MustFirst(
new(big.Int).SetString("340282366920938463426481119284349109", 10),
),
},
"InitialMargin 100 BIPs, MaintenanceMargin 50 BIPs, atomic resolution 6": {
price: 5_555,
exponent: 0,
baseCurrencyAtomicResolution: -6,
bigBaseQuantums: big.NewInt(7_000),
initialMarginPpm: uint32(oneBip * 100),
maintenanceFractionPpm: uint32(500_000), // 50% of IM
// initialMarginPpmQuoteQuantums = initialMarginPpm * quoteQuantums / 1_000_000
// = 10_000 * 38_885_000 / 1_000_000 ~= 388_850.
bigExpectedInitialMarginPpm: big.NewInt(388_850),
bigExpectedMaintenanceMarginPpm: big.NewInt(388_850 / 2),
},
"InitialMargin 20%, MaintenanceMargin 10%, atomic resolution 6": {
price: 36_750,
exponent: 0,
baseCurrencyAtomicResolution: -6,
bigBaseQuantums: big.NewInt(12_000),
initialMarginPpm: uint32(200_000),
maintenanceFractionPpm: uint32(500_000), // 50% of IM
// quoteQuantums = 36_750 * 12_000 = 441_000_000
// initialMarginPpmQuoteQuantums = initialMarginPpm * quoteQuantums / 1_000_000
// = 200_000 * 441_000_000 / 1_000_000 ~= 88_200_000
bigExpectedInitialMarginPpm: big.NewInt(88_200_000),
bigExpectedMaintenanceMarginPpm: big.NewInt(88_200_000 / 2),
},
"InitialMargin 5%, MaintenanceMargin 3%, atomic resolution 6": {
price: 123_456,
exponent: 0,
baseCurrencyAtomicResolution: -6,
bigBaseQuantums: big.NewInt(74_523),
initialMarginPpm: uint32(50_000),
maintenanceFractionPpm: uint32(600_000), // 60% of IM
// quoteQuantums = 123_456 * 74_523 = 9_200_311_488
// initialMarginPpmQuoteQuantums = initialMarginPpm * quoteQuantums / 1_000_000
// = 50_000 * 9_200_311_488 / 1_000_000 ~= 460_015_575
bigExpectedInitialMarginPpm: big.NewInt(460_015_575),
bigExpectedMaintenanceMarginPpm: big.NewInt(276_009_345),
},
"InitialMargin 25%, MaintenanceMargin 15%, atomic resolution 6": {
price: 123_456,
exponent: 0,
baseCurrencyAtomicResolution: -6,
bigBaseQuantums: big.NewInt(74_523),
initialMarginPpm: uint32(250_000),
maintenanceFractionPpm: uint32(600_000), // 60% of IM
// quoteQuantums = 123_456 * 74_523 = 9_200_311_488
bigExpectedInitialMarginPpm: big.NewInt(2_300_077_872),
bigExpectedMaintenanceMarginPpm: big.NewInt(1_380_046_724), // Rounded up
},
"OIMF: IM 20%, scaled to 60%, MaintenanceMargin 10%, atomic resolution 6": {
price: 36_750,
exponent: 0,
baseCurrencyAtomicResolution: -6,
bigBaseQuantums: big.NewInt(12_000),
initialMarginPpm: uint32(200_000),
maintenanceFractionPpm: uint32(500_000), // 50% of IM
openInterest: big.NewInt(408_163_265), // 408.163265
openInterestLowerCap: 10_000_000_000_000,
openInterestUpperCap: 20_000_000_000_000,
// quoteQuantums = 36_750 * 12_000 = 441_000_000
// initialMarginPpmQuoteQuantums = initialMarginPpm * quoteQuantums / 1_000_000
// = 200_000 * 441_000_000 / 1_000_000 ~= 88_200_000
bigExpectedInitialMarginPpm: big.NewInt(88_200_000 * 3),
bigExpectedMaintenanceMarginPpm: big.NewInt(88_200_000 / 2),
},
"OIMF: IM 20%, scaled to 100%, MaintenanceMargin 10%, atomic resolution 6": {
price: 36_750,
exponent: 0,
baseCurrencyAtomicResolution: -6,
bigBaseQuantums: big.NewInt(12_000),
initialMarginPpm: uint32(200_000),
maintenanceFractionPpm: uint32(500_000), // 50% of IM
openInterest: big.NewInt(1_000_000_000), // 1000 or ~$36mm notional
openInterestLowerCap: 10_000_000_000_000,
openInterestUpperCap: 20_000_000_000_000,
// quoteQuantums = 36_750 * 12_000 = 441_000_000
// initialMarginPpmQuoteQuantums = initialMarginPpm * quoteQuantums / 1_000_000
// = 200_000 * 441_000_000 / 1_000_000 ~= 88_200_000
bigExpectedInitialMarginPpm: big.NewInt(441_000_000),
bigExpectedMaintenanceMarginPpm: big.NewInt(88_200_000 / 2),
},
"OIMF: IM 20%, lower_cap < realistic open interest < upper_cap, MaintenanceMargin 10%, atomic resolution 6": {
price: 36_750,
exponent: 0,
baseCurrencyAtomicResolution: -6,
bigBaseQuantums: big.NewInt(12_000),
initialMarginPpm: uint32(200_000),
maintenanceFractionPpm: uint32(500_000), // 50% of IM
openInterest: big.NewInt(1_123_456_789), // 1123.456 or ~$41mm notional
openInterestLowerCap: 25_000_000_000_000,
openInterestUpperCap: 50_000_000_000_000,
// quoteQuantums = 36_750 * 12_000 = 441_000_000
// initialMarginPpmQuoteQuantums = initialMarginPpm * quoteQuantums / 1_000_000
// = ((1123.456789 * 36750 - 25000000) / 25000000 * 0.8 + 0.2) * 441_000_000
// ~= 318042667
bigExpectedInitialMarginPpm: big.NewInt(318_042_667),
bigExpectedMaintenanceMarginPpm: big.NewInt(88_200_000 / 2),
},
}

// Run tests.
for name, tc := range tests {
t.Run(name, func(t *testing.T) {
// Individual test setup.
pc := keepertest.PerpetualsKeepers(t)
// Create a new market param and price.
marketId := keepertest.GetNumMarkets(t, pc.Ctx, pc.PricesKeeper)
_, err := pc.PricesKeeper.CreateMarket(
pc.Ctx,
pricestypes.MarketParam{
Id: marketId,
Pair: "marketName",
Exponent: tc.exponent,
MinExchanges: uint32(1),
MinPriceChangePpm: uint32(50),
ExchangeConfigJson: "{}",
},
pricestypes.MarketPrice{
Id: marketId,
Exponent: tc.exponent,
Price: 1_000, // leave this as a placeholder b/c we cannot set the price to 0
},
)
require.NoError(t, err)

// Update `Market.price`. By updating prices this way, we can simulate conditions where the oracle
// price may become 0.
err = pc.PricesKeeper.UpdateMarketPrices(
pc.Ctx,
[]*pricestypes.MsgUpdateMarketPrices_MarketPrice{pricestypes.NewMarketPriceUpdate(
marketId,
tc.price,
)},
)
require.NoError(t, err)

// Create `LiquidityTier` struct.
_, err = pc.PerpetualsKeeper.SetLiquidityTier(
pc.Ctx,
0,
"name",
tc.initialMarginPpm,
tc.maintenanceFractionPpm,
1, // dummy impact notional value
tc.openInterestLowerCap,
tc.openInterestUpperCap,
)
require.NoError(t, err)

// Create `Perpetual` struct with baseAssetAtomicResolution and marketId.
perpetual, err := pc.PerpetualsKeeper.CreatePerpetual(
pc.Ctx,
0, // PerpetualId
"getMarginRequirementsTicker", // Ticker
marketId, // MarketId
tc.baseCurrencyAtomicResolution, // AtomicResolution
int32(0), // DefaultFundingPpm
0, // LiquidityTier
types.PerpetualMarketType_PERPETUAL_MARKET_TYPE_CROSS, // MarketType
)
require.NoError(t, err)

// If test case contains non-nil open interest, set it up.
if tc.openInterest != nil {
require.NoError(t, pc.PerpetualsKeeper.ModifyOpenInterest(
pc.Ctx,
perpetual.Params.Id,
tc.openInterest, // initialized as zero, so passing `openInterest` as delta amount.
))
}

// Verify initial and maintenance margin requirements are calculated correctly.
bigInitialMargin, bigMaintenanceMargin, err := pc.PerpetualsKeeper.GetMarginRequirements(
pc.Ctx,
perpetual.Params.Id,
tc.bigBaseQuantums,
)
require.NoError(t, err)

if tc.bigExpectedInitialMarginPpm.Cmp(bigInitialMargin) != 0 {
t.Fatalf(
"%s: expectedInitialMargin: %s, initialMargin: %s",
name,
tc.bigExpectedInitialMarginPpm.String(),
bigInitialMargin.String())
}

if tc.bigExpectedMaintenanceMarginPpm.Cmp(bigMaintenanceMargin) != 0 {
t.Fatalf(
"%s: expectedMaintenanceMargin: %s, maintenanceMargin: %s",
name,
tc.bigExpectedMaintenanceMarginPpm.String(),
bigMaintenanceMargin.String())
}
})
}
}

func TestGetMarginRequirements_PerpetualNotFound(t *testing.T) {
=======
func TestGetPerpetualAndMarketPriceAndLiquidityTier_PerpetualNotFound(t *testing.T) {
>>>>>>> edcc82b7 ([Performance] Remove the need to get each perpetual and price twice when checking collateralization (#1681))
pc := keepertest.PerpetualsKeepers(t)
nonExistentPerpetualId := uint32(0)
_, _, _, err := pc.PerpetualsKeeper.GetPerpetualAndMarketPriceAndLiquidityTier(
Expand Down

0 comments on commit dacd0da

Please sign in to comment.