Skip to content

Commit

Permalink
add full unit testing suite
Browse files Browse the repository at this point in the history
  • Loading branch information
fbac committed Oct 10, 2024
1 parent 445b5c3 commit ed0d764
Show file tree
Hide file tree
Showing 10 changed files with 1,101 additions and 220 deletions.
20 changes: 10 additions & 10 deletions e2e/e2etests/test_precompiles_bank.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"github.com/zeta-chain/node/e2e/runner"
"github.com/zeta-chain/node/e2e/utils"
"github.com/zeta-chain/node/precompiles/bank"
fungibletypes "github.com/zeta-chain/node/x/fungible/types"
)

func TestPrecompilesBank(r *runner.E2ERunner, args []string) {
Expand All @@ -21,6 +20,7 @@ func TestPrecompilesBank(r *runner.E2ERunner, args []string) {
higherBalanceAmount := big.NewInt(1001)
higherAllowanceAmount := big.NewInt(501)
spender := r.EVMAddress()
bankAddress := bank.ContractAddress

// Increase the gasLimit. It's required because of the gas consumed by precompiled functions.
previousGasLimit := r.ZEVMAuth.GasLimit
Expand All @@ -30,7 +30,7 @@ func TestPrecompilesBank(r *runner.E2ERunner, args []string) {

// Reset the allowance to 0; this is needed when running upgrade tests where
// this test runs twice.
tx, err := r.ERC20ZRC20.Approve(r.ZEVMAuth, fungibletypes.ModuleAddressZEVM, big.NewInt(0))
tx, err := r.ERC20ZRC20.Approve(r.ZEVMAuth, bankAddress, big.NewInt(0))
require.NoError(r, err)
receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout)
utils.RequireTxSuccessful(r, receipt, "Resetting allowance failed")
Expand Down Expand Up @@ -60,7 +60,7 @@ func TestPrecompilesBank(r *runner.E2ERunner, args []string) {
require.Equal(r, uint64(0), cosmosBalance.Uint64(), "spender cosmos coin balance should be 0")

// Approve allowance of 500 ERC20ZRC20 tokens for the bank contract. Should pass.
tx, err := r.ERC20ZRC20.Approve(r.ZEVMAuth, fungibletypes.ModuleAddressZEVM, depositAmount)
tx, err := r.ERC20ZRC20.Approve(r.ZEVMAuth, bankAddress, depositAmount)
require.NoError(r, err)
receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout)
utils.RequireTxSuccessful(r, receipt, "Approve ETHZRC20 bank allowance tx failed")
Expand All @@ -73,7 +73,7 @@ func TestPrecompilesBank(r *runner.E2ERunner, args []string) {
utils.RequiredTxFailed(r, receipt, "Depositting an amount higher than allowed should fail")

// Approve allowance of 1000 ERC20ZRC20 tokens.
tx, err = r.ERC20ZRC20.Approve(r.ZEVMAuth, fungibletypes.ModuleAddressZEVM, big.NewInt(1e3))
tx, err = r.ERC20ZRC20.Approve(r.ZEVMAuth, bankAddress, big.NewInt(1e3))
require.NoError(r, err)
receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout)
utils.RequireTxSuccessful(r, receipt, "Approve ETHZRC20 bank allowance tx failed")
Expand Down Expand Up @@ -104,7 +104,7 @@ func TestPrecompilesBank(r *runner.E2ERunner, args []string) {
require.Equal(r, uint64(500), cosmosBalance.Uint64(), "spender cosmos coin balance should be 500")

// Bank: ERC20ZRC20 balance should be 500 tokens locked.
bankZRC20Balance, err := r.ERC20ZRC20.BalanceOf(&bind.CallOpts{Context: r.Ctx}, fungibletypes.ModuleAddressZEVM)
bankZRC20Balance, err := r.ERC20ZRC20.BalanceOf(&bind.CallOpts{Context: r.Ctx}, bankAddress)
require.NoError(r, err, "Call ERC20ZRC20.BalanceOf")
require.Equal(r, uint64(500), bankZRC20Balance.Uint64(), "bank ERC20ZRC20 balance should be 500")

Expand All @@ -116,7 +116,7 @@ func TestPrecompilesBank(r *runner.E2ERunner, args []string) {

// Bank: ERC20ZRC20 balance should be 500 tokens locked after a failed withdraw.
// No tokens should be unlocked with a failed withdraw.
bankZRC20Balance, err = r.ERC20ZRC20.BalanceOf(&bind.CallOpts{Context: r.Ctx}, fungibletypes.ModuleAddressZEVM)
bankZRC20Balance, err = r.ERC20ZRC20.BalanceOf(&bind.CallOpts{Context: r.Ctx}, bankAddress)
require.NoError(r, err, "Call ERC20ZRC20.BalanceOf")
require.Equal(r, uint64(500), bankZRC20Balance.Uint64(), "bank ERC20ZRC20 balance should be 500")

Expand Down Expand Up @@ -144,7 +144,7 @@ func TestPrecompilesBank(r *runner.E2ERunner, args []string) {
require.Equal(r, uint64(1000), zrc20Balance.Uint64(), "spender ERC20ZRC20 balance should be 1000")

// Bank: ERC20ZRC20 balance should be 0 tokens locked.
bankZRC20Balance, err = r.ERC20ZRC20.BalanceOf(&bind.CallOpts{Context: r.Ctx}, fungibletypes.ModuleAddressZEVM)
bankZRC20Balance, err = r.ERC20ZRC20.BalanceOf(&bind.CallOpts{Context: r.Ctx}, bankAddress)
require.NoError(r, err, "Call ERC20ZRC20.BalanceOf")
require.Equal(r, uint64(0), bankZRC20Balance.Uint64(), "bank ERC20ZRC20 balance should be 0")
}
Expand All @@ -159,7 +159,7 @@ func TestPrecompilesBankNonZRC20(r *runner.E2ERunner, args []string) {
r.ZEVMAuth.GasLimit = previousGasLimit
}()

spender, bankAddr := r.EVMAddress(), fungibletypes.ModuleAddressZEVM
spender, bankAddress := r.EVMAddress(), bank.ContractAddress

// Create a bank contract caller.
bankContract, err := bank.NewIBank(bank.ContractAddress, r.ZEVMClient)
Expand All @@ -180,13 +180,13 @@ func TestPrecompilesBankNonZRC20(r *runner.E2ERunner, args []string) {
)

// Allow the bank contract to spend 25 WZeta tokens.
tx, err := r.WZeta.Approve(r.ZEVMAuth, bankAddr, big.NewInt(25))
tx, err := r.WZeta.Approve(r.ZEVMAuth, bankAddress, big.NewInt(25))
require.NoError(r, err, "Error approving allowance for bank contract")
receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout)
require.EqualValues(r, uint64(1), receipt.Status, "approve allowance tx failed")

// Check the allowance of the bank in WZeta tokens. Should be 25.
allowance, err := r.WZeta.Allowance(&bind.CallOpts{Context: r.Ctx}, spender, bankAddr)
allowance, err := r.WZeta.Allowance(&bind.CallOpts{Context: r.Ctx}, spender, bankAddress)
require.NoError(r, err, "Error retrieving bank allowance")
require.EqualValues(r, uint64(25), allowance.Uint64(), "Error allowance for bank contract")

Expand Down
20 changes: 10 additions & 10 deletions e2e/e2etests/test_precompiles_bank_through_contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ import (
"github.com/zeta-chain/node/e2e/runner"
"github.com/zeta-chain/node/e2e/utils"
"github.com/zeta-chain/node/precompiles/bank"
fungibletypes "github.com/zeta-chain/node/x/fungible/types"
)

func TestPrecompilesBankThroughContract(r *runner.E2ERunner, args []string) {
require.Len(r, args, 0, "No arguments expected")

spender := r.EVMAddress()
bankAddress := bank.ContractAddress
zrc20Address := r.ERC20ZRC20Addr
oneThousand := big.NewInt(1e3)
oneThousandOne := big.NewInt(1001)
Expand Down Expand Up @@ -60,7 +60,7 @@ func TestPrecompilesBankThroughContract(r *runner.E2ERunner, args []string) {
// Check initial balances.
balanceShouldBe(r, 0, checkCosmosBalance(r, testBank, zrc20Address, spender))
balanceShouldBe(r, 1000, checkZRC20Balance(r, spender))
balanceShouldBe(r, 0, checkZRC20Balance(r, fungibletypes.ModuleAddressZEVM))
balanceShouldBe(r, 0, checkZRC20Balance(r, bankAddress))

// Deposit without previous alllowance should fail.
receipt = depositThroughTestBank(r, testBank, zrc20Address, oneThousand)
Expand All @@ -69,10 +69,10 @@ func TestPrecompilesBankThroughContract(r *runner.E2ERunner, args []string) {
// Check balances, should be the same.
balanceShouldBe(r, 0, checkCosmosBalance(r, testBank, zrc20Address, spender))
balanceShouldBe(r, 1000, checkZRC20Balance(r, spender))
balanceShouldBe(r, 0, checkZRC20Balance(r, fungibletypes.ModuleAddressZEVM))
balanceShouldBe(r, 0, checkZRC20Balance(r, bankAddress))

// Allow 500 ZRC20 to bank precompile.
approveAllowance(r, fungibletypes.ModuleAddressZEVM, fiveHundred)
approveAllowance(r, bankAddress, fiveHundred)

// Deposit 501 ERC20ZRC20 tokens to the bank contract, through TestBank.
// It's higher than allowance but lower than balance, should fail.
Expand All @@ -82,10 +82,10 @@ func TestPrecompilesBankThroughContract(r *runner.E2ERunner, args []string) {
// Balances shouldn't change.
balanceShouldBe(r, 0, checkCosmosBalance(r, testBank, zrc20Address, spender))
balanceShouldBe(r, 1000, checkZRC20Balance(r, spender))
balanceShouldBe(r, 0, checkZRC20Balance(r, fungibletypes.ModuleAddressZEVM))
balanceShouldBe(r, 0, checkZRC20Balance(r, bankAddress))

// Allow 1000 ZRC20 to bank precompile.
approveAllowance(r, fungibletypes.ModuleAddressZEVM, oneThousand)
approveAllowance(r, bankAddress, oneThousand)

// Deposit 1001 ERC20ZRC20 tokens to the bank contract.
// It's higher than spender balance but within approved allowance, should fail.
Expand All @@ -95,7 +95,7 @@ func TestPrecompilesBankThroughContract(r *runner.E2ERunner, args []string) {
// Balances shouldn't change.
balanceShouldBe(r, 0, checkCosmosBalance(r, testBank, zrc20Address, spender))
balanceShouldBe(r, 1000, checkZRC20Balance(r, spender))
balanceShouldBe(r, 0, checkZRC20Balance(r, fungibletypes.ModuleAddressZEVM))
balanceShouldBe(r, 0, checkZRC20Balance(r, bankAddress))

// Deposit 500 ERC20ZRC20 tokens to the bank contract, it's within allowance and balance. Should pass.
receipt = depositThroughTestBank(r, testBank, zrc20Address, fiveHundred)
Expand All @@ -104,7 +104,7 @@ func TestPrecompilesBankThroughContract(r *runner.E2ERunner, args []string) {
// Balances should be transferred. Bank now locks 500 ZRC20 tokens.
balanceShouldBe(r, 500, checkCosmosBalance(r, testBank, zrc20Address, spender))
balanceShouldBe(r, 500, checkZRC20Balance(r, spender))
balanceShouldBe(r, 500, checkZRC20Balance(r, fungibletypes.ModuleAddressZEVM))
balanceShouldBe(r, 500, checkZRC20Balance(r, bankAddress))

// Check the deposit event.
eventDeposit, err := bankPrecompileCaller.ParseDeposit(*receipt.Logs[0])
Expand All @@ -120,7 +120,7 @@ func TestPrecompilesBankThroughContract(r *runner.E2ERunner, args []string) {
// Balances shouldn't change.
balanceShouldBe(r, 500, checkCosmosBalance(r, testBank, zrc20Address, spender))
balanceShouldBe(r, 500, checkZRC20Balance(r, spender))
balanceShouldBe(r, 500, checkZRC20Balance(r, fungibletypes.ModuleAddressZEVM))
balanceShouldBe(r, 500, checkZRC20Balance(r, bankAddress))

// Try to withdraw 500 ERC20ZRC20 tokens. Should pass.
receipt = withdrawThroughTestBank(r, testBank, zrc20Address, fiveHundred)
Expand All @@ -129,7 +129,7 @@ func TestPrecompilesBankThroughContract(r *runner.E2ERunner, args []string) {
// Balances should be reverted to initial state.
balanceShouldBe(r, 0, checkCosmosBalance(r, testBank, zrc20Address, spender))
balanceShouldBe(r, 1000, checkZRC20Balance(r, spender))
balanceShouldBe(r, 0, checkZRC20Balance(r, fungibletypes.ModuleAddressZEVM))
balanceShouldBe(r, 0, checkZRC20Balance(r, bankAddress))

// Check the withdraw event.
eventWithdraw, err := bankPrecompileCaller.ParseWithdraw(*receipt.Logs[0])
Expand Down
4 changes: 2 additions & 2 deletions precompiles/bank/method_deposit.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
// The caller cosmos address will be calculated from the EVM caller address. by executing toAddr := sdk.AccAddress(addr.Bytes()).
// This function can be think of a permissionless way of minting cosmos coins.
// This is how deposit works:
// - The caller has to allow the Fungible ZEVM address to spend a certain amount ZRC20 token coins on its behalf. This is mandatory.
// - The caller has to allow the bank precompile address to spend a certain amount ZRC20 token coins on its behalf. This is mandatory.
// - Then, the caller calls deposit(ZRC20 address, amount), to deposit the amount and receive cosmos coins.
// - The bank will check there's enough balance, the caller is not a blocked address, and the token is a not paused ZRC20.
// - Then the cosmos coins "zrc20/0x12345" will be minted and sent to the caller's cosmos address.
Expand Down Expand Up @@ -100,7 +100,7 @@ func (c *Contract) deposit(
}

// 2. Effect: subtract balance.
if err := c.fungibleKeeper.LockZRC20(ctx, c.zrc20ABI, zrc20Addr, caller, amount); err != nil {
if err := c.fungibleKeeper.LockZRC20(ctx, c.zrc20ABI, zrc20Addr, caller, c.Address(), amount); err != nil {
return nil, &ptypes.ErrUnexpected{
When: "LockZRC20InBank",
Got: err.Error(),
Expand Down
2 changes: 1 addition & 1 deletion precompiles/bank/method_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ func allowBank(t *testing.T, ts testSuite, amount *big.Int) {
fungibletypes.ModuleAddressZEVM,
ts.zrc20Address,
"approve",
[]interface{}{fungibletypes.ModuleAddressZEVM, amount},
[]interface{}{ts.bankContract.Address(), amount},
)
require.NoError(t, err, "error allowing bank to spend ZRC20 tokens")

Expand Down
6 changes: 3 additions & 3 deletions precompiles/bank/method_withdraw.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ func (c *Contract) withdraw(
return nil, err
}

// Check if fungible address has enough ZRC20 balance.
if err := c.fungibleKeeper.CheckFungibleZRC20Balance(ctx, c.zrc20ABI, zrc20Addr, amount); err != nil {
// Check if bank address has enough ZRC20 balance.
if err := c.fungibleKeeper.CheckZRC20Balance(ctx, c.zrc20ABI, zrc20Addr, c.Address(), amount); err != nil {
return nil, &ptypes.ErrInsufficientBalance{
Requested: amount.String(),
Got: err.Error(),
Expand All @@ -108,7 +108,7 @@ func (c *Contract) withdraw(
}

// 3. Interactions: send ZRC20.
if err := c.fungibleKeeper.UnlockZRC20(ctx, c.zrc20ABI, zrc20Addr, caller, amount); err != nil {
if err := c.fungibleKeeper.UnlockZRC20(ctx, c.zrc20ABI, zrc20Addr, caller, c.Address(), amount); err != nil {
return nil, &ptypes.ErrUnexpected{
When: "UnlockZRC20InBank",
Got: err.Error(),
Expand Down
Loading

0 comments on commit ed0d764

Please sign in to comment.