diff --git a/protocol/lib/quantums.go b/protocol/lib/quantums.go index a4e1ac6417..2bd813689b 100644 --- a/protocol/lib/quantums.go +++ b/protocol/lib/quantums.go @@ -20,7 +20,7 @@ import ( // (10^quoteCurrencyAtomicResolution) // = // baseQuantums * priceValue * -// 10^(priceExponent + baseCurrencyAtomicResolution - quoteCurrencyAtomicResolution) +// 10^(priceExponent + baseCurrencyAtomicResolution - quoteCurrencyAtomicResolution) [expression 1] // // The result is rounded down. func BaseToQuoteQuantums( @@ -87,7 +87,12 @@ func QuoteToBaseQuantums( // multiplyByPrice multiples a value by price, factoring in exponents of base // and quote currencies. // Given `value`, returns result of the following: -// `value * priceValue * 10^(priceExponent + baseCurrencyAtomicResolution - quoteCurrencyAtomicResolution)` +// +// `value * priceValue * 10^(priceExponent + baseAtomicResolution - quoteAtomicResolution)` [expression 2] +// +// Note that both `BaseToQuoteQuantums` and `FundingRateToIndex` directly wrap around this function. +// - For `BaseToQuoteQuantums`, substituing `value` with `baseQuantums` in expression 2 yields expression 1. +// - For `FundingRateToIndex`, substituing `value` with `fundingRatePpm * time` in expression 2 yields expression 3. func multiplyByPrice( value *big.Rat, baseCurrencyAtomicResolution int32, @@ -122,7 +127,7 @@ func multiplyByPrice( // - right side: // ``` // fundingRate * time * quoteQuantums / baseQuantums = fundingRatePpm / 1_000_000 * -// priceValue * 10^(priceExponent + baseCurrencyAtomicResolution - quoteCurrencyAtomicResolution) +// priceValue * 10^(priceExponent + baseCurrencyAtomicResolution - quoteCurrencyAtomicResolution) [expression 3] // ``` // // Hence, further multiplying both sides by 1_000_000, we have: @@ -134,7 +139,6 @@ func multiplyByPrice( // Arguments: // // proratedFundingRate: prorated funding rate adjusted by time delta, in parts-per-million -// timeSinceLastFunding: time (in seconds) since last funding index update // baseCurrencyAtomicResolution: atomic resolution of the base currency // priceValue: index price of the perpetual market according to the pricesKeeper // priceExponent: priceExponent of the market according to the pricesKeeper diff --git a/protocol/lib/quantums_test.go b/protocol/lib/quantums_test.go index 2ba83a87ba..cbc590e080 100644 --- a/protocol/lib/quantums_test.go +++ b/protocol/lib/quantums_test.go @@ -144,6 +144,20 @@ func TestQuoteToBaseQuantums(t *testing.T) { priceExponent: 0, bigExpectedBaseQuantums: big.NewInt(5_000_000), }, + "realistic values: 1 BTC at $29001": { + bigQuoteQuantums: big.NewInt(29_001_000_000), // $29_001 + baseCurrencyAtomicResolution: -10, + priceValue: 2_900_100_000, + priceExponent: -5, + bigExpectedBaseQuantums: big.NewInt(10_000_000_000), + }, + "realistic values: 25.123 BTC at $29001": { + bigQuoteQuantums: big.NewInt(728_592_123_000), // $728_592.123 + baseCurrencyAtomicResolution: -10, + priceValue: 2_900_100_000, + priceExponent: -5, + bigExpectedBaseQuantums: big.NewInt(251_230_000_000), + }, "baseCurrencyAtomicResolution is greater than 10^6": { bigQuoteQuantums: big.NewInt(350_000), baseCurrencyAtomicResolution: -8,