Skip to content

Commit b71e6e8

Browse files
mergify[bot]Nikolas De Giorgiscrodriguezvega
authored
(feat) Add possibility to transfer entire balance. (backport #6877) (#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]>
1 parent de87319 commit b71e6e8

File tree

9 files changed

+93
-17
lines changed

9 files changed

+93
-17
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"chain-a": [
3+
"main"
4+
],
5+
"chain-b": [
6+
"main"
7+
],
8+
"entrypoint": [
9+
"TestTransferTestSuite"
10+
],
11+
"test": [
12+
"TestMsgTransfer_Succeeds_Nonincentivized_MultiDenom",
13+
"TestMsgTransfer_EntireBalance",
14+
"TestMsgTransfer_Fails_InvalidAddress_MultiDenom"
15+
],
16+
"relayer-type": [
17+
"hermes"
18+
]
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"chain-a": [
3+
"release-v9.0.x"
4+
],
5+
"chain-b": [
6+
"release-v9.0.x"
7+
],
8+
"entrypoint": [
9+
"TestTransferTestSuite"
10+
],
11+
"test": [
12+
"TestMsgTransfer_Succeeds_Nonincentivized_MultiDenom",
13+
"TestMsgTransfer_EntireBalance",
14+
"TestMsgTransfer_Fails_InvalidAddress_MultiDenom"
15+
],
16+
"relayer-type": [
17+
"hermes"
18+
]
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"chain-a": [
3+
"release-v9.0.x"
4+
],
5+
"chain-b": [
6+
"release-v9.0.x"
7+
],
8+
"entrypoint": [
9+
"TestTransferTestSuite"
10+
],
11+
"test": [
12+
"TestMsgTransfer_Succeeds_Nonincentivized_MultiDenom",
13+
"TestMsgTransfer_EntireBalance",
14+
"TestMsgTransfer_Fails_InvalidAddress_MultiDenom"
15+
],
16+
"relayer-type": [
17+
"hermes"
18+
]
19+
}

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ Ref: https://keepachangelog.com/en/1.0.0/
4848

4949
### Features
5050

51+
* (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.
52+
5153
### Bug Fixes
5254

5355
## [v7.6.0](https://github.com/cosmos/ibc-go/releases/tag/v7.6.0) - 2024-06-20

modules/apps/transfer/keeper/relay.go

+5
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,11 @@ func (k Keeper) sendTransfer(
9393
telemetry.NewLabel(coretypes.LabelDestinationChannel, destinationChannel),
9494
}
9595

96+
// Using types.UnboundedSpendLimit allows us to send the entire balance of a given denom.
97+
if token.Amount.Equal(types.UnboundedSpendLimit()) {
98+
token.Amount = k.bankKeeper.GetBalance(ctx, sender, token.Denom).Amount
99+
}
100+
96101
// NOTE: SendTransfer simply sends the denomination as it exists on its own
97102
// chain inside the packet data. The receiving chain will perform denom
98103
// prefixing as necessary.

modules/apps/transfer/keeper/relay_test.go

+9
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,15 @@ func (suite *KeeperTestSuite) TestSendTransfer() {
5858
memo = "memo"
5959
}, true,
6060
},
61+
{
62+
"successful transfer of entire balance",
63+
func() {
64+
coin.Amount = types.UnboundedSpendLimit()
65+
var ok bool
66+
expEscrowAmount, ok = sdk.NewIntFromString(ibctesting.DefaultGenesisAccBalance)
67+
suite.Require().True(ok)
68+
}, true,
69+
},
6170
{
6271
"source channel not found",
6372
func() {

modules/apps/transfer/types/coin.go

+15-2
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,16 @@ package types
22

33
import (
44
"fmt"
5+
"math/big"
56
"strings"
67

7-
"cosmossdk.io/math"
8+
sdkmath "cosmossdk.io/math"
89
sdk "github.com/cosmos/cosmos-sdk/types"
910
)
1011

12+
// maxUint256 is the maximum value for a 256 bit unsigned integer.
13+
var maxUint256 = new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(1))
14+
1115
// SenderChainIsSource returns false if the denomination originally came
1216
// from the receiving chain and true otherwise.
1317
func SenderChainIsSource(sourcePort, sourceChannel, denom string) bool {
@@ -42,7 +46,16 @@ func GetPrefixedDenom(portID, channelID, baseDenom string) string {
4246

4347
// GetTransferCoin creates a transfer coin with the port ID and channel ID
4448
// prefixed to the base denom.
45-
func GetTransferCoin(portID, channelID, baseDenom string, amount math.Int) sdk.Coin {
49+
func GetTransferCoin(portID, channelID, baseDenom string, amount sdkmath.Int) sdk.Coin {
4650
denomTrace := ParseDenomTrace(GetPrefixedDenom(portID, channelID, baseDenom))
4751
return sdk.NewCoin(denomTrace.IBCDenom(), amount)
4852
}
53+
54+
// UnboundedSpendLimit returns the sentinel value that can be used
55+
// as the amount for a denomination's spend limit for which spend limit updating
56+
// should be disabled. Please note that using this sentinel value means that a grantee
57+
// will be granted the privilege to do ICS20 token transfers for the total amount
58+
// of the denomination available at the granter's account.
59+
func UnboundedSpendLimit() sdkmath.Int {
60+
return sdkmath.NewIntFromBigInt(maxUint256)
61+
}

modules/apps/transfer/types/transfer_authorization.go

-14
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
package types
22

33
import (
4-
"math/big"
54
"strings"
65

7-
sdkmath "cosmossdk.io/math"
86
sdk "github.com/cosmos/cosmos-sdk/types"
97
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
108
"github.com/cosmos/cosmos-sdk/x/authz"
@@ -15,9 +13,6 @@ import (
1513

1614
var _ authz.Authorization = &TransferAuthorization{}
1715

18-
// maxUint256 is the maximum value for a 256 bit unsigned integer.
19-
var maxUint256 = new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(1))
20-
2116
// NewTransferAuthorization creates a new TransferAuthorization object.
2217
func NewTransferAuthorization(allocations ...Allocation) *TransferAuthorization {
2318
return &TransferAuthorization{
@@ -174,12 +169,3 @@ func validateMemo(ctx sdk.Context, memo string, allowedMemos []string) error {
174169

175170
return sdkerrors.Wrapf(ErrInvalidAuthorization, "not allowed memo: %s", memo)
176171
}
177-
178-
// UnboundedSpendLimit returns the sentinel value that can be used
179-
// as the amount for a denomination's spend limit for which spend limit updating
180-
// should be disabled. Please note that using this sentinel value means that a grantee
181-
// will be granted the privilege to do ICS20 token transfers for the total amount
182-
// of the denomination available at the granter's account.
183-
func UnboundedSpendLimit() sdkmath.Int {
184-
return sdk.NewIntFromBigInt(maxUint256)
185-
}

testing/chain.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ type SenderAccount struct {
4242
SenderAccount authtypes.AccountI
4343
}
4444

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

110114
// add sender account

0 commit comments

Comments
 (0)