Skip to content

Commit

Permalink
fix: use exponent when calculating coin values
Browse files Browse the repository at this point in the history
  • Loading branch information
hallazzang committed Aug 12, 2024
1 parent c871758 commit 811b64a
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 24 deletions.
23 changes: 14 additions & 9 deletions x/rewards/keeper/oracle.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package keeper

import (
"context"
stdmath "math"

"cosmossdk.io/collections"
"cosmossdk.io/errors"
Expand All @@ -10,16 +11,17 @@ import (
slinkytypes "github.com/skip-mev/slinky/pkg/types"

"github.com/milkyway-labs/milkyway/x/rewards/types"
tickerstypes "github.com/milkyway-labs/milkyway/x/tickers/types"
)

func (k *Keeper) GetPrice(ctx context.Context, denom string) (math.LegacyDec, error) {
func (k *Keeper) GetAssetAndPrice(ctx context.Context, denom string) (tickerstypes.Asset, math.LegacyDec, error) {
asset, err := k.tickersKeeper.GetAsset(ctx, denom)
if err != nil {
// If asset is not found, then we return 0 as price.
if errors.IsOf(err, collections.ErrNotFound) {
return math.LegacyZeroDec(), nil
return tickerstypes.Asset{}, math.LegacyZeroDec(), nil
}
return math.LegacyDec{}, err
return tickerstypes.Asset{}, math.LegacyDec{}, err
}

sdkCtx := sdk.UnwrapSDKContext(ctx)
Expand All @@ -28,26 +30,29 @@ func (k *Keeper) GetPrice(ctx context.Context, denom string) (math.LegacyDec, er
if err != nil {
// If currency pair is not found return 0 as well.
if errors.IsOf(err, collections.ErrNotFound) {
return math.LegacyZeroDec(), nil
return asset, math.LegacyZeroDec(), nil
}
return math.LegacyDec{}, err
return asset, math.LegacyDec{}, err
}
decimals, err := k.oracleKeeper.GetDecimalsForCurrencyPair(sdkCtx, cp)
if err != nil {
return math.LegacyDec{}, err
return asset, math.LegacyDec{}, err
}

// Divide returned quote price by 10^{decimals} gives us the real price in
// decimal number.
return math.LegacyNewDecFromIntWithPrec(qpn.Price, int64(decimals)), nil
return asset, math.LegacyNewDecFromIntWithPrec(qpn.Price, int64(decimals)), nil
}

func (k *Keeper) GetCoinValue(ctx context.Context, coin sdk.Coin) (math.LegacyDec, error) {
price, err := k.GetPrice(ctx, coin.Denom)
asset, price, err := k.GetAssetAndPrice(ctx, coin.Denom)
if err != nil {
return math.LegacyDec{}, err
}
return price.MulInt(coin.Amount), nil
if price.IsZero() {
return math.LegacyZeroDec(), nil
}
return price.MulInt(coin.Amount).QuoInt64(int64(stdmath.Pow10(int(asset.Exponent)))), nil
}

func (k *Keeper) GetCoinsValue(ctx context.Context, coins sdk.Coins) (math.LegacyDec, error) {
Expand Down
45 changes: 30 additions & 15 deletions x/rewards/keeper/oracle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,44 @@ import (
"github.com/milkyway-labs/milkyway/utils"
)

func (s *KeeperTestSuite) TestGetPrice() {
func (s *KeeperTestSuite) TestGetAssetAndPrice() {
s.RegisterCurrency("umilk", "MILK", 6, utils.MustParseDec("2"))

price, err := s.keeper.GetPrice(s.Ctx, "umilk")
_, price, err := s.keeper.GetAssetAndPrice(s.Ctx, "umilk")
s.Require().NoError(err)
s.Require().Equal(utils.MustParseDec("2"), price)

_, price, err = s.keeper.GetAssetAndPrice(s.Ctx, "uinit")
s.Require().NoError(err)
s.Require().True(price.IsZero())
}

func (s *KeeperTestSuite) TestGetCoinValue() {
// TODO: uncomment this after adding exponent to tickers module
//s.RegisterCurrency("umilk", "MILK", utils.MustParseDec("2"))
//
//value, err := s.keeper.GetCoinValue(s.Ctx, utils.MustParseCoin("10_000000umilk"))
//s.Require().NoError(err)
//s.Require().Equal(utils.MustParseDec("20"), value)
s.RegisterCurrency("umilk", "MILK", 6, utils.MustParseDec("2"))
s.RegisterCurrency("afoo", "FOO", 18, utils.MustParseDec("0.53"))

value, err := s.keeper.GetCoinValue(s.Ctx, utils.MustParseCoin("10_000000umilk"))
s.Require().NoError(err)
s.Require().Equal(utils.MustParseDec("20"), value)

value, err = s.keeper.GetCoinValue(s.Ctx, utils.MustParseCoin("10_000000uinit"))
s.Require().NoError(err)
s.Require().True(value.IsZero())

value, err = s.keeper.GetCoinValue(s.Ctx, utils.MustParseCoin("1200000000000000afoo")) // 0.0012 $FOO
s.Require().NoError(err)
s.Require().Equal(utils.MustParseDec("0.000636"), value)
}

func (s *KeeperTestSuite) TestGetCoinsValue() {
// TODO: uncomment this after adding exponent to tickers module
//s.RegisterCurrency("umilk", "MILK", utils.MustParseDec("2"))
//s.RegisterCurrency("uinit", "INIT", utils.MustParseDec("3"))
//
//value, err := s.keeper.GetCoinsValue(s.Ctx, utils.MustParseCoins("10_000000umilk,5_5000000uinit"))
//s.Require().NoError(err)
//s.Require().Equal(utils.MustParseDec("36.5"), value)
s.RegisterCurrency("umilk", "MILK", 6, utils.MustParseDec("2"))
s.RegisterCurrency("uinit", "INIT", 6, utils.MustParseDec("3"))

value, err := s.keeper.GetCoinsValue(s.Ctx, utils.MustParseCoins("10_000000umilk,5_500000uinit"))
s.Require().NoError(err)
s.Require().Equal(utils.MustParseDec("36.5"), value)

value, err = s.keeper.GetCoinsValue(s.Ctx, utils.MustParseCoins("10_000000umilk,10_000000uatom"))
s.Require().NoError(err)
s.Require().Equal(utils.MustParseDec("20"), value)
}

0 comments on commit 811b64a

Please sign in to comment.