Skip to content

Commit

Permalink
test(e2e): update kvtool & e2e tests (#1659)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
pirtleshell authored Aug 2, 2023
1 parent 667b6d0 commit 839dc80
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 50 deletions.
11 changes: 7 additions & 4 deletions tests/e2e/.env
Original file line number Diff line number Diff line change
Expand Up @@ -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
11 changes: 7 additions & 4 deletions tests/e2e/.env.live-network-example
Original file line number Diff line number Diff line change
Expand Up @@ -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
59 changes: 33 additions & 26 deletions tests/e2e/e2e_evm_contracts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
Expand All @@ -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
Expand All @@ -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)
Expand All @@ -158,38 +162,41 @@ 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(),
depositor.EvmAddress.Hex(),
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")
}
2 changes: 1 addition & 1 deletion tests/e2e/kvtool
Submodule kvtool updated 67 files
+8 −0 Makefile
+1 −1 README.md
+4 −0 cmd/root.go
+14 −1 cmd/testnet/dc.go
+44 −0 cmd/testnet/root.go
+95 −146 config/generate/genesis/cdp.params.collateral_params.json
+2 −2 config/generate/genesis/evm.accounts.json
+175 −0 config/generate/genesis/evm.params.eip712_allowed_msgs.json
+23 −13 config/generate/genesis/generate-kava-genesis.sh
+209 −101 config/generate/genesis/hard.params.money_markets.json
+246 −241 config/generate/genesis/incentive.params.json
+261 −169 config/generate/genesis/pricefeed.json
+35 −10 config/generate/genesis/swap.json
+4 −4 config/templates/ibcchain/master/initstate/.kava/config/app.toml
+3 −3 config/templates/kava/master/initstate/.kava/config/app.toml
+937 −809 config/templates/kava/master/initstate/.kava/config/genesis.json
+1 −1 config/templates/kava/master/initstate/.kava/config/gentx/gentx-461d9761df5db0a112407ca8a82f1774ef2dbaa3.json
+24 −0 config/templates/kava/v0.24/docker-compose.yaml
+339 −0 config/templates/kava/v0.24/initstate/.kava/config/app.toml
+17 −0 config/templates/kava/v0.24/initstate/.kava/config/client.toml
+471 −0 config/templates/kava/v0.24/initstate/.kava/config/config.toml
+3,801 −0 config/templates/kava/v0.24/initstate/.kava/config/genesis.json
+1 −0 config/templates/kava/v0.24/initstate/.kava/config/gentx/gentx-461d9761df5db0a112407ca8a82f1774ef2dbaa3.json
+16 −0 config/templates/kava/v0.24/initstate/.kava/config/init-data-directory.sh
+1 −0 config/templates/kava/v0.24/initstate/.kava/config/node_key.json
+11 −0 config/templates/kava/v0.24/initstate/.kava/config/priv_validator_key.json
+5 −0 config/templates/kava/v0.24/initstate/.kava/config/priv_validator_state.json.example
+1 −0 config/templates/kava/v0.24/initstate/.kava/keyring-test/03db6b11f47d074a532b9eb8a98ab7ada5845087.address
+1 −0 config/templates/kava/v0.24/initstate/.kava/keyring-test/1448b9047aecf1f3a1c778b49af84586f88f14fa.address
+1 −0 config/templates/kava/v0.24/initstate/.kava/keyring-test/1c73b6247855552c246549488c46a258434398dc.address
+1 −0 config/templates/kava/v0.24/initstate/.kava/keyring-test/206417edf50903e8ddc85e1ed458cfc946323738.address
+1 −0 config/templates/kava/v0.24/initstate/.kava/keyring-test/24d2a5743eacb429fe8f8f69a22a26a41691bfae.address
+1 −0 config/templates/kava/v0.24/initstate/.kava/keyring-test/4462e7eef5dcbffbf651255b8759c0e190e1efa5.address
+1 −0 config/templates/kava/v0.24/initstate/.kava/keyring-test/4b92edaf4ce0531d978c0b61ce62ad474e1a357f.address
+1 −0 config/templates/kava/v0.24/initstate/.kava/keyring-test/5d5ace45598bca115f6d9c7a0c4bf2f16e53fb41.address
+1 −0 config/templates/kava/v0.24/initstate/.kava/keyring-test/77057b4d493cc19574239b97195a4c60cbbf37f6.address
+1 −0 config/templates/kava/v0.24/initstate/.kava/keyring-test/7bbf300890857b8c241b219c6a489431669b3afa.address
+1 −0 config/templates/kava/v0.24/initstate/.kava/keyring-test/83a9586900f6bb8dc69f86b74c3ec32c5b05a077.address
+1 −0 config/templates/kava/v0.24/initstate/.kava/keyring-test/91659f27507b356f376866b94b507c53d49a2530.address
+1 −0 config/templates/kava/v0.24/initstate/.kava/keyring-test/a2f728f997f62f47d4262a70947f6c36885df9fa.address
+1 −0 config/templates/kava/v0.24/initstate/.kava/keyring-test/a8290eb8cd32c3d0d0d482052f32b00c7989e25f.address
+1 −0 config/templates/kava/v0.24/initstate/.kava/keyring-test/b7fb577df8c33dc3d319db211214feb82cfea70c.address
+1 −0 config/templates/kava/v0.24/initstate/.kava/keyring-test/bridge_relayer.info
+1 −0 config/templates/kava/v0.24/initstate/.kava/keyring-test/cd9686908f12a2004dbaf4e1103122425126d0d9.address
+1 −0 config/templates/kava/v0.24/initstate/.kava/keyring-test/committee.info
+1 −0 config/templates/kava/v0.24/initstate/.kava/keyring-test/deputy-bnb-cold.info
+1 −0 config/templates/kava/v0.24/initstate/.kava/keyring-test/deputy-bnb-hot.info
+1 −0 config/templates/kava/v0.24/initstate/.kava/keyring-test/deputy-btcb-cold.info
+1 −0 config/templates/kava/v0.24/initstate/.kava/keyring-test/deputy-btcb-hot.info
+1 −0 config/templates/kava/v0.24/initstate/.kava/keyring-test/deputy-busd-cold.info
+1 −0 config/templates/kava/v0.24/initstate/.kava/keyring-test/deputy-busd-hot.info
+1 −0 config/templates/kava/v0.24/initstate/.kava/keyring-test/deputy-xrpb-cold.info
+1 −0 config/templates/kava/v0.24/initstate/.kava/keyring-test/deputy-xrpb-hot.info
+1 −0 config/templates/kava/v0.24/initstate/.kava/keyring-test/ea30c5bfcbc39eb47f8fbedcdce213e182a236b4.address
+1 −0 config/templates/kava/v0.24/initstate/.kava/keyring-test/ee119aaf0cba620d26f48a50eef7cc802af730da.address
+1 −0 config/templates/kava/v0.24/initstate/.kava/keyring-test/f45ca10947f423acba73b26bb976709aef39c05e.address
+1 −0 config/templates/kava/v0.24/initstate/.kava/keyring-test/generic-0.info
+1 −0 config/templates/kava/v0.24/initstate/.kava/keyring-test/generic-1.info
+1 −0 config/templates/kava/v0.24/initstate/.kava/keyring-test/generic-2.info
+1 −0 config/templates/kava/v0.24/initstate/.kava/keyring-test/oracle.info
+1 −0 config/templates/kava/v0.24/initstate/.kava/keyring-test/user.info
+1 −0 config/templates/kava/v0.24/initstate/.kava/keyring-test/validator.info
+1 −0 config/templates/kava/v0.24/initstate/.kava/keyring-test/vesting-periodic.info
+1 −0 config/templates/kava/v0.24/initstate/.kava/keyring-test/whale.info
+1 −0 config/templates/kava/v0.24/initstate/.kava/keyring-test/whale2.info
+2 −2 go.mod
+4 −4 go.sum
15 changes: 12 additions & 3 deletions tests/e2e/testutil/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)

Expand Down
3 changes: 3 additions & 0 deletions tests/e2e/testutil/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand Down
24 changes: 16 additions & 8 deletions tests/e2e/testutil/init_evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand Down Expand Up @@ -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),
)
if err != nil {
panic(fmt.Sprintf("failed to find earn vault with denom %s: %s", suite.DeployedErc20.CosmosDenom, err))
// 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),
)
}

// deploy an example contract
Expand Down
8 changes: 4 additions & 4 deletions tests/e2e/testutil/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand Down
4 changes: 4 additions & 0 deletions tests/util/sdksigner.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
}
Expand Down

0 comments on commit 839dc80

Please sign in to comment.