-
Notifications
You must be signed in to change notification settings - Fork 608
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
fix(gamm): SpotPrice keeper function #3715
Changes from all commits
16eb3e5
a96cf58
09e0ce2
f9d1f58
d40e20b
88ff590
2b4174e
63dee1b
4f8cfeb
b258cfa
6652e9a
d8de9b8
cdfff9f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,8 +24,8 @@ import ( | |
func (k Keeper) CalculateSpotPrice( | ||
ctx sdk.Context, | ||
poolID uint64, | ||
baseAssetDenom string, | ||
quoteAssetDenom string, | ||
baseAssetDenom string, | ||
) (spotPrice sdk.Dec, err error) { | ||
pool, err := k.GetPoolAndPoke(ctx, poolID) | ||
if err != nil { | ||
|
@@ -40,7 +40,7 @@ func (k Keeper) CalculateSpotPrice( | |
} | ||
}() | ||
|
||
spotPrice, err = pool.SpotPrice(ctx, baseAssetDenom, quoteAssetDenom) | ||
spotPrice, err = pool.SpotPrice(ctx, quoteAssetDenom, baseAssetDenom) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. note: technically, pools could keep the existing parameter order and just get fixed on the implementation level. However, I think it is useful to keep the order consistent with the keeper. As a result, I changed the denom order for pools as well |
||
if err != nil { | ||
return sdk.Dec{}, err | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -611,14 +611,20 @@ func (p *Pool) applySwap(ctx sdk.Context, tokensIn sdk.Coins, tokensOut sdk.Coin | |
|
||
// SpotPrice returns the spot price of the pool | ||
// This is the weight-adjusted balance of the tokens in the pool. | ||
// In order reduce the propagated effect of incorrect trailing digits, | ||
// To reduce the propagated effect of incorrect trailing digits, | ||
// we take the ratio of weights and divide this by ratio of supplies | ||
// this is equivalent to spot_price = (Base_supply / Weight_base) / (Quote_supply / Weight_quote) | ||
// but cancels out the common term in weight. | ||
// this is equivalent to spot_price = (Quote Supply / Quote Weight) / (Base Supply / Base Weight) | ||
// | ||
// As an example, assume equal weights. uosmo supply of 2 and uatom supply of 4. | ||
// | ||
// Case 1: base = uosmo, quote = uatom -> for one uosmo, get 2 uatom = 4 / 2 = 2 | ||
// In other words, it costs 2 uatom to get one uosmo. | ||
// | ||
// Case 2: base = uatom, quote = uosmo -> for one uatom, get 0.5 uosmo = 2 / 4 = 0.5 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the same thing, but I find it easier to read "it costs 0.5 uosmo to get one uatom" and "it costs "2 uatom to get 1 osmo". I think this is because the word "quote" implies to me that it is the price/cost of the base asset denominated in quote asset. So, what you're "getting" is the base asset. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Gotcha, I added your interpretation in comments as well |
||
// In other words, it costs 0.5 uosmo to get one uatom. | ||
// | ||
// panics if the pool in state is incorrect, and has any weight that is 0. | ||
// TODO: Come back and improve docs for this. | ||
func (p Pool) SpotPrice(ctx sdk.Context, baseAsset, quoteAsset string) (spotPrice sdk.Dec, err error) { | ||
func (p Pool) SpotPrice(ctx sdk.Context, quoteAsset, baseAsset string) (spotPrice sdk.Dec, err error) { | ||
quote, base, err := p.parsePoolAssetsByDenoms(quoteAsset, baseAsset) | ||
if err != nil { | ||
return sdk.Dec{}, err | ||
|
@@ -627,10 +633,11 @@ func (p Pool) SpotPrice(ctx sdk.Context, baseAsset, quoteAsset string) (spotPric | |
return sdk.Dec{}, errors.New("pool is misconfigured, got 0 weight") | ||
} | ||
|
||
// spot_price = (Base_supply / Weight_base) / (Quote_supply / Weight_quote) | ||
// spot_price = (weight_quote / weight_base) * (base_supply / quote_supply) | ||
invWeightRatio := quote.Weight.ToDec().Quo(base.Weight.ToDec()) | ||
supplyRatio := base.Token.Amount.ToDec().Quo(quote.Token.Amount.ToDec()) | ||
// spot_price = (Quote Supply / Quote Weight) / (Base Supply / Base Weight) | ||
// = (Quote Supply / Quote Weight) * (Base Weight / Base Supply) | ||
// = (Base Weight / Quote Weight) * (Quote Supply / Base Supply) | ||
invWeightRatio := base.Weight.ToDec().Quo(quote.Weight.ToDec()) | ||
supplyRatio := quote.Token.Amount.ToDec().Quo(base.Token.Amount.ToDec()) | ||
spotPrice = supplyRatio.Mul(invWeightRatio) | ||
|
||
return spotPrice, err | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -55,7 +55,9 @@ func getSpotPrices( | |
previousErrorTime time.Time, | ||
) (sp0 sdk.Dec, sp1 sdk.Dec, latestErrTime time.Time) { | ||
latestErrTime = previousErrorTime | ||
// sp0 = denom0 quote, denom1 base. | ||
sp0, err0 := k.CalculateSpotPrice(ctx, poolId, denom0, denom1) | ||
// sp1 = denom0 base, denom1 quote. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. useful to have these comments here! |
||
sp1, err1 := k.CalculateSpotPrice(ctx, poolId, denom1, denom0) | ||
if err0 != nil || err1 != nil { | ||
latestErrTime = ctx.BlockTime() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: the order is changed to avoid twap migrations