Skip to content

Commit

Permalink
test(evm): e2e tests configuration enhancements (#2184)
Browse files Browse the repository at this point in the history
* chore: changelog

* chore: cleanup

* chore: formatting
  • Loading branch information
onikonychev authored Jan 29, 2025
1 parent 57371ae commit 5d1f87b
Show file tree
Hide file tree
Showing 12 changed files with 155 additions and 129 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ needed to include double quotes around the hexadecimal string.
- [#2176](https://github.com/NibiruChain/nibiru/pull/2176) - tests(evm): add dirty state tests from code4rena audit
- [#2180](https://github.com/NibiruChain/nibiru/pull/2180) - fix(evm): apply gas consumption across the entire EVM codebase at `CallContractWithInput`
- [#2183](https://github.com/NibiruChain/nibiru/pull/2183) - fix(evm): bank keeper extension gas meter type
- [#2184](https://github.com/NibiruChain/nibiru/pull/2184) - test(evm): e2e tests configuration enhancements
-
#### Nibiru EVM | Before Audit 2 - 2024-12-06

Expand Down
2 changes: 2 additions & 0 deletions evm-e2e/.env_sample
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
JSON_RPC_ENDPOINT="http://127.0.0.1:8545"
MNEMONIC="guard cream sadness conduct invite crumble clock pudding hole grit liar hotel maid produce squeeze return argue turtle know drive eight casino maze host"
TEST_TIMEOUT=15000
TX_WAIT_TIMEOUT=5000
29 changes: 17 additions & 12 deletions evm-e2e/test/contract_infinite_loop_gas.test.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
import { describe, expect, it } from '@jest/globals';
import { toBigInt } from 'ethers';
import { deployContractInfiniteLoopGas } from './utils';
import { TEST_TIMEOUT } from './setup';

describe('Infinite loop gas contract', () => {
it('should fail due to out of gas error', async () => {
const contract = await deployContractInfiniteLoopGas();
it(
'should fail due to out of gas error',
async () => {
const contract = await deployContractInfiniteLoopGas();

expect(contract.counter()).resolves.toBe(toBigInt(0));
await expect(contract.counter()).resolves.toBe(toBigInt(0));

try {
const tx = await contract.forever({ gasLimit: 1e6 });
await tx.wait();
throw new Error('The transaction should have failed but did not.');
} catch (error) {
expect(error.message).toContain('transaction execution reverted');
}
try {
const tx = await contract.forever({ gasLimit: 1e6 });
await tx.wait();
throw new Error('The transaction should have failed but did not.');
} catch (error) {
expect(error.message).toContain('transaction execution reverted');
}

expect(contract.counter()).resolves.toBe(toBigInt(0));
}, 20e3);
await expect(contract.counter()).resolves.toBe(toBigInt(0));
},
TEST_TIMEOUT,
);
});
11 changes: 5 additions & 6 deletions evm-e2e/test/contract_send_nibi.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
*/
import { describe, expect, it } from '@jest/globals';
import { parseEther, toBigInt, Wallet } from 'ethers';
import { account, provider } from './setup';
import { account, provider, TEST_TIMEOUT, TX_WAIT_TIMEOUT } from './setup';
import { deployContractSendNibi } from './utils';

async function testSendNibi(method: 'sendViaTransfer' | 'sendViaSend' | 'sendViaCall', weiToSend: bigint) {
Expand All @@ -23,7 +23,7 @@ async function testSendNibi(method: 'sendViaTransfer' | 'sendViaSend' | 'sendVia
expect(recipientBalanceBefore).toEqual(BigInt(0));

const tx = await contract[method](recipient, { value: weiToSend });
const receipt = await tx.wait(1, 5e3);
const receipt = await tx.wait(1, TX_WAIT_TIMEOUT);

const tenPow12 = toBigInt(1e12);
const txCostMicronibi = weiToSend / tenPow12 + receipt.gasUsed;
Expand Down Expand Up @@ -52,14 +52,13 @@ async function testSendNibi(method: 'sendViaTransfer' | 'sendViaSend' | 'sendVia
}

describe('Send NIBI via smart contract', () => {
const TIMEOUT_MS = 20e3;
it(
'method sendViaTransfer',
async () => {
const weiToSend: bigint = toBigInt(5e12) * toBigInt(1e6);
await testSendNibi('sendViaTransfer', weiToSend);
},
TIMEOUT_MS,
TEST_TIMEOUT,
);

it(
Expand All @@ -68,7 +67,7 @@ describe('Send NIBI via smart contract', () => {
const weiToSend: bigint = toBigInt(100e12) * toBigInt(1e6);
await testSendNibi('sendViaSend', weiToSend);
},
TIMEOUT_MS,
TEST_TIMEOUT,
);

it(
Expand All @@ -77,6 +76,6 @@ describe('Send NIBI via smart contract', () => {
const weiToSend: bigint = toBigInt(100e12) * toBigInt(1e6);
await testSendNibi('sendViaCall', weiToSend);
},
TIMEOUT_MS,
TEST_TIMEOUT,
);
});
6 changes: 3 additions & 3 deletions evm-e2e/test/debug_queries.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { describe, expect, it, beforeAll } from '@jest/globals';
import { TransactionReceipt, parseEther } from 'ethers';
import { provider } from './setup';
import { provider, TEST_TIMEOUT, TX_WAIT_TIMEOUT } from './setup';
import { alice, deployContractTestERC20, hexify } from './utils';
import { TestERC20__factory } from '../types';

Expand All @@ -18,14 +18,14 @@ describe('debug queries', () => {

// Execute some contract TX
const txResponse = await contract.transfer(alice, parseEther('0.01'));
await txResponse.wait(1, 5e3);
await txResponse.wait(1, TX_WAIT_TIMEOUT);

const receipt: TransactionReceipt = await provider.getTransactionReceipt(txResponse.hash);
txHash = txResponse.hash;
txIndex = txResponse.index;
blockNumber = receipt.blockNumber;
blockHash = receipt.blockHash;
}, 20e3);
}, TEST_TIMEOUT);

it('debug_traceBlockByNumber', async () => {
const traceResult = await provider.send('debug_traceBlockByNumber', [
Expand Down
34 changes: 19 additions & 15 deletions evm-e2e/test/erc20.test.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,29 @@
import { describe, expect, it } from '@jest/globals';
import { parseUnits, toBigInt, Wallet } from 'ethers';
import { account } from './setup';
import { account, TEST_TIMEOUT } from './setup';
import { deployContractTestERC20 } from './utils';

describe('ERC-20 contract tests', () => {
it('should send properly', async () => {
const contract = await deployContractTestERC20();
expect(contract.getAddress()).resolves.toBeDefined();
it(
'should send properly',
async () => {
const contract = await deployContractTestERC20();
expect(contract.getAddress()).resolves.toBeDefined();

const ownerInitialBalance = parseUnits('1000000', 18);
const alice = Wallet.createRandom();
const ownerInitialBalance = parseUnits('1000000', 18);
const alice = Wallet.createRandom();

expect(contract.balanceOf(account)).resolves.toEqual(ownerInitialBalance);
expect(contract.balanceOf(alice)).resolves.toEqual(toBigInt(0));
expect(contract.balanceOf(account)).resolves.toEqual(ownerInitialBalance);
expect(contract.balanceOf(alice)).resolves.toEqual(toBigInt(0));

// send to alice
const amountToSend = parseUnits('1000', 18); // contract tokens
let tx = await contract.transfer(alice, amountToSend);
await tx.wait();
// send to alice
const amountToSend = parseUnits('1000', 18); // contract tokens
let tx = await contract.transfer(alice, amountToSend);
await tx.wait();

expect(contract.balanceOf(account)).resolves.toEqual(ownerInitialBalance - amountToSend);
expect(contract.balanceOf(alice)).resolves.toEqual(amountToSend);
}, 20e3);
expect(contract.balanceOf(account)).resolves.toEqual(ownerInitialBalance - amountToSend);
expect(contract.balanceOf(alice)).resolves.toEqual(amountToSend);
},
TEST_TIMEOUT,
);
});
30 changes: 17 additions & 13 deletions evm-e2e/test/eth_queries.test.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
import { describe, expect, it, jest } from '@jest/globals';
import { parseEther, keccak256, AbiCoder } from 'ethers';
import { account, provider } from './setup';
import { parseEther, keccak256, AbiCoder, ethers } from 'ethers';
import { account, provider, TEST_TIMEOUT, TX_WAIT_TIMEOUT } from './setup';
import {
INTRINSIC_TX_GAS,
alice,
deployContractTestERC20,
deployContractSendNibi,
hexify,
sendTestNibi,
numberToHex,
} from './utils';

describe('eth queries', () => {
jest.setTimeout(15e3);
jest.setTimeout(TEST_TIMEOUT);

it('eth_accounts', async () => {
const accounts = await provider.listAccounts();
expect(accounts).not.toHaveLength(0);
expect(accounts).not.toBeNull();
});

it('eth_estimateGas', async () => {
Expand Down Expand Up @@ -54,7 +55,7 @@ describe('eth queries', () => {
});

it('eth_getBlockByNumber, eth_getBlockByHash', async () => {
const blockNumber = 1;
const blockNumber = 'latest';
const blockByNumber = await provider.send('eth_getBlockByNumber', [blockNumber, false]);
expect(blockByNumber).toBeDefined();
expect(blockByNumber).toHaveProperty('hash');
Expand All @@ -66,14 +67,14 @@ describe('eth queries', () => {
});

it('eth_getBlockTransactionCountByHash', async () => {
const blockNumber = 1;
const blockNumber = 'latest';
const block = await provider.send('eth_getBlockByNumber', [blockNumber, false]);
const txCount = await provider.send('eth_getBlockTransactionCountByHash', [block.hash]);
expect(parseInt(txCount)).toBeGreaterThanOrEqual(0);
});

it('eth_getBlockTransactionCountByNumber', async () => {
const blockNumber = 1;
const blockNumber = 'latest';
const txCount = await provider.send('eth_getBlockTransactionCountByNumber', [blockNumber]);
expect(parseInt(txCount)).toBeGreaterThanOrEqual(0);
});
Expand All @@ -86,11 +87,12 @@ describe('eth queries', () => {
});

it('eth_getFilterChanges', async () => {
const currentBlock = await provider.getBlockNumber();
// Deploy ERC-20 contract
const contract = await deployContractTestERC20();
const contractAddr = await contract.getAddress();
const filter = {
fromBlock: '0x1',
fromBlock: numberToHex(currentBlock),
address: contractAddr,
};
// Create the filter for a contract
Expand All @@ -99,7 +101,7 @@ describe('eth queries', () => {

// Execute some contract TX
const tx = await contract.transfer(alice, parseEther('0.01'));
await tx.wait(1, 5e3);
await tx.wait(1, TX_WAIT_TIMEOUT);
await new Promise((resolve) => setTimeout(resolve, 3000));

// Assert logs
Expand All @@ -114,16 +116,17 @@ describe('eth queries', () => {
});

it('eth_getFilterLogs', async () => {
const currentBlock = await provider.getBlockNumber();
// Deploy ERC-20 contract
const contract = await deployContractTestERC20();
const contractAddr = await contract.getAddress();
const filter = {
fromBlock: '0x1',
fromBlock: numberToHex(currentBlock),
address: contractAddr,
};
// Execute some contract TX
const tx = await contract.transfer(alice, parseEther('0.01'));
await tx.wait(1, 5e3);
await tx.wait(1, TX_WAIT_TIMEOUT);
await new Promise((resolve) => setTimeout(resolve, 3000));

// Create the filter for a contract
Expand All @@ -139,16 +142,17 @@ describe('eth queries', () => {
});

it('eth_getLogs', async () => {
const currentBlock = await provider.getBlockNumber();
// Deploy ERC-20 contract
const contract = await deployContractTestERC20();
const contractAddr = await contract.getAddress();
const filter = {
fromBlock: '0x1',
fromBlock: numberToHex(currentBlock),
address: contractAddr,
};
// Execute some contract TX
const tx = await contract.transfer(alice, parseEther('0.01'));
await tx.wait(1, 5e3);
await tx.wait(1, TX_WAIT_TIMEOUT);
await new Promise((resolve) => setTimeout(resolve, 3000));

// Assert logs
Expand Down
76 changes: 40 additions & 36 deletions evm-e2e/test/native_transfer.test.ts
Original file line number Diff line number Diff line change
@@ -1,45 +1,49 @@
import { describe, expect, it } from '@jest/globals';
import { parseEther, toBigInt } from 'ethers';
import { account, provider } from './setup';
import { account, provider, TEST_TIMEOUT, TX_WAIT_TIMEOUT } from './setup';
import { alice } from './utils';

describe('native transfer', () => {
it('simple transfer, balance check', async () => {
const amountToSend = toBigInt(5e12) * toBigInt(1e6); // unibi
const senderBalanceBefore = await provider.getBalance(account);
const recipientBalanceBefore = await provider.getBalance(alice);
expect(senderBalanceBefore).toBeGreaterThan(0);
expect(recipientBalanceBefore).toEqual(BigInt(0));
it(
'simple transfer, balance check',
async () => {
const amountToSend = toBigInt(5e12) * toBigInt(1e6); // unibi
const senderBalanceBefore = await provider.getBalance(account);
const recipientBalanceBefore = await provider.getBalance(alice);
expect(senderBalanceBefore).toBeGreaterThan(0);
expect(recipientBalanceBefore).toEqual(BigInt(0));

// Execute EVM transfer
const transaction = {
gasLimit: toBigInt(100e3),
to: alice,
value: amountToSend,
};
const txResponse = await account.sendTransaction(transaction);
await txResponse.wait(1, 10e3);
expect(txResponse).toHaveProperty('blockHash');
// Execute EVM transfer
const transaction = {
gasLimit: toBigInt(100e3),
to: alice,
value: amountToSend,
};
const txResponse = await account.sendTransaction(transaction);
await txResponse.wait(1, TX_WAIT_TIMEOUT);
expect(txResponse).toHaveProperty('blockHash');

const senderBalanceAfter = await provider.getBalance(account);
const recipientBalanceAfter = await provider.getBalance(alice);
const senderBalanceAfter = await provider.getBalance(account);
const recipientBalanceAfter = await provider.getBalance(alice);

// Assert balances with logging
const tenPow12 = toBigInt(1e12);
const gasUsed = transaction.gasLimit;
const txCostMicronibi = amountToSend / tenPow12 + gasUsed;
const txCostWei = txCostMicronibi * tenPow12;
const expectedSenderWei = senderBalanceBefore - txCostWei;
console.debug('DEBUG should send via transfer method %o:', {
senderBalanceBefore,
amountToSend,
expectedSenderWei,
senderBalanceAfter,
txResponse,
});
expect(recipientBalanceAfter).toEqual(amountToSend);
const delta = senderBalanceAfter - expectedSenderWei;
const deltaFromExpectation = delta >= 0 ? delta : -delta;
expect(deltaFromExpectation).toBeLessThan(parseEther('0.1'));
}, 20e3);
// Assert balances with logging
const tenPow12 = toBigInt(1e12);
const gasUsed = transaction.gasLimit;
const txCostMicronibi = amountToSend / tenPow12 + gasUsed;
const txCostWei = txCostMicronibi * tenPow12;
const expectedSenderWei = senderBalanceBefore - txCostWei;
console.debug('DEBUG should send via transfer method %o:', {
senderBalanceBefore,
amountToSend,
expectedSenderWei,
senderBalanceAfter,
txResponse,
});
expect(recipientBalanceAfter).toEqual(amountToSend);
const delta = senderBalanceAfter - expectedSenderWei;
const deltaFromExpectation = delta >= 0 ? delta : -delta;
expect(deltaFromExpectation).toBeLessThan(parseEther('0.1'));
},
TEST_TIMEOUT,
);
});
Loading

0 comments on commit 5d1f87b

Please sign in to comment.