From 7e0ebc3b8d991f7ec8bc0fd222b2ab7d65f3b790 Mon Sep 17 00:00:00 2001 From: Will Meister Date: Wed, 19 Feb 2020 11:10:16 -0600 Subject: [PATCH 1/3] Making ExecutionManager always return an address on ovmCREATE* -- will be 0 address on failure --- .../ovm/src/contracts/ExecutionManager.sol | 57 +++++++++++++++---- 1 file changed, 45 insertions(+), 12 deletions(-) diff --git a/packages/ovm/src/contracts/ExecutionManager.sol b/packages/ovm/src/contracts/ExecutionManager.sol index ad5b507e263..c8e64d532e2 100644 --- a/packages/ovm/src/contracts/ExecutionManager.sol +++ b/packages/ovm/src/contracts/ExecutionManager.sol @@ -511,10 +511,17 @@ contract ExecutionManager is FullStateManager { * calldata: variable-length bytes: * [methodID (bytes4)] * [ovmInitcode (bytes (variable length))] - * returndata: [newOvmContractAddress (as bytes32)] + * returndata: [newOvmContractAddress (as bytes32)] -- will be all 0s if this create failed. */ function ovmCREATE() public { - require(!executionContext.inStaticContext, "Cannot create new contracts from a STATICCALL."); + if (executionContext.inStaticContext) { + // Cannot create new contracts from a STATICCALL -- return 0 address + assembly { + let returnData := mload(0x40) + mstore(returnData, 0) + return(returnData, 0x20) + } + } bytes memory _ovmInitcode; assembly { @@ -534,7 +541,14 @@ contract ExecutionManager is FullStateManager { uint creatorNonce = getOvmContractNonce(creator); address _newOvmContractAddress = contractAddressGenerator.getAddressFromCREATE(creator, creatorNonce); // Next we need to actually create the contract in our state at that address - createNewContract(_newOvmContractAddress, _ovmInitcode); + if (!createNewContract(_newOvmContractAddress, _ovmInitcode)) { + // Failure: Return 0 address + assembly { + let returnData := mload(0x40) + mstore(returnData, 0) + return(returnData, 0x20) + } + } // We also need to increment the contract nonce incrementOvmContractNonce(creator); @@ -557,10 +571,17 @@ contract ExecutionManager is FullStateManager { * [methodID (bytes4)] * [salt (bytes32)] * [ovmInitcode (bytes (variable length))] - * returndata: [newOvmContractAddress (as bytes32)] + * returndata: [newOvmContractAddress (as bytes32)] -- will be all 0s if this create failed. */ function ovmCREATE2() public { - require(!executionContext.inStaticContext, "Cannot create new contracts from a STATICCALL."); + if (executionContext.inStaticContext) { + // Cannot create new contracts from a STATICCALL -- return 0 address + assembly { + let returnData := mload(0x40) + mstore(returnData, 0) + return(returnData, 0x20) + } + } bytes memory _ovmInitcode; bytes32 _salt; @@ -582,7 +603,14 @@ contract ExecutionManager is FullStateManager { address creator = executionContext.ovmActiveContract; address _newOvmContractAddress = contractAddressGenerator.getAddressFromCREATE2(creator, _salt, _ovmInitcode); // Next we need to actually create the contract in our state at that address - createNewContract(_newOvmContractAddress, _ovmInitcode); + if (!createNewContract(_newOvmContractAddress, _ovmInitcode)) { + // Failure: Return 0 address + assembly { + let returnData := mload(0x40) + mstore(returnData, 0) + return(returnData, 0x20) + } + } // Shifting so that it is left-padded, big-endian ('00'x12 + 20 bytes of address) bytes32 newOvmContractAddressBytes32 = bytes32(bytes20(_newOvmContractAddress)) >> 96; @@ -601,10 +629,14 @@ contract ExecutionManager is FullStateManager { * @notice Create a new contract at some OVM contract address. * @param _newOvmContractAddress The desired OVM contract address for this new contract we will deploy. * @param _ovmInitcode The initcode for our new contract + * @return True if this succeeded, false otherwise. */ - function createNewContract(address _newOvmContractAddress, bytes memory _ovmInitcode) internal { + function createNewContract(address _newOvmContractAddress, bytes memory _ovmInitcode) internal returns (bool){ // Purity check the initcode -- unless the overridePurityChecker flag is set to true - require(overridePurityChecker || purityChecker.isBytecodePure(_ovmInitcode), "createNewContract: Contract init code is not pure."); + if (!overridePurityChecker && !purityChecker.isBytecodePure(_ovmInitcode)) { + // Contract init code is not pure. + return false; + } // Switch the context to be the new contract (address oldMsgSender, address oldActiveContract) = switchActiveContract(_newOvmContractAddress); // Deploy the _ovmInitcode as a code contract -- Note the init script will run in the newly set context @@ -612,10 +644,10 @@ contract ExecutionManager is FullStateManager { // Get the runtime bytecode bytes memory codeContractBytecode = getCodeContractBytecode(codeContractAddress); // Purity check the runtime bytecode -- unless the overridePurityChecker flag is set to true - require( - overridePurityChecker || purityChecker.isBytecodePure(codeContractBytecode), - "createNewContract: Contract runtime bytecode is not pure." - ); + if (!overridePurityChecker && !purityChecker.isBytecodePure(codeContractBytecode)) { + // Contract runtime bytecode is not pure. + return false; + } // Associate the code contract with our ovm contract associateCodeContract(_newOvmContractAddress, codeContractAddress); // Get the code contract address to be emitted by a CreatedContract event @@ -624,6 +656,7 @@ contract ExecutionManager is FullStateManager { restoreContractContext(oldMsgSender, oldActiveContract); // Emit CreatedContract event! We've created a new contract! emit CreatedContract(_newOvmContractAddress, codeContractAddress, codeContractHash); + return true; } /** From 8d1cd8169918d473a71d5a16dfe8c0cabc53b547 Mon Sep 17 00:00:00 2001 From: Will Meister Date: Wed, 19 Feb 2020 15:47:37 -0600 Subject: [PATCH 2/3] Adding tests, removing unwatned it.only --- .../testing-contracts/InvalidOpcodes.sol | 16 ++++ .../execution-manager.call-opcodes.spec.ts | 58 +++++++++----- .../execution-manager.create-opcodes.spec.ts | 78 ++++++++++++++++--- .../execution-manager.purity-checking.spec.ts | 40 +++++----- .../ovm/test/contracts/revert-test.spec.ts | 2 +- packages/ovm/test/helpers.ts | 21 +++++ 6 files changed, 165 insertions(+), 50 deletions(-) create mode 100644 packages/ovm/src/contracts/testing-contracts/InvalidOpcodes.sol diff --git a/packages/ovm/src/contracts/testing-contracts/InvalidOpcodes.sol b/packages/ovm/src/contracts/testing-contracts/InvalidOpcodes.sol new file mode 100644 index 00000000000..fb0ea0a89f3 --- /dev/null +++ b/packages/ovm/src/contracts/testing-contracts/InvalidOpcodes.sol @@ -0,0 +1,16 @@ +pragma solidity ^0.5.0; +pragma experimental ABIEncoderV2; + +contract InvalidOpcodes { + function getCoinbase() public returns (address){ + return block.coinbase; + } + + function getDifficulty() public returns (uint){ + return block.difficulty; + } + + function getBlockNumber() public returns (uint) { + return block.number; + } +} diff --git a/packages/ovm/test/contracts/execution-manager.call-opcodes.spec.ts b/packages/ovm/test/contracts/execution-manager.call-opcodes.spec.ts index 5f590d34dc1..0b6115a01c6 100644 --- a/packages/ovm/test/contracts/execution-manager.call-opcodes.spec.ts +++ b/packages/ovm/test/contracts/execution-manager.call-opcodes.spec.ts @@ -24,8 +24,10 @@ import { manuallyDeployOvmContract, addressToBytes32Address, DEFAULT_ETHNODE_GAS_LIMIT, + didCreateSucceed, } from '../helpers' import { GAS_LIMIT, OPCODE_WHITELIST_MASK } from '../../src/app' +import { TransactionReceipt } from 'ethers/providers' export const abi = new ethers.utils.AbiCoder() @@ -215,9 +217,12 @@ describe('Execution Manager -- Call opcodes', () => { log.debug(`RESULT: ${result}`) - result - .substr(2) - .length.should.equal(64, 'Should have got a bytes32 address back') + const address = remove0x(result) + address.length.should.equal(64, 'Should have got a bytes32 address back!') + address.length.should.not.equal( + '00'.repeat(32), + 'Should not be 0 address!' + ) }) it('properly executes ovmCALL to CREATE2', async () => { @@ -231,9 +236,12 @@ describe('Execution Manager -- Call opcodes', () => { log.debug(`RESULT: ${result}`) - result - .substr(2) - .length.should.equal(64, 'Should have got a bytes32 address back') + const address = remove0x(result) + address.length.should.equal(64, 'Should have got a bytes32 address back!') + address.length.should.not.equal( + '00'.repeat(32), + 'Should not be 0 address!' + ) }) }) @@ -415,30 +423,38 @@ describe('Execution Manager -- Call opcodes', () => { }) }) - it('fails on ovmSTATICCALL to CREATE', async () => { + it('Fails to create on ovmSTATICCALL to CREATE', async () => { const data: string = `${executeCallToCallContractData}${staticCallMethodId}${callContract2Address32}${createMethodIdAndData}` - await TestUtils.assertThrowsAsync(async () => { - // Note: Send transaction vs call so it is persisted - await wallet.sendTransaction({ - to: executionManager.address, - data, - gasLimit: 6_700_000, - }) + // Note: Send transaction vs call so it is persisted + const receipt = await wallet.sendTransaction({ + to: executionManager.address, + data, + gasLimit: 6_700_000, }) + + const creatSucceeded = await didCreateSucceed( + executionManager, + receipt.hash + ) + creatSucceeded.should.equal(false, 'Create should have failed!') }) it('fails on ovmSTATICCALL to CREATE2', async () => { const data: string = `${executeCallToCallContractData}${staticCallMethodId}${callContract2Address32}${create2MethodIdAndData}` - await TestUtils.assertThrowsAsync(async () => { - // Note: Send transaction vs call so it is persisted - await wallet.sendTransaction({ - to: executionManager.address, - data, - gasLimit: 6_700_000, - }) + // Note: Send transaction vs call so it is persisted + const receipt = await wallet.sendTransaction({ + to: executionManager.address, + data, + gasLimit: 6_700_000, }) + + const creatSucceeded = await didCreateSucceed( + executionManager, + receipt.hash + ) + creatSucceeded.should.equal(false, 'Create should have failed!') }) }) }) diff --git a/packages/ovm/test/contracts/execution-manager.create-opcodes.spec.ts b/packages/ovm/test/contracts/execution-manager.create-opcodes.spec.ts index c2511088c15..6ce0f4fd6b6 100644 --- a/packages/ovm/test/contracts/execution-manager.create-opcodes.spec.ts +++ b/packages/ovm/test/contracts/execution-manager.create-opcodes.spec.ts @@ -9,6 +9,7 @@ import { Contract, ContractFactory } from 'ethers' /* Contract Imports */ import * as ExecutionManager from '../../build/contracts/ExecutionManager.json' import * as SimpleStorage from '../../build/contracts/SimpleStorage.json' +import * as InvalidOpcodes from '../../build/contracts/InvalidOpcodes.json' const log = getLogger('execution-manager-create', true) @@ -24,7 +25,9 @@ describe('ExecutionManager -- Create opcodes', () => { const provider = createMockProvider({ gasLimit: DEFAULT_ETHNODE_GAS_LIMIT }) const [wallet] = getWallets(provider) let executionManager: Contract + let purityCheckedExecutioManager: Contract let deployTx + let deployInvalidTx /* Deploy contracts before each test */ beforeEach(async () => { @@ -35,17 +38,27 @@ describe('ExecutionManager -- Create opcodes', () => { [OPCODE_WHITELIST_MASK, '0x' + '00'.repeat(20), GAS_LIMIT, true], { gasLimit: DEFAULT_ETHNODE_GAS_LIMIT } ) + deployTx = new ContractFactory( SimpleStorage.abi, SimpleStorage.bytecode ).getDeployTransaction(executionManager.address) + + purityCheckedExecutioManager = await deployContract( + wallet, + ExecutionManager, // Note: this is false, so it's purity checked. + [OPCODE_WHITELIST_MASK, '0x' + '00'.repeat(20), GAS_LIMIT, false], + { gasLimit: DEFAULT_ETHNODE_GAS_LIMIT } + ) + + deployInvalidTx = new ContractFactory( + InvalidOpcodes.abi, + InvalidOpcodes.bytecode + ).getDeployTransaction() }) - /* - * Test CREATE opcode - */ describe('ovmCREATE', async () => { - it('does not throw when passed bytecode', async () => { + it('returns created address when passed valid bytecode', async () => { const methodId: string = ethereumjsAbi .methodID('ovmCREATE', []) .toString('hex') @@ -61,15 +74,35 @@ describe('ExecutionManager -- Create opcodes', () => { log.debug(`Result: [${result}]`) - result.length.should.be.greaterThan(2, 'Should not just be 0x') + const address: string = remove0x(result) + address.length.should.equal(64, 'Should be a full word for the address') + address.should.not.equal('00'.repeat(32), 'Should not be 0 address') + }) + + it('returns 0 address when passed invalid bytecode', async () => { + const methodId: string = ethereumjsAbi + .methodID('ovmCREATE', []) + .toString('hex') + + const data = `0x${methodId}${remove0x(deployInvalidTx.data)}` + + // Now actually apply it to our execution manager + const result = await executionManager.provider.call({ + to: purityCheckedExecutioManager.address, + data, + gasLimit: 6_700_000, + }) + + log.debug(`Result: [${result}]`) + + const address: string = remove0x(result) + address.length.should.equal(64, 'Should be a full word for the address') + address.should.equal('00'.repeat(32), 'Should be 0 address') }) }) - /* - * Test CREATE2 opcode - */ describe('ovmCREATE2', async () => { - it('does not throw when passed salt and bytecode', async () => { + it('returns created address when passed salt and bytecode', async () => { const methodId: string = ethereumjsAbi .methodID('ovmCREATE2', []) .toString('hex') @@ -85,7 +118,32 @@ describe('ExecutionManager -- Create opcodes', () => { log.debug(`Result: [${result}]`) - result.length.should.be.greaterThan(2, 'Should not just be 0x') + const address: string = remove0x(result) + address.length.should.equal(64, 'Should be a full word for the address') + address.should.not.equal('00'.repeat(32), 'Should not be 0 address') + }) + + it('returns 0 address when passed salt and invalid bytecode', async () => { + const methodId: string = ethereumjsAbi + .methodID('ovmCREATE2', []) + .toString('hex') + + const data = `0x${methodId}${'00'.repeat(32)}${remove0x( + deployInvalidTx.data + )}` + + // Now actually apply it to our execution manager + const result = await executionManager.provider.call({ + to: purityCheckedExecutioManager.address, + data, + gasLimit: 6_700_000, + }) + + log.debug(`Result: [${result}]`) + + const address: string = remove0x(result) + address.length.should.equal(64, 'Should be a full word for the address') + address.should.equal('00'.repeat(32), 'Should be 0 address') }) }) }) diff --git a/packages/ovm/test/contracts/execution-manager.purity-checking.spec.ts b/packages/ovm/test/contracts/execution-manager.purity-checking.spec.ts index a8795ff2bd9..60e93a770f4 100644 --- a/packages/ovm/test/contracts/execution-manager.purity-checking.spec.ts +++ b/packages/ovm/test/contracts/execution-manager.purity-checking.spec.ts @@ -16,6 +16,7 @@ import { manuallyDeployOvmContract, DEFAULT_ETHNODE_GAS_LIMIT, manuallyDeployOvmContractReturnReceipt, + didCreateSucceed, } from '../helpers' import { TransactionReceipt } from 'ethers/providers' @@ -50,28 +51,31 @@ describe('Execution Manager -- Purity Checking', () => { DummyContract, [] ) - receipt.status.should.equal( - 0, + const createSucceeded = await didCreateSucceed( + executionManager, + receipt.transactionHash + ) + + createSucceeded.should.equal( + false, `DummyContract.sol should not have been considered pure because it uses storage in its constructor` ) }) it('should successfully deploy a pure contract', async () => { - let failed = false - try { - await manuallyDeployOvmContract( - wallet, - provider, - executionManager, - AddThree, - [] - ) - } catch (e) { - if (e.message.indexOf('revert') >= 0) { - failed = true - } - } - failed.should.equal( - false, + const receipt = await manuallyDeployOvmContractReturnReceipt( + wallet, + provider, + executionManager, + AddThree, + [] + ) + const createSucceeded = await didCreateSucceed( + executionManager, + receipt.transactionHash + ) + + createSucceeded.should.equal( + true, `AddThree.sol contract should have been considered pure` ) }) diff --git a/packages/ovm/test/contracts/revert-test.spec.ts b/packages/ovm/test/contracts/revert-test.spec.ts index 0d75dae2334..14dca6ba0fb 100644 --- a/packages/ovm/test/contracts/revert-test.spec.ts +++ b/packages/ovm/test/contracts/revert-test.spec.ts @@ -28,7 +28,7 @@ describe('Revert Test', () => { }) describe('Test that revert will blow away modified state from successful sub-calls', async () => { - it.only('reverts sub-call state', async () => { + it('reverts sub-call state', async () => { await revertTestContract.entryPoint() const a = await revertTestContract.getA() diff --git a/packages/ovm/test/helpers.ts b/packages/ovm/test/helpers.ts index 1569a990e2f..740feae42f4 100644 --- a/packages/ovm/test/helpers.ts +++ b/packages/ovm/test/helpers.ts @@ -272,3 +272,24 @@ export const getTransactionResult = async ( const receipt = await provider.waitForTransaction(tx.hash) return abi.decode([returnType], receipt.logs.pop().data) } + +/** + * Returns whether the provided Create transaction succeeded. + * + * @param executionManager The ExecutionManager contract. + * @param createTxHash The transaction hash in question. + * @returns True if there was a successful create in this tx, false otherwise. + */ +export const didCreateSucceed = async ( + executionManager: Contract, + createTxHash: string +): Promise => { + const receipt = await executionManager.provider.waitForTransaction( + createTxHash + ) + return ( + receipt.logs + .map((x) => executionManager.interface.parseLog(x)) + .filter((x) => x.name === 'CreatedContract').length > 0 + ) +} From 0c5a321016860a2537725e3dd923a1262002ac1f Mon Sep 17 00:00:00 2001 From: Will Meister Date: Wed, 19 Feb 2020 16:27:39 -0600 Subject: [PATCH 3/3] PR feedback --- .../execution-manager.call-opcodes.spec.ts | 77 +++++++++++++------ .../execution-manager.code-opcodes.spec.ts | 7 +- .../execution-manager.context-opcodes.spec.ts | 19 ++--- .../execution-manager.create-opcodes.spec.ts | 10 +-- .../execution-manager.storage-opcodes.spec.ts | 6 +- .../ovm/test/contracts/simple-storage.spec.ts | 3 +- packages/ovm/test/helpers.ts | 2 +- 7 files changed, 77 insertions(+), 47 deletions(-) diff --git a/packages/ovm/test/contracts/execution-manager.call-opcodes.spec.ts b/packages/ovm/test/contracts/execution-manager.call-opcodes.spec.ts index 0b6115a01c6..6f9191465d8 100644 --- a/packages/ovm/test/contracts/execution-manager.call-opcodes.spec.ts +++ b/packages/ovm/test/contracts/execution-manager.call-opcodes.spec.ts @@ -25,6 +25,7 @@ import { addressToBytes32Address, DEFAULT_ETHNODE_GAS_LIMIT, didCreateSucceed, + gasLimit, } from '../helpers' import { GAS_LIMIT, OPCODE_WHITELIST_MASK } from '../../src/app' import { TransactionReceipt } from 'ethers/providers' @@ -174,7 +175,7 @@ describe('Execution Manager -- Call opcodes', () => { const result = await executionManager.provider.call({ to: executionManager.address, data, - gasLimit: 6_700_000, + gasLimit, }) log.debug(`Result: [${result}]`) @@ -189,7 +190,7 @@ describe('Execution Manager -- Call opcodes', () => { await wallet.sendTransaction({ to: executionManager.address, data, - gasLimit: 6_700_000, + gasLimit, }) const fetchData: string = `${executeCallToCallContractData}${callMethodId}${callContract2Address32}${sloadMethodIdAndParams}` @@ -197,7 +198,7 @@ describe('Execution Manager -- Call opcodes', () => { const result = await executionManager.provider.call({ to: executionManager.address, data: fetchData, - gasLimit: 6_700_000, + gasLimit, }) log.debug(`Result: [${result}]`) @@ -212,7 +213,7 @@ describe('Execution Manager -- Call opcodes', () => { const result = await executionManager.provider.call({ to: executionManager.address, data, - gasLimit: 6_700_000, + gasLimit, }) log.debug(`RESULT: ${result}`) @@ -231,7 +232,7 @@ describe('Execution Manager -- Call opcodes', () => { const result = await executionManager.provider.call({ to: executionManager.address, data, - gasLimit: 6_700_000, + gasLimit, }) log.debug(`RESULT: ${result}`) @@ -261,7 +262,7 @@ describe('Execution Manager -- Call opcodes', () => { await wallet.sendTransaction({ to: executionManager.address, data, - gasLimit: 6_700_000, + gasLimit, }) // Stored in contract 2 via delegate call but accessed via contract 1 @@ -270,7 +271,7 @@ describe('Execution Manager -- Call opcodes', () => { const result = await executionManager.provider.call({ to: executionManager.address, data: fetchData, - gasLimit: 6_700_000, + gasLimit, }) log.debug(`Result: [${result}]`) @@ -284,7 +285,7 @@ describe('Execution Manager -- Call opcodes', () => { const contract2Result = await executionManager.provider.call({ to: executionManager.address, data: contract2FetchData, - gasLimit: 6_700_000, + gasLimit, }) log.debug(`Result: [${contract2Result}]`) @@ -304,14 +305,14 @@ describe('Execution Manager -- Call opcodes', () => { await wallet.sendTransaction({ to: executionManager.address, data, - gasLimit: 6_700_000, + gasLimit, }) const contract1FetchData: string = `${executeCallToCallContractData}${callMethodId}${callContractAddress32}${sloadMethodIdAndParams}` const contract1Result = await executionManager.provider.call({ to: executionManager.address, data: contract1FetchData, - gasLimit: 6_700_000, + gasLimit, }) log.debug(`Result 1: [${contract1Result}]`) @@ -326,7 +327,7 @@ describe('Execution Manager -- Call opcodes', () => { const contract2Result = await executionManager.provider.call({ to: executionManager.address, data: contract2FetchData, - gasLimit: 6_700_000, + gasLimit, }) log.debug(`Result 2: [${contract2Result}]`) @@ -341,7 +342,7 @@ describe('Execution Manager -- Call opcodes', () => { const contract3Result = await executionManager.provider.call({ to: executionManager.address, data: contract3FetchData, - gasLimit: 6_700_000, + gasLimit, }) log.debug(`Result 3: [${contract3Result}]`) @@ -365,7 +366,7 @@ describe('Execution Manager -- Call opcodes', () => { const result = await executionManager.provider.call({ to: executionManager.address, data, - gasLimit: 6_700_000, + gasLimit, }) log.debug(`Result: [${result}]`) @@ -379,7 +380,7 @@ describe('Execution Manager -- Call opcodes', () => { const result = await executionManager.provider.call({ to: executionManager.address, data, - gasLimit: 6_700_000, + gasLimit, }) log.debug(`Result: [${result}]`) @@ -394,7 +395,7 @@ describe('Execution Manager -- Call opcodes', () => { await executionManager.provider.call({ to: executionManager.address, data, - gasLimit: 6_700_000, + gasLimit, }) }) @@ -405,7 +406,7 @@ describe('Execution Manager -- Call opcodes', () => { const res = await executionManager.provider.call({ to: executionManager.address, data, - gasLimit: 6_700_000, + gasLimit, }) }) }) @@ -418,43 +419,69 @@ describe('Execution Manager -- Call opcodes', () => { await wallet.sendTransaction({ to: executionManager.address, data, - gasLimit: 6_700_000, + gasLimit, }) }) }) - it('Fails to create on ovmSTATICCALL to CREATE', async () => { + it('Fails to create on ovmSTATICCALL to CREATE -- tx', async () => { const data: string = `${executeCallToCallContractData}${staticCallMethodId}${callContract2Address32}${createMethodIdAndData}` // Note: Send transaction vs call so it is persisted const receipt = await wallet.sendTransaction({ to: executionManager.address, data, - gasLimit: 6_700_000, + gasLimit, }) - const creatSucceeded = await didCreateSucceed( + const createSucceeded = await didCreateSucceed( executionManager, receipt.hash ) - creatSucceeded.should.equal(false, 'Create should have failed!') + createSucceeded.should.equal(false, 'Create should have failed!') }) - it('fails on ovmSTATICCALL to CREATE2', async () => { + it('Fails to create on ovmSTATICCALL to CREATE -- call', async () => { + const data: string = `${executeCallToCallContractData}${staticCallMethodId}${callContract2Address32}${createMethodIdAndData}` + + const res = await wallet.provider.call({ + to: executionManager.address, + data, + gasLimit, + }) + + const address = remove0x(res) + address.should.equal('00'.repeat(32), 'Should be 0 address!') + }) + + it('fails on ovmSTATICCALL to CREATE2 -- tx', async () => { const data: string = `${executeCallToCallContractData}${staticCallMethodId}${callContract2Address32}${create2MethodIdAndData}` // Note: Send transaction vs call so it is persisted const receipt = await wallet.sendTransaction({ to: executionManager.address, data, - gasLimit: 6_700_000, + gasLimit, }) - const creatSucceeded = await didCreateSucceed( + const createSucceeded = await didCreateSucceed( executionManager, receipt.hash ) - creatSucceeded.should.equal(false, 'Create should have failed!') + createSucceeded.should.equal(false, 'Create should have failed!') + }) + + it('fails on ovmSTATICCALL to CREATE2 -- call', async () => { + const data: string = `${executeCallToCallContractData}${staticCallMethodId}${callContract2Address32}${create2MethodIdAndData}` + + const res = await wallet.provider.call({ + to: executionManager.address, + data, + gasLimit, + }) + + const address = remove0x(res) + address.should.equal('00'.repeat(32), 'Should be 0 address!') }) }) }) diff --git a/packages/ovm/test/contracts/execution-manager.code-opcodes.spec.ts b/packages/ovm/test/contracts/execution-manager.code-opcodes.spec.ts index a35ecff1ac1..bcbb0f5b40a 100644 --- a/packages/ovm/test/contracts/execution-manager.code-opcodes.spec.ts +++ b/packages/ovm/test/contracts/execution-manager.code-opcodes.spec.ts @@ -26,6 +26,7 @@ import { manuallyDeployOvmContract, getUnsignedTransactionCalldata, DEFAULT_ETHNODE_GAS_LIMIT, + gasLimit, } from '../helpers' import { GAS_LIMIT, OPCODE_WHITELIST_MASK } from '../../src/app' @@ -91,7 +92,7 @@ describe('Execution Manager -- Code-related opcodes', () => { const result: string = await executionManager.provider.call({ to: add0x(executionManager.address), data, - gasLimit: 6_700_000, + gasLimit, }) log.debug(`Resulting size: [${result}]`) @@ -116,7 +117,7 @@ describe('Execution Manager -- Code-related opcodes', () => { const codeHash: string = await executionManager.provider.call({ to: add0x(executionManager.address), data, - gasLimit: 6_700_000, + gasLimit, }) log.debug(`Resulting hash: [${codeHash}]`) @@ -144,7 +145,7 @@ describe('Execution Manager -- Code-related opcodes', () => { const code: string = await executionManager.provider.call({ to: executionManager.address, data, - gasLimit: 6_700_000_000, + gasLimit, }) log.debug(`Resulting code: [${code}]`) diff --git a/packages/ovm/test/contracts/execution-manager.context-opcodes.spec.ts b/packages/ovm/test/contracts/execution-manager.context-opcodes.spec.ts index 66681faa35d..b461caa9192 100644 --- a/packages/ovm/test/contracts/execution-manager.context-opcodes.spec.ts +++ b/packages/ovm/test/contracts/execution-manager.context-opcodes.spec.ts @@ -25,6 +25,7 @@ import { bytes32AddressToAddress, addressToBytes32Address, DEFAULT_ETHNODE_GAS_LIMIT, + gasLimit, } from '../helpers' import { GAS_LIMIT, OPCODE_WHITELIST_MASK } from '../../src/app' @@ -119,7 +120,7 @@ describe('Execution Manager -- Context opcodes', () => { await executionManager.provider.call({ to: executionManager.address, data, - gasLimit: 6_700_000, + gasLimit, }) }) }) @@ -140,7 +141,7 @@ describe('Execution Manager -- Context opcodes', () => { const result = await executionManager.provider.call({ to: executionManager.address, data, - gasLimit: 6_700_000, + gasLimit, }) log.debug(`CALLER result: ${result}`) @@ -164,7 +165,7 @@ describe('Execution Manager -- Context opcodes', () => { await executionManager.provider.call({ to: executionManager.address, data, - gasLimit: 6_700_000, + gasLimit, }) }) }) @@ -185,7 +186,7 @@ describe('Execution Manager -- Context opcodes', () => { const result = await executionManager.provider.call({ to: executionManager.address, data, - gasLimit: 6_700_000, + gasLimit, }) log.debug(`ADDRESS result: ${result}`) @@ -213,7 +214,7 @@ describe('Execution Manager -- Context opcodes', () => { await executionManager.provider.call({ to: executionManager.address, data, - gasLimit: 6_700_000, + gasLimit, }) }) }) @@ -237,7 +238,7 @@ describe('Execution Manager -- Context opcodes', () => { const result = await executionManager.provider.call({ to: executionManager.address, data, - gasLimit: 6_700_000, + gasLimit, }) log.debug(`TIMESTAMP result: ${result}`) @@ -264,7 +265,7 @@ describe('Execution Manager -- Context opcodes', () => { const result = await executionManager.provider.call({ to: executionManager.address, data, - gasLimit: 6_700_000, + gasLimit, }) log.debug(`GASLIMIT result: ${result}`) @@ -294,7 +295,7 @@ describe('Execution Manager -- Context opcodes', () => { const result = await executionManager.provider.call({ to: executionManager.address, data, - gasLimit: 6_700_000, + gasLimit, }) log.debug(`QUEUE ORIGIN result: ${result}`) @@ -325,7 +326,7 @@ describe('Execution Manager -- Context opcodes', () => { const result = await executionManager.provider.call({ to: executionManager.address, data, - gasLimit: 6_700_000, + gasLimit, }) log.debug(`QUEUE ORIGIN result: ${result}`) diff --git a/packages/ovm/test/contracts/execution-manager.create-opcodes.spec.ts b/packages/ovm/test/contracts/execution-manager.create-opcodes.spec.ts index 6ce0f4fd6b6..8e791e305c0 100644 --- a/packages/ovm/test/contracts/execution-manager.create-opcodes.spec.ts +++ b/packages/ovm/test/contracts/execution-manager.create-opcodes.spec.ts @@ -15,7 +15,7 @@ const log = getLogger('execution-manager-create', true) /* Internal Imports */ import { OPCODE_WHITELIST_MASK, GAS_LIMIT } from '../../src/app' -import { DEFAULT_ETHNODE_GAS_LIMIT } from '../helpers' +import { DEFAULT_ETHNODE_GAS_LIMIT, gasLimit } from '../helpers' /********* * TESTS * @@ -69,7 +69,7 @@ describe('ExecutionManager -- Create opcodes', () => { const result = await executionManager.provider.call({ to: executionManager.address, data, - gasLimit: 6_700_000, + gasLimit, }) log.debug(`Result: [${result}]`) @@ -90,7 +90,7 @@ describe('ExecutionManager -- Create opcodes', () => { const result = await executionManager.provider.call({ to: purityCheckedExecutioManager.address, data, - gasLimit: 6_700_000, + gasLimit, }) log.debug(`Result: [${result}]`) @@ -113,7 +113,7 @@ describe('ExecutionManager -- Create opcodes', () => { const result = await executionManager.provider.call({ to: executionManager.address, data, - gasLimit: 6_700_000, + gasLimit, }) log.debug(`Result: [${result}]`) @@ -136,7 +136,7 @@ describe('ExecutionManager -- Create opcodes', () => { const result = await executionManager.provider.call({ to: purityCheckedExecutioManager.address, data, - gasLimit: 6_700_000, + gasLimit, }) log.debug(`Result: [${result}]`) diff --git a/packages/ovm/test/contracts/execution-manager.storage-opcodes.spec.ts b/packages/ovm/test/contracts/execution-manager.storage-opcodes.spec.ts index 931313ec696..29eac8145b6 100644 --- a/packages/ovm/test/contracts/execution-manager.storage-opcodes.spec.ts +++ b/packages/ovm/test/contracts/execution-manager.storage-opcodes.spec.ts @@ -12,7 +12,7 @@ import * as SimpleStorage from '../../build/contracts/SimpleStorage.json' /* Internal Imports */ import { OPCODE_WHITELIST_MASK, GAS_LIMIT } from '../../src/app' -import { DEFAULT_ETHNODE_GAS_LIMIT } from '../helpers' +import { DEFAULT_ETHNODE_GAS_LIMIT, gasLimit } from '../helpers' const log = getLogger('execution-manager-storage', true) @@ -52,7 +52,7 @@ describe('ExecutionManager -- Storage opcodes', () => { const tx = await wallet.sendTransaction({ to: executionManager.address, data, - gasLimit: 6_700_000, + gasLimit, }) const reciept = await provider.getTransactionReceipt(tx.hash) @@ -94,7 +94,7 @@ describe('ExecutionManager -- Storage opcodes', () => { const result = await executionManager.provider.call({ to: executionManager.address, data, - gasLimit: 6_700_000, + gasLimit, }) // It should load the value which we just set diff --git a/packages/ovm/test/contracts/simple-storage.spec.ts b/packages/ovm/test/contracts/simple-storage.spec.ts index 1cd383136e6..de125ebc84c 100644 --- a/packages/ovm/test/contracts/simple-storage.spec.ts +++ b/packages/ovm/test/contracts/simple-storage.spec.ts @@ -18,6 +18,7 @@ import { getUnsignedTransactionCalldata, executeUnsignedEOACall, DEFAULT_ETHNODE_GAS_LIMIT, + gasLimit, } from '../helpers' import { CHAIN_ID, GAS_LIMIT, OPCODE_WHITELIST_MASK } from '../../src/app' @@ -118,7 +119,7 @@ describe('SimpleStorage', () => { const result = await executionManager.provider.call({ to: executionManager.address, data: add0x(callData), - gasLimit: 6_700_000, + gasLimit, }) result.should.equal(add0x(value)) }) diff --git a/packages/ovm/test/helpers.ts b/packages/ovm/test/helpers.ts index 740feae42f4..f993d8f5960 100644 --- a/packages/ovm/test/helpers.ts +++ b/packages/ovm/test/helpers.ts @@ -28,7 +28,7 @@ import { type Signature = [string, string, string] export const DEFAULT_ETHNODE_GAS_LIMIT = 9_000_000 - +export const gasLimit = 6_700_000 const log = getLogger('helpers', true) /**