From 38420951b65ea9c9ee3fdb845ff4349fb97ece16 Mon Sep 17 00:00:00 2001 From: HuangYi Date: Sat, 24 Jul 2021 11:22:32 +0800 Subject: [PATCH 1/3] add exception revert test case --- .../suites/exception/contracts/TestRevert.sol | 34 +++++++++++++++++++ .../exception/contracts/test/Migrations.sol | 19 +++++++++++ .../migrations/1_initial_migration.js | 5 +++ tests/solidity/suites/exception/package.json | 15 ++++++++ tests/solidity/suites/exception/test/.gitkeep | 0 .../solidity/suites/exception/test/revert.js | 31 +++++++++++++++++ .../suites/exception/truffle-config.js | 17 ++++++++++ 7 files changed, 121 insertions(+) create mode 100644 tests/solidity/suites/exception/contracts/TestRevert.sol create mode 100644 tests/solidity/suites/exception/contracts/test/Migrations.sol create mode 100644 tests/solidity/suites/exception/migrations/1_initial_migration.js create mode 100644 tests/solidity/suites/exception/package.json create mode 100644 tests/solidity/suites/exception/test/.gitkeep create mode 100644 tests/solidity/suites/exception/test/revert.js create mode 100644 tests/solidity/suites/exception/truffle-config.js diff --git a/tests/solidity/suites/exception/contracts/TestRevert.sol b/tests/solidity/suites/exception/contracts/TestRevert.sol new file mode 100644 index 0000000000..aa3e7af6a7 --- /dev/null +++ b/tests/solidity/suites/exception/contracts/TestRevert.sol @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +contract State { + uint256 a = 0; + function set(uint256 input) public { + a = input; + require(a < 10); + } + function force_set(uint256 input) public { + a = input; + } + function query() public view returns(uint256) { + return a; + } +} + +contract TestRevert { + State state; + constructor() { + state = new State(); + } + function try_set(uint256 input) public { + try state.set(input) { + } catch (bytes memory) { + } + } + function set(uint256 input) public { + state.force_set(input); + } + function query() public view returns(uint256) { + return state.query(); + } +} diff --git a/tests/solidity/suites/exception/contracts/test/Migrations.sol b/tests/solidity/suites/exception/contracts/test/Migrations.sol new file mode 100644 index 0000000000..ef49fe5af4 --- /dev/null +++ b/tests/solidity/suites/exception/contracts/test/Migrations.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +contract Migrations { + address public owner = msg.sender; + uint public last_completed_migration; + + modifier restricted() { + require( + msg.sender == owner, + "This function is restricted to the contract's owner" + ); + _; + } + + function setCompleted(uint completed) public restricted { + last_completed_migration = completed; + } +} diff --git a/tests/solidity/suites/exception/migrations/1_initial_migration.js b/tests/solidity/suites/exception/migrations/1_initial_migration.js new file mode 100644 index 0000000000..16a7ba52f4 --- /dev/null +++ b/tests/solidity/suites/exception/migrations/1_initial_migration.js @@ -0,0 +1,5 @@ +const Migrations = artifacts.require("Migrations"); + +module.exports = function (deployer) { + deployer.deploy(Migrations); +}; diff --git a/tests/solidity/suites/exception/package.json b/tests/solidity/suites/exception/package.json new file mode 100644 index 0000000000..63e94e15b0 --- /dev/null +++ b/tests/solidity/suites/exception/package.json @@ -0,0 +1,15 @@ +{ + "name": "exception", + "version": "1.0.0", + "author": "huangyi ", + "license": "GPL-3.0-or-later", + "scripts": { + "test-ganache": "yarn truffle test", + "test-ethermint": "yarn truffle test --network ethermint" + }, + "devDependencies": { + "truffle": "^5.1.42", + "truffle-assertions": "^0.9.2", + "web3": "^1.2.11" + } +} diff --git a/tests/solidity/suites/exception/test/.gitkeep b/tests/solidity/suites/exception/test/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/solidity/suites/exception/test/revert.js b/tests/solidity/suites/exception/test/revert.js new file mode 100644 index 0000000000..68e7b3a90b --- /dev/null +++ b/tests/solidity/suites/exception/test/revert.js @@ -0,0 +1,31 @@ +const TestRevert = artifacts.require("TestRevert") +const truffleAssert = require('truffle-assertions'); + +async function expectRevert(promise) { + try { + await promise; + } catch (error) { + if (error.message.indexOf('revert') === -1) { + expect('revert').to.equal(error.message, 'Wrong kind of exception received'); + } + return; + } + expect.fail('Expected an exception but none was received'); +} + +contract('TestRevert', (accounts) => { + let revert + + beforeEach(async () => { + revert = await TestRevert.new() + }) + it('should revert', async () => { + await revert.try_set(10) + no = await revert.query() + assert.equal(no, '0', 'The set should be reverted') + + await revert.set(10) + no = await revert.query() + assert.equal(no, '10', 'The force set should not be reverted') + }) +}) diff --git a/tests/solidity/suites/exception/truffle-config.js b/tests/solidity/suites/exception/truffle-config.js new file mode 100644 index 0000000000..b0dbcc9d24 --- /dev/null +++ b/tests/solidity/suites/exception/truffle-config.js @@ -0,0 +1,17 @@ +module.exports = { + networks: { + // Development network is just left as truffle's default settings + ethermint: { + host: "127.0.0.1", // Localhost (default: none) + port: 8545, // Standard Ethereum port (default: none) + network_id: "*", // Any network (default: none) + gas: 5000000, // Gas sent with each transaction + gasPrice: 1000000000, // 1 gwei (in wei) + }, + }, + compilers: { + solc: { + version: "0.8.6", + }, + }, +} From c68475f77d41d538395e804172a4740f5c58fac8 Mon Sep 17 00:00:00 2001 From: HuangYi Date: Mon, 26 Jul 2021 21:55:08 +0800 Subject: [PATCH 2/3] verify partial revert --- tests/solidity/suites/exception/contracts/TestRevert.sol | 7 ++++++- tests/solidity/suites/exception/test/revert.js | 8 +++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/tests/solidity/suites/exception/contracts/TestRevert.sol b/tests/solidity/suites/exception/contracts/TestRevert.sol index aa3e7af6a7..547270dfef 100644 --- a/tests/solidity/suites/exception/contracts/TestRevert.sol +++ b/tests/solidity/suites/exception/contracts/TestRevert.sol @@ -17,10 +17,12 @@ contract State { contract TestRevert { State state; + uint256 b = 0; constructor() { state = new State(); } function try_set(uint256 input) public { + b = input; try state.set(input) { } catch (bytes memory) { } @@ -28,7 +30,10 @@ contract TestRevert { function set(uint256 input) public { state.force_set(input); } - function query() public view returns(uint256) { + function query_a() public view returns(uint256) { return state.query(); } + function query_b() public view returns(uint256) { + return b; + } } diff --git a/tests/solidity/suites/exception/test/revert.js b/tests/solidity/suites/exception/test/revert.js index 68e7b3a90b..8ddaacc69e 100644 --- a/tests/solidity/suites/exception/test/revert.js +++ b/tests/solidity/suites/exception/test/revert.js @@ -21,11 +21,13 @@ contract('TestRevert', (accounts) => { }) it('should revert', async () => { await revert.try_set(10) - no = await revert.query() - assert.equal(no, '0', 'The set should be reverted') + no = await revert.query_a() + assert.equal(no, '0', 'The modification on a should be reverted') + no = await revert.query_b() + assert.equal(no, '10', 'The modification on b should not be reverted') await revert.set(10) - no = await revert.query() + no = await revert.query_a() assert.equal(no, '10', 'The force set should not be reverted') }) }) From 0775537c36cce60fb613fb33603db0c2b1b9aabc Mon Sep 17 00:00:00 2001 From: HuangYi Date: Tue, 27 Jul 2021 11:43:11 +0800 Subject: [PATCH 3/3] mutate state after the reverted subcall --- tests/solidity/suites/exception/contracts/TestRevert.sol | 5 +++++ tests/solidity/suites/exception/test/revert.js | 2 ++ 2 files changed, 7 insertions(+) diff --git a/tests/solidity/suites/exception/contracts/TestRevert.sol b/tests/solidity/suites/exception/contracts/TestRevert.sol index 547270dfef..57d5807c77 100644 --- a/tests/solidity/suites/exception/contracts/TestRevert.sol +++ b/tests/solidity/suites/exception/contracts/TestRevert.sol @@ -18,6 +18,7 @@ contract State { contract TestRevert { State state; uint256 b = 0; + uint256 c = 0; constructor() { state = new State(); } @@ -26,6 +27,7 @@ contract TestRevert { try state.set(input) { } catch (bytes memory) { } + c = input; } function set(uint256 input) public { state.force_set(input); @@ -36,4 +38,7 @@ contract TestRevert { function query_b() public view returns(uint256) { return b; } + function query_c() public view returns(uint256) { + return c; + } } diff --git a/tests/solidity/suites/exception/test/revert.js b/tests/solidity/suites/exception/test/revert.js index 8ddaacc69e..73d53e4db7 100644 --- a/tests/solidity/suites/exception/test/revert.js +++ b/tests/solidity/suites/exception/test/revert.js @@ -25,6 +25,8 @@ contract('TestRevert', (accounts) => { assert.equal(no, '0', 'The modification on a should be reverted') no = await revert.query_b() assert.equal(no, '10', 'The modification on b should not be reverted') + no = await revert.query_c() + assert.equal(no, '10', 'The modification on c should not be reverted') await revert.set(10) no = await revert.query_a()