Skip to content

Commit

Permalink
Merge branch 'main' into bez/TestCalcJoinPoolShares-swap-tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mattverse authored Jun 10, 2022
2 parents 7da3a11 + e8050e2 commit 88743ef
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 13 deletions.
7 changes: 6 additions & 1 deletion x/gamm/pool-models/balancer/amm.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package balancer

import (
"errors"
fmt "fmt"
"fmt"

sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
Expand Down Expand Up @@ -236,6 +236,11 @@ func calcPoolSharesOutGivenSingleAssetIn(

// calcPoolOutGivenSingleIn - balance pAo.
func (p *Pool) calcSingleAssetJoin(tokenIn sdk.Coin, swapFee sdk.Dec, tokenInPoolAsset PoolAsset, totalShares sdk.Int) (numShares sdk.Int, err error) {
_, err = p.GetPoolAsset(tokenIn.Denom)
if err != nil {
return sdk.ZeroInt(), err
}

totalWeight := p.GetTotalWeight()
if totalWeight.IsZero() {
return sdk.ZeroInt(), errors.New("pool misconfigured, total weight = 0")
Expand Down
56 changes: 47 additions & 9 deletions x/gamm/pool-models/balancer/amm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package balancer_test
import (
"fmt"
"math/rand"
"strings"
"testing"
"time"

Expand All @@ -25,16 +26,21 @@ type calcJoinSharesTestCase struct {
swapFee sdk.Dec
poolAssets []balancer.PoolAsset
tokensIn sdk.Coins
expectErr bool
expectShares sdk.Int
expectLiq sdk.Coins
expErr error
}

// allowedErrRatio is the maximal multiplicative difference in either
// direction (positive or negative) that we accept to tolerate in
// unit tests for calcuating the number of shares to be returned by
// joining a pool. The comparison is done between Wolfram estimates and our AMM logic.
const allowedErrRatio = "0.0000001"
const (
// allowedErrRatio is the maximal multiplicative difference in either
// direction (positive or negative) that we accept to tolerate in
// unit tests for calcuating the number of shares to be returned by
// joining a pool. The comparison is done between Wolfram estimates and our AMM logic.
allowedErrRatio = "0.0000001"
// doesNotExistDenom denom name assummed to be used in test cases where the provided
// denom does not exist in pool
doesNotExistDenom = "doesnotexist"
)

// see calcJoinSharesTestCase struct definition.
var calcSingleAssetJoinTestCases = []calcJoinSharesTestCase{
Expand Down Expand Up @@ -281,6 +287,23 @@ var calcSingleAssetJoinTestCases = []calcJoinSharesTestCase{
expectShares: sdk.NewInt(819_444_430_000),
expectLiq: sdk.NewCoins(sdk.NewInt64Coin("uosmo", 50_000)),
},
{
name: "tokenIn asset does not exist in pool",
swapFee: sdk.MustNewDecFromStr("0"),
poolAssets: []balancer.PoolAsset{
{
Token: sdk.NewInt64Coin("uosmo", 1_000_000_000_000),
Weight: sdk.NewInt(100),
},
{
Token: sdk.NewInt64Coin("uatom", 1_000_000_000_000),
Weight: sdk.NewInt(100),
},
},
tokensIn: sdk.NewCoins(sdk.NewInt64Coin(doesNotExistDenom, 50_000)),
expectShares: sdk.ZeroInt(),
expErr: fmt.Errorf(balancer.ErrMsgFormatNoPoolAssetFound, doesNotExistDenom),
},
}

// This test sets up 2 asset pools, and then checks the spot price on them.
Expand Down Expand Up @@ -616,8 +639,9 @@ func TestCalcJoinPoolShares(t *testing.T) {
pool := createTestPool(t, tc.swapFee, sdk.MustNewDecFromStr("0"), tc.poolAssets...)

shares, liquidity, err := pool.CalcJoinPoolShares(sdk.Context{}, tc.tokensIn, tc.swapFee)
if tc.expectErr {
if tc.expErr != nil {
require.Error(t, err)
require.Equal(t, tc.expErr, err)
require.Equal(t, sdk.ZeroInt(), shares)
require.Equal(t, sdk.NewCoins(), liquidity)
} else {
Expand All @@ -640,14 +664,28 @@ func TestCalcSingleAssetJoin(t *testing.T) {

tokenIn := tc.tokensIn[0]

poolAssetInDenom := tokenIn.Denom
// when testing a case with tokenIn that does not exist in pool, we just want
// to provide any pool asset.
if tc.expErr != nil && strings.Contains(tc.expErr.Error(), doesNotExistDenom) {
poolAssetInDenom = tc.poolAssets[0].Token.Denom
}

// find pool asset in pool
// must be in pool since weights get scaled in Balancer pool
// constructor
poolAssetIn, err := balancerPool.GetPoolAsset(tokenIn.Denom)
poolAssetIn, err := balancerPool.GetPoolAsset(poolAssetInDenom)
require.NoError(t, err)

shares, err := balancerPool.CalcSingleAssetJoin(tokenIn, tc.swapFee, poolAssetIn, pool.GetTotalShares())
// It is impossible to set up a test case with error here so we omit it.

if tc.expErr != nil {
require.Error(t, err)
require.Equal(t, tc.expErr, err)
require.Equal(t, sdk.ZeroInt(), shares)
return
}

require.NoError(t, err)
assertExpectedSharesErrRatio(t, tc.expectShares, shares)
})
Expand Down
10 changes: 7 additions & 3 deletions x/gamm/pool-models/balancer/balancer_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ import (
"github.com/osmosis-labs/osmosis/v7/x/gamm/types"
)

const (
errMsgFormatNoPoolAssetFound = "can't find the PoolAsset (%s)"
)

var (
_ types.PoolI = &Pool{}
_ types.PoolAmountOutExtension = &Pool{}
Expand Down Expand Up @@ -220,7 +224,7 @@ func (pa Pool) getPoolAssetAndIndex(denom string) (int, PoolAsset, error) {
}

if len(pa.PoolAssets) == 0 {
return -1, PoolAsset{}, fmt.Errorf("can't find the PoolAsset (%s)", denom)
return -1, PoolAsset{}, fmt.Errorf(errMsgFormatNoPoolAssetFound, denom)
}

i := sort.Search(len(pa.PoolAssets), func(i int) bool {
Expand All @@ -231,11 +235,11 @@ func (pa Pool) getPoolAssetAndIndex(denom string) (int, PoolAsset, error) {
})

if i < 0 || i >= len(pa.PoolAssets) {
return -1, PoolAsset{}, fmt.Errorf("can't find the PoolAsset (%s)", denom)
return -1, PoolAsset{}, fmt.Errorf(errMsgFormatNoPoolAssetFound, denom)
}

if pa.PoolAssets[i].Token.Denom != denom {
return -1, PoolAsset{}, fmt.Errorf("can't find the PoolAsset (%s)", denom)
return -1, PoolAsset{}, fmt.Errorf(errMsgFormatNoPoolAssetFound, denom)
}

return i, pa.PoolAssets[i], nil
Expand Down
1 change: 1 addition & 0 deletions x/gamm/pool-models/balancer/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import sdk "github.com/cosmos/cosmos-sdk/types"

const (
ErrMsgFormatRepeatingPoolAssetsNotAllowed = errMsgFormatRepeatingPoolAssetsNotAllowed
ErrMsgFormatNoPoolAssetFound = errMsgFormatNoPoolAssetFound
)

var (
Expand Down

0 comments on commit 88743ef

Please sign in to comment.