Skip to content
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

Feature/add details to join exit pool reponse #1886

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Breaking Changes


* [#1889](https://github.com/osmosis-labs/osmosis/pull/1825) Add proto responses to gamm LP messages:
* MsgJoinPoolResponse: share_out_amount and token_in fields
* MsgExitPoolResponse: token_out field
* [#1825](https://github.com/osmosis-labs/osmosis/pull/1825) Fixes Interchain Accounts (host side) by adding it to AppModuleBasics
* [#1699](https://github.com/osmosis-labs/osmosis/pull/1699) Fixes bug in sig fig rounding on spot price queries for small values

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ require (
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect
github.com/gofrs/flock v0.8.1 // indirect
github.com/gogo/gateway v1.1.0 // indirect
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect
github.com/golang/glog v1.0.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/snappy v0.0.3 // indirect
github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 // indirect
Expand Down
3 changes: 2 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -487,8 +487,9 @@ github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzw
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
github.com/golang-sql/sqlexp v0.0.0-20170517235910-f1bb20e5a188/go.mod h1:vXjM/+wXQnTPR4KqTKDgJukSZ6amVRtWMPEjE6sQoK8=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ=
github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4=
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
Expand Down
19 changes: 17 additions & 2 deletions proto/osmosis/gamm/v1beta1/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,17 @@ message MsgJoinPool {
];
}

message MsgJoinPoolResponse {}
message MsgJoinPoolResponse {
string share_out_amount = 1 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.moretags) = "yaml:\"share_out_amount\"",
(gogoproto.nullable) = false
];
repeated cosmos.base.v1beta1.Coin token_in = 2 [
(gogoproto.moretags) = "yaml:\"token_in\"",
(gogoproto.nullable) = false
];
}

// ===================== MsgExitPool
message MsgExitPool {
Expand All @@ -57,7 +67,12 @@ message MsgExitPool {
];
}

message MsgExitPoolResponse {}
message MsgExitPoolResponse {
repeated cosmos.base.v1beta1.Coin token_out = 1 [
(gogoproto.moretags) = "yaml:\"token_out\"",
(gogoproto.nullable) = false
];
}

// ===================== MsgSwapExactAmountIn
message SwapAmountInRoute {
Expand Down
6 changes: 3 additions & 3 deletions x/gamm/keeper/gas_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func (suite *KeeperTestSuite) measureJoinPoolGas(
shareOutAmountMax sdk.Int, maxCoins sdk.Coins,
) uint64 {
alreadySpent := suite.Ctx.GasMeter().GasConsumed()
err := suite.App.GAMMKeeper.JoinPoolNoSwap(suite.Ctx, addr, poolID, shareOutAmountMax, maxCoins)
_, _, err := suite.App.GAMMKeeper.JoinPoolNoSwap(suite.Ctx, addr, poolID, shareOutAmountMax, maxCoins)
suite.Require().NoError(err)
newSpent := suite.Ctx.GasMeter().GasConsumed()
spentNow := newSpent - alreadySpent
Expand Down Expand Up @@ -76,7 +76,7 @@ func (suite *KeeperTestSuite) TestJoinPoolGas() {
suite.Assert().LessOrEqual(int(firstJoinGas), 100000)

for i := 1; i < startAveragingAt; i++ {
err := suite.App.GAMMKeeper.JoinPoolNoSwap(suite.Ctx, defaultAddr, poolId, minShareOutAmount, sdk.Coins{})
_, _, err := suite.App.GAMMKeeper.JoinPoolNoSwap(suite.Ctx, defaultAddr, poolId, minShareOutAmount, sdk.Coins{})
suite.Require().NoError(err)
}

Expand Down Expand Up @@ -133,7 +133,7 @@ func (suite *KeeperTestSuite) TestRepeatedJoinPoolDistinctDenom() {
firstJoinGas := suite.measureJoinPoolGas(defaultAddr, initialPoolId, minShareOutAmount, defaultCoins)

for i := 2; i < denomNumber; i++ {
err := suite.App.GAMMKeeper.JoinPoolNoSwap(suite.Ctx, defaultAddr, uint64(i), minShareOutAmount, sdk.Coins{})
_, _, err := suite.App.GAMMKeeper.JoinPoolNoSwap(suite.Ctx, defaultAddr, uint64(i), minShareOutAmount, sdk.Coins{})
suite.Require().NoError(err)
}

Expand Down
13 changes: 9 additions & 4 deletions x/gamm/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func (server msgServer) JoinPool(goCtx context.Context, msg *types.MsgJoinPool)
return nil, err
}

err = server.keeper.JoinPoolNoSwap(ctx, sender, msg.PoolId, msg.ShareOutAmount, msg.TokenInMaxs)
neededLp, sharesOut, err := server.keeper.JoinPoolNoSwap(ctx, sender, msg.PoolId, msg.ShareOutAmount, msg.TokenInMaxs)
if err != nil {
return nil, err
}
Expand All @@ -125,7 +125,10 @@ func (server msgServer) JoinPool(goCtx context.Context, msg *types.MsgJoinPool)
),
})

return &types.MsgJoinPoolResponse{}, nil
return &types.MsgJoinPoolResponse{
ShareOutAmount: sharesOut,
TokenIn: neededLp,
}, nil
}

func (server msgServer) ExitPool(goCtx context.Context, msg *types.MsgExitPool) (*types.MsgExitPoolResponse, error) {
Expand All @@ -136,7 +139,7 @@ func (server msgServer) ExitPool(goCtx context.Context, msg *types.MsgExitPool)
return nil, err
}

_, err = server.keeper.ExitPool(ctx, sender, msg.PoolId, msg.ShareInAmount, msg.TokenOutMins)
exitCoins, err := server.keeper.ExitPool(ctx, sender, msg.PoolId, msg.ShareInAmount, msg.TokenOutMins)
if err != nil {
return nil, err
}
Expand All @@ -153,7 +156,9 @@ func (server msgServer) ExitPool(goCtx context.Context, msg *types.MsgExitPool)
),
})

return &types.MsgExitPoolResponse{}, nil
return &types.MsgExitPoolResponse{
TokenOut: exitCoins,
}, nil
}

func (server msgServer) SwapExactAmountIn(goCtx context.Context, msg *types.MsgSwapExactAmountIn) (*types.MsgSwapExactAmountInResponse, error) {
Expand Down
16 changes: 8 additions & 8 deletions x/gamm/keeper/pool_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,35 +183,35 @@ func (k Keeper) JoinPoolNoSwap(
poolId uint64,
shareOutAmount sdk.Int,
tokenInMaxs sdk.Coins,
) (err error) {
) (tokenIn sdk.Coins, sharesOut sdk.Int, err error) {
// all pools handled within this method are pointer references, `JoinPool` directly updates the pools
pool, err := k.GetPoolAndPoke(ctx, poolId)
if err != nil {
return err
return nil, sdk.ZeroInt(), err
}

// we do an abstract calculation on the lp liquidity coins needed to have
// the designated amount of given shares of the pool without performing swap
neededLpLiquidity, err := getMaximalNoSwapLPAmount(ctx, pool, shareOutAmount)
if err != nil {
return err
return nil, sdk.ZeroInt(), err
}

// check that needed lp liquidity does not exceed the given `tokenInMaxs` parameter. Return error if so.
// if tokenInMaxs == 0, don't do this check.
if tokenInMaxs.Len() != 0 {
if !(neededLpLiquidity.DenomsSubsetOf(tokenInMaxs) && tokenInMaxs.IsAllGTE(neededLpLiquidity)) {
return sdkerrors.Wrapf(types.ErrLimitMaxAmount, "TokenInMaxs is less than the needed LP liquidity to this JoinPoolNoSwap,"+
return nil, sdk.ZeroInt(), sdkerrors.Wrapf(types.ErrLimitMaxAmount, "TokenInMaxs is less than the needed LP liquidity to this JoinPoolNoSwap,"+
" upperbound: %v, needed %v", tokenInMaxs, neededLpLiquidity)
} else if !(tokenInMaxs.DenomsSubsetOf(neededLpLiquidity)) {
return sdkerrors.Wrapf(types.ErrDenomNotFoundInPool, "TokenInMaxs includes tokens that are not part of the target pool,"+
return nil, sdk.ZeroInt(), sdkerrors.Wrapf(types.ErrDenomNotFoundInPool, "TokenInMaxs includes tokens that are not part of the target pool,"+
" input tokens: %v, pool tokens %v", tokenInMaxs, neededLpLiquidity)
}
}

sharesOut, err := pool.JoinPool(ctx, neededLpLiquidity, pool.GetSwapFee(ctx))
sharesOut, err = pool.JoinPool(ctx, neededLpLiquidity, pool.GetSwapFee(ctx))
if err != nil {
return err
return nil, sdk.ZeroInt(), err
}
// sanity check, don't return error as not worth halting the LP. We know its not too much.
if sharesOut.LT(shareOutAmount) {
Expand All @@ -220,7 +220,7 @@ func (k Keeper) JoinPoolNoSwap(
}

err = k.applyJoinPoolStateChange(ctx, pool, sender, sharesOut, neededLpLiquidity)
return err
return neededLpLiquidity, sharesOut, err
}

// getMaximalNoSwapLPAmount returns the coins(lp liquidity) needed to get the specified amount of shares in the pool.
Expand Down
31 changes: 20 additions & 11 deletions x/gamm/keeper/pool_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,21 +255,24 @@ func (suite *KeeperTestSuite) TestCreateBalancerPool() {

// TODO: Add more edge cases around TokenInMaxs not containing every token in pool.
func (suite *KeeperTestSuite) TestJoinPoolNoSwap() {
fiveKFooAndBar := sdk.NewCoins(sdk.NewCoin("bar", sdk.NewInt(5000)), sdk.NewCoin("foo", sdk.NewInt(5000)))
tests := []struct {
fn func(poolId uint64)
}{
{
fn: func(poolId uint64) {
keeper := suite.App.GAMMKeeper
balancesBefore := suite.App.BankKeeper.GetAllBalances(suite.Ctx, suite.TestAccs[1])
err := keeper.JoinPoolNoSwap(suite.Ctx, suite.TestAccs[1], poolId, types.OneShare.MulRaw(50), sdk.Coins{})
neededLp, sharesOut, err := keeper.JoinPoolNoSwap(suite.Ctx, suite.TestAccs[1], poolId, types.OneShare.MulRaw(50), sdk.Coins{})
suite.Require().NoError(err)
suite.Require().Equal(types.OneShare.MulRaw(50).String(), sharesOut.String())
suite.Require().Equal(types.OneShare.MulRaw(50).String(), suite.App.BankKeeper.GetBalance(suite.Ctx, suite.TestAccs[1], "gamm/pool/1").Amount.String())
balancesAfter := suite.App.BankKeeper.GetAllBalances(suite.Ctx, suite.TestAccs[1])

deltaBalances, _ := balancesBefore.SafeSub(balancesAfter)
// The pool was created with the 10000foo, 10000bar, and the pool share was minted as 100000000gamm/pool/1.
// Thus, to get the 50*OneShare gamm/pool/1, (10000foo, 10000bar) * (1 / 2) balances should be provided.
suite.Require().Equal(deltaBalances.FilterDenoms([]string{"foo", "bar"}).Sort().String(), neededLp.Sort().String())
suite.Require().Equal("5000", deltaBalances.AmountOf("foo").String())
suite.Require().Equal("5000", deltaBalances.AmountOf("bar").String())

Expand All @@ -280,14 +283,14 @@ func (suite *KeeperTestSuite) TestJoinPoolNoSwap() {
{
fn: func(poolId uint64) {
keeper := suite.App.GAMMKeeper
err := keeper.JoinPoolNoSwap(suite.Ctx, suite.TestAccs[1], poolId, sdk.NewInt(0), sdk.Coins{})
_, _, err := keeper.JoinPoolNoSwap(suite.Ctx, suite.TestAccs[1], poolId, sdk.NewInt(0), sdk.Coins{})
suite.Require().Error(err, "can't join the pool with requesting 0 share amount")
},
},
{
fn: func(poolId uint64) {
keeper := suite.App.GAMMKeeper
err := keeper.JoinPoolNoSwap(suite.Ctx, suite.TestAccs[1], poolId, sdk.NewInt(-1), sdk.Coins{})
_, _, err := keeper.JoinPoolNoSwap(suite.Ctx, suite.TestAccs[1], poolId, sdk.NewInt(-1), sdk.Coins{})
suite.Require().Error(err, "can't join the pool with requesting negative share amount")
},
},
Expand All @@ -296,7 +299,7 @@ func (suite *KeeperTestSuite) TestJoinPoolNoSwap() {
keeper := suite.App.GAMMKeeper
// Test the "tokenInMaxs"
// In this case, to get the 50 * OneShare amount of share token, the foo, bar token are expected to be provided as 5000 amounts.
err := keeper.JoinPoolNoSwap(suite.Ctx, suite.TestAccs[1], poolId, types.OneShare.MulRaw(50), sdk.Coins{
_, _, err := keeper.JoinPoolNoSwap(suite.Ctx, suite.TestAccs[1], poolId, types.OneShare.MulRaw(50), sdk.Coins{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add check and test ShareOutAmount and TokenIn returned here is as expected?

sdk.NewCoin("bar", sdk.NewInt(4999)), sdk.NewCoin("foo", sdk.NewInt(4999)),
})
suite.Require().Error(err)
Expand All @@ -307,13 +310,17 @@ func (suite *KeeperTestSuite) TestJoinPoolNoSwap() {
keeper := suite.App.GAMMKeeper
// Test the "tokenInMaxs"
// In this case, to get the 50 * OneShare amount of share token, the foo, bar token are expected to be provided as 5000 amounts.
err := keeper.JoinPoolNoSwap(suite.Ctx, suite.TestAccs[1], poolId, types.OneShare.MulRaw(50), sdk.Coins{
sdk.NewCoin("bar", sdk.NewInt(5000)), sdk.NewCoin("foo", sdk.NewInt(5000)),
})
actualTokenIn, actualSharesOut, err := keeper.JoinPoolNoSwap(suite.Ctx, suite.TestAccs[1], poolId, types.OneShare.MulRaw(50), sdk.Coins{
fiveKFooAndBar[0], fiveKFooAndBar[1]})
suite.Require().NoError(err)

liquidity := suite.App.GAMMKeeper.GetTotalLiquidity(suite.Ctx)
suite.Require().Equal("15000bar,15000foo", liquidity.String())
// TODO: Add these tests to more cases, as part of improving this test structure.
// 100% add, so actualTokenIn = max provided
suite.Require().Equal(fiveKFooAndBar, actualTokenIn)
// shares out was estimated perfectly
suite.Require().Equal(types.OneShare.MulRaw(50), actualSharesOut)
},
},
{
Expand All @@ -322,7 +329,7 @@ func (suite *KeeperTestSuite) TestJoinPoolNoSwap() {
// Test the "tokenInMaxs" with an additional invalid denom
// In this case, to get the 50 * OneShare amount of share token, the foo, bar token are expected to be provided as 5000 amounts.
// The test input has the correct amount for each, but also includes an incorrect denom that should cause an error
err := keeper.JoinPoolNoSwap(suite.Ctx, suite.TestAccs[1], poolId, types.OneShare.MulRaw(50), sdk.Coins{
_, _, err := keeper.JoinPoolNoSwap(suite.Ctx, suite.TestAccs[1], poolId, types.OneShare.MulRaw(50), sdk.Coins{
sdk.NewCoin("bar", sdk.NewInt(5000)), sdk.NewCoin("foo", sdk.NewInt(5000)), sdk.NewCoin("baz", sdk.NewInt(5000)),
})
suite.Require().Error(err)
Expand Down Expand Up @@ -351,6 +358,7 @@ func (suite *KeeperTestSuite) TestJoinPoolNoSwap() {
}

func (suite *KeeperTestSuite) TestExitPool() {
fiveKFooAndBar := sdk.NewCoins(sdk.NewCoin("bar", sdk.NewInt(5000)), sdk.NewCoin("foo", sdk.NewInt(5000)))
tests := []struct {
fn func(poolId uint64)
}{
Expand Down Expand Up @@ -414,10 +422,11 @@ func (suite *KeeperTestSuite) TestExitPool() {

// Test the "tokenOutMins"
// In this case, to refund the 50000000 amount of share token, the foo, bar token are expected to be refunded as 5000 amounts.
_, err := keeper.ExitPool(suite.Ctx, suite.TestAccs[0], poolId, types.OneShare.MulRaw(50), sdk.Coins{
exitedCoins, err := keeper.ExitPool(suite.Ctx, suite.TestAccs[0], poolId, types.OneShare.MulRaw(50), sdk.Coins{
sdk.NewCoin("foo", sdk.NewInt(5000)),
})
suite.Require().NoError(err)
suite.Require().Equal(fiveKFooAndBar, exitedCoins)
},
},
}
Expand Down Expand Up @@ -505,7 +514,7 @@ func (suite *KeeperTestSuite) TestJoinPoolExitPool_InverseRelationship() {
balanceBeforeJoin := suite.App.BankKeeper.GetAllBalances(suite.Ctx, joinPoolAcc)
fmt.Println(balanceBeforeJoin.String())

err = suite.App.GAMMKeeper.JoinPoolNoSwap(suite.Ctx, joinPoolAcc, poolId, tc.joinPoolShareAmt, sdk.Coins{})
_, _, err = suite.App.GAMMKeeper.JoinPoolNoSwap(suite.Ctx, joinPoolAcc, poolId, tc.joinPoolShareAmt, sdk.Coins{})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto:Can we add check and test ShareOutAmount and TokenIn returned here is as expected?

suite.Require().NoError(err)

_, err = suite.App.GAMMKeeper.ExitPool(suite.Ctx, joinPoolAcc, poolId, tc.joinPoolShareAmt, sdk.Coins{})
Expand Down Expand Up @@ -547,7 +556,7 @@ func (suite *KeeperTestSuite) TestActiveBalancerPool() {
suite.Ctx = suite.Ctx.WithBlockTime(tc.blockTime)

// uneffected by start time
err := suite.App.GAMMKeeper.JoinPoolNoSwap(suite.Ctx, suite.TestAccs[0], poolId, types.OneShare.MulRaw(50), sdk.Coins{})
_, _, err := suite.App.GAMMKeeper.JoinPoolNoSwap(suite.Ctx, suite.TestAccs[0], poolId, types.OneShare.MulRaw(50), sdk.Coins{})
suite.Require().NoError(err)
_, err = suite.App.GAMMKeeper.ExitPool(suite.Ctx, suite.TestAccs[0], poolId, types.InitPoolSharesSupply.QuoRaw(2), sdk.Coins{})
suite.Require().NoError(err)
Expand Down
Loading