0g-chain/tests/e2e/e2e_convert_cosmos_coins_test.go
Robert Pirtle a1f1f0d957
test(e2e): add tests for cosmos coin conversion (#1612)
* add e2e test for cosmos coin conversion

* add e2e test for eip712 signing of converts

* update kvtool
2023-06-05 13:22:23 -07:00

245 lines
8.6 KiB
Go

package e2e_test
import (
"context"
"math/big"
"time"
sdkerrors "cosmossdk.io/errors"
sdk "github.com/cosmos/cosmos-sdk/types"
txtypes "github.com/cosmos/cosmos-sdk/types/tx"
"github.com/ethereum/go-ethereum"
"github.com/kava-labs/kava/tests/e2e/testutil"
"github.com/kava-labs/kava/tests/util"
evmutiltypes "github.com/kava-labs/kava/x/evmutil/types"
)
func setupConvertToCoinTest(
suite *IntegrationTestSuite, accountName string,
) (denom string, initialFunds sdk.Coins, user *testutil.SigningAccount) {
// we expect a denom to be registered to the allowed denoms param
// and for the funded account to have a balance for that denom
params, err := suite.Kava.Evmutil.Params(context.Background(), &evmutiltypes.QueryParamsRequest{})
suite.NoError(err)
suite.GreaterOrEqual(
len(params.Params.AllowedCosmosDenoms), 1,
"kava chain expected to have at least one AllowedCosmosDenom for ERC20 conversion",
)
tokenInfo := params.Params.AllowedCosmosDenoms[0]
denom = tokenInfo.CosmosDenom
initialFunds = sdk.NewCoins(
sdk.NewInt64Coin(suite.Kava.StakingDenom, 1e6), // gas money
sdk.NewInt64Coin(denom, 1e10), // conversion-enabled cosmos coin
)
user = suite.Kava.NewFundedAccount(accountName, initialFunds)
return denom, initialFunds, user
}
func (suite *IntegrationTestSuite) TestConvertCosmosCoinsToFromERC20() {
denom, initialFunds, user := setupConvertToCoinTest(suite, "cosmo-coin-converter")
fee := sdk.NewCoins(ukava(7500))
convertAmount := int64(5e9)
initialModuleBalance := suite.Kava.GetModuleBalances(evmutiltypes.ModuleName).AmountOf(denom)
///////////////////////////////
// CONVERT COSMOS COIN -> ERC20
///////////////////////////////
convertToErc20Msg := evmutiltypes.NewMsgConvertCosmosCoinToERC20(
user.SdkAddress.String(),
user.EvmAddress.Hex(),
sdk.NewInt64Coin(denom, convertAmount),
)
tx := util.KavaMsgRequest{
Msgs: []sdk.Msg{&convertToErc20Msg},
GasLimit: 2e6,
FeeAmount: fee,
Data: "converting sdk coin to erc20",
}
res := user.SignAndBroadcastKavaTx(tx)
suite.NoError(res.Err)
// query for the deployed contract
deployedContracts, err := suite.Kava.Evmutil.DeployedCosmosCoinContracts(
context.Background(),
&evmutiltypes.QueryDeployedCosmosCoinContractsRequest{CosmosDenoms: []string{denom}},
)
suite.NoError(err)
suite.Len(deployedContracts.DeployedCosmosCoinContracts, 1)
contractAddress := deployedContracts.DeployedCosmosCoinContracts[0].Address
// check erc20 balance
bz, err := suite.Kava.EvmClient.CallContract(context.Background(), ethereum.CallMsg{
To: &contractAddress.Address,
Data: util.BuildErc20BalanceOfCallData(user.EvmAddress),
}, nil)
suite.NoError(err)
erc20Balance := new(big.Int).SetBytes(bz)
suite.BigIntsEqual(big.NewInt(convertAmount), erc20Balance, "unexpected erc20 balance post-convert")
// check cosmos coin is deducted from account
expectedFunds := initialFunds.AmountOf(denom).SubRaw(convertAmount)
balance := suite.Kava.QuerySdkForBalances(user.SdkAddress).AmountOf(denom)
suite.Equal(expectedFunds, balance)
// check that module account has sdk coins
expectedModuleBalance := initialModuleBalance.AddRaw(convertAmount)
actualModuleBalance := suite.Kava.GetModuleBalances(evmutiltypes.ModuleName).AmountOf(denom)
suite.Equal(expectedModuleBalance, actualModuleBalance)
///////////////////////////////
// CONVERT ERC20 -> COSMOS COIN
///////////////////////////////
convertFromErc20Msg := evmutiltypes.NewMsgConvertCosmosCoinFromERC20(
user.EvmAddress.Hex(),
user.SdkAddress.String(),
sdk.NewInt64Coin(denom, convertAmount),
)
tx = util.KavaMsgRequest{
Msgs: []sdk.Msg{&convertFromErc20Msg},
GasLimit: 2e5,
FeeAmount: fee,
Data: "converting erc20 to cosmos coin",
}
res = user.SignAndBroadcastKavaTx(tx)
suite.NoError(res.Err)
// check erc20 balance
bz, err = suite.Kava.EvmClient.CallContract(context.Background(), ethereum.CallMsg{
To: &contractAddress.Address,
Data: util.BuildErc20BalanceOfCallData(user.EvmAddress),
}, nil)
suite.NoError(err)
erc20Balance = new(big.Int).SetBytes(bz)
suite.BigIntsEqual(big.NewInt(0), erc20Balance, "expected all erc20 to be converted back")
// check cosmos coin is added back to account
expectedFunds = initialFunds.AmountOf(denom)
balance = suite.Kava.QuerySdkForBalances(user.SdkAddress).AmountOf(denom)
suite.Equal(expectedFunds, balance)
// check that module account has sdk coins deducted
actualModuleBalance = suite.Kava.GetModuleBalances(evmutiltypes.ModuleName).AmountOf(denom)
suite.Equal(initialModuleBalance, actualModuleBalance)
}
// like the above, but confirming we can sign the messages with eip712
func (suite *IntegrationTestSuite) TestEIP712ConvertCosmosCoinsToFromERC20() {
denom, initialFunds, user := setupConvertToCoinTest(suite, "cosmo-coin-converter-eip712")
convertAmount := int64(5e9)
initialModuleBalance := suite.Kava.GetModuleBalances(evmutiltypes.ModuleName).AmountOf(denom)
///////////////////////////////
// CONVERT COSMOS COIN -> ERC20
///////////////////////////////
convertToErc20Msg := evmutiltypes.NewMsgConvertCosmosCoinToERC20(
user.SdkAddress.String(),
user.EvmAddress.Hex(),
sdk.NewInt64Coin(denom, convertAmount),
)
tx := suite.NewEip712TxBuilder(
user,
suite.Kava,
2e6,
sdk.NewCoins(ukava(1e4)),
[]sdk.Msg{&convertToErc20Msg},
"this is a memo",
).GetTx()
txBytes, err := suite.Kava.EncodingConfig.TxConfig.TxEncoder()(tx)
suite.NoError(err)
// submit the eip712 message to the chain.
res, err := suite.Kava.Tx.BroadcastTx(context.Background(), &txtypes.BroadcastTxRequest{
TxBytes: txBytes,
Mode: txtypes.BroadcastMode_BROADCAST_MODE_SYNC,
})
suite.NoError(err)
suite.Equal(sdkerrors.SuccessABCICode, res.TxResponse.Code)
_, err = util.WaitForSdkTxCommit(suite.Kava.Tx, res.TxResponse.TxHash, 6*time.Second)
suite.NoError(err)
// query for the deployed contract
deployedContracts, err := suite.Kava.Evmutil.DeployedCosmosCoinContracts(
context.Background(),
&evmutiltypes.QueryDeployedCosmosCoinContractsRequest{CosmosDenoms: []string{denom}},
)
suite.NoError(err)
suite.Len(deployedContracts.DeployedCosmosCoinContracts, 1)
contractAddress := deployedContracts.DeployedCosmosCoinContracts[0].Address
// check erc20 balance
bz, err := suite.Kava.EvmClient.CallContract(context.Background(), ethereum.CallMsg{
To: &contractAddress.Address,
Data: util.BuildErc20BalanceOfCallData(user.EvmAddress),
}, nil)
suite.NoError(err)
erc20Balance := new(big.Int).SetBytes(bz)
suite.BigIntsEqual(big.NewInt(convertAmount), erc20Balance, "unexpected erc20 balance post-convert")
// check cosmos coin is deducted from account
expectedFunds := initialFunds.AmountOf(denom).SubRaw(convertAmount)
balance := suite.Kava.QuerySdkForBalances(user.SdkAddress).AmountOf(denom)
suite.Equal(expectedFunds, balance)
// check that module account has sdk coins
expectedModuleBalance := initialModuleBalance.AddRaw(convertAmount)
actualModuleBalance := suite.Kava.GetModuleBalances(evmutiltypes.ModuleName).AmountOf(denom)
suite.Equal(expectedModuleBalance, actualModuleBalance)
///////////////////////////////
// CONVERT ERC20 -> COSMOS COIN
///////////////////////////////
convertFromErc20Msg := evmutiltypes.NewMsgConvertCosmosCoinFromERC20(
user.EvmAddress.Hex(),
user.SdkAddress.String(),
sdk.NewInt64Coin(denom, convertAmount),
)
tx = suite.NewEip712TxBuilder(
user,
suite.Kava,
2e5,
sdk.NewCoins(ukava(1e4)),
[]sdk.Msg{&convertFromErc20Msg},
"",
).GetTx()
txBytes, err = suite.Kava.EncodingConfig.TxConfig.TxEncoder()(tx)
suite.NoError(err)
// submit the eip712 message to the chain
res, err = suite.Kava.Tx.BroadcastTx(context.Background(), &txtypes.BroadcastTxRequest{
TxBytes: txBytes,
Mode: txtypes.BroadcastMode_BROADCAST_MODE_SYNC,
})
suite.NoError(err)
suite.Equal(sdkerrors.SuccessABCICode, res.TxResponse.Code)
_, err = util.WaitForSdkTxCommit(suite.Kava.Tx, res.TxResponse.TxHash, 6*time.Second)
suite.NoError(err)
// check erc20 balance
bz, err = suite.Kava.EvmClient.CallContract(context.Background(), ethereum.CallMsg{
To: &contractAddress.Address,
Data: util.BuildErc20BalanceOfCallData(user.EvmAddress),
}, nil)
suite.NoError(err)
erc20Balance = new(big.Int).SetBytes(bz)
suite.BigIntsEqual(big.NewInt(0), erc20Balance, "expected all erc20 to be converted back")
// check cosmos coin is added back to account
expectedFunds = initialFunds.AmountOf(denom)
balance = suite.Kava.QuerySdkForBalances(user.SdkAddress).AmountOf(denom)
suite.Equal(expectedFunds, balance)
// check that module account has sdk coins deducted
actualModuleBalance = suite.Kava.GetModuleBalances(evmutiltypes.ModuleName).AmountOf(denom)
suite.Equal(initialModuleBalance, actualModuleBalance)
}