diff --git a/contracts/contracts/tests/SemanticTests.sol b/contracts/contracts/tests/SemanticTests.sol new file mode 100644 index 00000000..c9376cfd --- /dev/null +++ b/contracts/contracts/tests/SemanticTests.sol @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: Apache-2.0 + +pragma solidity ^0.8.0; + +contract SemanticTests { + function testViewLength(uint256 len) external pure returns (bytes memory) { + return new bytes(len); + } + + error CustomError(uint256 value); + uint256 private x; + + uint256 constant ERROR_NUM = + 0x1023456789abcdef1023456789abcdef1023456789abcdef1023456789abcdef; + + function testCustomRevert() external { + x += 1; + revert CustomError(ERROR_NUM); + } + + function testCustomViewRevert() external pure returns (uint256) { + revert CustomError(ERROR_NUM); + } + + function testViewRevert() external pure returns (uint256) { + require(false, "ThisIsAnError"); + return ERROR_NUM; + } + + function testRevert() external { + x += 1; + require(false, "ThisIsAnError"); + } +} diff --git a/contracts/hardhat.config.ts b/contracts/hardhat.config.ts index 67427a34..fd95dc01 100644 --- a/contracts/hardhat.config.ts +++ b/contracts/hardhat.config.ts @@ -64,7 +64,7 @@ const config: HardhatUserConfig = { chainId: 0x5aff, accounts: process.env.SAPPHIRE_TESTNET_PRIVATE_KEY ? [process.env.SAPPHIRE_TESTNET_PRIVATE_KEY] - : TEST_HDWALLET, + : [], }, 'sapphire-mainnet': { url: 'https://sapphire.oasis.io', diff --git a/contracts/test/semantics.ts b/contracts/test/semantics.ts new file mode 100644 index 00000000..49a7817d --- /dev/null +++ b/contracts/test/semantics.ts @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: Apache-2.0 + +import { ethers } from 'hardhat'; +import { expect } from 'chai'; +import { SemanticTests } from '../typechain-types/contracts/tests/SemanticTests'; +import { SemanticTests__factory } from '../typechain-types/factories/contracts/tests'; + +const ERROR_NUM = + '0x1023456789abcdef1023456789abcdef1023456789abcdef1023456789abcdef'; + +describe('EVM Semantics', () => { + let c: SemanticTests; + let chainId: number; + + before(async () => { + const f = (await ethers.getContractFactory( + 'SemanticTests', + )) as SemanticTests__factory; + c = await f.deploy(); + await c.deployed(); + chainId = (await c.provider.getNetwork()).chainId; + }); + + it('eth_call maximum return length vs gas limit', async () => { + const i = 1787872; + const respHex = await c.testViewLength(i); + const respBytes = ethers.utils.arrayify(respHex); + expect(respBytes.length).eq(i); + expect(c.testViewLength(i + 1)).reverted; + }); + + it('Error string in view call', async () => { + try { + await c.testViewRevert(); + } catch (x: any) { + expect(x.errorArgs[0]).to.eq('ThisIsAnError'); + expect(x.errorName).to.eq('Error'); + } + }); + + it('Custom revert in view call', async () => { + // Perform view call, which is expected to revert + try { + await c.testCustomViewRevert(); + expect(false).to.be.true; + } catch (x: any) { + expect(x.errorArgs[0]).to.eq(ERROR_NUM); + expect(x.errorName).to.eq('CustomError'); + } + }); +});