255 lines
13 KiB
Go
255 lines
13 KiB
Go
package ictest
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"fmt"
|
|
"testing"
|
|
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
"github.com/strangelove-ventures/interchaintest/v4"
|
|
"github.com/strangelove-ventures/interchaintest/v4/chain/cosmos"
|
|
"github.com/strangelove-ventures/interchaintest/v4/ibc"
|
|
"github.com/stretchr/testify/require"
|
|
"github.com/wormhole-foundation/wormchain/interchaintest/guardians"
|
|
"github.com/wormhole-foundation/wormchain/interchaintest/helpers"
|
|
"github.com/wormhole-foundation/wormchain/interchaintest/helpers/cw_wormhole"
|
|
"github.com/wormhole-foundation/wormhole/sdk/vaa"
|
|
)
|
|
|
|
// TestShutdownCoreContract tests the endpoints of a contract in its "shutdown" state
|
|
func TestShutdownCoreContract(t *testing.T) {
|
|
// Setup chain and contract
|
|
numVals := 1
|
|
oldGuardians := guardians.CreateValSet(t, numVals)
|
|
chain := createSingleNodeCluster(t, "v2.24.2", *oldGuardians)
|
|
ctx, _ := buildSingleNodeInterchain(t, chain)
|
|
|
|
// Chains
|
|
wormchain := chain.(*cosmos.CosmosChain)
|
|
|
|
// Users
|
|
users := interchaintest.GetAndFundTestUsers(t, ctx, t.Name(), 1, wormchain)
|
|
user := users[0]
|
|
|
|
// Deploy contract to wormhole
|
|
coreInstantiateMsg := helpers.CoreContractInstantiateMsg(t, wormchainConfig, vaa.ChainIDWormchain, oldGuardians)
|
|
contractInfo := helpers.StoreAndInstantiateWormholeContract(t, ctx, wormchain, "faucet", "./contracts/wormhole_core.wasm", "wormhole_core", coreInstantiateMsg, oldGuardians)
|
|
contractAddr := contractInfo.Address
|
|
|
|
// Store a new version of the contract to upgrade to
|
|
wormNewCodeId := helpers.StoreContract(t, ctx, wormchain, "faucet", "./contracts/shutdown_wormhole_core.wasm", oldGuardians)
|
|
|
|
// Submit contract upgrade
|
|
err := cw_wormhole.SubmitContractUpgrade(t, ctx, oldGuardians, wormchain, contractAddr, wormNewCodeId)
|
|
require.NoError(t, err)
|
|
|
|
// -----------------------------------
|
|
|
|
// Try to post a message - should fail
|
|
message := []byte("test message")
|
|
messageBase64 := base64.StdEncoding.EncodeToString(message)
|
|
nonce := 1
|
|
|
|
executeMsg, err := json.Marshal(cw_wormhole.ExecuteMsg{
|
|
PostMessage: &cw_wormhole.ExecuteMsg_PostMessage{
|
|
Message: cw_wormhole.Binary(messageBase64),
|
|
Nonce: nonce,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// Execute contract
|
|
_, err = wormchain.ExecuteContract(ctx, "faucet", contractAddr, string(executeMsg))
|
|
require.Error(t, err)
|
|
|
|
// -----------------------------------
|
|
|
|
// Try to set fees - should fail
|
|
_, err = cw_wormhole.SubmitFeeUpdate(t, ctx, oldGuardians, wormchain, contractAddr, "1000000", false)
|
|
require.Error(t, err)
|
|
|
|
// -----------------------------------
|
|
|
|
// Try to transfer fees - should fail
|
|
_, err = cw_wormhole.SubmitTransferFee(t, ctx, oldGuardians, wormchain, contractAddr, []byte(user.Address), "10000000000", false)
|
|
require.Error(t, err)
|
|
|
|
// -----------------------------------
|
|
|
|
// Try to submit a guardian set update - should pass
|
|
initialIndex := int(helpers.QueryConsensusGuardianSetIndex(t, wormchain, ctx))
|
|
signingGuardians := guardians.CreateValSet(t, numVals)
|
|
|
|
newGuardians := signingGuardians
|
|
err = cw_wormhole.SubmitGuardianSetUpdate(t, ctx, wormchain, contractAddr, newGuardians, uint32(initialIndex+1), oldGuardians)
|
|
require.NoError(t, err)
|
|
cw_wormhole.VerifyGuardianSet(t, ctx, wormchain, contractAddr, newGuardians, initialIndex+1)
|
|
|
|
// -----------------------------------
|
|
|
|
// Migrate contract back to original contract id
|
|
err = cw_wormhole.SubmitContractUpgrade(t, ctx, signingGuardians, wormchain, contractAddr, contractInfo.ContractInfo.CodeID)
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
// TestShutdownTokenBridge tests the endpoints of a contract in its "shutdown" state
|
|
// The shutdown contract only allows the following: Upgrading the Contract & Registering a new chain.
|
|
func TestShutdownTokenBridge(t *testing.T) {
|
|
// Setup chain and contract
|
|
numVals := 1
|
|
guardians := guardians.CreateValSet(t, numVals)
|
|
chains := CreateChains(t, "v2.24.2", *guardians)
|
|
ctx, r, eRep, _ := BuildInterchain(t, chains)
|
|
|
|
// Chains
|
|
wormchain := chains[0].(*cosmos.CosmosChain)
|
|
gaia := chains[1].(*cosmos.CosmosChain)
|
|
osmosis := chains[2].(*cosmos.CosmosChain)
|
|
|
|
wormchainFaucetAddrBz, err := wormchain.GetAddress(ctx, "faucet")
|
|
require.NoError(t, err)
|
|
wormchainFaucetAddr := sdk.MustBech32ifyAddressBytes(wormchain.Config().Bech32Prefix, wormchainFaucetAddrBz)
|
|
fmt.Println("Wormchain faucet addr: ", wormchainFaucetAddr)
|
|
|
|
osmoToWormChannel, err := ibc.GetTransferChannel(ctx, r, eRep, osmosis.Config().ChainID, wormchain.Config().ChainID)
|
|
require.NoError(t, err)
|
|
wormToOsmoChannel := osmoToWormChannel.Counterparty
|
|
gaiaToWormChannel, err := ibc.GetTransferChannel(ctx, r, eRep, gaia.Config().ChainID, wormchain.Config().ChainID)
|
|
require.NoError(t, err)
|
|
wormToGaiaChannel := gaiaToWormChannel.Counterparty
|
|
|
|
users := interchaintest.GetAndFundTestUsers(t, ctx, "default", int64(10_000_000_000), gaia, osmosis, osmosis)
|
|
gaiaUser := users[0]
|
|
osmoUser1 := users[1]
|
|
osmoUser2 := users[2]
|
|
|
|
// Store wormhole core contract
|
|
coreContractCodeId := helpers.StoreContract(t, ctx, wormchain, "faucet", "./contracts/wormhole_core.wasm", guardians)
|
|
fmt.Println("Core contract code id: ", coreContractCodeId)
|
|
|
|
// Instantiate wormhole core contract
|
|
coreInstantiateMsg := helpers.CoreContractInstantiateMsg(t, wormchainConfig, vaa.ChainIDWormchain, guardians)
|
|
coreContractAddr := helpers.InstantiateContract(t, ctx, wormchain, "faucet", coreContractCodeId, "wormhole_core", coreInstantiateMsg, guardians)
|
|
fmt.Println("Core contract address: ", coreContractAddr)
|
|
|
|
// Store cw20_wrapped_2 contract
|
|
wrappedAssetCodeId := helpers.StoreContract(t, ctx, wormchain, "faucet", "./contracts/cw20_wrapped_2.wasm", guardians)
|
|
fmt.Println("CW20 wrapped_2 code id: ", wrappedAssetCodeId)
|
|
|
|
// Store token bridge contract
|
|
tbContractCodeId := helpers.StoreContract(t, ctx, wormchain, "faucet", "./contracts/token_bridge.wasm", guardians)
|
|
fmt.Println("Token bridge contract code id: ", tbContractCodeId)
|
|
|
|
// Instantiate token bridge contract
|
|
tbInstantiateMsg := helpers.TbContractInstantiateMsg(t, wormchainConfig, coreContractAddr, wrappedAssetCodeId)
|
|
tbContractAddr := helpers.InstantiateContract(t, ctx, wormchain, "faucet", tbContractCodeId, "token_bridge", tbInstantiateMsg, guardians)
|
|
fmt.Println("Token bridge contract address: ", tbContractAddr)
|
|
|
|
helpers.SubmitAllowlistInstantiateContract(t, ctx, wormchain, "faucet", wormchain.Config(), tbContractAddr, wrappedAssetCodeId, guardians)
|
|
|
|
// Store a new version of the token bridge to upgrade to
|
|
tbNewCodeId := helpers.StoreContract(t, ctx, wormchain, "faucet", "./contracts/shutdown_token_bridge.wasm", guardians)
|
|
|
|
// Submit contract upgrade
|
|
err = cw_wormhole.SubmitContractUpgrade(t, ctx, guardians, wormchain, tbContractAddr, tbNewCodeId)
|
|
require.NoError(t, err)
|
|
|
|
// -----------------------------------
|
|
|
|
// Registering a new chain - should pass
|
|
tbRegisterChainMsg := helpers.TbRegisterChainMsg(t, ExternalChainId, ExternalChainEmitterAddr, guardians)
|
|
_, err = wormchain.ExecuteContract(ctx, "faucet", tbContractAddr, string(tbRegisterChainMsg))
|
|
require.NoError(t, err)
|
|
|
|
// -----------------------------------
|
|
|
|
// Registering a new token - should fail
|
|
tbRegisterForeignAssetMsg := helpers.TbRegisterForeignAsset(t, Asset1ContractAddr, Asset1ChainID, ExternalChainEmitterAddr, Asset1Decimals, Asset1Symbol, Asset1Name, guardians)
|
|
_, err = wormchain.ExecuteContract(ctx, "faucet", tbContractAddr, string(tbRegisterForeignAssetMsg))
|
|
require.Error(t, err)
|
|
require.ErrorContains(t, err, "InvalidVAAAction")
|
|
|
|
// -----------------------------------
|
|
|
|
// Upgrade contract back to original contract id - should pass
|
|
err = cw_wormhole.SubmitContractUpgrade(t, ctx, guardians, wormchain, tbContractAddr, tbContractCodeId)
|
|
require.NoError(t, err)
|
|
|
|
// -----------------------------------
|
|
|
|
// Setup chains in "full" mode in preparation for transfer vaas
|
|
|
|
// Now register a new token - should pass on original contract
|
|
tbRegisterForeignAssetMsg = helpers.TbRegisterForeignAsset(t, Asset1ContractAddr, Asset1ChainID, ExternalChainEmitterAddr, Asset1Decimals, Asset1Symbol, Asset1Name, guardians)
|
|
_, err = wormchain.ExecuteContract(ctx, "faucet", tbContractAddr, string(tbRegisterForeignAssetMsg))
|
|
require.NoError(t, err)
|
|
|
|
// Store ibc translator contract
|
|
ibcTranslatorCodeId := helpers.StoreContract(t, ctx, wormchain, "faucet", "./contracts/ibc_translator.wasm", guardians)
|
|
fmt.Println("Ibc translator code id: ", ibcTranslatorCodeId)
|
|
|
|
// Instantiate ibc translator contract
|
|
ibcTranslatorInstantiateMsg := helpers.IbcTranslatorContractInstantiateMsg(t, tbContractAddr)
|
|
ibcTranslatorContractAddr := helpers.InstantiateContract(t, ctx, wormchain, "faucet", ibcTranslatorCodeId, "ibc_translator", ibcTranslatorInstantiateMsg, guardians)
|
|
fmt.Println("Ibc translator contract address: ", ibcTranslatorContractAddr)
|
|
|
|
helpers.SetMiddlewareContract(t, ctx, wormchain, "faucet", wormchain.Config(), ibcTranslatorContractAddr, guardians)
|
|
|
|
// Allowlist worm/osmo chain id / channel
|
|
wormOsmoAllowlistMsg := helpers.SubmitUpdateChainToChannelMapMsg(t, OsmoChainID, wormToOsmoChannel.ChannelID, guardians)
|
|
_, err = wormchain.ExecuteContract(ctx, "faucet", ibcTranslatorContractAddr, wormOsmoAllowlistMsg)
|
|
require.NoError(t, err)
|
|
|
|
// Allowlist worm/gaia chain id / channel
|
|
wormGaiaAllowlistMsg := helpers.SubmitUpdateChainToChannelMapMsg(t, GaiaChainID, wormToGaiaChannel.ChannelID, guardians)
|
|
_, err = wormchain.ExecuteContract(ctx, "faucet", ibcTranslatorContractAddr, wormGaiaAllowlistMsg)
|
|
require.NoError(t, err)
|
|
|
|
ibcHooksCodeId, err := osmosis.StoreContract(ctx, osmoUser1.KeyName, "./contracts/ibc_hooks.wasm")
|
|
require.NoError(t, err)
|
|
fmt.Println("IBC hooks code id: ", ibcHooksCodeId)
|
|
|
|
ibcHooksContractAddr, err := osmosis.InstantiateContract(ctx, osmoUser1.KeyName, ibcHooksCodeId, "{}", true)
|
|
require.NoError(t, err)
|
|
fmt.Println("IBC hooks contract addr: ", ibcHooksContractAddr)
|
|
|
|
// -----------------------------------
|
|
|
|
// Upgrade contract to shutdown contract
|
|
err = cw_wormhole.SubmitContractUpgrade(t, ctx, guardians, wormchain, tbContractAddr, tbNewCodeId)
|
|
require.NoError(t, err)
|
|
|
|
// -----------------------------------
|
|
|
|
// Send transfer vaas - all should fail
|
|
|
|
// Create and process a simple ibc payload3: Transfers 10.000_018 of asset1 from external chain through wormchain to gaia user
|
|
simplePayload := helpers.CreateGatewayIbcTokenBridgePayloadTransfer(t, GaiaChainID, gaiaUser.Bech32Address(gaia.Config().Bech32Prefix), 0, 1)
|
|
externalSender := []byte{1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8}
|
|
payload3 := helpers.CreatePayload3(wormchain.Config(), uint64(AmountExternalToGaiaUser1), Asset1ContractAddr, Asset1ChainID, ibcTranslatorContractAddr, uint16(vaa.ChainIDWormchain), externalSender, simplePayload)
|
|
completeTransferAndConvertMsg := helpers.IbcTranslatorCompleteTransferAndConvertMsg(t, ExternalChainId, ExternalChainEmitterAddr, payload3, guardians)
|
|
_, err = wormchain.ExecuteContract(ctx, "faucet", ibcTranslatorContractAddr, completeTransferAndConvertMsg)
|
|
require.Error(t, err)
|
|
require.ErrorContains(t, err, "Invalid during shutdown mode")
|
|
|
|
// Create and process a simple ibc payload3: Transfers 1.000_001 of asset1 from external chain through wormchain to osmo user1
|
|
simplePayload = helpers.CreateGatewayIbcTokenBridgePayloadTransfer(t, OsmoChainID, osmoUser1.Bech32Address(osmosis.Config().Bech32Prefix), 0, 1)
|
|
payload3 = helpers.CreatePayload3(wormchain.Config(), uint64(AmountExternalToOsmoUser1), Asset1ContractAddr, Asset1ChainID, ibcTranslatorContractAddr, uint16(vaa.ChainIDWormchain), externalSender, simplePayload)
|
|
completeTransferAndConvertMsg = helpers.IbcTranslatorCompleteTransferAndConvertMsg(t, ExternalChainId, ExternalChainEmitterAddr, payload3, guardians)
|
|
_, err = wormchain.ExecuteContract(ctx, "faucet", ibcTranslatorContractAddr, completeTransferAndConvertMsg)
|
|
require.Error(t, err)
|
|
require.ErrorContains(t, err, "Invalid during shutdown mode")
|
|
|
|
// Create and process a contract controlled ibc payload3
|
|
// Transfers 1.000_002 of asset1 from external chain through wormchain to ibc hooks contract addr
|
|
// IBC hooks is used to route the contract controlled payload to a test contract which forwards tokens to osmo user2
|
|
ibcHooksPayload := helpers.CreateIbcHooksMsg(t, ibcHooksContractAddr, osmoUser2.Bech32Address(osmosis.Config().Bech32Prefix))
|
|
contractControlledPayload := helpers.CreateGatewayIbcTokenBridgePayloadTransferWithPayload(t, OsmoChainID, ibcHooksContractAddr, ibcHooksPayload, 1)
|
|
payload3 = helpers.CreatePayload3(wormchain.Config(), uint64(AmountExternalToOsmoUser2), Asset1ContractAddr, Asset1ChainID, ibcTranslatorContractAddr, uint16(vaa.ChainIDWormchain), externalSender, contractControlledPayload)
|
|
completeTransferAndConvertMsg = helpers.IbcTranslatorCompleteTransferAndConvertMsg(t, ExternalChainId, ExternalChainEmitterAddr, payload3, guardians)
|
|
_, err = wormchain.ExecuteContract(ctx, "faucet", ibcTranslatorContractAddr, completeTransferAndConvertMsg)
|
|
require.Error(t, err)
|
|
require.ErrorContains(t, err, "Invalid during shutdown mode")
|
|
}
|