Skip to content

Commit

Permalink
(feat) Add possibility to transfer entire balance. (backport #6877) (#…
Browse files Browse the repository at this point in the history
…6929)

* (feat) Add possibility to transfer entire balance. (#6877)

* Add possibility to transfer entire balance.

* Added entry to the Changelog.

* Added e2e test

* Added forwarding

* Update modules/apps/transfer/keeper/relay.go

Co-authored-by: DimitrisJim <[email protected]>

* Move UnboundedSpendLimit to token.go

* add documentation

* add test to compatibility matrices

* PR Feedback.

---------

Co-authored-by: DimitrisJim <[email protected]>
Co-authored-by: Carlos Rodriguez <[email protected]>
(cherry picked from commit 92e1f38)

# Conflicts:
#	.github/compatibility-test-matrices/main/transfer-v2-multidenom-chain-a.json
#	.github/compatibility-test-matrices/release-v9.0.x/transfer-v2-multidenom-chain-a.json
#	.github/compatibility-test-matrices/unreleased/transfer-v2-multidenom.json
#	CHANGELOG.md
#	docs/docs/02-apps/01-transfer/04-messages.md
#	docs/docs/02-apps/01-transfer/10-ICS20-v1/04-messages.md
#	e2e/tests/transfer/base_test.go
#	modules/apps/transfer/keeper/relay.go
#	modules/apps/transfer/keeper/relay_test.go
#	modules/apps/transfer/types/token.go
#	modules/apps/transfer/types/transfer_authorization.go
#	testing/chain.go

* fix conflicts

* lint

* delete docs

---------

Co-authored-by: Nikolas De Giorgis <[email protected]>
Co-authored-by: Carlos Rodriguez <[email protected]>
  • Loading branch information
3 people authored Jul 25, 2024
1 parent de87319 commit b71e6e8
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"chain-a": [
"main"
],
"chain-b": [
"main"
],
"entrypoint": [
"TestTransferTestSuite"
],
"test": [
"TestMsgTransfer_Succeeds_Nonincentivized_MultiDenom",
"TestMsgTransfer_EntireBalance",
"TestMsgTransfer_Fails_InvalidAddress_MultiDenom"
],
"relayer-type": [
"hermes"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"chain-a": [
"release-v9.0.x"
],
"chain-b": [
"release-v9.0.x"
],
"entrypoint": [
"TestTransferTestSuite"
],
"test": [
"TestMsgTransfer_Succeeds_Nonincentivized_MultiDenom",
"TestMsgTransfer_EntireBalance",
"TestMsgTransfer_Fails_InvalidAddress_MultiDenom"
],
"relayer-type": [
"hermes"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"chain-a": [
"release-v9.0.x"
],
"chain-b": [
"release-v9.0.x"
],
"entrypoint": [
"TestTransferTestSuite"
],
"test": [
"TestMsgTransfer_Succeeds_Nonincentivized_MultiDenom",
"TestMsgTransfer_EntireBalance",
"TestMsgTransfer_Fails_InvalidAddress_MultiDenom"
],
"relayer-type": [
"hermes"
]
}
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ Ref: https://keepachangelog.com/en/1.0.0/

### Features

* (apps/transfer) [\#6877](https://github.com/cosmos/ibc-go/pull/6877) Added the possibility to transfer the entire user balance of a particular denomination by using [`UnboundedSpendLimit`](https://github.com/cosmos/ibc-go/blob/715f00eef8727da41db25fdd4763b709bdbba07e/modules/apps/transfer/types/transfer_authorization.go#L253-L255) as the token amount.

### Bug Fixes

## [v7.6.0](https://github.com/cosmos/ibc-go/releases/tag/v7.6.0) - 2024-06-20
Expand Down
5 changes: 5 additions & 0 deletions modules/apps/transfer/keeper/relay.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@ func (k Keeper) sendTransfer(
telemetry.NewLabel(coretypes.LabelDestinationChannel, destinationChannel),
}

// Using types.UnboundedSpendLimit allows us to send the entire balance of a given denom.
if token.Amount.Equal(types.UnboundedSpendLimit()) {
token.Amount = k.bankKeeper.GetBalance(ctx, sender, token.Denom).Amount
}

// NOTE: SendTransfer simply sends the denomination as it exists on its own
// chain inside the packet data. The receiving chain will perform denom
// prefixing as necessary.
Expand Down
9 changes: 9 additions & 0 deletions modules/apps/transfer/keeper/relay_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,15 @@ func (suite *KeeperTestSuite) TestSendTransfer() {
memo = "memo"
}, true,
},
{
"successful transfer of entire balance",
func() {
coin.Amount = types.UnboundedSpendLimit()
var ok bool
expEscrowAmount, ok = sdk.NewIntFromString(ibctesting.DefaultGenesisAccBalance)
suite.Require().True(ok)
}, true,
},
{
"source channel not found",
func() {
Expand Down
17 changes: 15 additions & 2 deletions modules/apps/transfer/types/coin.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@ package types

import (
"fmt"
"math/big"
"strings"

"cosmossdk.io/math"
sdkmath "cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
)

// maxUint256 is the maximum value for a 256 bit unsigned integer.
var maxUint256 = new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(1))

// SenderChainIsSource returns false if the denomination originally came
// from the receiving chain and true otherwise.
func SenderChainIsSource(sourcePort, sourceChannel, denom string) bool {
Expand Down Expand Up @@ -42,7 +46,16 @@ func GetPrefixedDenom(portID, channelID, baseDenom string) string {

// GetTransferCoin creates a transfer coin with the port ID and channel ID
// prefixed to the base denom.
func GetTransferCoin(portID, channelID, baseDenom string, amount math.Int) sdk.Coin {
func GetTransferCoin(portID, channelID, baseDenom string, amount sdkmath.Int) sdk.Coin {
denomTrace := ParseDenomTrace(GetPrefixedDenom(portID, channelID, baseDenom))
return sdk.NewCoin(denomTrace.IBCDenom(), amount)
}

// UnboundedSpendLimit returns the sentinel value that can be used
// as the amount for a denomination's spend limit for which spend limit updating
// should be disabled. Please note that using this sentinel value means that a grantee
// will be granted the privilege to do ICS20 token transfers for the total amount
// of the denomination available at the granter's account.
func UnboundedSpendLimit() sdkmath.Int {
return sdkmath.NewIntFromBigInt(maxUint256)
}
14 changes: 0 additions & 14 deletions modules/apps/transfer/types/transfer_authorization.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package types

import (
"math/big"
"strings"

sdkmath "cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/x/authz"
Expand All @@ -15,9 +13,6 @@ import (

var _ authz.Authorization = &TransferAuthorization{}

// maxUint256 is the maximum value for a 256 bit unsigned integer.
var maxUint256 = new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(1))

// NewTransferAuthorization creates a new TransferAuthorization object.
func NewTransferAuthorization(allocations ...Allocation) *TransferAuthorization {
return &TransferAuthorization{
Expand Down Expand Up @@ -174,12 +169,3 @@ func validateMemo(ctx sdk.Context, memo string, allowedMemos []string) error {

return sdkerrors.Wrapf(ErrInvalidAuthorization, "not allowed memo: %s", memo)
}

// UnboundedSpendLimit returns the sentinel value that can be used
// as the amount for a denomination's spend limit for which spend limit updating
// should be disabled. Please note that using this sentinel value means that a grantee
// will be granted the privilege to do ICS20 token transfers for the total amount
// of the denomination available at the granter's account.
func UnboundedSpendLimit() sdkmath.Int {
return sdk.NewIntFromBigInt(maxUint256)
}
6 changes: 5 additions & 1 deletion testing/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ type SenderAccount struct {
SenderAccount authtypes.AccountI
}

const (
DefaultGenesisAccBalance = "10000000000000000000"
)

// TestChain is a testing struct that wraps a simapp with the last TM Header, the current ABCI
// header and the validators of the TestChain. It also contains a field called ChainID. This
// is the clientID that *other* chains use to refer to this TestChain. The SenderAccount
Expand Down Expand Up @@ -104,7 +108,7 @@ func NewTestChainWithValSet(t *testing.T, coord *Coordinator, chainID string, va
for i := 0; i < MaxAccounts; i++ {
senderPrivKey := secp256k1.GenPrivKey()
acc := authtypes.NewBaseAccount(senderPrivKey.PubKey().Address().Bytes(), senderPrivKey.PubKey(), uint64(i), 0)
amount, ok := sdk.NewIntFromString("10000000000000000000")
amount, ok := sdk.NewIntFromString(DefaultGenesisAccBalance)
require.True(t, ok)

// add sender account
Expand Down

0 comments on commit b71e6e8

Please sign in to comment.