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

Add custom recipient field for amm swap functions #278

Merged
merged 4 commits into from
Nov 27, 2023
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
8 changes: 5 additions & 3 deletions proto/elys/amm/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,12 @@ message MsgSwapExactAmountIn {
cosmos.base.v1beta1.Coin token_in = 3 [(gogoproto.nullable) = false ] ;
string token_out_min_amount = 4 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false];
string discount = 5 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false];

string recipient = 6;
}

message MsgSwapExactAmountInResponse {
string token_out_amount = 1 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false];
string discount = 2 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false];
string discount = 2 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false];
}

message MsgSwapExactAmountOut {
Expand All @@ -77,11 +77,12 @@ message MsgSwapExactAmountOut {
cosmos.base.v1beta1.Coin token_out = 3 [(gogoproto.nullable) = false ] ;
string token_in_max_amount = 4 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false];
string discount = 5 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false];
string recipient = 6;
cosmic-vagabond marked this conversation as resolved.
Show resolved Hide resolved
}

message MsgSwapExactAmountOutResponse {
string token_in_amount = 1 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false];
string discount = 2 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false];
string discount = 2 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false];
}

message MsgFeedMultipleExternalLiquidity {
Expand Down Expand Up @@ -111,6 +112,7 @@ message MsgSwapByDenom {
string denom_in = 5;
string denom_out = 6;
string discount = 7 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false];
string recipient = 8;
}

message MsgSwapByDenomResponse {
Expand Down
1 change: 1 addition & 0 deletions x/amm/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ var (

const (
FlagDiscount = "discount"
FlagRecipient = "recipient"
flagPacketTimeoutTimestamp = "packet-timeout-timestamp"
listSeparator = ","
)
Expand Down
7 changes: 7 additions & 0 deletions x/amm/client/cli/tx_swap_by_denom.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,19 @@ func CmdSwapByDenom() *cobra.Command {
return err
}

recipient, err := cmd.Flags().GetString(FlagRecipient)
if err != nil {
return err
}

clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

msg := types.NewMsgSwapByDenom(
clientCtx.GetFromAddress().String(),
recipient,
argAmount,
minAmount,
maxAmount,
Expand All @@ -91,6 +97,7 @@ func CmdSwapByDenom() *cobra.Command {
cmd.Flags().String(FlagMinAmount, "", "minimum amount of tokens to receive")
cmd.Flags().String(FlagMaxAmount, "", "maximum amount of tokens to send")
cmd.Flags().String(FlagDiscount, "0.0", "discount to apply to the swap fee (only smart contract broker can apply the discount)")
cmd.Flags().String(FlagRecipient, "", "optional recipient field for the tokens swapped to be sent to")

return cmd
}
7 changes: 7 additions & 0 deletions x/amm/client/cli/tx_swap_exact_amount_in.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,19 @@ func CmdSwapExactAmountIn() *cobra.Command {
return err
}

recipient, err := cmd.Flags().GetString(FlagRecipient)
if err != nil {
return err
}

clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

msg := types.NewMsgSwapExactAmountIn(
clientCtx.GetFromAddress().String(),
recipient,
argTokenIn,
argTokenOutMinAmount,
argSwapRoutePoolIds,
Expand All @@ -76,6 +82,7 @@ func CmdSwapExactAmountIn() *cobra.Command {
flags.AddTxFlagsToCmd(cmd)

cmd.Flags().String(FlagDiscount, "0.0", "discount to apply to the swap fee (only smart contract broker can apply the discount)")
cmd.Flags().String(FlagRecipient, "", "optional recipient field for the tokens swapped to be sent to")

return cmd
}
7 changes: 7 additions & 0 deletions x/amm/client/cli/tx_swap_exact_amount_out.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,19 @@ func CmdSwapExactAmountOut() *cobra.Command {
return err
}

recipient, err := cmd.Flags().GetString(FlagRecipient)
if err != nil {
return err
}

clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

msg := types.NewMsgSwapExactAmountOut(
clientCtx.GetFromAddress().String(),
recipient,
argTokenOut,
argTokenOutMaxAmount,
argSwapRoutePoolIds,
Expand All @@ -76,6 +82,7 @@ func CmdSwapExactAmountOut() *cobra.Command {
flags.AddTxFlagsToCmd(cmd)

cmd.Flags().String(FlagDiscount, "0.0", "discount to apply to the swap fee (only smart contract broker can apply the discount)")
cmd.Flags().String(FlagRecipient, "", "optional recipient field for the tokens swapped to be sent to")

return cmd
}
12 changes: 10 additions & 2 deletions x/amm/keeper/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ func (k Keeper) ApplySwapRequest(ctx sdk.Context, msg sdk.Msg) error {
if err != nil {
return err
}
_, err = k.RouteExactAmountIn(ctx, sender, msg.Routes, msg.TokenIn, math.Int(msg.TokenOutMinAmount), msg.Discount)
recipient, err := sdk.AccAddressFromBech32(msg.Recipient)
if err != nil {
recipient = sender
}
_, err = k.RouteExactAmountIn(ctx, sender, recipient, msg.Routes, msg.TokenIn, math.Int(msg.TokenOutMinAmount), msg.Discount)
if err != nil {
return err
}
Expand All @@ -38,7 +42,11 @@ func (k Keeper) ApplySwapRequest(ctx sdk.Context, msg sdk.Msg) error {
if err != nil {
return err
}
_, err = k.RouteExactAmountOut(ctx, sender, msg.Routes, msg.TokenInMaxAmount, msg.TokenOut, msg.Discount)
recipient, err := sdk.AccAddressFromBech32(msg.Recipient)
if err != nil {
recipient = sender
}
_, err = k.RouteExactAmountOut(ctx, sender, recipient, msg.Routes, msg.TokenInMaxAmount, msg.TokenOut, msg.Discount)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion x/amm/keeper/fee.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func (k Keeper) SwapFeesToRevenueToken(ctx sdk.Context, pool types.Pool, fee sdk

// Settles balances between the tx sender and the pool to match the swap that was executed earlier.
// Also emits a swap event and updates related liquidity metrics.
err, _ = k.UpdatePoolForSwap(ctx, pool, poolRevenueAddress, tokenIn, tokenOutCoin, sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec())
err, _ = k.UpdatePoolForSwap(ctx, pool, poolRevenueAddress, poolRevenueAddress, tokenIn, tokenOutCoin, sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec())
if err != nil {
return err
}
Expand Down
3 changes: 2 additions & 1 deletion x/amm/keeper/keeper_swap_exact_amount_in.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
func (k Keeper) SwapExactAmountIn(
ctx sdk.Context,
sender sdk.AccAddress,
recipient sdk.AccAddress,
pool types.Pool,
tokenIn sdk.Coin,
tokenOutDenom string,
Expand Down Expand Up @@ -61,7 +62,7 @@ func (k Keeper) SwapExactAmountIn(

// Settles balances between the tx sender and the pool to match the swap that was executed earlier.
// Also emits a swap event and updates related liquidity metrics.
err, swapOutFee := k.UpdatePoolForSwap(ctx, pool, sender, tokenIn, tokenOutCoin, sdk.ZeroDec(), swapFee, weightBalanceBonus)
err, swapOutFee := k.UpdatePoolForSwap(ctx, pool, sender, recipient, tokenIn, tokenOutCoin, sdk.ZeroDec(), swapFee, weightBalanceBonus)
if err != nil {
return math.Int{}, err
}
Expand Down
47 changes: 46 additions & 1 deletion x/amm/keeper/keeper_swap_exact_amount_in_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ func (suite *KeeperTestSuite) TestSwapExactAmountIn() {
tokenOut sdk.Coin
weightBalanceBonus sdk.Dec
isOraclePool bool
useNewRecipient bool
expSenderBalance sdk.Coins
expRecipientBalance sdk.Coins
expPoolBalance sdk.Coins
expTreasuryBalance sdk.Coins
expPass bool
Expand All @@ -38,7 +40,9 @@ func (suite *KeeperTestSuite) TestSwapExactAmountIn() {
tokenOut: sdk.NewInt64Coin(ptypes.BaseCurrency, 10000),
weightBalanceBonus: sdk.ZeroDec(),
isOraclePool: false,
useNewRecipient: false,
expSenderBalance: sdk.Coins{},
expRecipientBalance: sdk.Coins{},
expPoolBalance: sdk.Coins{},
expTreasuryBalance: sdk.Coins{},
expPass: false,
Expand All @@ -55,7 +59,9 @@ func (suite *KeeperTestSuite) TestSwapExactAmountIn() {
tokenOut: sdk.NewInt64Coin(ptypes.BaseCurrency, 10000),
weightBalanceBonus: sdk.ZeroDec(),
isOraclePool: false,
useNewRecipient: false,
expSenderBalance: sdk.Coins{},
expRecipientBalance: sdk.Coins{},
expPoolBalance: sdk.Coins{},
expTreasuryBalance: sdk.Coins{},
expPass: false,
Expand All @@ -72,7 +78,9 @@ func (suite *KeeperTestSuite) TestSwapExactAmountIn() {
tokenOut: sdk.NewInt64Coin(ptypes.BaseCurrency, 9704),
weightBalanceBonus: sdk.ZeroDec(),
isOraclePool: false,
useNewRecipient: false,
expSenderBalance: sdk.Coins{sdk.NewInt64Coin("uusda", 990000), sdk.NewInt64Coin(ptypes.BaseCurrency, 1009704)},
expRecipientBalance: sdk.Coins{},
expPoolBalance: sdk.Coins{sdk.NewInt64Coin("uusda", 1010000), sdk.NewInt64Coin(ptypes.BaseCurrency, 990198)},
expTreasuryBalance: sdk.Coins{sdk.NewInt64Coin("uusda", 1000000), sdk.NewInt64Coin(ptypes.BaseCurrency, 1000010)},
expPass: true,
Expand All @@ -89,7 +97,9 @@ func (suite *KeeperTestSuite) TestSwapExactAmountIn() {
tokenOut: sdk.NewInt64Coin(ptypes.BaseCurrency, 9900),
weightBalanceBonus: sdk.ZeroDec(),
isOraclePool: false,
useNewRecipient: false,
expSenderBalance: sdk.Coins{sdk.NewInt64Coin("uusda", 990000), sdk.NewInt64Coin(ptypes.BaseCurrency, 1009900)},
expRecipientBalance: sdk.Coins{},
expPoolBalance: sdk.Coins{sdk.NewInt64Coin("uusda", 1010000), sdk.NewInt64Coin(ptypes.BaseCurrency, 990100)},
expTreasuryBalance: sdk.Coins{sdk.NewInt64Coin("uusda", 1000000), sdk.NewInt64Coin(ptypes.BaseCurrency, 1000000)},
expPass: true,
Expand All @@ -106,7 +116,9 @@ func (suite *KeeperTestSuite) TestSwapExactAmountIn() {
tokenOut: sdk.NewInt64Coin(ptypes.BaseCurrency, 9975),
weightBalanceBonus: sdk.ZeroDec(),
isOraclePool: true,
useNewRecipient: false,
expSenderBalance: sdk.Coins{sdk.NewInt64Coin("uusda", 990000), sdk.NewInt64Coin(ptypes.BaseCurrency, 1009975)},
expRecipientBalance: sdk.Coins{},
expPoolBalance: sdk.Coins{sdk.NewInt64Coin("uusda", 1010000), sdk.NewInt64Coin(ptypes.BaseCurrency, 990025)},
expTreasuryBalance: sdk.Coins{sdk.NewInt64Coin("uusda", 1000000), sdk.NewInt64Coin(ptypes.BaseCurrency, 1000000)},
expPass: true,
Expand All @@ -123,7 +135,9 @@ func (suite *KeeperTestSuite) TestSwapExactAmountIn() {
tokenOut: sdk.NewInt64Coin(ptypes.BaseCurrency, 9900),
weightBalanceBonus: sdk.NewDecWithPrec(3, 1), // 30% bonus
isOraclePool: false,
useNewRecipient: false,
expSenderBalance: sdk.Coins{sdk.NewInt64Coin("uusda", 990000), sdk.NewInt64Coin(ptypes.BaseCurrency, 1009900)},
expRecipientBalance: sdk.Coins{},
expPoolBalance: sdk.Coins{sdk.NewInt64Coin("uusda", 1010000), sdk.NewInt64Coin(ptypes.BaseCurrency, 990100)},
expTreasuryBalance: sdk.Coins{sdk.NewInt64Coin("uusda", 1000000), sdk.NewInt64Coin(ptypes.BaseCurrency, 1000000)},
expPass: true,
Expand All @@ -140,7 +154,28 @@ func (suite *KeeperTestSuite) TestSwapExactAmountIn() {
tokenOut: sdk.NewInt64Coin(ptypes.BaseCurrency, 9900),
weightBalanceBonus: sdk.NewDecWithPrec(3, 1), // 30% bonus
isOraclePool: false,
useNewRecipient: false,
expSenderBalance: sdk.Coins{sdk.NewInt64Coin("uusda", 990000), sdk.NewInt64Coin(ptypes.BaseCurrency, 1009900)},
expRecipientBalance: sdk.Coins{},
expPoolBalance: sdk.Coins{sdk.NewInt64Coin("uusda", 1010000), sdk.NewInt64Coin(ptypes.BaseCurrency, 990100)},
expTreasuryBalance: sdk.Coins{sdk.NewInt64Coin("uusda", 1000000), sdk.NewInt64Coin(ptypes.BaseCurrency, 100)},
expPass: true,
},
{
desc: "new recipient address",
senderInitBalance: sdk.Coins{sdk.NewInt64Coin("uusda", 1000000), sdk.NewInt64Coin(ptypes.BaseCurrency, 1000000)},
poolInitBalance: sdk.Coins{sdk.NewInt64Coin("uusda", 1000000), sdk.NewInt64Coin(ptypes.BaseCurrency, 1000000)},
treasuryInitBalance: sdk.Coins{sdk.NewInt64Coin("uusda", 1000000), sdk.NewInt64Coin(ptypes.BaseCurrency, 100)},
swapFeeIn: sdk.ZeroDec(),
swapFeeOut: sdk.ZeroDec(),
tokenIn: sdk.NewInt64Coin("uusda", 10000),
tokenOutMin: sdk.ZeroInt(),
tokenOut: sdk.NewInt64Coin(ptypes.BaseCurrency, 9900),
weightBalanceBonus: sdk.NewDecWithPrec(3, 1), // 30% bonus
isOraclePool: false,
useNewRecipient: true,
expSenderBalance: sdk.Coins{sdk.NewInt64Coin("uusda", 990000), sdk.NewInt64Coin(ptypes.BaseCurrency, 1000000)},
expRecipientBalance: sdk.Coins{sdk.NewInt64Coin(ptypes.BaseCurrency, 9900)},
expPoolBalance: sdk.Coins{sdk.NewInt64Coin("uusda", 1010000), sdk.NewInt64Coin(ptypes.BaseCurrency, 990100)},
expTreasuryBalance: sdk.Coins{sdk.NewInt64Coin("uusda", 1000000), sdk.NewInt64Coin(ptypes.BaseCurrency, 100)},
expPass: true,
Expand All @@ -152,8 +187,12 @@ func (suite *KeeperTestSuite) TestSwapExactAmountIn() {

// bootstrap accounts
sender := sdk.AccAddress(ed25519.GenPrivKey().PubKey().Address())
recipient := sender
poolAddr := sdk.AccAddress(ed25519.GenPrivKey().PubKey().Address())
treasuryAddr := sdk.AccAddress(ed25519.GenPrivKey().PubKey().Address())
if tc.useNewRecipient {
recipient = sdk.AccAddress(ed25519.GenPrivKey().PubKey().Address())
}

// bootstrap balances
err := suite.app.BankKeeper.MintCoins(suite.ctx, minttypes.ModuleName, tc.senderInitBalance)
Expand Down Expand Up @@ -205,7 +244,7 @@ func (suite *KeeperTestSuite) TestSwapExactAmountIn() {
TotalWeight: sdk.ZeroInt(),
}

tokenOut, err := suite.app.AmmKeeper.SwapExactAmountIn(suite.ctx, sender, pool, tc.tokenIn, tc.tokenOut.Denom, tc.tokenOutMin, tc.swapFeeIn)
tokenOut, err := suite.app.AmmKeeper.SwapExactAmountIn(suite.ctx, sender, recipient, pool, tc.tokenIn, tc.tokenOut.Denom, tc.tokenOutMin, tc.swapFeeIn)
if !tc.expPass {
suite.Require().Error(err)
} else {
Expand All @@ -220,6 +259,12 @@ func (suite *KeeperTestSuite) TestSwapExactAmountIn() {
balances = suite.app.BankKeeper.GetAllBalances(suite.ctx, sender)
suite.Require().Equal(balances.String(), tc.expSenderBalance.String())

if tc.useNewRecipient {
// check balance change on recipient
balances = suite.app.BankKeeper.GetAllBalances(suite.ctx, recipient)
suite.Require().Equal(balances.String(), tc.expRecipientBalance.String())
}

// check balance change on treasury
balances = suite.app.BankKeeper.GetAllBalances(suite.ctx, treasuryAddr)
suite.Require().Equal(balances.String(), tc.expTreasuryBalance.String())
Expand Down
3 changes: 2 additions & 1 deletion x/amm/keeper/keeper_swap_exact_amount_out.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
func (k Keeper) SwapExactAmountOut(
ctx sdk.Context,
sender sdk.AccAddress,
recipient sdk.AccAddress,
pool types.Pool,
tokenInDenom string,
tokenInMaxAmount math.Int,
Expand Down Expand Up @@ -54,7 +55,7 @@ func (k Keeper) SwapExactAmountOut(
return math.Int{}, sdkerrors.Wrapf(types.ErrLimitMaxAmount, "swap requires %s, which is greater than the amount %s", tokenIn, tokenInMaxAmount)
}

err, _ = k.UpdatePoolForSwap(ctx, pool, sender, tokenIn, tokenOut, swapFee, sdk.ZeroDec(), weightBalanceBonus)
err, _ = k.UpdatePoolForSwap(ctx, pool, sender, recipient, tokenIn, tokenOut, swapFee, sdk.ZeroDec(), weightBalanceBonus)
if err != nil {
return math.Int{}, err
}
Expand Down
Loading
Loading