Skip to content

Commit

Permalink
test: Add auto-generating basic abi tests for solidity interfaces (#2018
Browse files Browse the repository at this point in the history
)

* chore: Prefer equal to eq matcher

The equal matcher is a bit clearer and more consistent.

* chore: Rename viem extension and add deploy

This moves the viem extension to a more clear place and adds viem
support for deploy contract on kvtool.

* chore: Fix the viem extensions path

This was changed in a previous commit, but forgot to add to the hardhat
config.

* chore: Add abitype explicit dependency

This is used by viem and required by the added test helpers as well as
typing for using ABI artifacts.

* test: Document EOA account call behavior

These tests assert and document the behavior of empty and eoa accounts
with value when called by external transactions with or without data.

In addition, they assert the gas usage is as expected and only depedent
on the base transaction cost plus calldata cost since no code is
executed.

* test: Add abi basic tests based on sol interfaces

These tests are added to exercise solidity function ABI's for function
and special function calling.

This is in preperation for expanding these tests to work against
stateful precompiles, ensuring that precompile contracts respect ABI
function and special function calling conventions.

These tests also serve to increase the test coverage of the Kava EVM
and document behavior for future code readers.

* chore: Remove unused imports

These were copied from the empty account tests but usage was removed.

* chore: Add solhint to CI and fix CI lint

Solhint previously failed due to no contracts, so this adds solhint to
CI now that contracts exist.

In addition, now that tyepscript uses abitypes from compiled contracts,
hardhat compile needs to be run before typescript lint.

* chore: format fixes for function parethesis

A common typo on my part that prettier keeps catching.

* chore: Explain throwOnTransactionFailures setting

This adds a comment to explain that this setting is required for
hardhat-viem to not throw an error when sending transactions that will
revert to match kava chain behavior.

* chore: Remove outdated comment

This removes a comment reference to the tseslint recommended config that
is not needed as we are staying with stricter settings.

* lint: Add eqeqeq smart validation and fix ==

This adds a linter for smart validation of === vs ==.  The linter was
verified to fail the comparison in this commit and then verified it
passes after the change from == to ===.

* chore: Add stricter settings for tsconfig

This adds noFallthroughCasesInSwitch for switch statements and turns on
isolatedModules.

* ci: Target the local build image for e2e-evm

This sets the KAVA_TAG to correctly target the image built locally in CI
when running e2e-evm tests for kvtool testnet up and down.

* doc: Add act cmds for running e2e-evm CI jobs

This documents the commands for using act to run the github CI jobs
related to e2e-evm locally for lint and e2e tests.

* lint: Fix readme prettier formatting

I guess double spaces between sentances are not liked by prettier.

* ci: Add explicit compile step to fix race cond

There is a race condition between the typechecking and compiler so we
add an explicit compile step here to ensure the race is not hit.

* test: Add empty account creation transaction

This adds a test that creates an account via a transaction with non-zero
value.  We test that the account has a balance (is created) and that the
gas charged is the 21000 instrinsic.
  • Loading branch information
nddeluca authored Sep 20, 2024
1 parent 8ac4c5d commit ee4fc56
Show file tree
Hide file tree
Showing 17 changed files with 844 additions and 19 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/ci-default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ jobs:
run: make docker-build test-e2e
test-e2e-evm:
runs-on: ubuntu-latest
env:
KAVA_TAG: local
steps:
- name: Checkout current commit
uses: actions/checkout@v4
Expand All @@ -58,6 +60,9 @@ jobs:
- name: Install npm dependencies
run: npm install
working-directory: tests/e2e-evm
- name: Run test suite against hardhat network
run: npm run compile
working-directory: tests/e2e-evm
- name: Run test suite against hardhat network
run: npm run test-hardhat
working-directory: tests/e2e-evm
Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/ci-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ jobs:
- name: Install npm dependencies
run: npm install
working-directory: tests/e2e-evm
- name: Run solhint
run: npm run solhint
working-directory: tests/e2e-evm
- name: Compile contracts and create artifcats
run: npm run compile
working-directory: tests/e2e-evm
- name: Run linter
run: npm run lint
working-directory: tests/e2e-evm
Expand Down
11 changes: 11 additions & 0 deletions tests/e2e-evm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,14 @@ npx hardhat test --network hardhat
```
npx hardhat test --network kvtool
```

## Running CI Locally

With act installed, the following commands will run the lint and e2e CI jobs locally.

```
act -W '.github/workflows/ci-lint.yml' -j e2e-evm-lint
act -W '.github/workflows/ci-default.yml' -j test-e2e-evm --bind
```

The `--bind` flag is required for volume mounts of docker containers correctly mount. Without this flag, volumes are mounted as an empty directory.
78 changes: 78 additions & 0 deletions tests/e2e-evm/contracts/ABI_BasicTests.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// solhint-disable one-contract-per-file
// solhint-disable no-empty-blocks
// solhint-disable payable-fallback

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

//
// Normal noop functions only with nonpayable, payable, view, and pure modifiers
//
interface NoopNoReceiveNoFallback {
function noopNonpayable() external;
function noopPayable() external payable;
function noopView() external view;
function noopPure() external pure;
}
contract NoopNoReceiveNoFallbackMock is NoopNoReceiveNoFallback {
function noopNonpayable() external {}
function noopPayable() external payable {}
function noopView() external view {}
function noopPure() external pure {}
}

//
// Added receive function (always payable)
//
interface NoopReceiveNoFallback is NoopNoReceiveNoFallback {
receive() external payable;
}
contract NoopReceiveNoFallbackMock is NoopReceiveNoFallback, NoopNoReceiveNoFallbackMock {
receive() external payable {}
}

//
// Added receive function and payable fallback
//
interface NoopReceivePayableFallback is NoopNoReceiveNoFallback {
receive() external payable;
fallback() external payable;
}
contract NoopReceivePayableFallbackMock is NoopReceivePayableFallback, NoopNoReceiveNoFallbackMock {
receive() external payable {}
fallback() external payable {}
}

//
// Added receive function and non-payable fallback
//
interface NoopReceiveNonpayableFallback is NoopNoReceiveNoFallback {
receive() external payable;
fallback() external;
}
contract NoopReceiveNonpayableFallbackMock is NoopReceiveNonpayableFallback, NoopNoReceiveNoFallbackMock {
receive() external payable {}
fallback() external {}
}

//
// Added payable fallback and no receive function
//
// solc-ignore-next-line missing-receive
interface NoopNoReceivePayableFallback is NoopNoReceiveNoFallback {
fallback() external payable;
}
// solc-ignore-next-line missing-receive
contract NoopNoReceivePayableFallbackMock is NoopNoReceivePayableFallback, NoopNoReceiveNoFallbackMock {
fallback() external payable {}
}

//
// Added non-payable fallback and no receive function
//
interface NoopNoReceiveNonpayableFallback is NoopNoReceiveNoFallback {
fallback() external;
}
contract NoopNoReceiveNonpayableFallbackMock is NoopNoReceiveNonpayableFallback, NoopNoReceiveNoFallbackMock {
fallback() external {}
}
6 changes: 5 additions & 1 deletion tests/e2e-evm/eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ import tseslint from 'typescript-eslint';

export default tseslint.config(
eslint.configs.recommended,
//...tseslint.configs.recommendedTypeChecked,
{
rules: {
eqeqeq: ["error", "smart"],
},
},
...tseslint.configs.strictTypeChecked,
...tseslint.configs.stylisticTypeChecked,
{
Expand Down
8 changes: 7 additions & 1 deletion tests/e2e-evm/hardhat.config.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { HardhatUserConfig, extendEnvironment } from "hardhat/config";
import "@nomicfoundation/hardhat-viem";
import { parseEther } from "viem";
import { extendViem } from "./test/extend";
import { extendViem } from "./test/extensions/viem";
import chai from "chai";
import chaiAsPromised from "chai-as-promised";
import "hardhat-ignore-warnings";

//
// Chai setup
Expand Down Expand Up @@ -56,6 +57,11 @@ const config: HardhatUserConfig = {
chainId: 31337, // The default hardhat network chain id
hardfork: "berlin", // The current hardfork of kava mainnet
accounts: accounts,
//
// This is required for hardhat-viem to have the same behavior
// for reverted transactions as on Kava.
//
throwOnTransactionFailures: false,
},
kvtool: {
chainId: 8888, // The evm chain id of the kvtool network
Expand Down
Loading

0 comments on commit ee4fc56

Please sign in to comment.