Skip to content

Commit

Permalink
Merge pull request #501 from ComposableFi/rustninja/cosmos-fee-priority
Browse files Browse the repository at this point in the history
Cosmos fee priority using memo
  • Loading branch information
kkast authored Apr 29, 2024
2 parents 4949bfd + 0427e0a commit 8941a37
Show file tree
Hide file tree
Showing 16 changed files with 729 additions and 140 deletions.
20 changes: 20 additions & 0 deletions app/upgrades/v6_5_5/constants.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package v6_5_5

import (
store "github.com/cosmos/cosmos-sdk/store/types"
"github.com/notional-labs/composable/v6/app/upgrades"
)

const (
// UpgradeName defines the on-chain upgrade name for the composable upgrade.
UpgradeName = "v6_5_5"
)

var Upgrade = upgrades.Upgrade{
UpgradeName: UpgradeName,
CreateUpgradeHandler: CreateUpgradeHandler,
StoreUpgrades: store.StoreUpgrades{
Added: []string{},
Deleted: []string{},
},
}
24 changes: 24 additions & 0 deletions app/upgrades/v6_5_5/upgrade.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package v6_5_5

import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"

"github.com/cosmos/cosmos-sdk/codec"
"github.com/notional-labs/composable/v6/app/keepers"

"github.com/notional-labs/composable/v6/app/upgrades"
)

func CreateUpgradeHandler(
mm *module.Manager,
configurator module.Configurator,
_ upgrades.BaseAppParamManager,
_ codec.Codec,
keepers *keepers.AppKeepers,
) upgradetypes.UpgradeHandler {
return func(ctx sdk.Context, plan upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) {
return mm.RunMigrations(ctx, configurator, vm)
}
}
44 changes: 42 additions & 2 deletions custom/ibc-transfer/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package keeper

import (
"context"
"encoding/json"
"fmt"
"time"

Expand All @@ -16,6 +17,7 @@ import (
"github.com/cosmos/ibc-go/v7/modules/core/exported"
custombankkeeper "github.com/notional-labs/composable/v6/custom/bank/keeper"
ibctransfermiddleware "github.com/notional-labs/composable/v6/x/ibctransfermiddleware/keeper"
ibctransfermiddlewaretypes "github.com/notional-labs/composable/v6/x/ibctransfermiddleware/types"
)

type Keeper struct {
Expand Down Expand Up @@ -57,6 +59,7 @@ func NewKeeper(
func (k Keeper) Transfer(goCtx context.Context, msg *types.MsgTransfer) (*types.MsgTransferResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
params := k.IbcTransfermiddleware.GetParams(ctx)
charge_coin := sdk.NewCoin(msg.Token.Denom, sdk.ZeroInt())
if params.ChannelFees != nil && len(params.ChannelFees) > 0 {
channelFee := findChannelParams(params.ChannelFees, msg.SourceChannel)
if channelFee != nil {
Expand All @@ -79,7 +82,16 @@ func (k Keeper) Transfer(goCtx context.Context, msg *types.MsgTransfer) (*types.
if coin == nil {
return nil, fmt.Errorf("token not allowed to be transferred in this channel")
}

minFee := coin.MinFee.Amount
priority := GetPriority(msg.Memo)
if priority != nil {
p := findPriority(coin.TxPriorityFee, *priority)
if p != nil && coin.MinFee.Denom == p.PriorityFee.Denom {
minFee = minFee.Add(p.PriorityFee.Amount)
}
}

charge := minFee
if charge.GT(msg.Token.Amount) {
charge = msg.Token.Amount
Expand All @@ -103,7 +115,8 @@ func (k Keeper) Transfer(goCtx context.Context, msg *types.MsgTransfer) (*types.
return nil, err
}

send_err := k.bank.SendCoins(ctx, msgSender, feeAddress, sdk.NewCoins(sdk.NewCoin(msg.Token.Denom, charge)))
charge_coin = sdk.NewCoin(msg.Token.Denom, charge)
send_err := k.bank.SendCoins(ctx, msgSender, feeAddress, sdk.NewCoins(charge_coin))
if send_err != nil {
return nil, send_err
}
Expand All @@ -114,5 +127,32 @@ func (k Keeper) Transfer(goCtx context.Context, msg *types.MsgTransfer) (*types.
msg.Token.Amount = newAmount
}
}
return k.Keeper.Transfer(goCtx, msg)
ret, err := k.Keeper.Transfer(goCtx, msg)
if err == nil && ret != nil && !charge_coin.IsZero() {
k.IbcTransfermiddleware.SetSequenceFee(ctx, ret.Sequence, charge_coin)
}
return ret, err
}

func GetPriority(jsonString string) *string {
var data map[string]interface{}
if err := json.Unmarshal([]byte(jsonString), &data); err != nil {
return nil
}

priority, ok := data["priority"].(string)
if !ok {
return nil
}

return &priority
}

func findPriority(priorities []*ibctransfermiddlewaretypes.TxPriorityFee, priority string) *ibctransfermiddlewaretypes.TxPriorityFee {
for _, p := range priorities {
if p.Priority == priority {
return p
}
}
return nil
}
19 changes: 17 additions & 2 deletions custom/ibc-transfer/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ func NewMsgServerImpl(ibcKeeper Keeper, bankKeeper custombankkeeper.Keeper) type
func (k msgServer) Transfer(goCtx context.Context, msg *types.MsgTransfer) (*types.MsgTransferResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
params := k.Keeper.IbcTransfermiddleware.GetParams(ctx)
charge_coin := sdk.NewCoin(msg.Token.Denom, sdk.ZeroInt())
if params.ChannelFees != nil && len(params.ChannelFees) > 0 {
channelFee := findChannelParams(params.ChannelFees, msg.SourceChannel)
if channelFee != nil {
Expand All @@ -55,7 +56,16 @@ func (k msgServer) Transfer(goCtx context.Context, msg *types.MsgTransfer) (*typ
if coin == nil {
return nil, fmt.Errorf("token not allowed to be transferred in this channel")
}

minFee := coin.MinFee.Amount
priority := GetPriority(msg.Memo)
if priority != nil {
p := findPriority(coin.TxPriorityFee, *priority)
if p != nil && coin.MinFee.Denom == p.PriorityFee.Denom {
minFee = minFee.Add(p.PriorityFee.Amount)
}
}

charge := minFee
if charge.GT(msg.Token.Amount) {
charge = msg.Token.Amount
Expand All @@ -79,7 +89,8 @@ func (k msgServer) Transfer(goCtx context.Context, msg *types.MsgTransfer) (*typ
return nil, err
}

send_err := k.bank.SendCoins(ctx, msgSender, feeAddress, sdk.NewCoins(sdk.NewCoin(msg.Token.Denom, charge)))
charge_coin = sdk.NewCoin(msg.Token.Denom, charge)
send_err := k.bank.SendCoins(ctx, msgSender, feeAddress, sdk.NewCoins(charge_coin))
if send_err != nil {
return nil, send_err
}
Expand All @@ -90,7 +101,11 @@ func (k msgServer) Transfer(goCtx context.Context, msg *types.MsgTransfer) (*typ
msg.Token.Amount = newAmount
}
}
return k.msgServer.Transfer(goCtx, msg)
ret, err := k.msgServer.Transfer(goCtx, msg)
if err == nil && ret != nil && !charge_coin.IsZero() {
k.IbcTransfermiddleware.SetSequenceFee(ctx, ret.Sequence, charge_coin)
}
return ret, err
}

func findChannelParams(channelFees []*ibctransfermiddlewaretypes.ChannelFee, targetChannelID string) *ibctransfermiddlewaretypes.ChannelFee {
Expand Down
3 changes: 3 additions & 0 deletions proto/composable/ibctransfermiddleware/v1beta1/genesis.proto
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@ package composable.ibctransfermiddleware.v1beta1;
import "gogoproto/gogo.proto";
import "composable/ibctransfermiddleware/v1beta1/ibctransfermiddleware.proto";
import "amino/amino.proto";
import "cosmos/base/v1beta1/coin.proto";


option go_package = "x/ibctransfermiddleware/types";

// GenesisState defines the ibctransfermiddleware module's genesis state.
message GenesisState {
Params params = 1 [ (gogoproto.nullable) = false ];

repeated cosmos.base.v1beta1.Coin taken_fee_by_ibc_sequence = 2 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true];
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,11 @@ message ChannelFee{
message CoinItem{
cosmos.base.v1beta1.Coin min_fee = 1 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true];
int64 percentage = 2;
repeated TxPriorityFee tx_priority_fee = 3;
}

message TxPriorityFee{
string priority = 1;
cosmos.base.v1beta1.Coin priority_fee = 2 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true];
}

2 changes: 2 additions & 0 deletions proto/composable/ibctransfermiddleware/v1beta1/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ message MsgAddAllowedIbcToken {
cosmos.base.v1beta1.Coin min_fee = 3 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true];

int64 percentage = 4;

repeated TxPriorityFee tx_priority_fee = 5;
}

message MsgAddAllowedIbcTokenResponse {}
Expand Down
18 changes: 15 additions & 3 deletions x/ibctransfermiddleware/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,17 +77,28 @@ func AddIBCFeeConfig() *cobra.Command {

func AddAllowedIbcToken() *cobra.Command {
cmd := &cobra.Command{
Use: "add-allowed-ibc-token [channel] [percentage] [coin]",
Use: "add-allowed-ibc-token [channel] [percentage] [coin] [Amountlow] [Amountmedium] [Amounthigh] ... [Amountxxx]",
Short: "add allowed ibc token",
Args: cobra.MatchAll(cobra.ExactArgs(3), cobra.OnlyValidArgs),
Example: fmt.Sprintf("%s tx ibctransfermiddleware add-allowed-ibc-token [channel] [percentage] [coin] (percentage '5' means 1/5 of amount will be taken as fee) ", version.AppName),
Args: cobra.MatchAll(cobra.RangeArgs(3, 10), cobra.OnlyValidArgs),
Example: fmt.Sprintf("%s tx ibctransfermiddleware add-allowed-ibc-token [channel] [percentage] [coin] .. [1000low] [10000medium] [100000high] ... [1000000xxx] (percentage '5' means 1/5 of amount will be taken as fee) ", version.AppName),
RunE: func(cmd *cobra.Command, args []string) error {
channel := args[0]
percentage := args[1]
coin, err := sdk.ParseCoinNormalized(args[2])
if err != nil {
return err
}
length := len(args)
cc := []*types.TxPriorityFee{}
for i := 3; i < length; i++ {
priority, err := sdk.ParseCoinNormalized(args[i])
if err != nil {
return err
}
priority_str := priority.Denom
priority.Denom = coin.Denom
cc = append(cc, &types.TxPriorityFee{Priority: priority_str, PriorityFee: priority})
}

clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
Expand All @@ -106,6 +117,7 @@ func AddAllowedIbcToken() *cobra.Command {
channel,
coin,
percentageInt,
cc,
)

if err := msg.ValidateBasic(); err != nil {
Expand Down
22 changes: 22 additions & 0 deletions x/ibctransfermiddleware/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,28 @@ func (k Keeper) GetParams(ctx sdk.Context) (p types.Params) {
return p
}

func (k Keeper) GetSequenceFee(ctx sdk.Context, sequence uint64) (coin sdk.Coin, found bool) {
store := ctx.KVStore(k.storeKey)

value := store.Get(types.GetSequenceKey(sequence))
if value == nil {
return sdk.Coin{}, false
}

fee := types.MustUnmarshalCoin(k.cdc, value)
return fee, true
}

func (k Keeper) SetSequenceFee(ctx sdk.Context, sequence uint64, coin sdk.Coin) {
store := ctx.KVStore(k.storeKey)
store.Set(types.GetSequenceKey(sequence), types.MustMarshalCoin(k.cdc, &coin))
}

func (k Keeper) DeleteSequenceFee(ctx sdk.Context, sequence uint64) {
store := ctx.KVStore(k.storeKey)
store.Delete(types.GetSequenceKey(sequence))
}

func (k Keeper) GetCoin(ctx sdk.Context, targetChannelID, denom string) *types.CoinItem {
params := k.GetParams(ctx)
channelFee := findChannelParams(params.ChannelFees, targetChannelID)
Expand Down
7 changes: 4 additions & 3 deletions x/ibctransfermiddleware/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,12 @@ func (ms msgServer) AddAllowedIbcToken(goCtx context.Context, req *types.MsgAddA
if coin != nil {
coin.MinFee = req.MinFee
coin.Percentage = req.Percentage
coin.TxPriorityFee = req.TxPriorityFee
} else {

coin := &types.CoinItem{
MinFee: req.MinFee,
Percentage: req.Percentage,
MinFee: req.MinFee,
Percentage: req.Percentage,
TxPriorityFee: req.TxPriorityFee,
}
channelFee.AllowedTokens = append(channelFee.AllowedTokens, coin)
}
Expand Down
Loading

0 comments on commit 8941a37

Please sign in to comment.