Commit 3e81548f authored by Kelvin Fichter's avatar Kelvin Fichter

Linted files

parent 8575b629
import { usePlugin, BuidlerConfig } from '@nomiclabs/buidler/config'
import {
DEFAULT_ACCOUNTS_BUIDLER,
GAS_LIMIT,
} from './test/helpers/constants'
import { DEFAULT_ACCOUNTS_BUIDLER, GAS_LIMIT } from './test/helpers/constants'
usePlugin('@nomiclabs/buidler-ethers')
usePlugin('@nomiclabs/buidler-waffle')
......@@ -21,7 +18,7 @@ const config: BuidlerConfig = {
timeout: 50000,
},
solc: {
version: "0.7.0",
version: '0.7.0',
optimizer: { enabled: true, runs: 200 },
},
}
......
......@@ -8,13 +8,13 @@
## Test Cases
- CALL-types
- for all: call an undeployed contract and make sure it errors or whatevs (or maybe that's just a unit test)
- ovmCALL
ALL DONE - ovmCALL
- -> ovmCALLER
- -> ovmADDRESS
- -> SLOAD
- -> SSTORE
- -> CREATE/2
- ovmSTATICCALL
ALL DONE - ovmSTATICCALL
- -> ovmCALLER
- -> ovmADDRESS
- -> SLOAD
......@@ -22,27 +22,31 @@
- -> CREATE/2 (fail)
- -> ovmCALL -> ovmSSTORE
- -> ovmCALL -> ovmCREATE
- -> ovmSTATICCALL -> RETURN -> SLOAD (fails)
- -> ovmSTATICCALL -> RETURN -> SSTORE (fails)
- ovmDELEGATECALL
- -> ovmCALLER
- -> ovmADDRESS
- -> SLOAD
- -> SSTORE
- -> CREATE/2
- -> ovmDELEGATECALL -> ovmCALLER
- -> ovmDELEGATECALL -> ovmADDRESS
DONE - -> ovmCALLER
DONE - -> ovmADDRESS
DONE - -> SLOAD
DONE - -> SSTORE
DONE - -> CREATE/2
DONE - -> ovmDELEGATECALL -> ovmCALLER
DONE - -> ovmDELEGATECALL -> ovmADDRESS
DONE - -> ovmDELEGATECALL -> ovmCREATE
- Code-related
- TODO: fill this in
- CREATE-types
- do we just duplicate these exactly for CREATE and CREATE2? Probably
- ovmCREATE -> success -> ovmEXTCODE{SIZE,HASH,COPY}
- ovmCREATE -> fail (ovmREVERT, NOT out of gas/invalid jump) -> ovmEXTCODE{SIZE,HASH,COPY}
DONE - ovmCREATE -> success -> ovmEXTCODE{SIZE,HASH,COPY}
DONE - ovmCREATE -> fail (ovmREVERT, NOT out of gas/invalid jump) -> ovmEXTCODE{SIZE,HASH,COPY}
- ovmCREATE -> fail -> ovmCALL what was attempted to be created (fail)
- ovmCREATE -> ovmCREATE (during constructor) -> success -> success (check right address for inner deployment)
- ovmCREATE -> ovmCALL(in constructor) -> ovmSSTORE, return -> ovmREVERT (deployment fails, storage not modified, but state access gas correctly increased)
DONE - ovmCREATE -> ovmCALL(in constructor) -> ovmSSTORE, return -> ovmREVERT (deployment fails, storage not modified, but state access gas correctly increased)
DONE - ovmCREATE -> INVALID -> returns 0 address
- ovmCREATE -> ovmCREATE (during constructor) -> success -> fail (outer contract)
- "creator" does ovmCREATE -> invalid jumpdest -> creator out-of-gasses (or at least, appears to--really it will revert with no data, so there will be some gas left)
- "creator" does ovmCREATE -> initcode does ovmCREATE -> invalid jumpdest -> creator out-of-gasses (or at least, appears to--really it will revert with no data, so there will be some gas left) AKA same as above but nested CREATEs
- CREATE collisions: TODO fill in what this needs
- OVM gas metering
- do everything for both queue origins/flip flopped roles:
......@@ -52,6 +56,7 @@
- out of gas
- ovmCALL -> [ovmCALL(gas()/2) -> out of gas] -> SSTORE (does not out of gas parent)
- ovmCREATE -> ovmCALL(in constructor) -> ovmSSTORE, return -> ovmREVERT (deployment fails, storage not modified, but state access gas correctly increased)
- State access limiting logic
......@@ -70,9 +75,9 @@
- Explicit invalid state access tests
- CALL -> CALL, ISA
- CALL -> CALL, CALL, ISA
- CREATE -> CREATE, ISA
DONE - CREATE -> CREATE, ISA
- CREATE -> CREATE -> CREATE ISA
- CREATE -> CALL, ISA
- CALL -> CREATE, ISA
DONE - CREATE -> CALL, ISA
DONE - CALL -> CREATE, ISA
- CALL -> CREATE -> CALL, ISA
- CREATE -> CALL -> CREATE, ISA
\ No newline at end of file
......@@ -7,7 +7,9 @@
"build": "yarn run build:contracts",
"build:contracts": "buidler compile",
"test": "yarn run test:contracts",
"test:contracts": "buidler test \"test/contracts/OVM/execution/OVM_ExecutionManager/ovmSTATICCALL.spec.ts\""
"test:contracts": "buidler test \"test/contracts/OVM/execution/OVM_ExecutionManager/ovmSTATICCALL.spec.ts\"",
"lint": "tslint --format stylish --project .",
"fix": "prettier --config prettier-config.json --write \"buidler.config.ts\" \"{src,test}/**/*.ts\""
},
"devDependencies": {
"@nomiclabs/buidler": "^1.4.4",
......@@ -23,7 +25,12 @@
"fs-extra": "^9.0.1",
"lodash": "^4.17.20",
"mocha": "^8.1.1",
"prettier": "^2.1.2",
"ts-node": "^9.0.0",
"tslint": "^6.1.3",
"tslint-config-prettier": "^1.18.0",
"tslint-no-focused-test": "^0.5.0",
"tslint-plugin-prettier": "^2.3.0",
"typescript": "^4.0.2"
}
}
{
"$schema": "http://json.schemastore.org/prettierrc",
"trailingComma": "es5",
"tabWidth": 2,
"semi": false,
"singleQuote": true,
"arrowParens": "always"
}
/* tslint:disable:no-empty */
import { expect } from '../../../setup'
describe('OVM_ECDSAContractAccount', () => {
describe('execute', () => {
describe('when provided an invalid signature', () => {
it('should revert', async () => {
})
it('should revert', async () => {})
})
describe('when provided a valid signature', () => {
describe('when provided an invalid nonce', () => {
it('should revert', async () => {
})
it('should revert', async () => {})
})
describe('when provided a valid nonce', () => {
describe('when executing ovmCREATE', () => {
it('should return the address of the created contract', async () => {
})
it('should return the address of the created contract', async () => {})
})
describe('when executing ovmCALL', () => {
it('should return the result of the call', async () => {
})
it('should return the result of the call', async () => {})
})
})
})
......
......@@ -12,7 +12,7 @@ import {
setProxyTarget,
NON_NULL_BYTES32,
FORCE_INCLUSION_PERIOD_SECONDS,
ZERO_ADDRESS
ZERO_ADDRESS,
} from '../../../helpers'
const getEthTime = async (): Promise<number> => {
......@@ -85,10 +85,10 @@ describe('OVM_CanonicalTransactionChain', () => {
const timestamp = await getEthTime()
Mock__OVM_L1ToL2TransactionQueue.setReturnValues('peek', [
{
timestamp: timestamp,
timestamp,
batchRoot: NON_NULL_BYTES32,
isL1ToL2Batch: true
}
isL1ToL2Batch: true,
},
])
await setEthTime(timestamp + FORCE_INCLUSION_PERIOD_SECONDS / 2)
})
......@@ -96,7 +96,9 @@ describe('OVM_CanonicalTransactionChain', () => {
it('should revert', async () => {
await expect(
OVM_CanonicalTransactionChain.appendQueueBatch()
).to.be.revertedWith('Cannot append until the inclusion delay period has elapsed.')
).to.be.revertedWith(
'Cannot append until the inclusion delay period has elapsed.'
)
})
})
......@@ -105,25 +107,24 @@ describe('OVM_CanonicalTransactionChain', () => {
const timestamp = await getEthTime()
Mock__OVM_L1ToL2TransactionQueue.setReturnValues('peek', [
{
timestamp: timestamp,
timestamp,
batchRoot: NON_NULL_BYTES32,
isL1ToL2Batch: true
}
isL1ToL2Batch: true,
},
])
Mock__OVM_L1ToL2TransactionQueue.setReturnValues('dequeue', [
{
timestamp: timestamp,
timestamp,
batchRoot: NON_NULL_BYTES32,
isL1ToL2Batch: true
}
isL1ToL2Batch: true,
},
])
await setEthTime(timestamp + FORCE_INCLUSION_PERIOD_SECONDS)
})
it('should append the top element of the queue and attempt to dequeue', async () => {
await expect(
OVM_CanonicalTransactionChain.appendQueueBatch()
).to.not.be.reverted
await expect(OVM_CanonicalTransactionChain.appendQueueBatch()).to.not
.be.reverted
// TODO: Check that the batch root was inserted.
......@@ -138,28 +139,19 @@ describe('OVM_CanonicalTransactionChain', () => {
describe('appendSequencerBatch()', () => {
describe('when the sender is not the sequencer', () => {
before(async () => {
await Proxy_Manager.setProxy(
'Sequencer',
ZERO_ADDRESS
)
await Proxy_Manager.setProxy('Sequencer', ZERO_ADDRESS)
})
it('should revert', async () => {
await expect(
OVM_CanonicalTransactionChain.appendSequencerBatch(
[],
0
)
OVM_CanonicalTransactionChain.appendSequencerBatch([], 0)
).to.be.revertedWith('Function can only be called by the Sequencer.')
})
})
describe('when the sender is the sequencer', () => {
before(async () => {
await Proxy_Manager.setProxy(
'Sequencer',
await signer.getAddress()
)
await Proxy_Manager.setProxy('Sequencer', await signer.getAddress())
})
describe('when the given batch is empty', () => {
......@@ -167,10 +159,7 @@ describe('OVM_CanonicalTransactionChain', () => {
it('should revert', async () => {
await expect(
OVM_CanonicalTransactionChain.appendSequencerBatch(
batch,
0
)
OVM_CanonicalTransactionChain.appendSequencerBatch(batch, 0)
).to.be.revertedWith('Cannot submit an empty batch.')
})
})
......@@ -179,7 +168,7 @@ describe('OVM_CanonicalTransactionChain', () => {
const batch = [NON_NULL_BYTES32]
describe('when the timestamp is not greater than the previous OVM timestamp', () => {
const timestamp = 0;
const timestamp = 0
it('should revert', async () => {
await expect(
......@@ -187,12 +176,14 @@ describe('OVM_CanonicalTransactionChain', () => {
batch,
timestamp
)
).to.be.revertedWith('Batch timestamp must be later than the last OVM timestamp.')
).to.be.revertedWith(
'Batch timestamp must be later than the last OVM timestamp.'
)
})
})
describe('when the timestamp is greater than the previous OVM timestamp', () => {
const timestamp = 1000;
const timestamp = 1000
describe('when the queue is not empty', () => {
before(() => {
......@@ -205,8 +196,8 @@ describe('OVM_CanonicalTransactionChain', () => {
{
timestamp: timestamp / 2,
batchRoot: NON_NULL_BYTES32,
isL1ToL2Batch: true
}
isL1ToL2Batch: true,
},
])
})
......@@ -216,7 +207,9 @@ describe('OVM_CanonicalTransactionChain', () => {
batch,
timestamp
)
).to.be.revertedWith('Older queue batches must be processed before a newer sequencer batch.')
).to.be.revertedWith(
'Older queue batches must be processed before a newer sequencer batch.'
)
})
})
......@@ -224,10 +217,10 @@ describe('OVM_CanonicalTransactionChain', () => {
before(() => {
Mock__OVM_L1ToL2TransactionQueue.setReturnValues('peek', [
{
timestamp: timestamp,
timestamp,
batchRoot: NON_NULL_BYTES32,
isL1ToL2Batch: true
}
isL1ToL2Batch: true,
},
])
})
......@@ -268,9 +261,9 @@ describe('OVM_CanonicalTransactionChain', () => {
describe('getTotalElements()', () => {
describe('when no batch elements have been inserted', () => {
it('should return zero', async () => {
expect(
await OVM_CanonicalTransactionChain.getTotalElements()
).to.equal(0)
expect(await OVM_CanonicalTransactionChain.getTotalElements()).to.equal(
0
)
})
})
......@@ -284,9 +277,9 @@ describe('OVM_CanonicalTransactionChain', () => {
})
it('should return the number of inserted batch elements', async () => {
expect(
await OVM_CanonicalTransactionChain.getTotalElements()
).to.equal(1)
expect(await OVM_CanonicalTransactionChain.getTotalElements()).to.equal(
1
)
})
})
......@@ -294,16 +287,13 @@ describe('OVM_CanonicalTransactionChain', () => {
const batch = Array(64).fill(NON_NULL_BYTES32)
beforeEach(async () => {
Mock__OVM_L1ToL2TransactionQueue.setReturnValues('size', [0])
await OVM_CanonicalTransactionChain.appendSequencerBatch(
batch,
1000
)
await OVM_CanonicalTransactionChain.appendSequencerBatch(batch, 1000)
})
it('should return the number of inserted batch elements', async () => {
expect(
await OVM_CanonicalTransactionChain.getTotalElements()
).to.equal(64)
expect(await OVM_CanonicalTransactionChain.getTotalElements()).to.equal(
64
)
})
})
......@@ -311,20 +301,14 @@ describe('OVM_CanonicalTransactionChain', () => {
const batch = Array(32).fill(NON_NULL_BYTES32)
beforeEach(async () => {
Mock__OVM_L1ToL2TransactionQueue.setReturnValues('size', [0])
await OVM_CanonicalTransactionChain.appendSequencerBatch(
batch,
1000
)
await OVM_CanonicalTransactionChain.appendSequencerBatch(
batch,
2000
)
await OVM_CanonicalTransactionChain.appendSequencerBatch(batch, 1000)
await OVM_CanonicalTransactionChain.appendSequencerBatch(batch, 2000)
})
it('should return the number of inserted batch elements', async () => {
expect(
await OVM_CanonicalTransactionChain.getTotalElements()
).to.equal(64)
expect(await OVM_CanonicalTransactionChain.getTotalElements()).to.equal(
64
)
})
})
})
......@@ -332,9 +316,9 @@ describe('OVM_CanonicalTransactionChain', () => {
describe('getTotalBatches()', () => {
describe('when no batches have been inserted', () => {
it('should return zero', async () => {
expect(
await OVM_CanonicalTransactionChain.getTotalBatches()
).to.equal(0)
expect(await OVM_CanonicalTransactionChain.getTotalBatches()).to.equal(
0
)
})
})
......@@ -348,9 +332,9 @@ describe('OVM_CanonicalTransactionChain', () => {
})
it('should return the number of inserted batch elements', async () => {
expect(
await OVM_CanonicalTransactionChain.getTotalBatches()
).to.equal(1)
expect(await OVM_CanonicalTransactionChain.getTotalBatches()).to.equal(
1
)
})
})
......@@ -366,9 +350,9 @@ describe('OVM_CanonicalTransactionChain', () => {
})
it('should return the number of inserted batch elements', async () => {
expect(
await OVM_CanonicalTransactionChain.getTotalBatches()
).to.equal(8)
expect(await OVM_CanonicalTransactionChain.getTotalBatches()).to.equal(
8
)
})
})
})
......
......@@ -11,7 +11,7 @@ import {
getMockContract,
setProxyTarget,
NON_NULL_BYTES32,
ZERO_ADDRESS
ZERO_ADDRESS,
} from '../../../helpers'
describe('OVM_StateCommitmentChain', () => {
......@@ -68,25 +68,32 @@ describe('OVM_StateCommitmentChain', () => {
describe('when submitting more elements than present in the OVM_CanonicalTransactionChain', () => {
before(() => {
Mock__OVM_CanonicalTransactionChain.setReturnValues('getTotalElements', [batch.length - 1])
Mock__OVM_CanonicalTransactionChain.setReturnValues(
'getTotalElements',
[batch.length - 1]
)
})
it('should revert', async () => {
await expect(
OVM_StateCommitmentChain.appendStateBatch(batch)
).to.be.revertedWith('Number of state roots cannot exceed the number of canonical transactions.')
).to.be.revertedWith(
'Number of state roots cannot exceed the number of canonical transactions.'
)
})
})
describe('when not submitting more elements than present in the OVM_CanonicalTransactionChain', () => {
before(() => {
Mock__OVM_CanonicalTransactionChain.setReturnValues('getTotalElements', [batch.length])
Mock__OVM_CanonicalTransactionChain.setReturnValues(
'getTotalElements',
[batch.length]
)
})
it('should append the state batch', async () => {
await expect(
OVM_StateCommitmentChain.appendStateBatch(batch)
).to.not.be.reverted
await expect(OVM_StateCommitmentChain.appendStateBatch(batch)).to.not
.be.reverted
// TODO: Check for correct insertion.
})
......@@ -102,26 +109,27 @@ describe('OVM_StateCommitmentChain', () => {
batchRoot: NON_NULL_BYTES32,
batchSize: 0,
prevTotalElements: 0,
extraData: '0x'
extraData: '0x',
}
beforeEach(async () => {
Mock__OVM_CanonicalTransactionChain.setReturnValues('getTotalElements', [batch.length])
Mock__OVM_CanonicalTransactionChain.setReturnValues('getTotalElements', [
batch.length,
])
await OVM_StateCommitmentChain.appendStateBatch(batch)
})
describe('when the sender is not the OVM_FraudVerifier', () => {
before(async () => {
await Proxy_Manager.setProxy(
'OVM_FraudVerifier',
ZERO_ADDRESS
)
await Proxy_Manager.setProxy('OVM_FraudVerifier', ZERO_ADDRESS)
})
it('should revert', async () => {
await expect(
OVM_StateCommitmentChain.deleteStateBatch(batchHeader)
).to.be.revertedWith('State batches can only be deleted by the OVM_FraudVerifier.')
).to.be.revertedWith(
'State batches can only be deleted by the OVM_FraudVerifier.'
)
})
})
......@@ -138,7 +146,7 @@ describe('OVM_StateCommitmentChain', () => {
await expect(
OVM_StateCommitmentChain.deleteStateBatch({
...batchHeader,
batchIndex: 1
batchIndex: 1,
})
).to.be.revertedWith('Invalid batch index.')
})
......@@ -150,7 +158,7 @@ describe('OVM_StateCommitmentChain', () => {
await expect(
OVM_StateCommitmentChain.deleteStateBatch({
...batchHeader,
extraData: '0x1234'
extraData: '0x1234',
})
).to.be.revertedWith('Invalid batch header.')
})
......@@ -158,9 +166,8 @@ describe('OVM_StateCommitmentChain', () => {
describe('when the provided batch header is valid', () => {
it('should remove the batch and all following batches', async () => {
await expect(
OVM_StateCommitmentChain.deleteStateBatch(batchHeader)
).to.not.be.reverted
await expect(OVM_StateCommitmentChain.deleteStateBatch(batchHeader))
.to.not.be.reverted
// TODO: Check that it deleted the batches.
})
......@@ -172,52 +179,53 @@ describe('OVM_StateCommitmentChain', () => {
describe('getTotalElements', () => {
describe('when no batch elements have been inserted', () => {
it('should return zero', async () => {
expect(
await OVM_StateCommitmentChain.getTotalElements()
).to.equal(0)
expect(await OVM_StateCommitmentChain.getTotalElements()).to.equal(0)
})
})
describe('when one batch element has been inserted', () => {
beforeEach(async () => {
const batch = [NON_NULL_BYTES32]
Mock__OVM_CanonicalTransactionChain.setReturnValues('getTotalElements', [batch.length])
Mock__OVM_CanonicalTransactionChain.setReturnValues(
'getTotalElements',
[batch.length]
)
await OVM_StateCommitmentChain.appendStateBatch(batch)
})
it('should return the number of inserted batch elements', async () => {
expect(
await OVM_StateCommitmentChain.getTotalElements()
).to.equal(1)
expect(await OVM_StateCommitmentChain.getTotalElements()).to.equal(1)
})
})
describe('when 64 batch elements have been inserted in one batch', () => {
beforeEach(async () => {
const batch = Array(64).fill(NON_NULL_BYTES32)
Mock__OVM_CanonicalTransactionChain.setReturnValues('getTotalElements', [batch.length])
Mock__OVM_CanonicalTransactionChain.setReturnValues(
'getTotalElements',
[batch.length]
)
await OVM_StateCommitmentChain.appendStateBatch(batch)
})
it('should return the number of inserted batch elements', async () => {
expect(
await OVM_StateCommitmentChain.getTotalElements()
).to.equal(64)
expect(await OVM_StateCommitmentChain.getTotalElements()).to.equal(64)
})
})
describe('when 32 batch elements have been inserted in each of two batches', () => {
beforeEach(async () => {
const batch = Array(32).fill(NON_NULL_BYTES32)
Mock__OVM_CanonicalTransactionChain.setReturnValues('getTotalElements', [batch.length * 2])
Mock__OVM_CanonicalTransactionChain.setReturnValues(
'getTotalElements',
[batch.length * 2]
)
await OVM_StateCommitmentChain.appendStateBatch(batch)
await OVM_StateCommitmentChain.appendStateBatch(batch)
})
it('should return the number of inserted batch elements', async () => {
expect(
await OVM_StateCommitmentChain.getTotalElements()
).to.equal(64)
expect(await OVM_StateCommitmentChain.getTotalElements()).to.equal(64)
})
})
})
......@@ -225,39 +233,39 @@ describe('OVM_StateCommitmentChain', () => {
describe('getTotalBatches()', () => {
describe('when no batches have been inserted', () => {
it('should return zero', async () => {
expect(
await OVM_StateCommitmentChain.getTotalBatches()
).to.equal(0)
expect(await OVM_StateCommitmentChain.getTotalBatches()).to.equal(0)
})
})
describe('when one batch has been inserted', () => {
beforeEach(async () => {
const batch = [NON_NULL_BYTES32]
Mock__OVM_CanonicalTransactionChain.setReturnValues('getTotalElements', [batch.length])
Mock__OVM_CanonicalTransactionChain.setReturnValues(
'getTotalElements',
[batch.length]
)
await OVM_StateCommitmentChain.appendStateBatch(batch)
})
it('should return the number of inserted batch elements', async () => {
expect(
await OVM_StateCommitmentChain.getTotalBatches()
).to.equal(1)
expect(await OVM_StateCommitmentChain.getTotalBatches()).to.equal(1)
})
})
describe('when 8 batches have been inserted', () => {
beforeEach(async () => {
const batch = [NON_NULL_BYTES32]
Mock__OVM_CanonicalTransactionChain.setReturnValues('getTotalElements', [batch.length * 8])
Mock__OVM_CanonicalTransactionChain.setReturnValues(
'getTotalElements',
[batch.length * 8]
)
for (let i = 0; i < 8; i++) {
await OVM_StateCommitmentChain.appendStateBatch(batch)
}
})
it('should return the number of inserted batch elements', async () => {
expect(
await OVM_StateCommitmentChain.getTotalBatches()
).to.equal(8)
expect(await OVM_StateCommitmentChain.getTotalBatches()).to.equal(8)
})
})
})
......
......@@ -7,39 +7,39 @@ import {
NON_NULL_BYTES32,
REVERT_FLAGS,
DUMMY_BYTECODE,
VERIFIED_EMPTY_CONTRACT_HASH
VERIFIED_EMPTY_CONTRACT_HASH,
} from '../../../../helpers'
const DUMMY_REVERT_DATA = "0xdeadbeef1e5420deadbeef1e5420deadbeef1e5420deadbeef1e5420deadbeef1e5420"
const DUMMY_REVERT_DATA =
'0xdeadbeef1e5420deadbeef1e5420deadbeef1e5420deadbeef1e5420deadbeef1e5420'
const test_ovmCALL: TestDefinition = {
name: "Basic tests for ovmCALL",
name: 'Basic tests for ovmCALL',
preState: {
ExecutionManager: {
ovmStateManager: "$OVM_STATE_MANAGER",
ovmSafetyChecker: "$OVM_SAFETY_CHECKER",
ovmStateManager: '$OVM_STATE_MANAGER',
ovmSafetyChecker: '$OVM_SAFETY_CHECKER',
messageRecord: {
nuisanceGasLeft: GAS_LIMIT
}
nuisanceGasLeft: GAS_LIMIT,
},
},
StateManager: {
owner: "$OVM_EXECUTION_MANAGER",
owner: '$OVM_EXECUTION_MANAGER',
accounts: {
"$DUMMY_OVM_ADDRESS_1": {
$DUMMY_OVM_ADDRESS_1: {
codeHash: NON_NULL_BYTES32,
ethAddress: "$OVM_CALL_HELPER"
ethAddress: '$OVM_CALL_HELPER',
},
"$DUMMY_OVM_ADDRESS_2": {
$DUMMY_OVM_ADDRESS_2: {
codeHash: NON_NULL_BYTES32,
ethAddress: "$OVM_CALL_HELPER"
ethAddress: '$OVM_CALL_HELPER',
},
"$DUMMY_OVM_ADDRESS_3": {
$DUMMY_OVM_ADDRESS_3: {
codeHash: VERIFIED_EMPTY_CONTRACT_HASH,
ethAddress: '0x' + '00'.repeat(20)
}
}
}
ethAddress: '0x' + '00'.repeat(20),
},
},
},
},
parameters: [
{
......@@ -48,66 +48,66 @@ const test_ovmCALL: TestDefinition = {
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT / 2,
"$DUMMY_OVM_ADDRESS_1",
'$DUMMY_OVM_ADDRESS_1',
[
{
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT / 2,
"$DUMMY_OVM_ADDRESS_2",
'$DUMMY_OVM_ADDRESS_2',
[
{
functionName: 'ovmCALLER',
functionParams: [],
expectedReturnStatus: true,
expectedReturnValues: ["$DUMMY_OVM_ADDRESS_1"]
expectedReturnValues: ['$DUMMY_OVM_ADDRESS_1'],
},
{
functionName: 'ovmADDRESS',
functionParams: [],
expectedReturnStatus: true,
expectedReturnValues: ["$DUMMY_OVM_ADDRESS_2"]
expectedReturnValues: ['$DUMMY_OVM_ADDRESS_2'],
},
{
functionName: 'ovmSSTORE',
functionParams: [ NON_NULL_BYTES32, NON_NULL_BYTES32 ],
functionParams: [NON_NULL_BYTES32, NON_NULL_BYTES32],
expectedReturnStatus: true,
expectedReturnValues: []
expectedReturnValues: [],
},
{
functionName: 'ovmSLOAD',
functionParams: [ NON_NULL_BYTES32 ],
functionParams: [NON_NULL_BYTES32],
expectedReturnStatus: true,
expectedReturnValues: [NON_NULL_BYTES32]
}
]
expectedReturnValues: [NON_NULL_BYTES32],
},
],
],
expectedReturnStatus: true,
expectedReturnValues: []
expectedReturnValues: [],
},
{
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT / 2,
"$DUMMY_OVM_ADDRESS_2",
'$DUMMY_OVM_ADDRESS_2',
[
{
functionName: 'ovmSLOAD',
functionParams: [ NON_NULL_BYTES32 ],
functionParams: [NON_NULL_BYTES32],
expectedReturnStatus: true,
expectedReturnValues: [NON_NULL_BYTES32]
}
]
expectedReturnValues: [NON_NULL_BYTES32],
},
],
],
expectedReturnStatus: true,
expectedReturnValues: []
expectedReturnValues: [],
},
]
],
],
expectedReturnStatus: true,
expectedReturnValues: []
}
]
expectedReturnValues: [],
},
],
},
{
steps: [
......@@ -115,49 +115,49 @@ const test_ovmCALL: TestDefinition = {
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT / 2,
"$DUMMY_OVM_ADDRESS_1",
'$DUMMY_OVM_ADDRESS_1',
[
{
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT / 2,
"$DUMMY_OVM_ADDRESS_2",
'$DUMMY_OVM_ADDRESS_2',
[
{
functionName: 'ovmCALLER',
functionParams: [],
expectedReturnStatus: true,
expectedReturnValues: ["$DUMMY_OVM_ADDRESS_1"]
expectedReturnValues: ['$DUMMY_OVM_ADDRESS_1'],
},
{
functionName: 'ovmADDRESS',
functionParams: [],
expectedReturnStatus: true,
expectedReturnValues: ["$DUMMY_OVM_ADDRESS_2"]
expectedReturnValues: ['$DUMMY_OVM_ADDRESS_2'],
},
{
functionName: 'ovmSSTORE',
functionParams: [ NON_NULL_BYTES32, NON_NULL_BYTES32 ],
functionParams: [NON_NULL_BYTES32, NON_NULL_BYTES32],
expectedReturnStatus: true,
expectedReturnValues: []
expectedReturnValues: [],
},
{
functionName: 'ovmSLOAD',
functionParams: [ NON_NULL_BYTES32 ],
functionParams: [NON_NULL_BYTES32],
expectedReturnStatus: true,
expectedReturnValues: [NON_NULL_BYTES32]
}
]
expectedReturnValues: [NON_NULL_BYTES32],
},
],
],
expectedReturnStatus: true,
expectedReturnValues: []
expectedReturnValues: [],
},
]
],
],
expectedReturnStatus: true,
expectedReturnValues: []
}
]
expectedReturnValues: [],
},
],
},
{
steps: [
......@@ -165,59 +165,55 @@ const test_ovmCALL: TestDefinition = {
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT / 2,
"$DUMMY_OVM_ADDRESS_1",
'$DUMMY_OVM_ADDRESS_1',
[
{
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT / 2,
"$DUMMY_OVM_ADDRESS_3",
[]
],
functionParams: [GAS_LIMIT / 2, '$DUMMY_OVM_ADDRESS_3', []],
expectedReturnStatus: true,
expectedReturnValues: [true, "0x"]
expectedReturnValues: [true, '0x'],
},
]
],
],
expectedReturnStatus: true,
expectedReturnValues: []
}
]
}
]
expectedReturnValues: [],
},
],
},
],
}
const test_ovmCALL_revert: TestDefinition = {
name: "Basic reverts in a code contract called via ovmCALL",
name: 'Basic reverts in a code contract called via ovmCALL',
preState: {
ExecutionManager: {
ovmStateManager: "$OVM_STATE_MANAGER",
ovmSafetyChecker: "$OVM_SAFETY_CHECKER",
ovmStateManager: '$OVM_STATE_MANAGER',
ovmSafetyChecker: '$OVM_SAFETY_CHECKER',
messageRecord: {
nuisanceGasLeft: GAS_LIMIT
}
nuisanceGasLeft: GAS_LIMIT,
},
},
StateManager: {
owner: "$OVM_EXECUTION_MANAGER",
owner: '$OVM_EXECUTION_MANAGER',
accounts: {
"$DUMMY_OVM_ADDRESS_1": {
$DUMMY_OVM_ADDRESS_1: {
codeHash: NON_NULL_BYTES32,
ethAddress: "$OVM_CALL_HELPER"
ethAddress: '$OVM_CALL_HELPER',
},
"$DUMMY_OVM_ADDRESS_2": {
$DUMMY_OVM_ADDRESS_2: {
codeHash: NON_NULL_BYTES32,
ethAddress: "$OVM_REVERT_HELPER"
ethAddress: '$OVM_REVERT_HELPER',
},
"$DUMMY_OVM_ADDRESS_3": {
$DUMMY_OVM_ADDRESS_3: {
codeHash: NON_NULL_BYTES32,
ethAddress: "$OVM_REVERT_HELPER"
ethAddress: '$OVM_REVERT_HELPER',
},
"$DUMMY_OVM_ADDRESS_4": {
$DUMMY_OVM_ADDRESS_4: {
codeHash: VERIFIED_EMPTY_CONTRACT_HASH,
ethAddress: '0x' + '00'.repeat(20)
}
}
}
ethAddress: '0x' + '00'.repeat(20),
},
},
},
},
parameters: [
{
......@@ -226,29 +222,29 @@ const test_ovmCALL_revert: TestDefinition = {
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT / 2,
"$DUMMY_OVM_ADDRESS_1",
'$DUMMY_OVM_ADDRESS_1',
[
{
functionName: 'ovmCALLToRevert',
functionParams: [
GAS_LIMIT / 2,
"$DUMMY_OVM_ADDRESS_2",
'$DUMMY_OVM_ADDRESS_2',
[
REVERT_FLAGS.INTENTIONAL_REVERT,
DUMMY_REVERT_DATA,
GAS_LIMIT / 2,
0
]
0,
],
],
expectedReturnStatus: true,
expectedReturnValues: [false, DUMMY_REVERT_DATA]
expectedReturnValues: [false, DUMMY_REVERT_DATA],
},
]
],
],
expectedReturnStatus: true,
expectedReturnValues: []
}
]
expectedReturnValues: [],
},
],
},
{
steps: [
......@@ -256,31 +252,26 @@ const test_ovmCALL_revert: TestDefinition = {
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT / 2,
"$DUMMY_OVM_ADDRESS_1",
'$DUMMY_OVM_ADDRESS_1',
[
{
functionName: 'ovmCALLToRevert',
functionParams: [
GAS_LIMIT / 2,
"$DUMMY_OVM_ADDRESS_2",
[
REVERT_FLAGS.EXCEEDS_NUISANCE_GAS,
"0x",
0,
0
]
'$DUMMY_OVM_ADDRESS_2',
[REVERT_FLAGS.EXCEEDS_NUISANCE_GAS, '0x', 0, 0],
],
expectedReturnStatus: true,
expectedReturnValues: [false, "0x"]
expectedReturnValues: [false, '0x'],
},
]
],
],
expectedReturnStatus: true,
expectedReturnValues: []
expectedReturnValues: [],
},
]
],
},
]
],
}
runExecutionManagerTest(test_ovmCALL)
......
......@@ -10,43 +10,44 @@ import {
ZERO_ADDRESS,
VERIFIED_EMPTY_CONTRACT_HASH,
DUMMY_BYTECODE_BYTELEN,
DUMMY_BYTECODE_HASH
DUMMY_BYTECODE_HASH,
} from '../../../../helpers'
const CREATED_CONTRACT_1 = "0x2bda4a99d5be88609d23b1e4ab5d1d34fb1c2feb"
const NESTED_CREATED_CONTRACT = "0xcb964b3f4162a0d4f5c997b40e19da5a546bc36f"
const CREATED_CONTRACT_1 = '0x2bda4a99d5be88609d23b1e4ab5d1d34fb1c2feb'
const NESTED_CREATED_CONTRACT = '0xcb964b3f4162a0d4f5c997b40e19da5a546bc36f'
const test_ovmCREATE: TestDefinition = {
name: "Basic tests for ovmCREATE",
name: 'Basic tests for ovmCREATE',
preState: {
ExecutionManager: {
ovmStateManager: "$OVM_STATE_MANAGER",
ovmSafetyChecker: "$OVM_SAFETY_CHECKER",
ovmStateManager: '$OVM_STATE_MANAGER',
ovmSafetyChecker: '$OVM_SAFETY_CHECKER',
messageRecord: {
nuisanceGasLeft: GAS_LIMIT
}
nuisanceGasLeft: GAS_LIMIT,
},
},
StateManager: {
owner: "$OVM_EXECUTION_MANAGER",
owner: '$OVM_EXECUTION_MANAGER',
accounts: {
"$DUMMY_OVM_ADDRESS_1": {
$DUMMY_OVM_ADDRESS_1: {
codeHash: NON_NULL_BYTES32,
ethAddress: "$OVM_CALL_HELPER"
ethAddress: '$OVM_CALL_HELPER',
},
"$DUMMY_OVM_ADDRESS_2": {
$DUMMY_OVM_ADDRESS_2: {
codeHash: NON_NULL_BYTES32,
ethAddress: "$OVM_CALL_HELPER"
ethAddress: '$OVM_CALL_HELPER',
},
[CREATED_CONTRACT_1]: {
codeHash: VERIFIED_EMPTY_CONTRACT_HASH,
ethAddress: '0x' + '00'.repeat(20)
}
}
}
ethAddress: '0x' + '00'.repeat(20),
},
},
},
},
parameters: [
{
name: "Should correctly expose code-related opcodes for a created address once deployed",
name:
'Should correctly expose code-related opcodes for a created address once deployed',
parameters: [
{
steps: [
......@@ -54,7 +55,7 @@ const test_ovmCREATE: TestDefinition = {
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT / 2,
"$DUMMY_OVM_ADDRESS_1",
'$DUMMY_OVM_ADDRESS_1',
[
{
functionName: 'ovmCREATE',
......@@ -62,40 +63,45 @@ const test_ovmCREATE: TestDefinition = {
DUMMY_BYTECODE,
// expect creation to succeed?
true,
[]
[],
],
expectedReturnStatus: true,
expectedReturnValues: [CREATED_CONTRACT_1]
expectedReturnValues: [CREATED_CONTRACT_1],
},
{
functionName: "ovmEXTCODESIZE",
functionName: 'ovmEXTCODESIZE',
functionParams: [CREATED_CONTRACT_1],
expectedReturnStatus: true,
expectedReturnValues: [DUMMY_BYTECODE_BYTELEN]
expectedReturnValues: [DUMMY_BYTECODE_BYTELEN],
},
{
functionName: "ovmEXTCODEHASH",
functionName: 'ovmEXTCODEHASH',
functionParams: [CREATED_CONTRACT_1],
expectedReturnStatus: true,
expectedReturnValues: [DUMMY_BYTECODE_HASH]
expectedReturnValues: [DUMMY_BYTECODE_HASH],
},
{
functionName: "ovmEXTCODECOPY",
functionParams: [CREATED_CONTRACT_1, 0, DUMMY_BYTECODE_BYTELEN],
functionName: 'ovmEXTCODECOPY',
functionParams: [
CREATED_CONTRACT_1,
0,
DUMMY_BYTECODE_BYTELEN,
],
expectedReturnStatus: true,
expectedReturnValues: [DUMMY_BYTECODE_HASH]
}
]
expectedReturnValues: [DUMMY_BYTECODE_HASH],
},
],
],
expectedReturnStatus: true,
expectedReturnValues: []
}
]
}
]
expectedReturnValues: [],
},
],
},
],
},
{
name: "Should return 0 address correctly expose empty code-related opcodes if deployment fails",
name:
'Should return 0 address correctly expose empty code-related opcodes if deployment fails',
parameters: [
{
steps: [
......@@ -103,7 +109,7 @@ const test_ovmCREATE: TestDefinition = {
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT / 2,
"$DUMMY_OVM_ADDRESS_1",
'$DUMMY_OVM_ADDRESS_1',
[
{
functionName: 'ovmCREATE',
......@@ -116,42 +122,42 @@ const test_ovmCREATE: TestDefinition = {
functionName: 'ovmREVERT',
functionParams: ['0x1234'],
expectedReturnStatus: undefined, // TODO: use this wherever not checked
expectedReturnValues: undefined
}
]
expectedReturnValues: undefined,
},
],
],
expectedReturnStatus: true,
expectedReturnValues: [ZERO_ADDRESS]
expectedReturnValues: [ZERO_ADDRESS],
},
{
functionName: "ovmEXTCODESIZE",
functionName: 'ovmEXTCODESIZE',
functionParams: [CREATED_CONTRACT_1],
expectedReturnStatus: true,
expectedReturnValues: [0]
expectedReturnValues: [0],
},
{
functionName: "ovmEXTCODEHASH",
functionName: 'ovmEXTCODEHASH',
functionParams: [CREATED_CONTRACT_1],
expectedReturnStatus: true,
expectedReturnValues: [NULL_BYTES32]
expectedReturnValues: [NULL_BYTES32],
},
{
functionName: "ovmEXTCODECOPY",
functionName: 'ovmEXTCODECOPY',
functionParams: [CREATED_CONTRACT_1, 0, 256],
expectedReturnStatus: true,
expectedReturnValues: ["0x" + "00".repeat(256)]
}
]
expectedReturnValues: ['0x' + '00'.repeat(256)],
},
],
],
expectedReturnStatus: true,
expectedReturnValues: []
}
]
}
]
expectedReturnValues: [],
},
],
},
],
},
{
name: "Basic relevant context opcodes should be accessible in initcode",
name: 'Basic relevant context opcodes should be accessible in initcode',
parameters: [
{
steps: [
......@@ -159,7 +165,7 @@ const test_ovmCREATE: TestDefinition = {
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT,
"$DUMMY_OVM_ADDRESS_1",
'$DUMMY_OVM_ADDRESS_1',
[
{
functionName: 'ovmCREATE',
......@@ -174,36 +180,37 @@ const test_ovmCREATE: TestDefinition = {
functionName: 'ovmCALLER',
functionParams: [],
expectedReturnStatus: true,
expectedReturnValues: ["$DUMMY_OVM_ADDRESS_1"]
expectedReturnValues: ['$DUMMY_OVM_ADDRESS_1'],
},
{
functionName: 'ovmADDRESS',
functionParams: [],
expectedReturnStatus: true,
expectedReturnValues: [CREATED_CONTRACT_1]
expectedReturnValues: [CREATED_CONTRACT_1],
},
{
functionName: 'ovmSLOAD',
functionParams: [NON_NULL_BYTES32],
expectedReturnStatus: true,
expectedReturnValues: [NULL_BYTES32]
}
]
expectedReturnValues: [NULL_BYTES32],
},
],
],
expectedReturnStatus: true,
expectedReturnValues: [CREATED_CONTRACT_1]
}
]
expectedReturnValues: [CREATED_CONTRACT_1],
},
],
],
expectedReturnStatus: true,
expectedReturnValues: []
}
]
}
]
expectedReturnValues: [],
},
],
},
],
},
{
name: "Internal storage manipulation during initcode should be correctly persisted, and all accessible",
name:
'Internal storage manipulation during initcode should be correctly persisted, and all accessible',
parameters: [
{
steps: [
......@@ -211,7 +218,7 @@ const test_ovmCREATE: TestDefinition = {
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT,
"$DUMMY_OVM_ADDRESS_1",
'$DUMMY_OVM_ADDRESS_1',
[
{
functionName: 'ovmCREATE',
......@@ -226,18 +233,18 @@ const test_ovmCREATE: TestDefinition = {
functionName: 'ovmSSTORE',
functionParams: [NON_NULL_BYTES32, NON_NULL_BYTES32],
expectedReturnStatus: true,
expectedReturnValues: []
expectedReturnValues: [],
},
{
functionName: 'ovmSLOAD',
functionParams: [NON_NULL_BYTES32],
expectedReturnStatus: true,
expectedReturnValues: [NON_NULL_BYTES32]
expectedReturnValues: [NON_NULL_BYTES32],
},
]
],
],
expectedReturnStatus: true,
expectedReturnValues: [CREATED_CONTRACT_1]
expectedReturnValues: [CREATED_CONTRACT_1],
},
{
functionName: 'ovmCALL',
......@@ -249,30 +256,31 @@ const test_ovmCREATE: TestDefinition = {
functionName: 'ovmSLOAD',
functionParams: [NON_NULL_BYTES32],
expectedReturnStatus: true,
expectedReturnValues: [NON_NULL_BYTES32]
expectedReturnValues: [NON_NULL_BYTES32],
},
{
functionName: 'ovmSLOAD',
functionParams: [NULL_BYTES32],
expectedReturnStatus: true,
expectedReturnValues: [NULL_BYTES32]
}
expectedReturnValues: [NULL_BYTES32],
},
],
],
expectedReturnStatus: true,
expectedReturnValues: []
}
]
expectedReturnValues: [],
},
],
],
expectedReturnStatus: true,
expectedReturnValues: []
}
]
}
]
expectedReturnValues: [],
},
],
},
],
},
{
name: "External storage manipulation during initcode subcalls should correctly be persisted",
name:
'External storage manipulation during initcode subcalls should correctly be persisted',
parameters: [
{
steps: [
......@@ -280,7 +288,7 @@ const test_ovmCREATE: TestDefinition = {
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT,
"$DUMMY_OVM_ADDRESS_1",
'$DUMMY_OVM_ADDRESS_1',
[
{
functionName: 'ovmCREATE',
......@@ -295,80 +303,84 @@ const test_ovmCREATE: TestDefinition = {
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT,
"$DUMMY_OVM_ADDRESS_2",
'$DUMMY_OVM_ADDRESS_2',
[
{
functionName: 'ovmSSTORE',
functionParams: [NULL_BYTES32, NON_NULL_BYTES32],
functionParams: [
NULL_BYTES32,
NON_NULL_BYTES32,
],
expectedReturnStatus: true,
expectedReturnValues: []
expectedReturnValues: [],
},
{
functionName: 'ovmSLOAD',
functionParams: [NULL_BYTES32],
expectedReturnStatus: true,
expectedReturnValues: [NON_NULL_BYTES32]
expectedReturnValues: [NON_NULL_BYTES32],
},
]
],
],
expectedReturnStatus: true,
expectedReturnValues: []
expectedReturnValues: [],
},
]
],
],
expectedReturnStatus: true,
expectedReturnValues: [CREATED_CONTRACT_1]
expectedReturnValues: [CREATED_CONTRACT_1],
},
{
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT,
"$DUMMY_OVM_ADDRESS_2",
'$DUMMY_OVM_ADDRESS_2',
[
{
functionName: 'ovmSLOAD',
functionParams: [NULL_BYTES32],
expectedReturnStatus: true,
expectedReturnValues: [NON_NULL_BYTES32]
}
expectedReturnValues: [NON_NULL_BYTES32],
},
],
],
expectedReturnStatus: true,
expectedReturnValues: []
}
]
expectedReturnValues: [],
},
],
],
expectedReturnStatus: true,
expectedReturnValues: []
}
]
}
]
expectedReturnValues: [],
},
],
},
],
},
{
name: "External storage manipulation during initcode subcalls should correctly NOT be persisted if ovmREVERTed",
name:
'External storage manipulation during initcode subcalls should correctly NOT be persisted if ovmREVERTed',
preState: {
StateManager: {
accounts: {
"$DUMMY_OVM_ADDRESS_1": {
$DUMMY_OVM_ADDRESS_1: {
codeHash: NON_NULL_BYTES32,
ethAddress: "$OVM_CALL_HELPER"
ethAddress: '$OVM_CALL_HELPER',
},
"$DUMMY_OVM_ADDRESS_2": {
$DUMMY_OVM_ADDRESS_2: {
codeHash: NON_NULL_BYTES32,
ethAddress: "$OVM_CALL_HELPER"
ethAddress: '$OVM_CALL_HELPER',
},
[CREATED_CONTRACT_1]: {
codeHash: VERIFIED_EMPTY_CONTRACT_HASH,
ethAddress: '0x' + '00'.repeat(20)
}
ethAddress: '0x' + '00'.repeat(20),
},
},
verifiedContractStorage: {
"$DUMMY_OVM_ADDRESS_2": {
[NULL_BYTES32]: true
}
}
}
$DUMMY_OVM_ADDRESS_2: {
[NULL_BYTES32]: true,
},
},
},
},
parameters: [
{
......@@ -377,7 +389,7 @@ const test_ovmCREATE: TestDefinition = {
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT / 2,
"$DUMMY_OVM_ADDRESS_1",
'$DUMMY_OVM_ADDRESS_1',
[
{
functionName: 'ovmCREATE',
......@@ -392,71 +404,75 @@ const test_ovmCREATE: TestDefinition = {
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT,
"$DUMMY_OVM_ADDRESS_2",
'$DUMMY_OVM_ADDRESS_2',
[
{
functionName: 'ovmSSTORE',
functionParams: [NULL_BYTES32, NON_NULL_BYTES32],
functionParams: [
NULL_BYTES32,
NON_NULL_BYTES32,
],
expectedReturnStatus: true,
expectedReturnValues: []
expectedReturnValues: [],
},
]
],
],
expectedReturnStatus: true,
expectedReturnValues: []
expectedReturnValues: [],
},
{
functionName: 'ovmREVERT',
functionParams: [ '0xdeadbeef' ],
functionParams: ['0xdeadbeef'],
expectedReturnStatus: true,
expectedReturnValues: [] // technically will return 1 single byte but impossible to assert
}
]
expectedReturnValues: [], // technically will return 1 single byte but impossible to assert
},
],
],
expectedReturnStatus: true,
expectedReturnValues: [ZERO_ADDRESS]
expectedReturnValues: [ZERO_ADDRESS],
},
{
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT,
"$DUMMY_OVM_ADDRESS_2",
'$DUMMY_OVM_ADDRESS_2',
[
{
functionName: 'ovmSLOAD',
functionParams: [NULL_BYTES32],
expectedReturnStatus: true,
expectedReturnValues: [NULL_BYTES32]
}
expectedReturnValues: [NULL_BYTES32],
},
],
],
expectedReturnStatus: true,
expectedReturnValues: []
expectedReturnValues: [],
},
]
],
],
expectedReturnStatus: true,
expectedReturnValues: []
}
]
}
]
expectedReturnValues: [],
},
],
},
],
},
{
name: "Should correctly revert on invalid state access in initcode made by a call",
name:
'Should correctly revert on invalid state access in initcode made by a call',
preState: {
StateManager: {
accounts: {
"$DUMMY_OVM_ADDRESS_1": {
$DUMMY_OVM_ADDRESS_1: {
codeHash: NON_NULL_BYTES32,
ethAddress: "$OVM_CALL_HELPER"
ethAddress: '$OVM_CALL_HELPER',
},
[CREATED_CONTRACT_1]: {
codeHash: VERIFIED_EMPTY_CONTRACT_HASH,
ethAddress: '0x' + '00'.repeat(20)
}
ethAddress: '0x' + '00'.repeat(20),
},
},
},
}
},
parameters: [
{
......@@ -465,7 +481,7 @@ const test_ovmCREATE: TestDefinition = {
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT / 2,
"$DUMMY_OVM_ADDRESS_1",
'$DUMMY_OVM_ADDRESS_1',
[
{
functionName: 'ovmCREATE',
......@@ -480,46 +496,51 @@ const test_ovmCREATE: TestDefinition = {
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT,
"$DUMMY_OVM_ADDRESS_3", // invalid state access, not in prestate.SM.accounts
[]
'$DUMMY_OVM_ADDRESS_3', // invalid state access, not in prestate.SM.accounts
[],
],
expectedReturnStatus: undefined,
expectedReturnValues: undefined
expectedReturnValues: undefined,
},
]
],
],
expectedReturnStatus: false,
expectedReturnValues: [REVERT_FLAGS.INVALID_STATE_ACCESS, "0x", 476756501, 0]
expectedReturnValues: [
REVERT_FLAGS.INVALID_STATE_ACCESS,
'0x',
476756501,
0,
],
},
]
],
],
// note: this would be false in practice, but our code contracts are unsafe, so they do not enforce propagation of ISA flag.
expectedReturnStatus: true,
expectedReturnValues: []
}
]
}
]
expectedReturnValues: [],
},
],
},
],
},
{
name: "Invalid state access on nested CREATE should be surfaced",
name: 'Invalid state access on nested CREATE should be surfaced',
preState: {
StateManager: {
accounts: {
"$DUMMY_OVM_ADDRESS_1": {
$DUMMY_OVM_ADDRESS_1: {
codeHash: NON_NULL_BYTES32,
ethAddress: "$OVM_CALL_HELPER"
ethAddress: '$OVM_CALL_HELPER',
},
[CREATED_CONTRACT_1]: {
codeHash: VERIFIED_EMPTY_CONTRACT_HASH,
ethAddress: '0x' + '00'.repeat(20)
ethAddress: '0x' + '00'.repeat(20),
},
[NESTED_CREATED_CONTRACT]: {
codeHash: VERIFIED_EMPTY_CONTRACT_HASH,
ethAddress: '0x' + '00'.repeat(20)
}
ethAddress: '0x' + '00'.repeat(20),
},
},
},
}
},
parameters: [
{
......@@ -528,7 +549,7 @@ const test_ovmCREATE: TestDefinition = {
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT / 2,
"$DUMMY_OVM_ADDRESS_1",
'$DUMMY_OVM_ADDRESS_1',
[
{
functionName: 'ovmCREATE',
......@@ -552,52 +573,57 @@ const test_ovmCREATE: TestDefinition = {
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT,
"$DUMMY_OVM_ADDRESS_3", // invalid state access, not in prestate.SM.accounts
[]
'$DUMMY_OVM_ADDRESS_3', // invalid state access, not in prestate.SM.accounts
[],
],
expectedReturnStatus: undefined,
expectedReturnValues: undefined
expectedReturnValues: undefined,
},
]
],
],
expectedReturnStatus: undefined,
expectedReturnValues: undefined
expectedReturnValues: undefined,
},
]
],
],
expectedReturnStatus: false,
expectedReturnValues: [REVERT_FLAGS.INVALID_STATE_ACCESS, "0x", 476709610, 0]
expectedReturnValues: [
REVERT_FLAGS.INVALID_STATE_ACCESS,
'0x',
476709610,
0,
],
},
]
],
],
// note: this would be false in practice, but our code contracts are unsafe, so they do not enforce propagation of ISA flag.
expectedReturnStatus: true,
expectedReturnValues: []
}
]
}
]
expectedReturnValues: [],
},
],
},
],
},
{
name: "CREATE should fail and return 0 address if out of gas",
name: 'CREATE should fail and return 0 address if out of gas',
focus: true,
preState: {
StateManager: {
accounts: {
"$DUMMY_OVM_ADDRESS_1": {
$DUMMY_OVM_ADDRESS_1: {
codeHash: NON_NULL_BYTES32,
ethAddress: "$OVM_CALL_HELPER"
ethAddress: '$OVM_CALL_HELPER',
},
[CREATED_CONTRACT_1]: {
codeHash: VERIFIED_EMPTY_CONTRACT_HASH,
ethAddress: '0x' + '00'.repeat(20)
ethAddress: '0x' + '00'.repeat(20),
},
[NESTED_CREATED_CONTRACT]: {
codeHash: VERIFIED_EMPTY_CONTRACT_HASH,
ethAddress: '0x' + '00'.repeat(20)
}
ethAddress: '0x' + '00'.repeat(20),
},
},
},
}
},
parameters: [
{
......@@ -606,25 +632,25 @@ const test_ovmCREATE: TestDefinition = {
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT / 2,
"$DUMMY_OVM_ADDRESS_1",
'$DUMMY_OVM_ADDRESS_1',
[
{
functionName: 'ovmCREATEToInvalid',
functionParams: [],
expectedReturnStatus: true,
expectedReturnValues: [ZERO_ADDRESS]
expectedReturnValues: [ZERO_ADDRESS],
},
]
],
],
// note: this would be false in practice, but our code contracts are unsafe, so they do not enforce propagation of ISA flag.
expectedReturnStatus: true,
expectedReturnValues: []
}
]
}
]
}
]
expectedReturnValues: [],
},
],
},
],
},
],
}
runExecutionManagerTest(test_ovmCREATE)
......@@ -6,43 +6,43 @@ import {
NULL_BYTES32,
NON_NULL_BYTES32,
REVERT_FLAGS,
DUMMY_BYTECODE
DUMMY_BYTECODE,
} from '../../../../helpers'
const CREATED_CONTRACT_1 = "0x2bda4a99d5be88609d23b1e4ab5d1d34fb1c2feb"
const CREATED_CONTRACT_2 = "0xe0d8be8101f36ebe6b01abacec884422c39a1f62"
const CREATED_CONTRACT_1 = '0x2bda4a99d5be88609d23b1e4ab5d1d34fb1c2feb'
const CREATED_CONTRACT_2 = '0xe0d8be8101f36ebe6b01abacec884422c39a1f62'
const test_ovmDELEGATECALL: TestDefinition = {
name: "Basic tests for ovmDELEGATECALL",
name: 'Basic tests for ovmDELEGATECALL',
preState: {
ExecutionManager: {
ovmStateManager: "$OVM_STATE_MANAGER",
ovmSafetyChecker: "$OVM_SAFETY_CHECKER",
ovmStateManager: '$OVM_STATE_MANAGER',
ovmSafetyChecker: '$OVM_SAFETY_CHECKER',
messageRecord: {
nuisanceGasLeft: GAS_LIMIT
}
nuisanceGasLeft: GAS_LIMIT,
},
},
StateManager: {
owner: "$OVM_EXECUTION_MANAGER",
owner: '$OVM_EXECUTION_MANAGER',
accounts: {
"$DUMMY_OVM_ADDRESS_1": {
$DUMMY_OVM_ADDRESS_1: {
codeHash: NON_NULL_BYTES32,
ethAddress: "$OVM_CALL_HELPER"
ethAddress: '$OVM_CALL_HELPER',
},
"$DUMMY_OVM_ADDRESS_2": {
$DUMMY_OVM_ADDRESS_2: {
codeHash: NON_NULL_BYTES32,
ethAddress: "$OVM_CALL_HELPER"
ethAddress: '$OVM_CALL_HELPER',
},
"$DUMMY_OVM_ADDRESS_3": {
$DUMMY_OVM_ADDRESS_3: {
codeHash: NON_NULL_BYTES32,
ethAddress: "$OVM_CALL_HELPER"
ethAddress: '$OVM_CALL_HELPER',
},
"$DUMMY_OVM_ADDRESS_4": {
$DUMMY_OVM_ADDRESS_4: {
codeHash: NON_NULL_BYTES32,
ethAddress: "$OVM_CALL_HELPER"
ethAddress: '$OVM_CALL_HELPER',
},
},
},
}
}
},
parameters: [
{
......@@ -51,77 +51,80 @@ const test_ovmDELEGATECALL: TestDefinition = {
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT,
"$DUMMY_OVM_ADDRESS_1",
'$DUMMY_OVM_ADDRESS_1',
[
{
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT,
"$DUMMY_OVM_ADDRESS_2",
'$DUMMY_OVM_ADDRESS_2',
[
{
functionName: 'ovmDELEGATECALL',
functionParams: [
GAS_LIMIT,
"$DUMMY_OVM_ADDRESS_3",
'$DUMMY_OVM_ADDRESS_3',
[
{
functionName: 'ovmCALLER',
functionParams: [],
expectedReturnStatus: true,
expectedReturnValues: ["$DUMMY_OVM_ADDRESS_1"]
expectedReturnValues: ['$DUMMY_OVM_ADDRESS_1'],
},
{
functionName: 'ovmADDRESS',
functionParams: [],
expectedReturnStatus: true,
expectedReturnValues: ["$DUMMY_OVM_ADDRESS_2"]
expectedReturnValues: ['$DUMMY_OVM_ADDRESS_2'],
},
{
functionName: 'ovmSSTORE',
functionParams: [ NON_NULL_BYTES32, NON_NULL_BYTES32 ],
functionParams: [
NON_NULL_BYTES32,
NON_NULL_BYTES32,
],
expectedReturnStatus: true,
expectedReturnValues: []
expectedReturnValues: [],
},
{
functionName: 'ovmSLOAD',
functionParams: [ NON_NULL_BYTES32 ],
functionParams: [NON_NULL_BYTES32],
expectedReturnStatus: true,
expectedReturnValues: [NON_NULL_BYTES32]
}
]
expectedReturnValues: [NON_NULL_BYTES32],
},
],
],
expectedReturnStatus: true,
expectedReturnValues: ["$DUMMY_OVM_ADDRESS_1"]
expectedReturnValues: ['$DUMMY_OVM_ADDRESS_1'],
},
]
],
],
expectedReturnStatus: true,
expectedReturnValues: []
expectedReturnValues: [],
},
{
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT / 2,
"$DUMMY_OVM_ADDRESS_2",
'$DUMMY_OVM_ADDRESS_2',
[
{
functionName: 'ovmSLOAD',
functionParams: [ NON_NULL_BYTES32 ],
functionParams: [NON_NULL_BYTES32],
expectedReturnStatus: true,
expectedReturnValues: [NON_NULL_BYTES32]
}
]
expectedReturnValues: [NON_NULL_BYTES32],
},
],
],
expectedReturnStatus: true,
expectedReturnValues: []
expectedReturnValues: [],
},
]
],
],
expectedReturnStatus: true,
expectedReturnValues: []
}
]
expectedReturnValues: [],
},
],
},
{
steps: [
......@@ -129,35 +132,31 @@ const test_ovmDELEGATECALL: TestDefinition = {
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT,
"$DUMMY_OVM_ADDRESS_1",
'$DUMMY_OVM_ADDRESS_1',
[
{
functionName: 'ovmDELEGATECALL',
functionParams: [
GAS_LIMIT,
"$DUMMY_OVM_ADDRESS_2",
'$DUMMY_OVM_ADDRESS_2',
[
{
functionName: 'ovmCREATE',
functionParams: [
DUMMY_BYTECODE,
true,
[]
],
functionParams: [DUMMY_BYTECODE, true, []],
expectedReturnStatus: true,
expectedReturnValues: [CREATED_CONTRACT_1]
expectedReturnValues: [CREATED_CONTRACT_1],
},
]
],
],
expectedReturnStatus: true,
expectedReturnValues: []
expectedReturnValues: [],
},
]
],
],
expectedReturnStatus: true,
expectedReturnValues: []
}
]
expectedReturnValues: [],
},
],
},
{
steps: [
......@@ -165,77 +164,77 @@ const test_ovmDELEGATECALL: TestDefinition = {
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT,
"$DUMMY_OVM_ADDRESS_1",
'$DUMMY_OVM_ADDRESS_1',
[
{
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT,
"$DUMMY_OVM_ADDRESS_2",
'$DUMMY_OVM_ADDRESS_2',
[
{
functionName: 'ovmDELEGATECALL',
functionParams: [
GAS_LIMIT,
"$DUMMY_OVM_ADDRESS_3",
'$DUMMY_OVM_ADDRESS_3',
[
{
functionName: "ovmDELEGATECALL",
functionName: 'ovmDELEGATECALL',
functionParams: [
GAS_LIMIT,
"$DUMMY_OVM_ADDRESS_4",
'$DUMMY_OVM_ADDRESS_4',
[
{
functionName: "ovmCALLER",
functionName: 'ovmCALLER',
functionParams: [],
expectedReturnStatus: true,
expectedReturnValues: [ "$DUMMY_OVM_ADDRESS_1" ]
expectedReturnValues: [
'$DUMMY_OVM_ADDRESS_1',
],
},
{
functionName: "ovmADDRESS",
functionName: 'ovmADDRESS',
functionParams: [],
expectedReturnStatus: true,
expectedReturnValues: [ "$DUMMY_OVM_ADDRESS_2" ]
expectedReturnValues: [
'$DUMMY_OVM_ADDRESS_2',
],
},
{
functionName: 'ovmCREATE',
functionParams: [
DUMMY_BYTECODE,
true,
[]
],
functionParams: [DUMMY_BYTECODE, true, []],
expectedReturnStatus: true,
expectedReturnValues: [CREATED_CONTRACT_2]
}
]
expectedReturnValues: [CREATED_CONTRACT_2],
},
],
],
expectedReturnStatus: true,
expectedReturnValues: []
}
]
expectedReturnValues: [],
},
],
],
expectedReturnStatus: true,
expectedReturnValues: []
expectedReturnValues: [],
},
]
],
],
expectedReturnStatus: true,
expectedReturnValues: []
expectedReturnValues: [],
},
{
functionName: "ovmADDRESS",
functionName: 'ovmADDRESS',
functionParams: [],
expectedReturnStatus: true,
expectedReturnValues: [ "$DUMMY_OVM_ADDRESS_1" ]
}
]
expectedReturnValues: ['$DUMMY_OVM_ADDRESS_1'],
},
],
],
expectedReturnStatus: true,
expectedReturnValues: []
}
]
}
]
expectedReturnValues: [],
},
],
},
],
}
runExecutionManagerTest(test_ovmDELEGATECALL)
......@@ -6,60 +6,60 @@ import {
NULL_BYTES32,
NON_NULL_BYTES32,
REVERT_FLAGS,
DUMMY_BYTECODE
DUMMY_BYTECODE,
} from '../../../../helpers'
const test_ovmREVERT: TestDefinition = {
name: "basic ovmREVERT unit tests",
name: 'basic ovmREVERT unit tests',
preState: {
ExecutionManager: {
ovmStateManager: "$OVM_STATE_MANAGER",
ovmSafetyChecker: "$OVM_SAFETY_CHECKER",
ovmStateManager: '$OVM_STATE_MANAGER',
ovmSafetyChecker: '$OVM_SAFETY_CHECKER',
messageRecord: {
nuisanceGasLeft: GAS_LIMIT
}
nuisanceGasLeft: GAS_LIMIT,
},
},
StateManager: {
owner: "$OVM_EXECUTION_MANAGER",
owner: '$OVM_EXECUTION_MANAGER',
accounts: {
"$DUMMY_OVM_ADDRESS_1": {
$DUMMY_OVM_ADDRESS_1: {
codeHash: NON_NULL_BYTES32,
ethAddress: "$OVM_CALL_HELPER"
ethAddress: '$OVM_CALL_HELPER',
},
},
},
}
}
},
parameters: [
{
name: "ovmREVERT inside ovmCALL should cause EM to revert",
name: 'ovmREVERT inside ovmCALL should cause EM to revert',
parameters: [
{
steps: [
{
functionName: "ovmCALL",
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT / 2,
"$DUMMY_OVM_ADDRESS_1",
'$DUMMY_OVM_ADDRESS_1',
[
{
functionName: "ovmREVERT",
functionParams: [ "0xdeadbeef" ],
functionName: 'ovmREVERT',
functionParams: ['0xdeadbeef'],
expectedReturnStatus: false,
expectedReturnValues: [
REVERT_FLAGS.INTENTIONAL_REVERT,
"0xdeadbeef",
'0xdeadbeef',
GAS_LIMIT / 2,
0
]
}
]
0,
],
},
],
],
expectedReturnStatus: true,
expectedReturnValues: []
}
]
}
]
expectedReturnValues: [],
},
],
},
],
},
// TODO: fix this. only way to do it is manually set up and call ovmREVERT directly inside a context which mirrors that during creation.
// {
......@@ -100,7 +100,7 @@ const test_ovmREVERT: TestDefinition = {
// }
// ]
// }
]
],
}
runExecutionManagerTest(test_ovmREVERT)
......@@ -6,37 +6,38 @@ import {
NULL_BYTES32,
NON_NULL_BYTES32,
REVERT_FLAGS,
DUMMY_BYTECODE
DUMMY_BYTECODE,
} from '../../../../helpers'
const test_ovmSLOAD: TestDefinition = {
name: "External storage manipulation during initcode subcalls should correctly NOT be persisted if ovmREVERTed",
name:
'External storage manipulation during initcode subcalls should correctly NOT be persisted if ovmREVERTed',
preState: {
ExecutionManager: {
ovmStateManager: "$OVM_STATE_MANAGER",
ovmSafetyChecker: "$OVM_SAFETY_CHECKER",
ovmStateManager: '$OVM_STATE_MANAGER',
ovmSafetyChecker: '$OVM_SAFETY_CHECKER',
messageRecord: {
nuisanceGasLeft: GAS_LIMIT
}
nuisanceGasLeft: GAS_LIMIT,
},
},
StateManager: {
owner: "$OVM_EXECUTION_MANAGER",
owner: '$OVM_EXECUTION_MANAGER',
accounts: {
"$DUMMY_OVM_ADDRESS_1": {
$DUMMY_OVM_ADDRESS_1: {
codeHash: NON_NULL_BYTES32,
ethAddress: "$OVM_CALL_HELPER"
ethAddress: '$OVM_CALL_HELPER',
},
"$DUMMY_OVM_ADDRESS_2": {
$DUMMY_OVM_ADDRESS_2: {
codeHash: NON_NULL_BYTES32,
ethAddress: "$OVM_CALL_HELPER"
ethAddress: '$OVM_CALL_HELPER',
},
},
verifiedContractStorage: {
"$DUMMY_OVM_ADDRESS_1": {
[NON_NULL_BYTES32]: true
}
}
}
$DUMMY_OVM_ADDRESS_1: {
[NON_NULL_BYTES32]: true,
},
},
},
},
parameters: [
{
......@@ -45,22 +46,22 @@ const test_ovmSLOAD: TestDefinition = {
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT,
"$DUMMY_OVM_ADDRESS_1",
'$DUMMY_OVM_ADDRESS_1',
[
{
functionName: 'ovmSLOAD',
functionParams: [NON_NULL_BYTES32],
expectedReturnStatus: true,
expectedReturnValues: [NULL_BYTES32]
expectedReturnValues: [NULL_BYTES32],
},
]
],
],
expectedReturnStatus: true,
expectedReturnValues: []
}
]
}
]
expectedReturnValues: [],
},
],
},
],
}
runExecutionManagerTest(test_ovmSLOAD)
......@@ -6,37 +6,37 @@ import {
NULL_BYTES32,
NON_NULL_BYTES32,
REVERT_FLAGS,
DUMMY_BYTECODE
DUMMY_BYTECODE,
} from '../../../../helpers'
const test_ovmSTATICCALL: TestDefinition = {
name: "Basic checks on staticcall",
name: 'Basic checks on staticcall',
preState: {
ExecutionManager: {
ovmStateManager: "$OVM_STATE_MANAGER",
ovmSafetyChecker: "$OVM_SAFETY_CHECKER",
ovmStateManager: '$OVM_STATE_MANAGER',
ovmSafetyChecker: '$OVM_SAFETY_CHECKER',
messageRecord: {
nuisanceGasLeft: GAS_LIMIT
}
nuisanceGasLeft: GAS_LIMIT,
},
},
StateManager: {
owner: "$OVM_EXECUTION_MANAGER",
owner: '$OVM_EXECUTION_MANAGER',
accounts: {
"$DUMMY_OVM_ADDRESS_1": {
$DUMMY_OVM_ADDRESS_1: {
codeHash: NON_NULL_BYTES32,
ethAddress: "$OVM_CALL_HELPER"
ethAddress: '$OVM_CALL_HELPER',
},
"$DUMMY_OVM_ADDRESS_2": {
$DUMMY_OVM_ADDRESS_2: {
codeHash: NON_NULL_BYTES32,
ethAddress: "$OVM_CALL_HELPER"
ethAddress: '$OVM_CALL_HELPER',
},
},
verifiedContractStorage: {
"$DUMMY_OVM_ADDRESS_2": {
[NON_NULL_BYTES32]: true
}
}
}
$DUMMY_OVM_ADDRESS_2: {
[NON_NULL_BYTES32]: true,
},
},
},
},
parameters: [
{
......@@ -45,59 +45,65 @@ const test_ovmSTATICCALL: TestDefinition = {
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT,
"$DUMMY_OVM_ADDRESS_1",
'$DUMMY_OVM_ADDRESS_1',
[
{
functionName: 'ovmSTATICCALL',
functionParams: [
GAS_LIMIT / 2,
"$DUMMY_OVM_ADDRESS_2",
'$DUMMY_OVM_ADDRESS_2',
[
{
functionName: 'ovmSSTORE',
functionParams: [NULL_BYTES32, NULL_BYTES32],
expectedReturnStatus: false,
expectedReturnValues: [REVERT_FLAGS.STATIC_VIOLATION, "0x", GAS_LIMIT / 2, 0]
expectedReturnValues: [
REVERT_FLAGS.STATIC_VIOLATION,
'0x',
GAS_LIMIT / 2,
0,
],
},
{
functionName: 'ovmCREATE',
functionParams: [
DUMMY_BYTECODE,
false,
[]
],
functionParams: [DUMMY_BYTECODE, false, []],
expectedReturnStatus: false,
expectedReturnValues: [REVERT_FLAGS.STATIC_VIOLATION, "0x", GAS_LIMIT / 2, 0]
expectedReturnValues: [
REVERT_FLAGS.STATIC_VIOLATION,
'0x',
GAS_LIMIT / 2,
0,
],
},
{
functionName: 'ovmSLOAD',
functionParams: [NON_NULL_BYTES32],
expectedReturnStatus: true,
expectedReturnValues: [NULL_BYTES32]
expectedReturnValues: [NULL_BYTES32],
},
{
functionName: 'ovmCALLER',
functionParams: [],
expectedReturnStatus: true,
expectedReturnValues: ["$DUMMY_OVM_ADDRESS_1"]
expectedReturnValues: ['$DUMMY_OVM_ADDRESS_1'],
},
{
functionName: 'ovmADDRESS',
functionParams: [],
expectedReturnStatus: true,
expectedReturnValues: ["$DUMMY_OVM_ADDRESS_2"]
expectedReturnValues: ['$DUMMY_OVM_ADDRESS_2'],
},
]
],
],
expectedReturnStatus: true,
expectedReturnValues: []
expectedReturnValues: [],
},
]
],
],
expectedReturnStatus: true,
expectedReturnValues: []
}
]
expectedReturnValues: [],
},
],
},
{
steps: [
......@@ -105,58 +111,64 @@ const test_ovmSTATICCALL: TestDefinition = {
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT,
"$DUMMY_OVM_ADDRESS_1",
'$DUMMY_OVM_ADDRESS_1',
[
{
functionName: 'ovmSTATICCALL',
functionParams: [
GAS_LIMIT,
"$DUMMY_OVM_ADDRESS_2",
'$DUMMY_OVM_ADDRESS_2',
[
{
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT,
"$DUMMY_OVM_ADDRESS_2",
'$DUMMY_OVM_ADDRESS_2',
[
{
functionName: 'ovmSLOAD',
functionParams: [NON_NULL_BYTES32],
expectedReturnStatus: true,
expectedReturnValues: [NULL_BYTES32]
expectedReturnValues: [NULL_BYTES32],
},
{
functionName: 'ovmSSTORE',
functionParams: [NULL_BYTES32, NULL_BYTES32],
expectedReturnStatus: false,
expectedReturnValues: [REVERT_FLAGS.STATIC_VIOLATION, "0x", 867484476, 2906]
expectedReturnValues: [
REVERT_FLAGS.STATIC_VIOLATION,
'0x',
867484476,
2906,
],
},
{
functionName: 'ovmCREATE',
functionParams: [
DUMMY_BYTECODE,
false,
[]
],
functionParams: [DUMMY_BYTECODE, false, []],
expectedReturnStatus: false,
expectedReturnValues: [REVERT_FLAGS.STATIC_VIOLATION, "0x", 867484476, 2906]
}
]
expectedReturnValues: [
REVERT_FLAGS.STATIC_VIOLATION,
'0x',
867484476,
2906,
],
},
],
],
expectedReturnStatus: true,
expectedReturnValues: []
}
]
expectedReturnValues: [],
},
],
],
expectedReturnStatus: true,
expectedReturnValues: []
expectedReturnValues: [],
},
]
],
],
expectedReturnStatus: true,
expectedReturnValues: []
}
]
expectedReturnValues: [],
},
],
},
{
steps: [
......@@ -164,41 +176,42 @@ const test_ovmSTATICCALL: TestDefinition = {
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT,
"$DUMMY_OVM_ADDRESS_1",
'$DUMMY_OVM_ADDRESS_1',
[
{
functionName: 'ovmSTATICCALL',
functionParams: [
GAS_LIMIT / 2,
"$DUMMY_OVM_ADDRESS_2",
'$DUMMY_OVM_ADDRESS_2',
[
{
functionName: 'ovmSTATICCALL',
functionParams: [
GAS_LIMIT,
"$DUMMY_OVM_ADDRESS_2",
[]
],
functionParams: [GAS_LIMIT, '$DUMMY_OVM_ADDRESS_2', []],
expectedReturnStatus: true,
expectedReturnValues: []
expectedReturnValues: [],
},
{
functionName: 'ovmSSTORE',
functionParams: [NULL_BYTES32, NULL_BYTES32],
expectedReturnStatus: false,
expectedReturnValues: [REVERT_FLAGS.STATIC_VIOLATION, "0x", GAS_LIMIT / 2, 33806]
}
]
expectedReturnValues: [
REVERT_FLAGS.STATIC_VIOLATION,
'0x',
GAS_LIMIT / 2,
33806,
],
},
],
],
expectedReturnStatus: true,
expectedReturnValues: []
expectedReturnValues: [],
},
]
],
],
expectedReturnStatus: true,
expectedReturnValues: []
}
]
expectedReturnValues: [],
},
],
},
{
steps: [
......@@ -206,29 +219,24 @@ const test_ovmSTATICCALL: TestDefinition = {
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT,
"$DUMMY_OVM_ADDRESS_1",
'$DUMMY_OVM_ADDRESS_1',
[
{
functionName: 'ovmSTATICCALLToRevert',
functionParams: [
GAS_LIMIT / 2,
"$DUMMY_OVM_ADDRESS_2",
[
REVERT_FLAGS.STATIC_VIOLATION,
"0x",
GAS_LIMIT / 2,
0
]
'$DUMMY_OVM_ADDRESS_2',
[REVERT_FLAGS.STATIC_VIOLATION, '0x', GAS_LIMIT / 2, 0],
],
expectedReturnStatus: true,
expectedReturnValues: [false, "0x"]
expectedReturnValues: [false, '0x'],
},
]
],
],
expectedReturnStatus: true,
expectedReturnValues: []
}
]
expectedReturnValues: [],
},
],
},
{
steps: [
......@@ -236,42 +244,37 @@ const test_ovmSTATICCALL: TestDefinition = {
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT,
"$DUMMY_OVM_ADDRESS_1",
'$DUMMY_OVM_ADDRESS_1',
[
{
functionName: 'ovmSTATICCALL',
functionParams: [
GAS_LIMIT,
"$DUMMY_OVM_ADDRESS_1",
'$DUMMY_OVM_ADDRESS_1',
[
{
functionName: 'ovmSTATICCALLToRevert',
functionParams: [
GAS_LIMIT / 2,
"$DUMMY_OVM_ADDRESS_2",
[
REVERT_FLAGS.STATIC_VIOLATION,
"0x",
GAS_LIMIT / 2,
0
]
'$DUMMY_OVM_ADDRESS_2',
[REVERT_FLAGS.STATIC_VIOLATION, '0x', GAS_LIMIT / 2, 0],
],
expectedReturnStatus: true,
expectedReturnValues: [false, "0x"]
expectedReturnValues: [false, '0x'],
},
]
],
],
expectedReturnStatus: true,
expectedReturnValues: []
}
]
expectedReturnValues: [],
},
],
],
expectedReturnStatus: true,
expectedReturnValues: []
}
]
}
]
expectedReturnValues: [],
},
],
},
],
}
runExecutionManagerTest(test_ovmSTATICCALL)
......@@ -21,9 +21,9 @@ describe('OVM_SafetyChecker', () => {
for (const testName of Object.keys(SAFETY_CHECKER_TEST_JSON)) {
const test = SAFETY_CHECKER_TEST_JSON[testName]
it(`should correctly classify: ${testName}`, async () => {
expect(
await OVM_SafetyChecker.isBytecodeSafe(test.in)
).to.equal(test.out)
expect(await OVM_SafetyChecker.isBytecodeSafe(test.in)).to.equal(
test.out
)
})
}
})
......
......@@ -5,11 +5,7 @@ import { ethers } from '@nomiclabs/buidler'
import { Contract, ContractFactory } from 'ethers'
/* Internal Imports */
import {
DUMMY_ACCOUNTS,
DUMMY_BYTES32,
toOVMAccount
} from '../../../helpers'
import { DUMMY_ACCOUNTS, DUMMY_BYTES32, toOVMAccount } from '../../../helpers'
describe('OVM_StateManager', () => {
let Factory__OVM_StateManager: ContractFactory
......@@ -58,7 +54,9 @@ describe('OVM_StateManager', () => {
expect(
toOVMAccount(
await OVM_StateManager.callStatic.getAccount(DUMMY_ACCOUNTS[0].address)
await OVM_StateManager.callStatic.getAccount(
DUMMY_ACCOUNTS[0].address
)
)
).to.deep.equal(DUMMY_ACCOUNTS[0].data)
})
......@@ -76,7 +74,9 @@ describe('OVM_StateManager', () => {
expect(
toOVMAccount(
await OVM_StateManager.callStatic.getAccount(DUMMY_ACCOUNTS[0].address)
await OVM_StateManager.callStatic.getAccount(
DUMMY_ACCOUNTS[0].address
)
)
).to.deep.equal(DUMMY_ACCOUNTS[1].data)
})
......@@ -107,7 +107,7 @@ describe('OVM_StateManager', () => {
OVM_StateManager.putContractStorage(
DUMMY_ACCOUNTS[0].address,
DUMMY_BYTES32[0],
DUMMY_BYTES32[1],
DUMMY_BYTES32[1]
)
).to.not.be.reverted
})
......@@ -116,14 +116,14 @@ describe('OVM_StateManager', () => {
await OVM_StateManager.putContractStorage(
DUMMY_ACCOUNTS[0].address,
DUMMY_BYTES32[0],
DUMMY_BYTES32[1],
DUMMY_BYTES32[1]
)
await expect(
OVM_StateManager.putContractStorage(
DUMMY_ACCOUNTS[0].address,
DUMMY_BYTES32[0],
DUMMY_BYTES32[2],
DUMMY_BYTES32[2]
)
).to.not.be.reverted
})
......@@ -134,7 +134,7 @@ describe('OVM_StateManager', () => {
await OVM_StateManager.putContractStorage(
DUMMY_ACCOUNTS[0].address,
DUMMY_BYTES32[0],
DUMMY_BYTES32[1],
DUMMY_BYTES32[1]
)
expect(
......@@ -149,13 +149,13 @@ describe('OVM_StateManager', () => {
await OVM_StateManager.putContractStorage(
DUMMY_ACCOUNTS[0].address,
DUMMY_BYTES32[0],
DUMMY_BYTES32[1],
DUMMY_BYTES32[1]
)
await OVM_StateManager.putContractStorage(
DUMMY_ACCOUNTS[0].address,
DUMMY_BYTES32[0],
DUMMY_BYTES32[2],
DUMMY_BYTES32[2]
)
expect(
......
......@@ -5,9 +5,7 @@ import { ethers } from '@nomiclabs/buidler'
import { Contract, ContractFactory, Signer } from 'ethers'
/* Internal Imports */
import {
getProxyManager, ZERO_ADDRESS, NULL_BYTES32
} from '../../../helpers'
import { getProxyManager, ZERO_ADDRESS, NULL_BYTES32 } from '../../../helpers'
const parseQueueElement = (result: any[]): any => {
return {
......@@ -57,13 +55,15 @@ describe('OVM_L1ToL2TransactionQueue', () => {
describe('enqueue()', () => {
it('should allow users to enqueue an element', async () => {
const [element] = makeQueueElements(1)
await expect(OVM_L1ToL2TransactionQueue.enqueue(element)).to.not.be.reverted
await expect(OVM_L1ToL2TransactionQueue.enqueue(element)).to.not.be
.reverted
})
it('should allow users to enqueue more than one element', async () => {
const elements = makeQueueElements(10)
for (let i = 0; i < elements.length; i++) {
await expect(OVM_L1ToL2TransactionQueue.enqueue(elements[i])).to.not.be.reverted
for (const element of elements) {
await expect(OVM_L1ToL2TransactionQueue.enqueue(element)).to.not.be
.reverted
}
})
})
......@@ -78,7 +78,9 @@ describe('OVM_L1ToL2TransactionQueue', () => {
})
it('should revert', async () => {
await expect(OVM_L1ToL2TransactionQueue.dequeue()).to.be.revertedWith('Sender is not allowed to enqueue.')
await expect(OVM_L1ToL2TransactionQueue.dequeue()).to.be.revertedWith(
'Sender is not allowed to enqueue.'
)
})
})
......@@ -91,7 +93,9 @@ describe('OVM_L1ToL2TransactionQueue', () => {
})
it('should revert if the queue is empty', async () => {
await expect(OVM_L1ToL2TransactionQueue.dequeue()).to.be.revertedWith('Queue is empty.')
await expect(OVM_L1ToL2TransactionQueue.dequeue()).to.be.revertedWith(
'Queue is empty.'
)
})
it('should allow users to dequeue an element', async () => {
......@@ -102,10 +106,10 @@ describe('OVM_L1ToL2TransactionQueue', () => {
it('should allow users to dequeue more than one element', async () => {
const elements = makeQueueElements(10)
for (let i = 0; i < elements.length; i++) {
await OVM_L1ToL2TransactionQueue.enqueue(elements[i])
for (const element of elements) {
await OVM_L1ToL2TransactionQueue.enqueue(element)
}
for (let i = 0; i < elements.length; i++) {
for (const element of elements) {
await expect(OVM_L1ToL2TransactionQueue.dequeue()).to.not.be.reverted
}
})
......@@ -136,8 +140,8 @@ describe('OVM_L1ToL2TransactionQueue', () => {
it('should decrease when elements are dequeued', async () => {
const elements = makeQueueElements(10)
for (let i = 0; i < elements.length; i++) {
await OVM_L1ToL2TransactionQueue.enqueue(elements[i])
for (const element of elements) {
await OVM_L1ToL2TransactionQueue.enqueue(element)
}
for (let i = 0; i < elements.length; i++) {
await OVM_L1ToL2TransactionQueue.dequeue()
......@@ -156,7 +160,9 @@ describe('OVM_L1ToL2TransactionQueue', () => {
})
it('should revert when the queue is empty', async () => {
await expect(OVM_L1ToL2TransactionQueue.peek()).to.be.revertedWith('Queue is empty.')
await expect(OVM_L1ToL2TransactionQueue.peek()).to.be.revertedWith(
'Queue is empty.'
)
})
it('should return the front element if only one exists', async () => {
......@@ -168,8 +174,8 @@ describe('OVM_L1ToL2TransactionQueue', () => {
it('should return the front if more than one exists', async () => {
const elements = makeQueueElements(10)
for (let i = 0; i < elements.length; i++) {
await OVM_L1ToL2TransactionQueue.enqueue(elements[i])
for (const element of elements) {
await OVM_L1ToL2TransactionQueue.enqueue(element)
const front = await OVM_L1ToL2TransactionQueue.peek()
expect(parseQueueElement(front)).to.deep.equal(elements[0])
}
......@@ -177,8 +183,8 @@ describe('OVM_L1ToL2TransactionQueue', () => {
it('should return the new front when elements are dequeued', async () => {
const elements = makeQueueElements(10)
for (let i = 0; i < elements.length; i++) {
await OVM_L1ToL2TransactionQueue.enqueue(elements[i])
for (const element of elements) {
await OVM_L1ToL2TransactionQueue.enqueue(elements)
}
for (let i = 0; i < elements.length - 1; i++) {
const front = await OVM_L1ToL2TransactionQueue.peek()
......
......@@ -5,19 +5,27 @@ import { ethers } from '@nomiclabs/buidler'
import { ContractFactory, Contract, Signer, BigNumber } from 'ethers'
/* Internal Imports */
import { getProxyManager, getMockContract, MockContract, ZERO_ADDRESS, NULL_BYTES32, NON_NULL_BYTES32, setProxyTarget} from '../../../helpers'
import {
getProxyManager,
getMockContract,
MockContract,
ZERO_ADDRESS,
NULL_BYTES32,
NON_NULL_BYTES32,
setProxyTarget,
} from '../../../helpers'
const DUMMY_BATCH_HEADER = {
batchIndex: 0,
batchRoot: NULL_BYTES32,
batchSize: 0,
prevTotalElements: 0,
extraData: NULL_BYTES32
extraData: NULL_BYTES32,
}
const DUMMY_BATCH_PROOF = {
index: 0,
siblings: [NULL_BYTES32]
siblings: [NULL_BYTES32],
}
const DUMMY_OVM_TRANSACTION = {
......@@ -27,7 +35,7 @@ const DUMMY_OVM_TRANSACTION = {
origin: ZERO_ADDRESS,
msgSender: ZERO_ADDRESS,
gasLimit: 0,
data: NULL_BYTES32
data: NULL_BYTES32,
}
describe('OVM_FraudVerifier', () => {
......@@ -82,18 +90,22 @@ describe('OVM_FraudVerifier', () => {
)
Mock__OVM_StateTransitionerFactory.setReturnValues('create', [
Mock__OVM_StateTransitioner.address
Mock__OVM_StateTransitioner.address,
])
})
let Factory__OVM_FraudVerifier: ContractFactory
before(async () => {
Factory__OVM_FraudVerifier = await ethers.getContractFactory('OVM_FraudVerifier')
Factory__OVM_FraudVerifier = await ethers.getContractFactory(
'OVM_FraudVerifier'
)
})
let OVM_FraudVerifier: Contract
beforeEach(async () => {
OVM_FraudVerifier = await Factory__OVM_FraudVerifier.deploy(Proxy_Manager.address)
OVM_FraudVerifier = await Factory__OVM_FraudVerifier.deploy(
Proxy_Manager.address
)
})
describe('initializeFraudVerification', () => {
......@@ -123,7 +135,9 @@ describe('OVM_FraudVerifier', () => {
describe('when provided an invalid transaction inclusion proof', () => {
before(() => {
Mock__OVM_CanonicalTransactionChain.setReturnValues('verifyElement', [false])
Mock__OVM_CanonicalTransactionChain.setReturnValues('verifyElement', [
false,
])
})
it('should revert', async () => {
......@@ -142,7 +156,9 @@ describe('OVM_FraudVerifier', () => {
describe('when provided a valid transaction inclusion proof', () => {
before(() => {
Mock__OVM_CanonicalTransactionChain.setReturnValues('verifyElement', [true])
Mock__OVM_CanonicalTransactionChain.setReturnValues('verifyElement', [
true,
])
})
it('should deploy a new state transitioner', async () => {
......@@ -165,11 +181,12 @@ describe('OVM_FraudVerifier', () => {
})
})
describe('finalizeFraudVerification', () => {
beforeEach(async () => {
Mock__OVM_StateCommitmentChain.setReturnValues('verifyElement', [true])
Mock__OVM_CanonicalTransactionChain.setReturnValues('verifyElement', [true])
Mock__OVM_CanonicalTransactionChain.setReturnValues('verifyElement', [
true,
])
await OVM_FraudVerifier.initializeFraudVerification(
NULL_BYTES32,
DUMMY_BATCH_HEADER,
......@@ -195,7 +212,9 @@ describe('OVM_FraudVerifier', () => {
DUMMY_BATCH_HEADER,
DUMMY_BATCH_PROOF
)
).to.be.revertedWith('State transition process must be completed prior to finalization.')
).to.be.revertedWith(
'State transition process must be completed prior to finalization.'
)
})
})
......@@ -207,7 +226,7 @@ describe('OVM_FraudVerifier', () => {
describe('when provided an invalid post-state root index', () => {
const batchProof = {
...DUMMY_BATCH_PROOF,
index: DUMMY_BATCH_PROOF.index + 2
index: DUMMY_BATCH_PROOF.index + 2,
}
it('should revert', async () => {
......@@ -227,12 +246,14 @@ describe('OVM_FraudVerifier', () => {
describe('when provided a valid post-state root index', () => {
const batchProof = {
...DUMMY_BATCH_PROOF,
index: DUMMY_BATCH_PROOF.index + 1
index: DUMMY_BATCH_PROOF.index + 1,
}
describe('when provided an invalid pre-state root inclusion proof', () => {
beforeEach(() => {
Mock__OVM_StateCommitmentChain.setReturnValues('verifyElement', [false])
Mock__OVM_StateCommitmentChain.setReturnValues('verifyElement', [
false,
])
})
it('should revert', async () => {
......@@ -251,14 +272,19 @@ describe('OVM_FraudVerifier', () => {
describe('when provided a valid pre-state root inclusion proof', () => {
before(() => {
Mock__OVM_StateCommitmentChain.setReturnValues('verifyElement', [true])
Mock__OVM_StateCommitmentChain.setReturnValues('verifyElement', [
true,
])
})
describe('when provided an invalid post-state root inclusion proof', () => {
beforeEach(() => {
Mock__OVM_StateCommitmentChain.setReturnValues('verifyElement', (stateRoot: string, ...args: any) => {
Mock__OVM_StateCommitmentChain.setReturnValues(
'verifyElement',
(stateRoot: string, ...args: any) => {
return [stateRoot !== NON_NULL_BYTES32]
})
}
)
})
it('should revert', async () => {
......@@ -277,12 +303,17 @@ describe('OVM_FraudVerifier', () => {
describe('when provided a valid post-state root inclusion proof', () => {
before(() => {
Mock__OVM_StateCommitmentChain.setReturnValues('verifyElement', [true])
Mock__OVM_StateCommitmentChain.setReturnValues('verifyElement', [
true,
])
})
describe('when the provided post-state root does not differ from the computed one', () => {
before(() => {
Mock__OVM_StateTransitioner.setReturnValues('getPostStateRoot', [NON_NULL_BYTES32])
Mock__OVM_StateTransitioner.setReturnValues(
'getPostStateRoot',
[NON_NULL_BYTES32]
)
})
it('should revert', async () => {
......@@ -295,13 +326,18 @@ describe('OVM_FraudVerifier', () => {
DUMMY_BATCH_HEADER,
batchProof
)
).to.be.revertedWith('State transition has not been proven fraudulent.')
).to.be.revertedWith(
'State transition has not been proven fraudulent.'
)
})
})
describe('when the provided post-state root differs from the computed one', () => {
before(() => {
Mock__OVM_StateTransitioner.setReturnValues('getPostStateRoot', [NULL_BYTES32])
Mock__OVM_StateTransitioner.setReturnValues(
'getPostStateRoot',
[NULL_BYTES32]
)
})
it('should succeed and attempt to delete a state batch', async () => {
......@@ -315,10 +351,17 @@ describe('OVM_FraudVerifier', () => {
)
expect(
Mock__OVM_StateCommitmentChain.getCallData('deleteStateBatch', 0)
).to.deep.equal([Object.values(DUMMY_BATCH_HEADER).map((value) => {
return Number.isInteger(value) ? BigNumber.from(value) : value
})])
Mock__OVM_StateCommitmentChain.getCallData(
'deleteStateBatch',
0
)
).to.deep.equal([
Object.values(DUMMY_BATCH_HEADER).map((value) => {
return Number.isInteger(value)
? BigNumber.from(value)
: value
}),
])
})
})
})
......
/* tslint:disable:no-empty */
import { expect } from '../../../setup'
describe('OVM_StateTransitioner', () => {
describe('proveContractState', () => {
describe('when provided an invalid code hash', () => {
it('should revert', async () => {
})
it('should revert', async () => {})
})
describe('when provided a valid code hash', () => {
describe('when provided an invalid account inclusion proof', () => {
it('should revert', async () => {
})
it('should revert', async () => {})
})
describe('when provided a valid account inclusion proof', () => {
})
describe('when provided a valid account inclusion proof', () => {})
})
})
describe('proveStorageSlot', () => {
describe('when the corresponding account is not proven', () => {
it('should revert', async () => {
})
it('should revert', async () => {})
})
describe('when the corresponding account is proven', () => {
describe('when provided an invalid slot inclusion proof', () => {
it('should revert', async () => {
})
it('should revert', async () => {})
})
describe('when provided a valid slot inclusion proof', () => {
})
describe('when provided a valid slot inclusion proof', () => {})
})
})
......@@ -47,63 +36,45 @@ describe('OVM_StateTransitioner', () => {
describe('commitContractState', () => {
describe('when the account was not changed', () => {
it('should revert', async () => {
})
it('should revert', async () => {})
})
describe('when the account was changed', () => {
describe('when the account has not been committed', () => {
it('should commit the account and update the state', async () => {
})
it('should commit the account and update the state', async () => {})
})
describe('when the account was already committed', () => {
it('should revert', () => {
})
it('should revert', () => {})
})
})
})
describe('commitStorageSlot', () => {
describe('when the slot was not changed', () => {
it('should revert', async () => {
})
it('should revert', async () => {})
})
describe('when the slot was changed', () => {
describe('when the slot has not been committed', () => {
it('should commit the slot and update the state', async () => {
})
it('should commit the slot and update the state', async () => {})
})
describe('when the slot was already committed', () => {
it('should revert', () => {
})
it('should revert', () => {})
})
})
})
describe('completeTransition', () => {
describe('when there are uncommitted accounts', () => {
it('should revert', async () => {
})
it('should revert', async () => {})
})
describe('when there are uncommitted storage slots', () => {
it('should revert', async () => {
it('should revert', async () => {})
})
})
describe('when all state changes are committed', () => {
})
describe('when all state changes are committed', () => {})
})
})
......@@ -2,19 +2,22 @@
import fsExtra from 'fs-extra'
import { internalTask } from '@nomiclabs/buidler/config'
import { pluralize } from '@nomiclabs/buidler/internal/util/strings'
import { getArtifactFromContractOutput, saveArtifact } from '@nomiclabs/buidler/internal/artifacts'
import {
getArtifactFromContractOutput,
saveArtifact,
} from '@nomiclabs/buidler/internal/artifacts'
import {
TASK_COMPILE_GET_COMPILER_INPUT,
TASK_BUILD_ARTIFACTS,
TASK_COMPILE_GET_SOURCE_PATHS,
TASK_COMPILE_CHECK_CACHE,
TASK_COMPILE_COMPILE
TASK_COMPILE_COMPILE,
} from '@nomiclabs/buidler/builtin-tasks/task-names'
internalTask(
TASK_COMPILE_GET_COMPILER_INPUT,
async (_, { config, run }, runSuper) => {
const input = await runSuper();
const input = await runSuper()
// Insert the "storageLayout" input option.
input.settings.outputSelection['*']['*'].push('storageLayout')
......@@ -25,51 +28,51 @@ internalTask(
internalTask(TASK_BUILD_ARTIFACTS).setAction(
async ({ force }, { config, run }) => {
const sources = await run(TASK_COMPILE_GET_SOURCE_PATHS);
const sources = await run(TASK_COMPILE_GET_SOURCE_PATHS)
if (sources.length === 0) {
console.log("No Solidity source file available.");
return;
console.log('No Solidity source file available.')
return
}
const isCached: boolean = await run(TASK_COMPILE_CHECK_CACHE, { force });
const isCached: boolean = await run(TASK_COMPILE_CHECK_CACHE, { force })
if (isCached) {
console.log(
"All contracts have already been compiled, skipping compilation."
);
return;
'All contracts have already been compiled, skipping compilation.'
)
return
}
const compilationOutput = await run(TASK_COMPILE_COMPILE);
const compilationOutput = await run(TASK_COMPILE_COMPILE)
if (compilationOutput === undefined) {
return;
return
}
await fsExtra.ensureDir(config.paths.artifacts);
let numberOfContracts = 0;
await fsExtra.ensureDir(config.paths.artifacts)
let numberOfContracts = 0
for (const file of Object.values<any>(compilationOutput.contracts)) {
for (const [contractName, contractOutput] of Object.entries(file)) {
const artifact: any = getArtifactFromContractOutput(
contractName,
contractOutput
);
numberOfContracts += 1;
)
numberOfContracts += 1
// Only difference here, set the "storageLayout" field of the artifact.
artifact.storageLayout = (contractOutput as any).storageLayout
await saveArtifact(config.paths.artifacts, artifact);
await saveArtifact(config.paths.artifacts, artifact)
}
}
console.log(
"Compiled",
'Compiled',
numberOfContracts,
pluralize(numberOfContracts, "contract"),
"successfully"
);
pluralize(numberOfContracts, 'contract'),
'successfully'
)
}
)
......@@ -8,24 +8,31 @@ export const encodeRevertData = (
ovmGasRefund: number = 0
): string => {
const abiEncoded: string = ethers.utils.defaultAbiCoder.encode(
['uint256','uint256','uint256','bytes'],
['uint256', 'uint256', 'uint256', 'bytes'],
[flag, nuisanceGasLeft, ovmGasRefund, data]
)
return abiEncoded
}
export const decodeRevertData = (
revertData: string
): any => {
export const decodeRevertData = (revertData: string): any => {
// const length: number = revertData.length/2 - 1
// const reencodedRevertData = '0x' + hexZeroPad('0x' + length.toString(16), 32) + revertData.slice(2)
const decoded = ethers.utils.defaultAbiCoder.decode(
['uint256','uint256','uint256','bytes'],
['uint256', 'uint256', 'uint256', 'bytes'],
revertData
)
console.log(`flag is: ${decoded[0].toNumber()}`)
return '[revertFlag:' + Object.keys(REVERT_FLAGS)[decoded[0]] + ', nuisanceGasLeft:' + decoded[1] + ', ovmGasRefund: ' + decoded[2] + ', data: ' + decoded[3] + ']'
return (
'[revertFlag:' +
Object.keys(REVERT_FLAGS)[decoded[0]] +
', nuisanceGasLeft:' +
decoded[1] +
', ovmGasRefund: ' +
decoded[2] +
', data: ' +
decoded[3] +
']'
)
}
export const REVERT_FLAGS = {
......@@ -37,5 +44,5 @@ export const REVERT_FLAGS = {
UNSAFE_BYTECODE: 5,
CREATE_COLLISION: 6,
STATIC_VIOLATION: 7,
CREATE_EXCEPTION: 8
CREATE_EXCEPTION: 8,
}
......@@ -5,7 +5,7 @@ import { makeAddress } from '../byte-utils'
import { OVMAccount } from '../types/ovm-types'
export const DUMMY_ACCOUNTS: Array<{
address: string,
address: string
data: OVMAccount
}> = [
{
......@@ -27,5 +27,5 @@ export const DUMMY_ACCOUNTS: Array<{
codeHash: DUMMY_BYTES32[3],
ethAddress: NON_ZERO_ADDRESS,
},
}
},
]
......@@ -3,7 +3,7 @@ import { NON_ZERO_ADDRESS } from '../constants'
export const DUMMY_CONTEXT = {
GLOBAL: {
ovmCHAINID: 11
ovmCHAINID: 11,
},
TRANSACTION: {
ovmORIGIN: NON_ZERO_ADDRESS,
......@@ -15,6 +15,6 @@ export const DUMMY_CONTEXT = {
MESSAGE: {
ovmCALLER: NON_ZERO_ADDRESS,
ovmADDRESS: NON_ZERO_ADDRESS,
ovmSTATICCTX: true
}
ovmSTATICCTX: true,
},
}
......@@ -24,7 +24,7 @@ export const bindMockWatcherToVM = (): void => {
// Set up some things we'll need for later.
let txid: string
let messages: Array<{
const messages: Array<{
address: string
sighash: string
calldata: string
......@@ -34,7 +34,7 @@ export const bindMockWatcherToVM = (): void => {
// Modify the vm.runTx function to capture an ID for each transaction.
const originalRunTx = vm.runTx.bind(vm)
const modifiedRunTx = async (opts: any): Promise<any> => {
function modifiedRunTx(opts: any): Promise<any> {
// Buidler runs transactions multiple times (e.g., for gas estimation).
// Here we're computing a unique ID for each transaction (based on sender,
// nonce, and transaction data) so that we don't log calls multiple times.
......@@ -54,7 +54,7 @@ export const bindMockWatcherToVM = (): void => {
// Modify the pre-message handler to capture calldata.
const originalBeforeMessageHandler = vmTracer['_beforeMessageHandler' as any]
const modifiedBeforeMessageHandler = async (message: any, next: any) => {
function modifiedBeforeMessageHandler(message: any, next: any) {
// We only care about capturing if we're sending to one of our mocks.
const address = message.to
? toHexString(message.to).toLowerCase()
......@@ -93,7 +93,7 @@ export const bindMockWatcherToVM = (): void => {
// Modify the post-message handler to insert the correct return data.
const originalAfterMessageHandler = vmTracer['_afterMessageHandler' as any]
const modifiedAfterMessageHandler = async (result: any, next: any) => {
function modifiedAfterMessageHandler(result: any, next: any) {
// We don't need to do anything if we haven't stored any mock messages.
if (messages.length > 0) {
// We need to look at the messages backwards since the first result will
......@@ -107,12 +107,10 @@ export const bindMockWatcherToVM = (): void => {
const inputParams = contract.__spec
? contract.__spec.interface.decodeFunctionData(
fn.functionName,
contract.__spec.interface.getSighash(fn.functionName) + message.calldata.slice(2)
)
: ethers.utils.defaultAbiCoder.decode(
fn.inputTypes,
message.calldata
contract.__spec.interface.getSighash(fn.functionName) +
message.calldata.slice(2)
)
: ethers.utils.defaultAbiCoder.decode(fn.inputTypes, message.calldata)
const returnValues = Array.isArray(fn.returnValues)
? fn.returnValues
......@@ -175,18 +173,20 @@ export const bindMockContractToVM = (
}
}
const sighash = mock.interface.getSighash(functionName)
return calls[sighash] || []
const sig = mock.interface.getSighash(functionName)
return calls[sig] || []
}
if (!Array.isArray(spec)) {
;(mock as any).__spec = spec
;(mock as any).__sigmap = Object.keys(mock.interface.functions).reduce((sigmap, fn) => {
;(mock as any).__sigmap = Object.keys(mock.interface.functions).reduce(
(sigmap, fn) => {
fn = fn.split('(')[0]
sigmap[spec.interface.getSighash(fn)] = mock.interface.getSighash(fn)
return sigmap
}, {})
},
{}
)
}
;(mock as any).getCallCount = (functionName: string): number => {
......@@ -204,9 +204,7 @@ export const bindMockContractToVM = (
const iface = mock.__spec ? mock.__spec.interface : mock.interface
const calldata = iface.getSighash(functionName) + calls[callIndex].slice(10)
return iface
.decodeFunctionData(functionName, calldata)
.map((element) => {
return iface.decodeFunctionData(functionName, calldata).map((element) => {
return element
})
}
......
......@@ -6,11 +6,7 @@ import { FunctionFragment, ParamType } from 'ethers/lib/utils'
/* Internal Imports */
import { MockContract, MockContractFunction } from './mock-contract.types'
import { bindMockContractToVM, bindMockWatcherToVM } from './mock-binding'
import {
SolidityCompiler,
getDefaultCompiler,
compile,
} from '../compilation'
import { SolidityCompiler, getDefaultCompiler, compile } from '../compilation'
/**
* Generates contract code for a mock contract.
......@@ -210,12 +206,12 @@ export const getMockContract = async (
originalDefinePropertyFn(object, name, props)
}
const MockContract = (await MockContractFactory.deploy()) as MockContract
const mock = (await MockContractFactory.deploy()) as MockContract
Object.defineProperty = originalDefinePropertyFn
bindMockWatcherToVM()
bindMockContractToVM(MockContract, fns, spec)
bindMockContractToVM(mock, fns, spec)
return MockContract
return mock
}
......@@ -19,10 +19,7 @@ export const makeProxies = async (
Proxy_Manager.address
)
await Proxy_Manager.setProxy(
name,
Proxy_Forwarder.address
)
await Proxy_Manager.setProxy(name, Proxy_Forwarder.address)
}
}
......@@ -33,14 +30,9 @@ export const setProxyTarget = async (
): Promise<void> => {
await makeProxies(Proxy_Manager, [name])
await Proxy_Manager.setTarget(
name,
target.address
)
await Proxy_Manager.setTarget(name, target.address)
}
export const getProxyManager = async (): Promise<Contract> => {
return (await ethers.getContractFactory(
'Proxy_Manager'
)).deploy()
return (await ethers.getContractFactory('Proxy_Manager')).deploy()
}
import bre, { ethers } from '@nomiclabs/buidler'
import { Contract, BigNumber, ContractFactory } from "ethers";
import { keccak256, defaultAbiCoder } from "ethers/lib/utils";
import { Contract, BigNumber, ContractFactory } from 'ethers'
import { keccak256, defaultAbiCoder } from 'ethers/lib/utils'
import { remove0x } from '../byte-utils'
import { readArtifact } from '@nomiclabs/buidler/internal/artifacts';
import { readArtifact } from '@nomiclabs/buidler/internal/artifacts'
const getFlattenedKeys = (
depth: number,
value: any,
): string[] => {
const getFlattenedKeys = (depth: number, value: any): string[] => {
if (depth === 0) {
return []
}
let keys = Object.keys(value)
if (depth > 1) {
keys = keys.concat(
getFlattenedKeys(
depth - 1,
Object.values(value)[0]
)
)
keys = keys.concat(getFlattenedKeys(depth - 1, Object.values(value)[0]))
}
return keys
......@@ -38,29 +30,25 @@ const toHexString32 = (
}
}
const getFlattenedValues = (
depth: number,
value: any
): any[] => {
const getFlattenedValues = (depth: number, value: any): any[] => {
if (depth > 0) {
return getFlattenedValues(
depth - 1,
Object.values(value)[0]
)
return getFlattenedValues(depth - 1, Object.values(value)[0])
}
if (typeof value === 'object' && value !== null) {
return Object.keys(value).map((key) => {
return {
label: key,
value: toHexString32(value[key])
value: toHexString32(value[key]),
}
})
} else {
return [{
label: "default",
value: toHexString32(value)
}]
return [
{
label: 'default',
value: toHexString32(value),
},
]
}
}
......@@ -68,33 +56,24 @@ const getStorageSlotHash = (
slot: number,
depth: number,
value: any
): string =>{
): string => {
let keys = []
if (typeof value === 'object' && value !== null) {
keys = getFlattenedKeys(depth, value)
}
if (keys.length === 0) {
return defaultAbiCoder.encode(
['uint256'],
[slot]
)
return defaultAbiCoder.encode(['uint256'], [slot])
} else {
let slotHash = toHexString32(slot)
for (const key of keys) {
slotHash = keccak256(
toHexString32(key) +
remove0x(slotHash)
)
slotHash = keccak256(toHexString32(key) + remove0x(slotHash))
}
return slotHash
}
}
const parseInputSlots = (
layout: any,
inputTypeName: string
): any[] => {
const parseInputSlots = (layout: any, inputTypeName: string): any[] => {
const inputType = layout.types[inputTypeName]
if (inputType.encoding === 'mapping') {
......@@ -104,14 +83,16 @@ const parseInputSlots = (
return inputType.members.map((member: any) => {
return {
label: member.label,
slot: member.slot
slot: member.slot,
}
})
} else {
return [{
label: "default",
slot: 0
}]
return [
{
label: 'default',
slot: 0,
},
]
}
} else {
throw new Error('Encoding type not supported.')
......@@ -122,17 +103,23 @@ export const getModifiableStorageFactory = async (
name: string
): Promise<ContractFactory> => {
const contractFactory = await ethers.getContractFactory(name)
const proxyFactory = await ethers.getContractFactory('Helper_ModifiableStorage')
const proxyFactory = await ethers.getContractFactory(
'Helper_ModifiableStorage'
)
const originalDeploy = contractFactory.deploy.bind(contractFactory)
contractFactory.deploy = async (...args: any[]): Promise<Contract> => {
const originalDefinePropertyFn = Object.defineProperty
Object.defineProperty = (object: any, name: string, props: any): void => {
Object.defineProperty = (
object: any,
propName: string,
props: any
): void => {
if (props.writable === false) {
props.writable = true
}
originalDefinePropertyFn(object, name, props)
originalDefinePropertyFn(object, propName, props)
}
const contract = await originalDeploy(...args)
......@@ -144,14 +131,16 @@ export const getModifiableStorageFactory = async (
;(contract as any).__setContractStorage = async (value: any) => {
await setContractStorage(
contract,
(await readArtifact(bre.config.paths.artifacts, name) as any).storageLayout,
((await readArtifact(bre.config.paths.artifacts, name)) as any)
.storageLayout,
value
)
}
;(contract as any).__checkContractStorage = async (value: any) => {
await checkContractStorage(
contract,
(await readArtifact(bre.config.paths.artifacts, name) as any).storageLayout,
((await readArtifact(bre.config.paths.artifacts, name)) as any)
.storageLayout,
value
)
}
......@@ -171,40 +160,35 @@ export const setContractStorage = async (
storage = storage || {}
for (const [key, value] of Object.entries(storage)) {
const layoutMap = layout.storage.find((layoutMap: any) => {
return layoutMap.label === key
const layoutMap = layout.storage.find((lmap: any) => {
return lmap.label === key
})
const inputSlots = parseInputSlots(layout, layoutMap.type)
const slot = parseInt(layoutMap.slot)
const slot = parseInt(layoutMap.slot, 10)
const depth = (layoutMap.type.match(/t_mapping/g) || []).length
if (typeof value !== 'object') {
const slotHash = getStorageSlotHash(slot, depth, value)
await contract.__setStorageSlot(
slotHash,
toHexString32(value as string)
)
await contract.__setStorageSlot(slotHash, toHexString32(value as string))
} else {
for (const [subKey, subValue] of Object.entries(value)) {
const baseSlotHash = getStorageSlotHash(slot, depth, {
[subKey]: subValue
[subKey]: subValue,
})
const slotValues = getFlattenedValues(depth, {
[subKey]: subValue
[subKey]: subValue,
})
for (let i = 0; i < slotValues.length; i++) {
const slotValue = slotValues[i]
for (const slotValue of slotValues) {
const slotIndex = inputSlots.find((inputSlot) => {
return inputSlot.label === slotValue.label
}).slot
const slotHash = toHexString32(BigNumber.from(baseSlotHash).add(slotIndex))
await contract.__setStorageSlot(
slotHash,
slotValue.value
const slotHash = toHexString32(
BigNumber.from(baseSlotHash).add(slotIndex)
)
await contract.__setStorageSlot(slotHash, slotValue.value)
}
}
}
......@@ -219,45 +203,48 @@ export const checkContractStorage = async (
storage = storage || {}
for (const [key, value] of Object.entries(storage)) {
const layoutMap = layout.storage.find((layoutMap: any) => {
return layoutMap.label === key
const layoutMap = layout.storage.find((lmap: any) => {
return lmap.label === key
})
const inputSlots = parseInputSlots(layout, layoutMap.type)
const slot = parseInt(layoutMap.slot)
const slot = parseInt(layoutMap.slot, 10)
const depth = (layoutMap.type.match(/t_mapping/g) || []).length
if (typeof value !== 'object') {
const slotHash = getStorageSlotHash(slot, depth, value)
const retSlotValue = await contract.__getStorageSlot(
slotHash
)
const retSlotValue = await contract.__getStorageSlot(slotHash)
if (retSlotValue !== toHexString32(value as string)) {
throw new Error(`Resulting state of ${key} (${retSlotValue}) did not match expected state (${toHexString32(value as string)})`)
throw new Error(
`Resulting state of ${key} (${retSlotValue}) did not match expected state (${toHexString32(
value as string
)})`
)
}
} else {
for (const [subKey, subValue] of Object.entries(value)) {
const baseSlotHash = getStorageSlotHash(slot, depth, {
[subKey]: subValue
[subKey]: subValue,
})
const slotValues = getFlattenedValues(depth, {
[subKey]: subValue
[subKey]: subValue,
})
for (let i = 0; i < slotValues.length; i++) {
const slotValue = slotValues[i]
for (const slotValue of slotValues) {
const slotIndex = inputSlots.find((inputSlot) => {
return inputSlot.label === slotValue.label
}).slot
const slotHash = toHexString32(BigNumber.from(baseSlotHash).add(slotIndex))
const retSlotValue = await contract.__getStorageSlot(
slotHash
const slotHash = toHexString32(
BigNumber.from(baseSlotHash).add(slotIndex)
)
const retSlotValue = await contract.__getStorageSlot(slotHash)
if (retSlotValue !== slotValue.value) {
throw new Error(`Resulting state of ${slotValue.label} (${retSlotValue}) did not match expected state (${slotValue.value}).`)
throw new Error(
`Resulting state of ${slotValue.label} (${retSlotValue}) did not match expected state (${slotValue.value}).`
)
}
}
}
......
......@@ -37,7 +37,7 @@ export class DefaultTestGenerator implements TestCallGenerator {
protected ovmCreateHelper: Interface,
protected ovmRevertHelper: Contract,
protected ovmInvalidHelper: Contract,
protected step: TestStep,
protected step: TestStep
) {}
getFunctionParams(): any[] {
......@@ -82,14 +82,14 @@ export class DefaultTestGenerator implements TestCallGenerator {
}
interpretActualReturnData(data: string, succeeded: boolean): string {
let interpretation: string = 'call to EM.' + this.step.functionName + ' returned values:'
interpretation += succeeded ?
this.ovmExecutionManager.interface.decodeFunctionResult(
let interpretation: string =
'call to EM.' + this.step.functionName + ' returned values:'
interpretation += succeeded
? this.ovmExecutionManager.interface.decodeFunctionResult(
this.step.functionName,
data
)
:
decodeRevertData(data)
: decodeRevertData(data)
return interpretation
}
}
......@@ -113,16 +113,13 @@ export class ovmCALLGenerator extends DefaultTestGenerator {
return [
this.step.functionParams[0],
this.step.functionParams[1],
this.ovmCallHelper.interface.encodeFunctionData(
'runSteps',
[
this.ovmCallHelper.interface.encodeFunctionData('runSteps', [
this.getCalleeGenerators().map((calleeGenerator) => {
return calleeGenerator.getCalldata()
}),
!this.step.expectedReturnStatus,
this.ovmCreateStorer.address
]
)
this.ovmCreateStorer.address,
]),
]
}
......@@ -130,22 +127,18 @@ export class ovmCALLGenerator extends DefaultTestGenerator {
if (this.step.expectedReturnValues.length <= 1) {
return [
!this.step.expectedReturnValues[0],
this.ovmCallHelper.interface.encodeFunctionResult(
'runSteps',
[
this.ovmCallHelper.interface.encodeFunctionResult('runSteps', [
this.getCalleeGenerators().map((calleeGenerator) => {
return {
success: calleeGenerator.shouldCallSucceed(),
data: calleeGenerator.getReturnData()
data: calleeGenerator.getReturnData(),
}
})
]
)
}),
]),
]
} else {
return this.step.expectedReturnValues
}
}
interpretActualReturnData(data: string, success: boolean): string {
......@@ -153,11 +146,17 @@ export class ovmCALLGenerator extends DefaultTestGenerator {
return 'ovmCALL-type reverted with flag:' + decodeRevertData(data)
}
if (this.step.expectedReturnValues.length >1) {
return 'ovmCALL-type returned successfully with overridden return data: ' + data
if (this.step.expectedReturnValues.length > 1) {
return (
'ovmCALL-type returned successfully with overridden return data: ' +
data
)
}
const resultOfOvmCALL = this.ovmExecutionManager.interface.decodeFunctionResult(this.step.functionName, data)
const resultOfOvmCALL = this.ovmExecutionManager.interface.decodeFunctionResult(
this.step.functionName,
data
)
const resultOfSubcalls = this.ovmCallHelper.interface.decodeFunctionResult(
'runSteps',
resultOfOvmCALL[1]
......@@ -168,10 +167,25 @@ export class ovmCALLGenerator extends DefaultTestGenerator {
const generator = calleeGenerators[i]
const EMsuccess = result[0]
const EMdata = result[1]
return 'subcall ' + i + '(' + generator.getFunctionName() + ') had return status: ' + EMsuccess + ' and appears to have done: ' + generator.interpretActualReturnData(EMdata, EMsuccess)
return (
'subcall ' +
i +
'(' +
generator.getFunctionName() +
') had return status: ' +
EMsuccess +
' and appears to have done: ' +
generator.interpretActualReturnData(EMdata, EMsuccess)
)
})
return 'ovmCALL returned ' + resultOfOvmCALL[0] + ' \n with subcalls:' + JSON.stringify(interpretedResults) + '\n'
return (
'ovmCALL returned ' +
resultOfOvmCALL[0] +
' \n with subcalls:' +
JSON.stringify(interpretedResults) +
'\n'
)
}
}
......@@ -193,25 +207,26 @@ export class ovmCREATEGenerator extends DefaultTestGenerator {
getFunctionParams(): any[] {
return [
getInitcode('Helper_CodeContractForCreates') +
this.ovmCreateHelper.encodeDeploy([
this.ovmCreateHelper
.encodeDeploy([
this.getInitcodeGenerators().map((initcodeGenerator) => {
return initcodeGenerator.getCalldata()
}),
!this.step.expectedReturnStatus,
this.step.functionParams[0],
this.ovmCreateStorer.address
]).slice(2)
this.ovmCreateStorer.address,
])
.slice(2),
]
}
getReturnData(): string {
const expectedDirectEMReturnData = this.step.expectedReturnStatus ?
this.ovmExecutionManager.interface.encodeFunctionResult(
const expectedDirectEMReturnData = this.step.expectedReturnStatus
? this.ovmExecutionManager.interface.encodeFunctionResult(
this.step.functionName,
this.getReturnValues()
)
:
encodeRevertData(
: encodeRevertData(
this.step.expectedReturnValues[0],
this.step.expectedReturnValues[1],
this.step.expectedReturnValues[2],
......@@ -219,10 +234,12 @@ export class ovmCREATEGenerator extends DefaultTestGenerator {
)
const responsesShouldBeReverted = !this.step.functionParams[1]
const expectedStoredValues = responsesShouldBeReverted ? [] : this.getInitcodeGenerators().map((initcodeGenerator) => {
const expectedStoredValues = responsesShouldBeReverted
? []
: this.getInitcodeGenerators().map((initcodeGenerator) => {
return {
success: initcodeGenerator.shouldCallSucceed(), // TODO: figure out if we need this and expose in generator interface if so.
data: initcodeGenerator.getReturnData()
data: initcodeGenerator.getReturnData(),
}
})
......@@ -232,24 +249,21 @@ export class ovmCREATEGenerator extends DefaultTestGenerator {
expectedDirectEMReturnData,
this.ovmCreateStorer.interface.encodeFunctionResult(
'getLastResponses',
[
expectedStoredValues
]
)
[expectedStoredValues]
),
]
)
return expectedReturnData
}
interpretActualReturnData(data: string, success: boolean): string {
const ovmCREATEDataAndInitcodeResults = abi.decode(
['bytes', 'bytes'],
data
)
const ovmCREATEDataAndInitcodeResults = abi.decode(['bytes', 'bytes'], data)
const ovmCREATEData = ovmCREATEDataAndInitcodeResults[0]
if (!success) {
return 'ovmCREATE reverted with: ' + decodeRevertData(ovmCREATEData.toString())
return (
'ovmCREATE reverted with: ' + decodeRevertData(ovmCREATEData.toString())
)
}
// const decodedDataFromOvmCREATE = this.ovmExecutionManager.interface.decodeFunctionResult(this.step.functionName, ovmCREATEData)
......@@ -261,7 +275,17 @@ export class ovmCREATEGenerator extends DefaultTestGenerator {
)[0]
const interpretedInitcodeResults = initcodeResults.map((result, i) => {
return '\n initcode subcall ' + i + ' had response status ' + result[0] + ' and appears to have done: ' + this.getInitcodeGenerators()[i].interpretActualReturnData(result[1], result[0])
return (
'\n initcode subcall ' +
i +
' had response status ' +
result[0] +
' and appears to have done: ' +
this.getInitcodeGenerators()[i].interpretActualReturnData(
result[1],
result[0]
)
)
})
return JSON.stringify(interpretedInitcodeResults)
}
......@@ -269,24 +293,18 @@ export class ovmCREATEGenerator extends DefaultTestGenerator {
class ovmCALLToRevertGenerator extends DefaultTestGenerator {
getCalldata(): string {
return this.ovmExecutionManager.interface.encodeFunctionData(
'ovmCALL',
[
return this.ovmExecutionManager.interface.encodeFunctionData('ovmCALL', [
this.step.functionParams[0],
this.step.functionParams[1],
this.ovmRevertHelper.interface.encodeFunctionData(
'doRevert',
[
this.ovmRevertHelper.interface.encodeFunctionData('doRevert', [
encodeRevertData(
this.step.functionParams[2][0],
this.step.functionParams[2][1],
this.step.functionParams[2][2],
this.step.functionParams[2][3]
)
]
)
]
)
),
]),
])
}
getReturnData(): string {
......@@ -309,15 +327,19 @@ class ovmCALLToRevertGenerator extends DefaultTestGenerator {
interpretActualReturnData(data: string, success: boolean): string {
if (success) {
return 'ovmCALL to revert heler, which succeeded with return params:' + JSON.stringify(
return (
'ovmCALL to revert heler, which succeeded with return params:' +
JSON.stringify(
this.ovmExecutionManager.interface.decodeFunctionResult(
'ovmCALL',
data
)
)
)
} else {
return 'ovmCALL to revert helper did itself revert with flag:' + JSON.stringify(
decodeRevertData(data)
return (
'ovmCALL to revert helper did itself revert with flag:' +
JSON.stringify(decodeRevertData(data))
)
}
}
......@@ -330,17 +352,14 @@ class ovmSTATICCALLToRevertGenerator extends DefaultTestGenerator {
[
this.step.functionParams[0],
this.step.functionParams[1],
this.ovmRevertHelper.interface.encodeFunctionData(
'doRevert',
[
this.ovmRevertHelper.interface.encodeFunctionData('doRevert', [
encodeRevertData(
this.step.functionParams[2][0],
this.step.functionParams[2][1],
this.step.functionParams[2][2],
this.step.functionParams[2][3]
)
]
)
),
]),
]
)
}
......@@ -365,15 +384,19 @@ class ovmSTATICCALLToRevertGenerator extends DefaultTestGenerator {
interpretActualReturnData(data: string, success: boolean): string {
if (success) {
return 'ovmCALL to revert heler, which succeeded with return params:' + JSON.stringify(
return (
'ovmCALL to revert heler, which succeeded with return params:' +
JSON.stringify(
this.ovmExecutionManager.interface.decodeFunctionResult(
'ovmCALL',
data
)
)
)
} else {
return 'ovmCALL to revert helper did itself revert with flag:' + JSON.stringify(
decodeRevertData(data)
return (
'ovmCALL to revert helper did itself revert with flag:' +
JSON.stringify(decodeRevertData(data))
)
}
}
......@@ -381,17 +404,11 @@ class ovmSTATICCALLToRevertGenerator extends DefaultTestGenerator {
class ovmCALLToInvalidGenerator extends DefaultTestGenerator {
getCalldata(): string {
return this.ovmExecutionManager.interface.encodeFunctionData(
'ovmCALL',
[
return this.ovmExecutionManager.interface.encodeFunctionData('ovmCALL', [
this.step.functionParams[0],
this.step.functionParams[1],
this.ovmInvalidHelper.interface.encodeFunctionData(
'doInvalid',
[]
)
]
)
this.ovmInvalidHelper.interface.encodeFunctionData('doInvalid', []),
])
}
getReturnData(): string {
......@@ -414,15 +431,19 @@ class ovmCALLToInvalidGenerator extends DefaultTestGenerator {
interpretActualReturnData(data: string, success: boolean): string {
if (success) {
return 'ovmCALL to InvalidJump/OutOfGas heler, which succeeded with return params:' + JSON.stringify(
return (
'ovmCALL to InvalidJump/OutOfGas heler, which succeeded with return params:' +
JSON.stringify(
this.ovmExecutionManager.interface.decodeFunctionResult(
'ovmCALL',
data
)
)
)
} else {
return 'ovmCALL to InvalidJump/OutOfGas helper did itself revert with flag:' + JSON.stringify(
decodeRevertData(data)
return (
'ovmCALL to InvalidJump/OutOfGas helper did itself revert with flag:' +
JSON.stringify(decodeRevertData(data))
)
}
}
......@@ -430,12 +451,9 @@ class ovmCALLToInvalidGenerator extends DefaultTestGenerator {
class ovmCREATEToInvalidGenerator extends DefaultTestGenerator {
getCalldata(): string {
return this.ovmExecutionManager.interface.encodeFunctionData(
'ovmCREATE',
[
getInitcode('Helper_CodeContractForInvalidInCreation')
]
)
return this.ovmExecutionManager.interface.encodeFunctionData('ovmCREATE', [
getInitcode('Helper_CodeContractForInvalidInCreation'),
])
}
getReturnData(): string {
......@@ -457,33 +475,36 @@ class ovmCREATEToInvalidGenerator extends DefaultTestGenerator {
['bytes', 'bytes'],
[
expectedEMResponse,
this.ovmCreateStorer.interface.encodeFunctionResult('getLastResponses', [[]])
this.ovmCreateStorer.interface.encodeFunctionResult(
'getLastResponses',
[[]]
),
]
)
}
interpretActualReturnData(data: string, success: boolean): string {
const EMResponse = abi.decode(
['bytes', 'bytes'],
data
)[0]
const EMResponse = abi.decode(['bytes', 'bytes'], data)[0]
console.log(`EMResponse is ${EMResponse}, success is ${success}`)
if (success) {
return 'ovmCREATE to InvalidJump/OutOfGas IN CONSTRUCTOR heler, which succeeded returning address:' + JSON.stringify(
return (
'ovmCREATE to InvalidJump/OutOfGas IN CONSTRUCTOR heler, which succeeded returning address:' +
JSON.stringify(
this.ovmExecutionManager.interface.decodeFunctionResult(
'ovmCREATE',
EMResponse
)
)
)
} else {
return 'ovmCALL to InvalidJump/OutOfGas IN CONSTRUCTOR heler did itself revert with flag:' + JSON.stringify(
decodeRevertData(EMResponse)
return (
'ovmCALL to InvalidJump/OutOfGas IN CONSTRUCTOR heler did itself revert with flag:' +
JSON.stringify(decodeRevertData(EMResponse))
)
}
}
}
export const getTestGenerator = (
step: TestStep,
ovmExecutionManager: Contract,
......
......@@ -22,11 +22,9 @@ const setPlaceholderStrings = (
ovmStateManager: Contract,
ovmSafetyChecker: Contract,
ovmCallHelper: Contract,
ovmRevertHelper: Contract,
ovmRevertHelper: Contract
): any => {
const setPlaceholder = (
kv: string
): string => {
const setPlaceholder = (kv: string): string => {
if (kv === '$OVM_EXECUTION_MANAGER') {
return ovmExecutionManager.address
} else if (kv === '$OVM_STATE_MANAGER') {
......@@ -82,13 +80,13 @@ const setPlaceholderStrings = (
return test
}
const fixtureDeployContracts = async (): Promise <{
OVM_SafetyChecker: Contract,
OVM_StateManager: Contract,
OVM_ExecutionManager: Contract,
OVM_CallHelper: Contract,
OVM_RevertHelper: Contract,
OVM_CreateStorer: Contract,
const fixtureDeployContracts = async (): Promise<{
OVM_SafetyChecker: Contract
OVM_StateManager: Contract
OVM_ExecutionManager: Contract
OVM_CallHelper: Contract
OVM_RevertHelper: Contract
OVM_CreateStorer: Contract
OVM_InvalidHelper: Contract
}> => {
const Factory__OVM_SafetyChecker = await ethers.getContractFactory(
......@@ -115,8 +113,12 @@ const fixtureDeployContracts = async (): Promise <{
)
const OVM_SafetyChecker = await Factory__OVM_SafetyChecker.deploy()
const OVM_ExecutionManager = await Factory__OVM_ExecutionManager.deploy(OVM_SafetyChecker.address)
const OVM_StateManager = await Factory__OVM_StateManager.deploy(OVM_ExecutionManager.address)
const OVM_ExecutionManager = await Factory__OVM_ExecutionManager.deploy(
OVM_SafetyChecker.address
)
const OVM_StateManager = await Factory__OVM_StateManager.deploy(
OVM_ExecutionManager.address
)
const OVM_CallHelper = await Factory__Helper_CodeContractForCalls.deploy()
const OVM_RevertHelper = await Factory__Helper_CodeContractForReverts.deploy()
const OVM_CreateStorer = await Factory__Helper_CreateEMResponsesStorer.deploy()
......@@ -129,32 +131,28 @@ const fixtureDeployContracts = async (): Promise <{
OVM_CallHelper,
OVM_RevertHelper,
OVM_CreateStorer,
OVM_InvalidHelper
OVM_InvalidHelper,
}
}
export const runExecutionManagerTest = (
test: TestDefinition
): void => {
export const runExecutionManagerTest = (test: TestDefinition): void => {
test.preState = test.preState || {}
test.postState = test.postState || {}
describe(`Standard test: ${test.name}`, () => {
test.parameters.map((parameters) => {
if (isTestDefinition(parameters)) {
runExecutionManagerTest(
{
runExecutionManagerTest({
...parameters,
preState: {
...test.preState,
...parameters.preState
...parameters.preState,
},
postState: {
...test.postState,
...parameters.postState
}
}
)
...parameters.postState,
},
})
} else {
let OVM_SafetyChecker: Contract
let OVM_StateManager: Contract
......@@ -196,28 +194,33 @@ export const runExecutionManagerTest = (
})
beforeEach(async () => {
await OVM_ExecutionManager.__setContractStorage(replacedTest.preState.ExecutionManager)
await OVM_StateManager.__setContractStorage(replacedTest.preState.StateManager)
await OVM_ExecutionManager.__setContractStorage(
replacedTest.preState.ExecutionManager
)
await OVM_StateManager.__setContractStorage(
replacedTest.preState.StateManager
)
})
afterEach(async () => {
await OVM_ExecutionManager.__checkContractStorage({
...replacedTest.postState.ExecutionManager
...replacedTest.postState.ExecutionManager,
})
await OVM_StateManager.__checkContractStorage({
...replacedTest.postState.StateManager
...replacedTest.postState.StateManager,
})
})
parameters.steps.map((step, idx) => {
const scopedFunction = (!!test.focus) ? it.only : it
const scopedFunction = !!test.focus ? it.only : it
scopedFunction(`should run test: ${test.name} ${idx}`, async () => {
const testGenerator = getTestGenerator(
replacedParams.steps[idx],
OVM_ExecutionManager,
OVM_CallHelper,
OVM_CreateStorer,
(await ethers.getContractFactory('Helper_CodeContractForCreates')).interface,
(await ethers.getContractFactory('Helper_CodeContractForCreates'))
.interface,
OVM_RevertHelper,
OVM_InvalidHelper
)
......@@ -225,21 +228,28 @@ export const runExecutionManagerTest = (
const callResult = await OVM_ExecutionManager.provider.call({
to: OVM_ExecutionManager.address,
data: testGenerator.getCalldata(),
gasLimit: GAS_LIMIT
gasLimit: GAS_LIMIT,
})
await OVM_ExecutionManager.signer.sendTransaction({
to: OVM_ExecutionManager.address,
data: testGenerator.getCalldata(),
gasLimit: GAS_LIMIT
gasLimit: GAS_LIMIT,
})
const interpretation = testGenerator.interpretActualReturnData(callResult, true)
const interpretation = testGenerator.interpretActualReturnData(
callResult,
true
)
console.log('interpretation of actual results:\n' + interpretation) // in future we can add conditional here but for now always assume succeed
const interpretationOfExpected = testGenerator.interpretActualReturnData(testGenerator.getReturnData(), true)
console.log('interpretation of expected: \n' + interpretationOfExpected)
const interpretationOfExpected = testGenerator.interpretActualReturnData(
testGenerator.getReturnData(),
true
)
console.log(
'interpretation of expected: \n' + interpretationOfExpected
)
expect(callResult).to.equal(testGenerator.getReturnData()) //, 'got bad response, looks like it did:\n' + testGenerator.interpretActualReturnData(callResult))
})
......
......@@ -5,7 +5,12 @@ export type SolidityFunctionParameter = string | number | BigNumber
export interface TestStep {
functionName: string
functionParams: Array<SolidityFunctionParameter | SolidityFunctionParameter[] | TestStep[] | boolean>
functionParams: Array<
| SolidityFunctionParameter
| SolidityFunctionParameter[]
| TestStep[]
| boolean
>
expectedReturnStatus: boolean
expectedReturnValues: any[]
}
......@@ -18,14 +23,14 @@ export interface TestDefinition {
name: string
focus?: boolean
preState?: {
ExecutionManager?: any,
ExecutionManager?: any
StateManager?: any
},
parameters: Array<TestParameters | TestDefinition>,
}
parameters: Array<TestParameters | TestDefinition>
postState?: {
ExecutionManager?: any,
ExecutionManager?: any
StateManager?: any
},
}
}
export const isTestDefinition = (
......
{
"compilerOptions": {
"module": "commonjs",
"target": "es2017",
"declaration": true,
"noImplicitAny": false,
"removeComments": true,
"noLib": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"sourceMap": true,
"outDir": "./build",
"baseUrl": "./",
"resolveJsonModule": true,
"esModuleInterop": true
"esModuleInterop": true,
"lib": [
"es7"
],
"typeRoots": [
"node_modules/@types"
]
},
"include": ["*.ts", "**/*.ts", "artifacts/*.json"],
"exclude": ["./build", "node_modules"],
......
{
"extends": [
"tslint:latest",
"tslint-config-prettier",
"tslint-plugin-prettier"
],
"rulesDirectory": [
"tslint-no-focused-test"
],
"rules": {
"ban-types": false,
"comment-format": false,
"interface-name": false,
"max-classes-per-file": false,
"member-ordering": false,
"no-bitwise": false,
"no-empty-interface": false,
"no-implicit-dependencies": [true, "dev"],
"no-string-literal": false,
"no-submodule-imports": false,
"no-unused-expression": false,
"object-literal-sort-keys": false,
"ordered-imports": false,
"prettier": [true, "prettier-config.json"],
"semicolon": false,
"variable-name": false,
"no-focused-test": true,
"no-console": false,
"array-type": false,
"class-name": false
},
"linterOptions": {
"exclude": [
"**/node_modules/**/*"
]
}
}
......@@ -2,6 +2,27 @@
# yarn lockfile v1
"@babel/code-frame@^7.0.0":
version "7.10.4"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a"
integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==
dependencies:
"@babel/highlight" "^7.10.4"
"@babel/helper-validator-identifier@^7.10.4":
version "7.10.4"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2"
integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==
"@babel/highlight@^7.10.4":
version "7.10.4"
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.4.tgz#7d1bdfd65753538fabe6c38596cdb76d9ac60143"
integrity sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==
dependencies:
"@babel/helper-validator-identifier" "^7.10.4"
chalk "^2.0.0"
js-tokens "^4.0.0"
"@ensdomains/ens@^0.4.4":
version "0.4.5"
resolved "https://registry.yarnpkg.com/@ensdomains/ens/-/ens-0.4.5.tgz#e0aebc005afdc066447c6e22feb4eda89a5edbfc"
......@@ -2007,6 +2028,11 @@ buffer@^5.0.5, buffer@^5.2.1, buffer@^5.6.0:
base64-js "^1.0.2"
ieee754 "^1.1.4"
builtin-modules@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f"
integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=
bytes@3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6"
......@@ -2129,7 +2155,7 @@ chalk@^1.1.3:
strip-ansi "^3.0.0"
supports-color "^2.0.0"
chalk@^2.4.2:
chalk@^2.0.0, chalk@^2.3.0, chalk@^2.4.2:
version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
......@@ -2352,7 +2378,7 @@ commander@3.0.2:
resolved "https://registry.yarnpkg.com/commander/-/commander-3.0.2.tgz#6837c3fb677ad9933d1cfba42dd14d5117d6b39e"
integrity sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==
commander@^2.8.1:
commander@^2.12.1, commander@^2.8.1:
version "2.20.3"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
......@@ -3054,6 +3080,14 @@ escape-string-regexp@4.0.0:
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
eslint-plugin-prettier@^2.2.0:
version "2.7.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-2.7.0.tgz#b4312dcf2c1d965379d7f9d5b5f8aaadc6a45904"
integrity sha512-CStQYJgALoQBw3FsBzH0VOVDRnJ/ZimUlpLm226U8qgqYJfPOY/CPK6wyRInMxh73HSKg5wyRwdS4BVYYHwokA==
dependencies:
fast-diff "^1.1.1"
jest-docblock "^21.0.0"
esprima@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
......@@ -3762,6 +3796,11 @@ fast-deep-equal@^3.1.1:
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
fast-diff@^1.1.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03"
integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==
fast-json-stable-stringify@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
......@@ -5150,6 +5189,11 @@ iterate-value@^1.0.0:
es-get-iterator "^1.0.2"
iterate-iterator "^1.0.1"
jest-docblock@^21.0.0:
version "21.2.0"
resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-21.2.0.tgz#51529c3b30d5fd159da60c27ceedc195faf8d414"
integrity sha512-5IZ7sY9dBAYSV+YjQ0Ovb540Ku7AO9Z5o2Cg789xj167iQuZ2cG+z0f3Uct6WeYLbU6aQiM2pCs7sZ+4dotydw==
js-sha3@0.5.7, js-sha3@^0.5.7:
version "0.5.7"
resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.7.tgz#0d4ffd8002d5333aabaf4a23eed2f6374c9f28e7"
......@@ -5160,7 +5204,7 @@ js-sha3@0.8.0, js-sha3@^0.8.0:
resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840"
integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==
"js-tokens@^3.0.0 || ^4.0.0":
"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
......@@ -5178,7 +5222,7 @@ js-yaml@3.13.1:
argparse "^1.0.7"
esprima "^4.0.0"
js-yaml@3.14.0:
js-yaml@3.14.0, js-yaml@^3.13.1:
version "3.14.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482"
integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==
......@@ -5558,6 +5602,11 @@ liftoff@^3.1.0:
rechoir "^0.6.2"
resolve "^1.1.7"
lines-and-columns@^1.1.6:
version "1.1.6"
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00"
integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=
load-json-file@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0"
......@@ -5916,7 +5965,7 @@ mkdirp@*:
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
mkdirp@0.5.5, mkdirp@^0.5.0, mkdirp@^0.5.1:
mkdirp@0.5.5, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3:
version "0.5.5"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
......@@ -6630,6 +6679,11 @@ prepend-http@^2.0.0:
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897"
integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=
prettier@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.1.2.tgz#3050700dae2e4c8b67c4c3f666cdb8af405e1ce5"
integrity sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg==
pretty-hrtime@^1.0.0:
version "1.0.3"
resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1"
......@@ -7135,7 +7189,7 @@ resolve-url@^0.2.1:
resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=
resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.4.0, resolve@~1.17.0:
resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.3.2, resolve@^1.4.0, resolve@~1.17.0:
version "1.17.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444"
integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==
......@@ -8074,16 +8128,61 @@ ts-node@^9.0.0:
source-map-support "^0.5.17"
yn "3.1.1"
tslib@^1.9.3:
tslib@^1.13.0, tslib@^1.7.1, tslib@^1.8.1, tslib@^1.9.3:
version "1.13.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043"
integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==
tslint-config-prettier@^1.18.0:
version "1.18.0"
resolved "https://registry.yarnpkg.com/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz#75f140bde947d35d8f0d238e0ebf809d64592c37"
integrity sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg==
tslint-no-focused-test@^0.5.0:
version "0.5.0"
resolved "https://registry.yarnpkg.com/tslint-no-focused-test/-/tslint-no-focused-test-0.5.0.tgz#e0a93ef3fa64bd91c7e7437d1f183204880a8ed5"
integrity sha512-YK0PSY5XAdJaTzVIXxnUGyvB5VAi+H9yTc3e40YVtu8Ix3+zLSz4ufvX6rXT3nWpim0DR6fxXoL/Zk8JI641Vg==
tslint-plugin-prettier@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/tslint-plugin-prettier/-/tslint-plugin-prettier-2.3.0.tgz#73fe71bf9f03842ac48c104122ca9b1de012ecf4"
integrity sha512-F9e4K03yc9xuvv+A0v1EmjcnDwpz8SpCD8HzqSDe0eyg34cBinwn9JjmnnRrNAs4HdleRQj7qijp+P/JTxt4vA==
dependencies:
eslint-plugin-prettier "^2.2.0"
lines-and-columns "^1.1.6"
tslib "^1.7.1"
tslint@^6.1.3:
version "6.1.3"
resolved "https://registry.yarnpkg.com/tslint/-/tslint-6.1.3.tgz#5c23b2eccc32487d5523bd3a470e9aa31789d904"
integrity sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==
dependencies:
"@babel/code-frame" "^7.0.0"
builtin-modules "^1.1.1"
chalk "^2.3.0"
commander "^2.12.1"
diff "^4.0.1"
glob "^7.1.1"
js-yaml "^3.13.1"
minimatch "^3.0.4"
mkdirp "^0.5.3"
resolve "^1.3.2"
semver "^5.3.0"
tslib "^1.13.0"
tsutils "^2.29.0"
tsort@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/tsort/-/tsort-0.0.1.tgz#e2280f5e817f8bf4275657fd0f9aebd44f5a2786"
integrity sha1-4igPXoF/i/QnVlf9D5rr1E9aJ4Y=
tsutils@^2.29.0:
version "2.29.0"
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99"
integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==
dependencies:
tslib "^1.8.1"
tunnel-agent@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment