test(e2e): update kvtool & e2e tests (#1659)

* add Cdp querier to Chain

* verify funded account has sufficient balance

* return error for nonzero status codes

* update e2e test for eip712 signing

complex eip712 workflow now uses x/cdp instead of x/earn vault

* update to master kvtool

* reset e2e env variables
This commit is contained in:
Robert Pirtle 2023-08-02 14:52:48 -07:00 committed by GitHub
parent 667b6d084e
commit 839dc80205
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 87 additions and 50 deletions

View File

@ -28,8 +28,11 @@ E2E_KAVA_UPGRADE_HEIGHT=
# E2E_KAVA_UPGRADE_BASE_IMAGE_TAG is the tag of the docker image the chain should upgrade from.
E2E_KAVA_UPGRADE_BASE_IMAGE_TAG=
# E2E_KAVA_ERC20_ADDRESS is the address of a pre-deployed ERC20 token.
# The E2E_KAVA_FUNDED_ACCOUNT_MNEMONIC account must have a balance.
# The ERC20 must be enabled via x/evmutil params for conversion to sdk.Coin.
# The corresponding sdk.Coin must be a supported vault in x/earn.
# E2E_KAVA_ERC20_ADDRESS is the address of a pre-deployed ERC20 token with the following properties:
# - the E2E_KAVA_FUNDED_ACCOUNT_MNEMONIC has nonzero balance
# - the ERC20 must be enabled via x/evmutil params for conversion to sdk.Coin
# - the corresponsing sdk.Coin must be supported as a cdp collateral type (w/ valid pricefeed)
# - the evmutil params must support conversion & deposits to mint in eip712 messages
#
# These requirements are verified on test startup in ./testutil/init_evm.go
E2E_KAVA_ERC20_ADDRESS=0xeA7100edA2f805356291B0E55DaD448599a72C6d

View File

@ -13,8 +13,11 @@ E2E_KAVA_EVM_RPC_URL='http://localhost:8545'
# E2E_INCLUDE_IBC_TESTS is not currently supported for running tests against a live network.
E2E_INCLUDE_IBC_TESTS=false
# E2E_KAVA_ERC20_ADDRESS is the address of a pre-deployed ERC20 token.
# The E2E_KAVA_FUNDED_ACCOUNT_MNEMONIC account must have a balance.
# The ERC20 must be enabled via x/evmutil params for conversion to sdk.Coin.
# The corresponding sdk.Coin must be a supported vault in x/earn.
# E2E_KAVA_ERC20_ADDRESS is the address of a pre-deployed ERC20 token with the following properties:
# - the E2E_KAVA_FUNDED_ACCOUNT_MNEMONIC has nonzero balance
# - the ERC20 must be enabled via x/evmutil params for conversion to sdk.Coin
# - the corresponsing sdk.Coin must be supported as a cdp collateral type (w/ valid pricefeed)
# - the evmutil params must support conversion & deposits to mint in eip712 messages
#
# These requirements are verified on test startup in ./testutil/init_evm.go
E2E_KAVA_ERC20_ADDRESS=0xeA7100edA2f805356291B0E55DaD448599a72C6d

View File

@ -11,7 +11,7 @@ import (
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/kava-labs/kava/app"
earntypes "github.com/kava-labs/kava/x/earn/types"
cdptypes "github.com/kava-labs/kava/x/cdp/types"
evmutiltypes "github.com/kava-labs/kava/x/evmutil/types"
"github.com/kava-labs/kava/tests/e2e/contracts/greeter"
@ -106,13 +106,16 @@ func (suite *IntegrationTestSuite) TestEip712BasicMessageAuthorization() {
suite.Equal(sdk.NewInt(1e3), balRes.Balance.Amount)
}
// Note that this test works because the deployed erc20 is configured in evmutil & earn params.
func (suite *IntegrationTestSuite) TestEip712ConvertToCoinAndDepositToEarn() {
amount := sdk.NewInt(1e2) // 0.0002 USDC
// Note that this test works because the deployed erc20 is configured in evmutil & cdp params.
// This test matches the webapp's "USDT Earn" workflow
func (suite *IntegrationTestSuite) TestEip712ConvertToCoinAndDepositToLend() {
// cdp requires minimum of $11 collateral
amount := sdk.NewInt(11e6) // 11 USDT
principal := sdk.NewCoin("usdx", sdk.NewInt(10e6))
sdkDenom := suite.DeployedErc20.CosmosDenom
// create new funded account
depositor := suite.Kava.NewFundedAccount("eip712-earn-depositor", sdk.NewCoins(ukava(1e5)))
depositor := suite.Kava.NewFundedAccount("eip712-lend-depositor", sdk.NewCoins(ukava(1e5)))
// give them erc20 balance to deposit
fundRes := suite.FundKavaErc20Balance(depositor.EvmAddress, amount.BigInt())
suite.NoError(fundRes.Err)
@ -124,16 +127,17 @@ func (suite *IntegrationTestSuite) TestEip712ConvertToCoinAndDepositToEarn() {
evmutiltypes.NewInternalEVMAddress(suite.DeployedErc20.Address),
amount,
)
depositMsg := earntypes.NewMsgDeposit(
depositor.SdkAddress.String(),
depositMsg := cdptypes.NewMsgCreateCDP(
depositor.SdkAddress,
sdk.NewCoin(sdkDenom, amount),
earntypes.STRATEGY_TYPE_SAVINGS,
principal,
suite.DeployedErc20.CdpCollateralType,
)
msgs := []sdk.Msg{
// convert to coin
&convertMsg,
// deposit into earn
depositMsg,
// deposit into cdp (Mint), take out USDX
&depositMsg,
}
// create tx
@ -143,7 +147,7 @@ func (suite *IntegrationTestSuite) TestEip712ConvertToCoinAndDepositToEarn() {
1e6,
sdk.NewCoins(ukava(1e4)),
msgs,
"depositing my USDC into Earn!",
"doing the USDT Earn workflow! erc20 -> sdk.Coin -> USDX hard deposit",
).GetTx()
txBytes, err := suite.Kava.EncodingConfig.TxConfig.TxEncoder()(tx)
@ -158,26 +162,26 @@ func (suite *IntegrationTestSuite) TestEip712ConvertToCoinAndDepositToEarn() {
suite.Equal(sdkerrors.SuccessABCICode, res.TxResponse.Code)
_, err = util.WaitForSdkTxCommit(suite.Kava.Tx, res.TxResponse.TxHash, 6*time.Second)
suite.NoError(err)
suite.Require().NoError(err)
// check that depositor no longer has erc20 balance
balance := suite.Kava.GetErc20Balance(suite.DeployedErc20.Address, depositor.EvmAddress)
suite.BigIntsEqual(big.NewInt(0), balance, "expected no erc20 balance")
// check that account has an earn deposit position
earnRes, err := suite.Kava.Earn.Deposits(context.Background(), &earntypes.QueryDepositsRequest{
Depositor: depositor.SdkAddress.String(),
Denom: sdkDenom,
// check that account has cdp
cdpRes, err := suite.Kava.Cdp.Cdp(context.Background(), &cdptypes.QueryCdpRequest{
CollateralType: suite.DeployedErc20.CdpCollateralType,
Owner: depositor.SdkAddress.String(),
})
suite.NoError(err)
suite.Len(earnRes.Deposits, 1)
suite.Equal(sdk.NewDecFromInt(amount), earnRes.Deposits[0].Shares.AmountOf(sdkDenom))
suite.True(cdpRes.Cdp.Collateral.Amount.Equal(amount))
suite.True(cdpRes.Cdp.Principal.Equal(principal))
// withdraw deposit & convert back to erc20 (this allows refund to recover erc20s used in test)
withdraw := earntypes.NewMsgWithdraw(
depositor.SdkAddress.String(),
sdk.NewCoin(sdkDenom, amount),
earntypes.STRATEGY_TYPE_SAVINGS,
withdraw := cdptypes.NewMsgRepayDebt(
depositor.SdkAddress,
suite.DeployedErc20.CdpCollateralType,
principal,
)
convertBack := evmutiltypes.NewMsgConvertCoinToERC20(
depositor.SdkAddress.String(),
@ -185,11 +189,14 @@ func (suite *IntegrationTestSuite) TestEip712ConvertToCoinAndDepositToEarn() {
sdk.NewCoin(sdkDenom, amount),
)
withdrawAndConvertBack := util.KavaMsgRequest{
Msgs: []sdk.Msg{withdraw, &convertBack},
GasLimit: 3e5,
FeeAmount: sdk.NewCoins(ukava(300)),
Data: "withdrawing from earn & converting back to erc20",
Msgs: []sdk.Msg{&withdraw, &convertBack},
GasLimit: 1e6,
FeeAmount: sdk.NewCoins(ukava(1000)),
Data: "withdrawing from mint & converting back to erc20",
}
lastRes := depositor.SignAndBroadcastKavaTx(withdrawAndConvertBack)
suite.NoError(lastRes.Err)
balance = suite.Kava.GetErc20Balance(suite.DeployedErc20.Address, depositor.EvmAddress)
suite.BigIntsEqual(amount.BigInt(), balance, "expected returned erc20 balance")
}

@ -1 +1 @@
Subproject commit 68f3a5ce9e688028ab66cecdb583223f03e153fc
Subproject commit b093fc9f2a28cf57b4a6924f45919edcfe551eaf

View File

@ -9,20 +9,23 @@ import (
"os"
"time"
"github.com/stretchr/testify/require"
sdkmath "cosmossdk.io/math"
"github.com/cosmos/cosmos-sdk/crypto/hd"
"github.com/cosmos/cosmos-sdk/crypto/types"
sdk "github.com/cosmos/cosmos-sdk/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/cosmos/go-bip39"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/evmos/ethermint/crypto/ethsecp256k1"
emtests "github.com/evmos/ethermint/tests"
emtypes "github.com/evmos/ethermint/types"
"github.com/stretchr/testify/require"
"github.com/kava-labs/kava/app"
"github.com/kava-labs/kava/tests/util"
@ -207,9 +210,15 @@ func (chain *Chain) NewFundedAccount(name string, funds sdk.Coins) *SigningAccou
return acc
}
// TODO: verify whale has funds.
whale := chain.GetAccount(FundedAccountName)
// check that the whale has the necessary balance to fund account
bal := chain.QuerySdkForBalances(whale.SdkAddress)
require.Truef(chain.t,
bal.IsAllGT(funds),
"funded account lacks funds for account %s\nneeds: %s\nhas: %s", name, funds, bal,
)
whale.l.Printf("attempting to fund created account (%s=%s)\n", name, acc.SdkAddress.String())
res := whale.BankSend(acc.SdkAddress, funds)

View File

@ -26,6 +26,7 @@ import (
kavaparams "github.com/kava-labs/kava/app/params"
"github.com/kava-labs/kava/tests/e2e/runner"
"github.com/kava-labs/kava/tests/util"
cdptypes "github.com/kava-labs/kava/x/cdp/types"
committeetypes "github.com/kava-labs/kava/x/committee/types"
communitytypes "github.com/kava-labs/kava/x/community/types"
earntypes "github.com/kava-labs/kava/x/earn/types"
@ -48,6 +49,7 @@ type Chain struct {
Auth authtypes.QueryClient
Bank banktypes.QueryClient
Cdp cdptypes.QueryClient
Committee committeetypes.QueryClient
Community communitytypes.QueryClient
Earn earntypes.QueryClient
@ -83,6 +85,7 @@ func NewChain(t *testing.T, details *runner.ChainDetails, fundedAccountMnemonic
chain.Auth = authtypes.NewQueryClient(grpcConn)
chain.Bank = banktypes.NewQueryClient(grpcConn)
chain.Cdp = cdptypes.NewQueryClient(grpcConn)
chain.Committee = committeetypes.NewQueryClient(grpcConn)
chain.Community = communitytypes.NewQueryClient(grpcConn)
chain.Earn = earntypes.NewQueryClient(grpcConn)

View File

@ -8,7 +8,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/kava-labs/kava/tests/e2e/contracts/greeter"
"github.com/kava-labs/kava/x/earn/types"
"github.com/kava-labs/kava/x/cdp/types"
evmutiltypes "github.com/kava-labs/kava/x/evmutil/types"
)
@ -41,13 +41,21 @@ func (suite *E2eTestSuite) InitKavaEvmData() {
}
suite.Kava.RegisterErc20(suite.DeployedErc20.Address)
// expect the erc20's cosmos denom to be a supported earn vault
_, err = suite.Kava.Earn.Vault(
context.Background(),
types.NewQueryVaultRequest(suite.DeployedErc20.CosmosDenom),
// expect the erc20's cosmos denom to be a supported cdp collateral type
cdpParams, err := suite.Kava.Cdp.Params(context.Background(), &types.QueryParamsRequest{})
suite.Require().NoError(err)
found = false
for _, cp := range cdpParams.Params.CollateralParams {
if cp.Denom == suite.DeployedErc20.CosmosDenom {
found = true
suite.DeployedErc20.CdpCollateralType = cp.Type
}
}
if !found {
panic(fmt.Sprintf(
"erc20's cosmos denom %s must be valid cdp collateral type",
suite.DeployedErc20.CosmosDenom),
)
if err != nil {
panic(fmt.Sprintf("failed to find earn vault with denom %s: %s", suite.DeployedErc20.CosmosDenom, err))
}
// deploy an example contract

View File

@ -33,11 +33,13 @@ const (
// The tests expect the following:
// - the funded account has a nonzero balance of the erc20
// - the erc20 is enabled for conversion to sdk.Coin
// - the corresponding sdk.Coin is enabled as an earn vault denom
// - the corresponding sdk.Coin is enabled as a cdp collateral type
// These requirements are checked in InitKavaEvmData().
type DeployedErc20 struct {
Address common.Address
CosmosDenom string
CdpCollateralType string
}
// E2eTestSuite is a testify test suite for running end-to-end integration tests on Kava.
@ -90,7 +92,7 @@ func (suite *E2eTestSuite) SetupSuite() {
suite.config = suiteConfig
suite.DeployedErc20 = DeployedErc20{
Address: common.HexToAddress(suiteConfig.KavaErc20Address),
// Denom is fetched in InitKavaEvmData()
// Denom & CdpCollateralType are fetched in InitKavaEvmData()
}
// setup the correct NodeRunner for the given config
@ -154,8 +156,6 @@ func (suite *E2eTestSuite) TearDownSuite() {
suite.cost.erc20BalanceAfter = suite.Kava.GetErc20Balance(suite.DeployedErc20.Address, whale.EvmAddress)
fmt.Println(suite.cost)
// TODO: track asset denoms & then return all funds to initial funding account.
// close all account request channels
suite.Kava.Shutdown()
if suite.Ibc != nil {

View File

@ -24,6 +24,7 @@ import (
var (
ErrSdkBroadcastTimeout = errors.New("timed out waiting for tx to be committed to block")
ErrUnsuccessfulTx = errors.New("tx committed but returned nonzero code")
)
type KavaMsgRequest struct {
@ -454,6 +455,9 @@ func WaitForSdkTxCommit(txClient txtypes.ServiceClient, txHash string, timeout t
break
}
txRes = res.TxResponse
if err == nil && txRes.Code != uint32(codes.OK) {
err = errorsmod.Wrapf(ErrUnsuccessfulTx, "code = %d; %s", txRes.Code, txRes.RawLog)
}
}
break
}