Skip to content

Commit

Permalink
feat: ibc e2e tests for fiattokenfactory (#374)
Browse files Browse the repository at this point in the history
Co-authored-by: John Letey <john@noble.xyz>
  • Loading branch information
boojamya and johnletey authored Oct 29, 2024
1 parent d0d1b19 commit 7d282f5
Show file tree
Hide file tree
Showing 3 changed files with 277 additions and 3 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/e2e-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:
- name: Install Go
uses: actions/setup-go@v5
with:
go-version: '1.21'
go-version: '1.22'

- name: Generate Matrix
id: set-matrix
Expand All @@ -74,7 +74,7 @@ jobs:
- name: Install Go
uses: actions/setup-go@v5
with:
go-version: '1.21'
go-version: '1.22'

- name: Download Tarball Artifact
uses: actions/download-artifact@v4
Expand Down
274 changes: 274 additions & 0 deletions e2e/fiat_tf_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ import (
fiattokenfactorytypes "github.com/circlefin/noble-fiattokenfactory/x/fiattokenfactory/types"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
sdk "github.com/cosmos/cosmos-sdk/types"
transfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types"
"github.com/noble-assets/noble/e2e"
"github.com/strangelove-ventures/interchaintest/v8"
"github.com/strangelove-ventures/interchaintest/v8/ibc"
"github.com/strangelove-ventures/interchaintest/v8/testutil"
"github.com/stretchr/testify/require"
)

Expand Down Expand Up @@ -1846,3 +1848,275 @@ func TestFiatTFBankSend(t *testing.T) {
require.NoError(t, err, "error getting balance")
require.Equal(t, amountToSend.Amount, bobBal)
}

func TestFiatTFIBCOut(t *testing.T) {
if testing.Short() {
t.Skip()
}
t.Parallel()

ctx := context.Background()

nw, gaia, _, r, ibcPathName, _, eRep, _, _ := e2e.NobleSpinUpIBC(t, ctx, true)
noble := nw.Chain
val := noble.Validators[0]

w := interchaintest.GetAndFundTestUsers(t, ctx, "default", math.OneInt(), noble, gaia)
nobleWallet := w[0]
gaiaWallet := w[1]

mintAmount := int64(100)
_, err := val.ExecTx(ctx, nw.FiatTfRoles.Minter.KeyName(), "fiat-tokenfactory", "mint", nobleWallet.FormattedAddress(), fmt.Sprintf("%duusdc", mintAmount))
require.NoError(t, err, "error minting")

// noble -> gaia channel info
nobleToGaiaChannelInfo, err := r.GetChannels(ctx, eRep, noble.Config().ChainID)
require.NoError(t, err)
nobleToGaiaChannelID := nobleToGaiaChannelInfo[0].ChannelID
// gaia -> noble channel info
gaiaToNobleChannelInfo, err := r.GetChannels(ctx, eRep, gaia.Config().ChainID)
require.NoError(t, err)
gaiaToNobleChannelID := gaiaToNobleChannelInfo[0].ChannelID

// uusdc IBC denom on gaia
srcDenomTrace := transfertypes.ParseDenomTrace(transfertypes.GetPrefixedDenom("transfer", gaiaToNobleChannelID, e2e.DenomMetadataUsdc.Base))
dstIbcDenom := srcDenomTrace.IBCDenom()

amountToSend := math.NewInt(5)
transfer := ibc.WalletAmount{
Address: gaiaWallet.FormattedAddress(),
Denom: e2e.DenomMetadataUsdc.Base,
Amount: amountToSend,
}

// ACTION: IBC send out a TF token while TF is paused
// EXPECTED: Request fails;

e2e.PauseFiatTF(t, ctx, val, nw.FiatTfRoles.Pauser)

// ibc transfer noble -> gaia
_, err = noble.SendIBCTransfer(ctx, nobleToGaiaChannelID, nobleWallet.KeyName(), transfer, ibc.TransferOptions{})
require.ErrorContains(t, err, "the chain is paused")

// relay MsgRecvPacket & MsgAcknowledgement
require.NoError(t, r.Flush(ctx, eRep, ibcPathName, nobleToGaiaChannelID))

gaiaWalletBal, err := gaia.GetBalance(ctx, gaiaWallet.FormattedAddress(), dstIbcDenom)
require.NoError(t, err)
require.True(t, gaiaWalletBal.IsZero())

e2e.UnpauseFiatTF(t, ctx, val, nw.FiatTfRoles.Pauser)

// ACTION: IBC send TF token from a blacklisted user
// EXPECTED: Request fails;

e2e.BlacklistAccount(t, ctx, val, nw.FiatTfRoles.Blacklister, nobleWallet)

_, err = noble.SendIBCTransfer(ctx, nobleToGaiaChannelID, nobleWallet.KeyName(), transfer, ibc.TransferOptions{})
require.ErrorContains(t, err, fmt.Sprintf("an address (%s) is blacklisted and can not send tokens", nobleWallet.FormattedAddress()))

require.NoError(t, r.Flush(ctx, eRep, ibcPathName, nobleToGaiaChannelID))

gaiaWalletBal, err = gaia.GetBalance(ctx, gaiaWallet.FormattedAddress(), dstIbcDenom)
require.NoError(t, err)
require.True(t, gaiaWalletBal.IsZero())

e2e.UnblacklistAccount(t, ctx, val, nw.FiatTfRoles.Blacklister, nobleWallet)

// ACTION: IBC send out a TF token to a blacklisted user
// EXPECTED: Request fails;

e2e.BlacklistAccount(t, ctx, val, nw.FiatTfRoles.Blacklister, gaiaWallet)

_, err = noble.SendIBCTransfer(ctx, nobleToGaiaChannelID, nobleWallet.KeyName(), transfer, ibc.TransferOptions{})
require.ErrorContains(t, err, fmt.Sprintf("an address (%s) is blacklisted and can not receive tokens", gaiaWallet.FormattedAddress()))

require.NoError(t, r.Flush(ctx, eRep, ibcPathName, nobleToGaiaChannelID))

gaiaWalletBal, err = gaia.GetBalance(ctx, gaiaWallet.FormattedAddress(), dstIbcDenom)
require.NoError(t, err)
require.True(t, gaiaWalletBal.IsZero())

e2e.UnblacklistAccount(t, ctx, val, nw.FiatTfRoles.Blacklister, gaiaWallet)

// ACTION: IBC send out a TF token to malformed address
// EXPECTED: Request fails;

transfer.Address = "malformed-address1234"

_, err = noble.SendIBCTransfer(ctx, nobleToGaiaChannelID, nobleWallet.KeyName(), transfer, ibc.TransferOptions{})
require.ErrorContains(t, err, "error decoding address")

// ACTION: Successfully IBC send out a TF token to an address on another chain
// EXPECTED: Success;

transfer.Address = gaiaWallet.FormattedAddress()

_, err = noble.SendIBCTransfer(ctx, nobleToGaiaChannelID, nobleWallet.KeyName(), transfer, ibc.TransferOptions{})
require.NoError(t, err)

require.NoError(t, r.Flush(ctx, eRep, ibcPathName, nobleToGaiaChannelID))

gaiaWalletBal, err = gaia.GetBalance(ctx, gaiaWallet.FormattedAddress(), dstIbcDenom)
require.NoError(t, err)
require.Equal(t, transfer.Amount, gaiaWalletBal)
}

func TestFiatTFIBCIn(t *testing.T) {
if testing.Short() {
t.Skip()
}
t.Parallel()

ctx := context.Background()

nw, gaia, _, r, ibcPathName, _, eRep, _, _ := e2e.NobleSpinUpIBC(t, ctx, true)
noble := nw.Chain
val := noble.Validators[0]

w := interchaintest.GetAndFundTestUsers(t, ctx, "default", math.NewInt(1_000_000), noble, gaia)
nobleWallet := w[0] // 1_000_000ustake
gaiaWallet := w[1] // 1_000_000uatom

mintAmount := int64(100)
_, err := val.ExecTx(ctx, nw.FiatTfRoles.Minter.KeyName(), "fiat-tokenfactory", "mint", nobleWallet.FormattedAddress(), fmt.Sprintf("%duusdc", mintAmount))
require.NoError(t, err, "error minting")

// noble -> gaia channel info
nobleToGaiaChannelInfo, err := r.GetChannels(ctx, eRep, noble.Config().ChainID)
require.NoError(t, err)
nobleToGaiaChannelID := nobleToGaiaChannelInfo[0].ChannelID
// gaia -> noble channel info
gaiaToNobleChannelInfo, err := r.GetChannels(ctx, eRep, gaia.Config().ChainID)
require.NoError(t, err)
gaiaToNobleChannelID := gaiaToNobleChannelInfo[0].ChannelID

amountToSend := math.NewInt(mintAmount)
transfer := ibc.WalletAmount{
Address: gaiaWallet.FormattedAddress(),
Denom: e2e.DenomMetadataUsdc.Base,
Amount: amountToSend,
}

// ibc transfer noble -> gaia
_, err = noble.SendIBCTransfer(ctx, nobleToGaiaChannelID, nobleWallet.KeyName(), transfer, ibc.TransferOptions{})
require.NoError(t, err)

// relay MsgRecvPacket & MsgAcknowledgement
require.NoError(t, r.Flush(ctx, eRep, ibcPathName, nobleToGaiaChannelID))

// uusdc IBC denom on gaia
srcDenomTrace := transfertypes.ParseDenomTrace(transfertypes.GetPrefixedDenom("transfer", gaiaToNobleChannelID, e2e.DenomMetadataUsdc.Base))
dstIbcDenom := srcDenomTrace.IBCDenom()

gaiaWalletBal, err := gaia.GetBalance(ctx, gaiaWallet.FormattedAddress(), dstIbcDenom)
require.NoError(t, err)
require.Equal(t, transfer.Amount, gaiaWalletBal)

// ACTION: IBC send in a TF token while TF is paused
// EXPECTED: Request fails;

e2e.PauseFiatTF(t, ctx, val, nw.FiatTfRoles.Pauser)

amountToSend = math.OneInt()
transfer = ibc.WalletAmount{
Address: nobleWallet.FormattedAddress(),
Denom: dstIbcDenom,
Amount: amountToSend,
}

height, err := gaia.Height(ctx)
require.NoError(t, err)

tx, err := gaia.SendIBCTransfer(ctx, gaiaToNobleChannelID, gaiaWallet.KeyName(), transfer, ibc.TransferOptions{})
require.NoError(t, err, "error broadcasting IBC send")

require.NoError(t, r.Flush(ctx, eRep, ibcPathName, gaiaToNobleChannelID))

heightAfterFlush, err := gaia.Height(ctx)
require.NoError(t, err)

ack, err := testutil.PollForAck(ctx, gaia, height, heightAfterFlush+5, tx.Packet)
require.NoError(t, err, "error polling for ack")
require.Contains(t, string(ack.Acknowledgement), "error handling packet")

nobleWalletBal, err := noble.GetBalance(ctx, nobleWallet.FormattedAddress(), e2e.DenomMetadataUsdc.Base)
require.NoError(t, err)
require.True(t, nobleWalletBal.IsZero())

e2e.UnpauseFiatTF(t, ctx, val, nw.FiatTfRoles.Pauser)

// ACTION: IBC send in a TF token FROM an address that is blacklisted
// EXPECTED: Request fails;

e2e.BlacklistAccount(t, ctx, val, nw.FiatTfRoles.Blacklister, gaiaWallet)

height, err = gaia.Height(ctx)
require.NoError(t, err)

tx, err = gaia.SendIBCTransfer(ctx, gaiaToNobleChannelID, gaiaWallet.KeyName(), transfer, ibc.TransferOptions{})
require.NoError(t, err, "error broadcasting IBC send")

require.NoError(t, r.Flush(ctx, eRep, ibcPathName, gaiaToNobleChannelID))

heightAfterFlush, err = gaia.Height(ctx)
require.NoError(t, err)

ack, err = testutil.PollForAck(ctx, gaia, height, heightAfterFlush+5, tx.Packet)
require.NoError(t, err, "error polling for ack")
require.Contains(t, string(ack.Acknowledgement), "error handling packet")

nobleWalletBal, err = noble.GetBalance(ctx, nobleWallet.FormattedAddress(), e2e.DenomMetadataUsdc.Base)
require.NoError(t, err)
require.True(t, nobleWalletBal.IsZero())

e2e.UnblacklistAccount(t, ctx, val, nw.FiatTfRoles.Blacklister, gaiaWallet)

// ACTION: IBC send in a TF token TO an address that is blacklisted
// EXPECTED: Request fails;

e2e.BlacklistAccount(t, ctx, val, nw.FiatTfRoles.Blacklister, nobleWallet)

height, err = gaia.Height(ctx)
require.NoError(t, err)

tx, err = gaia.SendIBCTransfer(ctx, gaiaToNobleChannelID, gaiaWallet.KeyName(), transfer, ibc.TransferOptions{})
require.NoError(t, err, "error broadcasting IBC send")

require.NoError(t, r.Flush(ctx, eRep, ibcPathName, gaiaToNobleChannelID))

heightAfterFlush, err = gaia.Height(ctx)
require.NoError(t, err)

ack, err = testutil.PollForAck(ctx, gaia, height, heightAfterFlush+5, tx.Packet)
require.NoError(t, err, "error polling for ack")
require.Contains(t, string(ack.Acknowledgement), "error handling packet")

nobleWalletBal, err = noble.GetBalance(ctx, nobleWallet.FormattedAddress(), e2e.DenomMetadataUsdc.Base)
require.NoError(t, err)
require.True(t, nobleWalletBal.IsZero())

e2e.UnblacklistAccount(t, ctx, val, nw.FiatTfRoles.Blacklister, nobleWallet)

// ACTION: Successfully IBC send in a TF token to an address on noble
// EXPECTED: Success;

height, err = gaia.Height(ctx)
require.NoError(t, err)

tx, err = gaia.SendIBCTransfer(ctx, gaiaToNobleChannelID, gaiaWallet.KeyName(), transfer, ibc.TransferOptions{})
require.NoError(t, err, "error broadcasting IBC send")

require.NoError(t, r.Flush(ctx, eRep, ibcPathName, gaiaToNobleChannelID))

heightAfterFlush, err = gaia.Height(ctx)
require.NoError(t, err)

ack, err = testutil.PollForAck(ctx, gaia, height, heightAfterFlush+5, tx.Packet)
require.NoError(t, err, "error polling for ack")
require.NotContains(t, string(ack.Acknowledgement), "error handling packet")

nobleWalletBal, err = noble.GetBalance(ctx, nobleWallet.FormattedAddress(), e2e.DenomMetadataUsdc.Base)
require.NoError(t, err)
require.Equal(t, transfer.Amount, nobleWalletBal)
}
2 changes: 1 addition & 1 deletion e2e/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ require (
github.com/circlefin/noble-fiattokenfactory v0.0.0-20241015182229-c20bd0c8442f
github.com/cosmos/cosmos-sdk v0.50.10
github.com/cosmos/gogoproto v1.7.0
github.com/cosmos/ibc-go/v8 v8.5.1
github.com/docker/docker v24.0.9+incompatible
github.com/ethereum/go-ethereum v1.14.8
github.com/strangelove-ventures/interchaintest/v8 v8.7.1
Expand Down Expand Up @@ -76,7 +77,6 @@ require (
github.com/cosmos/gogogateway v1.2.0 // indirect
github.com/cosmos/iavl v1.2.0 // indirect
github.com/cosmos/ibc-go/modules/capability v1.0.1 // indirect
github.com/cosmos/ibc-go/v8 v8.5.1 // indirect
github.com/cosmos/ics23/go v0.11.0 // indirect
github.com/cosmos/interchain-security/v5 v5.1.1 // indirect
github.com/cosmos/ledger-cosmos-go v0.13.3 // indirect
Expand Down

0 comments on commit 7d282f5

Please sign in to comment.