diff --git a/.circleci/config.yml b/.circleci/config.yml index 4cdfbcab..310233f1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -17,10 +17,12 @@ jobs: name: Run tests command: | npm run test-cov - - run: - name: Upload coverage - command: | - bash <(curl -s https://codecov.io/bash) + + # TODO: Re-enable + #- run: + # name: Upload coverage + # command: | + # bash <(curl -s https://codecov.io/bash) # This works but takes a while.... e2e-colony: @@ -53,7 +55,7 @@ jobs: sudo yarn add "$PR_PATH" --dev && sudo npm run coverage - # AND...this doesn't work either! Thanks to truffle "obtain" and circle permission denied. + # AND...this is trouble too thanks to truffle "obtain" and circle permission denied. e2e-metacoin: docker: - image: circleci/node:10.12-stretch @@ -75,16 +77,18 @@ workflows: build: jobs: - unit-test - - e2e-zeppelin - - e2e-metacoin - nightly: - triggers: - - schedule: - cron: "0 1 * * *" # 1am UTC - filters: - branches: - only: - - master - jobs: - - e2e-zeppelin + # TODO: re-enable + #- e2e-zeppelin + #- e2e-metacoin + #nightly: + # triggers: + # - schedule: + # cron: "0 1 * * *" # 1am UTC + # filters: + # branches: + # only: + # - master + # jobs: + # TODO: re-enable + #- e2e-zeppelin #- e2e-colony diff --git a/.gitignore b/.gitignore index 70336c6d..ccbbf4bb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,7 @@ -allFiredEvents -scTopics -scDebugLog coverage.json coverage/ node_modules/ .changelog .DS_Store +test/artifacts +test/cache diff --git a/.npmignore b/.npmignore new file mode 100644 index 00000000..2b4f4f7a --- /dev/null +++ b/.npmignore @@ -0,0 +1,3 @@ +test/ +.circleci/ +docs/ \ No newline at end of file diff --git a/buidler.config.js b/buidler.config.js new file mode 100644 index 00000000..4ce54044 --- /dev/null +++ b/buidler.config.js @@ -0,0 +1,18 @@ + +// Mute compiler warnings - this will need to be addressed properly in +// the Buidler plugin by overloading TASK_COMPILE_COMPILE. +const originalLog = console.log; +console.warn = () => {}; +console.log = val => val === '\n' ? null : originalLog(val); + +module.exports = { + solc: { + version: "0.5.8" + }, + paths: { + artifacts: "./test/artifacts", + cache: "./test/cache", + test: "./test/units", + sources: "./test/sources/contracts", + } +} diff --git a/lib/app.js b/lib/app.js index 832d16ee..7e146e71 100644 --- a/lib/app.js +++ b/lib/app.js @@ -1,15 +1,10 @@ const shell = require('shelljs'); const fs = require('fs'); const path = require('path'); -const childprocess = require('child_process'); -const readline = require('readline'); -const reqCwd = require('req-cwd'); const istanbul = require('istanbul'); -const treeKill = require('tree-kill'); -const getInstrumentedVersion = require('./instrumentSolidity.js'); -const CoverageMap = require('./coverageMap.js'); -const defaultTruffleConfig = require('./truffleConfig.js'); -const preprocessor = require('./preprocessor'); + +const Instrumenter = require('./instrumenter'); +const Coverage = require('./coverage'); const isWin = /^win/.test(process.platform); @@ -21,37 +16,24 @@ const gasPriceHex = 0x01; // Low gas price */ class App { constructor(config) { - this.coverageDir = './coverageEnv'; // Env that instrumented .sols are tested in + this.coverage = new Coverage(); + this.instrumenter = new Instrumenter(); + this.provider = config.provider; // Options - this.network = ''; // Default truffle network execution flag - this.silence = ''; // Default log level passed to shell - this.log = console.log; + this.silence = ''; // Default log level (passed to shell) + this.log = config.logger || console.log; // Configurable logging // Other - this.testrpcProcess = null; // ref to testrpc server we need to close on exit - this.events = null; // ref to string array loaded from 'allFiredEvents' - this.testsErrored = null; // flag set to non-null if truffle tests error - this.coverage = new CoverageMap(); // initialize a coverage map - this.originalArtifacts = []; // Artifacts from original build (we swap these in) + this.testsErrored = false; // Toggle true when tests error this.skippedFolders = []; // Config this.config = config || {}; + this.contractsDir = config.contractsDir || 'contracts'; + this.coverageDir = './.coverageEnv'; // Contracts dir of instrumented .sols this.workingDir = config.dir || '.'; // Relative path to contracts folder - this.accounts = config.accounts || 35; // Number of accounts to testrpc launches with - this.skipFiles = config.skipFiles || []; // Which files should be skipped during instrumentation - this.norpc = config.norpc || false; // Launch testrpc-sc internally? - this.port = config.port || 8555; // Port testrpc should listen on - this.buildDirPath = config.buildDirPath || '/build/contracts' // Build directory path for compiled smart contracts - - this.copyNodeModules = config.copyNodeModules || false; // Copy node modules into coverageEnv? - this.copyPackages = config.copyPackages || []; // Only copy specific node_modules packages into coverageEnv - this.testrpcOptions = config.testrpcOptions || null; // Options for testrpc-sc - this.testCommand = config.testCommand || null; // Optional test command - this.compileCommand = config.compileCommand || null; // Optional compile command - this.deepSkip = config.deepSkip || null; // Don't post-process skipped files - + this.skipFiles = config.skipFiles || []; // Files to exclude from instrumentation this.setLoggingLevel(config.silent); } @@ -59,70 +41,17 @@ class App { /** * Generates a copy of the target project configured for solidity-coverage and saves to - * the coverage environment folder. Process exits(1) if try fails + * the coverage environment folder. */ generateCoverageEnvironment() { this.log('Generating coverage environment'); try { this.sanityCheckContext(); + this.identifySkippedFolders(); - let files = shell.ls('-A', this.workingDir); - const nmIndex = files.indexOf('node_modules'); - - // Removes node_modules from array (unless requested). - if (!this.copyNodeModules && nmIndex > -1) { - files.splice(nmIndex, 1); - } - - // Identify folders to exclude - this.skipFiles.forEach(item => { - if (path.extname(item) !== '.sol') - this.skippedFolders.push(item); - }); - - files = files.map(file => `${this.workingDir}/${file}`); shell.mkdir(this.coverageDir); - shell.cp('-R', files, this.coverageDir); - - // Add specific node_modules packages. - if (!this.copyNodeModules && this.copyPackages.length) { - shell.mkdir(this.coverageDir + '/node_modules'); - this.copyPackages.forEach((nodePackage) => { - shell.mkdir('-p', this.coverageDir + '/node_modules/' + nodePackage); - shell.cp('-rfL', 'node_modules/' + nodePackage + '/.', this.coverageDir + '/node_modules/' + nodePackage); - }); - } - - // Load config - let truffleConfig; - let oldTrufflePath = `${this.workingDir}/truffle.js`; - let newTrufflePath = `${this.workingDir}/truffle-config.js`; - - if (shell.test('-e', oldTrufflePath)) truffleConfig = reqCwd.silent(oldTrufflePath); - else if (shell.test('-e', newTrufflePath)) truffleConfig = reqCwd.silent(newTrufflePath); - - // Coverage network opts specified: use port if declared - if (truffleConfig && truffleConfig.networks && truffleConfig.networks.coverage) { - this.port = truffleConfig.networks.coverage.port || this.port; - this.network = '--network coverage'; - - // No coverage network defaults to the dev network on port 8555, high gas / low price. - } else { - const trufflejs = defaultTruffleConfig(this.port, gasLimitHex, gasPriceHex); - fs.writeFileSync(`${this.coverageDir}/truffle-config.js`, trufflejs); - } - - // Compile the contracts before instrumentation and preserve their ABI's. - // We will be stripping out access modifiers like view before we recompile - // post-instrumentation. - if (shell.test('-e', `${this.coverageDir}${this.buildDirPath}`)){ - shell.rm('-Rf', `${this.coverageDir}${this.buildDirPath}`) - } - - this.runCompileCommand(); - this.originalArtifacts = this.loadArtifacts(); - shell.rm('-Rf', `${this.coverageDir}${this.buildDirPath}`); + shell.cp('-Rf', this.contractsDir, this.coverageDir) } catch (err) { const msg = ('There was a problem generating the coverage environment: '); @@ -135,31 +64,33 @@ class App { * + Generate file path reference for coverage report * + Load contract as string * + Instrument contract - * + Save instrumented contract in the coverage environment folder where covered tests will run + * + Save instrumented contract to a temp folder which will be the new 'contractsDir for tests' * + Add instrumentation info to the coverage map */ + instrumentTarget() { - this.skipFiles = this.skipFiles.map(contract => `${this.coverageDir}/contracts/${contract}`); - this.skipFiles.push(`${this.coverageDir}/contracts/Migrations.sol`); + this.skipFiles = this.skipFiles.map(contract => `${this.coverageDir}/${contract}`); + this.skipFiles.push(`${this.coverageDir}/Migrations.sol`); - const instrumentedFiles = []; let currentFile; try { - shell.ls(`${this.coverageDir}/contracts/**/*.sol`).forEach(file => { + shell.ls(`${this.coverageDir}/**/*.sol`).forEach(file => { currentFile = file; if (!this.skipFiles.includes(file) && !this.inSkippedFolder(file)) { this.log('Instrumenting ', file); + // Remember the real path const contractPath = this.platformNeutralPath(file); const working = this.workingDir.substring(1); const canonicalPath = contractPath.split('/coverageEnv').join(working); - const contract = fs.readFileSync(contractPath).toString(); - const instrumentedContractInfo = getInstrumentedVersion(contract, canonicalPath); - fs.writeFileSync(contractPath, instrumentedContractInfo.contract); - this.coverage.addContract(instrumentedContractInfo, canonicalPath); - instrumentedFiles.push(file); + // Instrument contract, save, add to coverage map + const contract = this.loadContract(contractPath); + const instrumented = this.instrumenter.instrument(contract, canonicalPath); + this.saveContract(contractPath, instrumented.contract); + this.coverage.addContract(instrumented, canonicalPath); + } else { this.log('Skipping instrumentation of ', file); } @@ -169,196 +100,58 @@ class App { this.cleanUp(msg + err); } - // Strip any view / pure modifiers in other files in case they depend on any instrumented files - shell - .ls(`${this.coverageDir}/**/*.sol`) - .filter(file => !instrumentedFiles.includes(file)) - .forEach(file => { - - // Skip post-processing of skipped files - if (this.deepSkip && (this.skipFiles.includes(file) || this.inSkippedFolder(file))) return; - - const contractPath = this.platformNeutralPath(file); - const contract = fs.readFileSync(contractPath).toString(); - const contractProcessed = preprocessor.run(contract); - if (contractProcessed.name && contractProcessed.name === 'SyntaxError' && file.slice(-15) !== 'SimpleError.sol') { - console.log(`Warning: The file at ${file} was identified as a Solidity Contract, ` + - 'but did not parse correctly. You may ignore this warning if it is not a Solidity file, ' + - 'or your project does not use it'); - } else { - fs.writeFileSync(contractPath, contractProcessed); - } - }); - - // Now that they've been modified, compile all the contracts again - this.runCompileCommand(); - - // And swap the original abis into the instrumented artifacts so that truffle etc uses 'call' - // on them. - this.modifyArtifacts(); + this.collector = new DataCollector( + this.provider, + this.instrumenter.intrumentationData + ) } /** - * Run modified testrpc with large block limit, on (hopefully) unused port. - * Changes here should be also be added to the before() block of test/run.js). - * @return {Promise} Resolves when testrpc prints 'Listening' to std out / norpc is true. + * Generate coverage / write coverage report / run istanbul */ - launchTestrpc() { - return new Promise((resolve, reject) => { - if (!this.norpc) { - const defaultRpcOptions = `--accounts ${this.accounts} --port ${this.port}`; - const options = (this.testrpcOptions || defaultRpcOptions) + ` --gasLimit ${gasLimitHex}`; - - // Launch - const execOpts = {maxBuffer: 1024 * 1024 * 100}; - this.testrpcProcess = childprocess.exec(`npx testrpc-sc ${options}`, execOpts, (err, stdout, stderr) => { - if (err) { - if (stdout) this.log(`testRpc stdout:\n${stdout}`); - if (stderr) this.log(`testRpc stderr:\n${stderr}`); - this.cleanUp('testRpc errored after launching as a childprocess.'); - } - }); + async generateReport() { + const collector = new istanbul.Collector(); + const reporter = new istanbul.Reporter(); - // Resolve when testrpc logs that it's listening. - this.testrpcProcess.stdout.on('data', data => { - if (data.includes('Listening')) { - this.log(`Launched testrpc on port ${this.port}`); - return resolve(); - } + return new Promise((resolve, reject) => { + try { + const contractsPath = `${this.workingDir}/${this.config.contractsDir}` + this.coverage.generate(this.instrumenter.instrumentationData, contractsPath); + + const relativeMapping = this.makeKeysRelative(this.coverage.data, this.workingDir); + this.saveCoverage(relativeMapping); + + collector.add(relativeMapping); + reporter.add('html'); + reporter.add('lcov'); + reporter.add('text'); + + reporter.write(collector, true, () => { + this.log('Istanbul coverage reports generated'); + this.cleanUp(); + resolve(); }); - } else { - return resolve(); + } catch (err) { + const msg = 'There was a problem generating the coverage map / running Istanbul.\n'; + console.log(err.stack); + this.cleanUp(msg + err); } }); } - /** - * Run truffle (or config.testCommand) over instrumented contracts in the - * coverage environment folder. Shell cd command needs to be invoked - * as its own statement for command line options to work, apparently. - * Also reads the 'allFiredEvents' log. - */ - runTestCommand() { - try { - const defaultCommand = `truffle test ${this.network} ${this.silence}`; - const command = this.testCommand || defaultCommand; - this.log(`Running: ${command}\n(this can take a few seconds)...`); - shell.cd(this.coverageDir); - shell.exec(command); - this.testsErrored = shell.error(); - shell.cd('./..'); - } catch (err) { - const msg = - ` - There was an error generating coverage. Possible reasons include: - 1. Another application is using port ${this.port} - 2. Your test runner (Truffle?) crashed because the tests encountered an error. - - `; - this.cleanUp(msg + err); - } - } - - /** - * Run truffle compile (or config.compileCommand) over instrumented contracts in the - * coverage environment folder. Shell cd command needs to be invoked - * as its own statement for command line options to work, apparently. - */ - runCompileCommand() { - try { - const defaultCommand = `truffle compile ${this.network} ${this.silence}`; - const command = this.compileCommand || defaultCommand; - this.log(`Running: ${command}\n(this can take a few seconds)...`); - - shell.cd(this.coverageDir); - shell.exec(command); - this.testsErrored = shell.error(); - shell.cd('./..'); - } catch (err) { - const msg = - ` - There was an error compiling the contracts. - `; - this.cleanUp(msg + err); - } - } - - /** - * Loads artifacts generated by compiling the contracts before we instrument them. - * @return {Array} Array of artifact objects - */ - loadArtifacts() { - const artifacts = []; - - shell.ls(`${this.coverageDir}${this.buildDirPath}/*.json`).forEach(file => { - const artifactPath = this.platformNeutralPath(file); - const artifactRaw = fs.readFileSync(artifactPath); - const artifact = JSON.parse(artifactRaw); - artifacts.push(artifact); - }) - return artifacts; + // ------------------------------------------ Utils ---------------------------------------------- + loadContract(_path){ + return fs.readFileSync(_path).toString(); } - /** - * Swaps original ABIs into artifacts generated post-instrumentation. We are stripping - * access modifiers like `view` out of the source during that step and need to ensure - * truffle automatically invokes those methods by `.call`, based on the ABI sig. - */ - modifyArtifacts(){ - shell.ls(`${this.coverageDir}${this.buildDirPath}/*.json`).forEach((file, index) => { - const artifactPath = this.platformNeutralPath(file); - const artifactRaw = fs.readFileSync(artifactPath); - const artifact = JSON.parse(artifactRaw); - artifact.abi = this.originalArtifacts[index].abi; - fs.writeFileSync(artifactPath, JSON.stringify(artifact)); - }) + saveContract(_path, contract){ + fs.writeFileSync(_path, contract); } - /** - * Generate coverage / write coverage report / run istanbul - */ - generateReport() { - const collector = new istanbul.Collector(); - const reporter = new istanbul.Reporter(); - - return new Promise((resolve, reject) => { - // Get events fired during instrumented contracts execution. - const stream = fs.createReadStream(`./allFiredEvents`); - stream.on('error', err => this.cleanUp('Event trace could not be read.\n' + err)); - const reader = readline.createInterface({ - input: stream, - }); - this.events = []; - reader - .on('line', line => this.events.push(line)) - .on('close', () => { - // Generate Istanbul report - try { - this.coverage.generate(this.events, `${this.workingDir}/contracts`); - const relativeMapping = this.makeKeysRelative(this.coverage.coverage, this.workingDir); - const json = JSON.stringify(relativeMapping); - fs.writeFileSync('./coverage.json', json); - - collector.add(relativeMapping); - reporter.add('html'); - reporter.add('lcov'); - reporter.add('text'); - reporter.write(collector, true, () => { - this.log('Istanbul coverage reports generated'); - this.cleanUp(); - resolve(); - }); - } catch (err) { - const msg = 'There was a problem generating the coverage map / running Istanbul.\n'; - console.log(err.stack); - this.cleanUp(msg + err); - } - }); - }); + saveCoverage(coverageObject){ + fs.writeFileSync('./coverage.json', JSON.stringify(coverageObject)); } - // ------------------------------------------ Utils ---------------------------------------------- - sanityCheckContext(){ if (!shell.test('-e', `${this.workingDir}/contracts`)){ this.cleanUp("Couldn't find a 'contracts' folder to instrument."); @@ -367,10 +160,6 @@ class App { if (shell.test('-e', `${this.workingDir}/${this.coverageDir}`)){ shell.rm('-Rf', this.coverageDir); } - - if (shell.test('-e', `${this.workingDir}/scTopics`)){ - shell.rm(`${this.workingDir}/scTopics`); - } } /** @@ -381,16 +170,14 @@ class App { */ makeKeysRelative(map, root) { const newCoverage = {}; - Object.keys(map).forEach(pathKey => { - newCoverage[path.relative(root, pathKey)] = map[pathKey]; - }); + Object.keys(map).forEach(pathKey => newCoverage[path.relative(root, pathKey)] = map[pathKey]); return newCoverage; } /** - * Conver absolute paths from Windows, if necessary + * Normalizes windows paths * @param {String} file path - * @return {[type]} normalized path + * @return {String} normalized path */ platformNeutralPath(file) { return (isWin) @@ -400,7 +187,7 @@ class App { /** * Determines if a file is in a folder marked skippable. - * @param {String} file file path + * @param {String} file file path * @return {Boolean} */ inSkippedFolder(file){ @@ -413,6 +200,18 @@ class App { return shouldSkip; } + /** + * Helper for parsing the skipFiles option, which also accepts folders. + */ + identifySkippedFolders(){ + let files = shell.ls('-A', this.workingDir); + + this.skipFiles.forEach(item => { + if (path.extname(item) !== '.sol') + this.skippedFolders.push(item); + }); + } + /** * Allows config to turn logging off (for CI) * @param {Boolean} isSilent @@ -424,10 +223,14 @@ class App { } } + + /** * Removes coverage build artifacts, kills testrpc. * Exits (1) and prints msg on error, exits (0) otherwise. * @param {String} err error message + * + * TODO this needs to delegate process exit to the outer tool.... */ cleanUp(err) { const self = this; @@ -447,17 +250,7 @@ class App { self.log('Cleaning up...'); shell.config.silent = true; shell.rm('-Rf', self.coverageDir); - shell.rm('./allFiredEvents'); - shell.rm('./scTopics'); - - if (self.testrpcProcess) { - treeKill(self.testrpcProcess.pid, function(killError){ - self.log(`Shutting down testrpc-sc (pid ${self.testrpcProcess.pid})`) - exit(err) - }); - } else { - exit(err); - } + exit(err); } } diff --git a/lib/collector.js b/lib/collector.js new file mode 100644 index 00000000..dba22661 --- /dev/null +++ b/lib/collector.js @@ -0,0 +1,39 @@ +const web3Utils = require('web3-utils') + +class DataCollector { + constructor(config={}, instrumentationData={}){ + this.instrumentationData = instrumentationData; + + this.vm = config.vmResolver + ? config.vmResolver(config.provider) + : this._ganacheVMResolver(config.provider); + + this._connect(); + } + + // Subscribes to vm.on('step'). + _connect(){ + const self = this; + this.vm.on("step", function(info){ + + if (info.opcode.name.includes("PUSH") && info.stack.length > 0){ + const idx = info.stack.length - 1; + const hash = web3Utils.toHex(info.stack[idx]).toString(); + + if(self.instrumentationData[hash]){ + self.instrumentationData[hash].hits++; + } + } + }) + } + + _ganacheVMResolver(provider){ + return provider.engine.manager.state.blockchain.vm; + } + + _setInstrumentationData(data){ + this.instrumentationData = data; + } +} + +module.exports = DataCollector; diff --git a/lib/coverage.js b/lib/coverage.js new file mode 100644 index 00000000..b2379a05 --- /dev/null +++ b/lib/coverage.js @@ -0,0 +1,115 @@ +/** + * Converts instrumentation data accumulated a the vm steps to an instanbul spec coverage object. + * @type {Coverage} + */ + +const util = require('util'); + +class Coverage { + + constructor() { + this.data = {}; + this.assertData = {}; + this.lineTopics = []; + this.functionTopics = []; + this.branchTopics = []; + this.statementTopics = []; + this.assertPreTopics = []; + this.assertPostTopics = []; + } + + /** + * Initializes a coverage map object for contract + * + instrumented per `info` + * + located at `canonicalContractPath` + * @param {Object} info `info = getIntrumentedVersion(contract, fileName, true)` + * @param {String} canonicalContractPath path to contract file + * @return {Object} coverage map with all values set to zero + */ + + addContract(info, canonicalContractPath) { + this.data[canonicalContractPath] = { + l: {}, + path: canonicalContractPath, + s: {}, + b: {}, + f: {}, + fnMap: {}, + statementMap: {}, + branchMap: {}, + }; + this.assertData[canonicalContractPath] = { }; + + info.runnableLines.forEach((item, idx) => { + this.data[canonicalContractPath].l[info.runnableLines[idx]] = 0; + }); + + this.data[canonicalContractPath].fnMap = info.fnMap; + for (let x = 1; x <= Object.keys(info.fnMap).length; x++) { + this.data[canonicalContractPath].f[x] = 0; + } + + this.data[canonicalContractPath].branchMap = info.branchMap; + for (let x = 1; x <= Object.keys(info.branchMap).length; x++) { + this.data[canonicalContractPath].b[x] = [0, 0]; + this.assertData[canonicalContractPath][x] = { + preEvents: 0, + postEvents: 0, + }; + } + + this.data[canonicalContractPath].statementMap = info.statementMap; + for (let x = 1; x <= Object.keys(info.statementMap).length; x++) { + this.data[canonicalContractPath].s[x] = 0; + } + } + + /** + * Populates an empty coverage map with values derived from a hash map of + * data collected as the instrumented contracts are tested + * @param {Object} map of collected instrumentation data + * @return {Object} coverage map. + */ + generate(collectedData) { + const hashes = Object.keys(collectedData); + + for (let hash of hashes){ + const data = collectedData[hash]; + const contractPath = collectedData[hash].contractPath; + const id = collectedData[hash].id; + const hits = collectedData[hash].hits; + + switch(collectedData[hash].type){ + case 'line': this.data[contractPath].l[id] = hits; break; + case 'function': this.data[contractPath].f[id] = hits; break; + case 'statement': this.data[contractPath].s[id] = hits; break; + case 'branch': this.data[contractPath].b[id][data.locationIdx] = hits; break; + case 'assertPre': this.assertData[contractPath][id].preEvents = hits; break; + case 'assertPost': this.assertData[contractPath][id].postEvents = hits; break; + } + } + + // Finally, interpret the assert pre/post events + const contractPaths = Object.keys(this.assertData); + + for (let contractPath of contractPaths){ + const contract = this.data[contractPath]; + + for (let i = 1; i <= Object.keys(contract.b).length; i++) { + const branch = this.assertData[contractPath][i]; + + // Was it an assert branch? + if (branch && branch.preEvents > 0){ + this.data[contractPath].b[i] = [ + branch.postEvents, + branch.preEvents - branch.postEvents + ] + } + } + } + + return Object.assign({}, this.data); + } +}; + +module.exports = Coverage; diff --git a/lib/coverageMap.js b/lib/coverageMap.js deleted file mode 100644 index 1fc4deed..00000000 --- a/lib/coverageMap.js +++ /dev/null @@ -1,145 +0,0 @@ - -/** - * This file contains methods that produce a coverage map to pass to instanbul - * from data generated by `instrumentSolidity.js` - */ -const { AbiCoder } = require('web3-eth-abi'); -const SolidityCoder = AbiCoder(); -const path = require('path'); -const keccak = require('keccakjs'); -const fs = require('fs'); - -/** - * Converts solcover event data into an object that can be - * be passed to instanbul to produce coverage reports. - * @type {CoverageMap} - */ -module.exports = class CoverageMap { - - constructor() { - this.coverage = {}; - this.assertCoverage = {}; - this.lineTopics = []; - this.functionTopics = []; - this.branchTopics = []; - this.statementTopics = []; - this.assertPreTopics = []; - this.assertPostTopics = []; - } - - /** - * Initializes a coverage map object for contract instrumented per `info` and located - * at `canonicalContractPath` - * @param {Object} info `info = getIntrumentedVersion(contract, fileName, true)` - * @param {String} canonicalContractPath target file location - * @return {Object} coverage map with all values set to zero - */ - - addContract(info, canonicalContractPath) { - this.coverage[canonicalContractPath] = { - l: {}, - path: canonicalContractPath, - s: {}, - b: {}, - f: {}, - fnMap: {}, - statementMap: {}, - branchMap: {}, - }; - this.assertCoverage[canonicalContractPath] = { }; - - info.runnableLines.forEach((item, idx) => { - this.coverage[canonicalContractPath].l[info.runnableLines[idx]] = 0; - }); - this.coverage[canonicalContractPath].fnMap = info.fnMap; - for (let x = 1; x <= Object.keys(info.fnMap).length; x++) { - this.coverage[canonicalContractPath].f[x] = 0; - } - this.coverage[canonicalContractPath].branchMap = info.branchMap; - for (let x = 1; x <= Object.keys(info.branchMap).length; x++) { - this.coverage[canonicalContractPath].b[x] = [0, 0]; - this.assertCoverage[canonicalContractPath][x] = { - preEvents: 0, - postEvents: 0, - }; - } - this.coverage[canonicalContractPath].statementMap = info.statementMap; - for (let x = 1; x <= Object.keys(info.statementMap).length; x++) { - this.coverage[canonicalContractPath].s[x] = 0; - } - - const keccakhex = (x => { - const hash = new keccak(256); // eslint-disable-line new-cap - hash.update(x); - return hash.digest('hex'); - }); - - const lineHash = keccakhex('__Coverage' + info.contractName + '(string,uint256)'); - const fnHash = keccakhex('__FunctionCoverage' + info.contractName + '(string,uint256)'); - const branchHash = keccakhex('__BranchCoverage' + info.contractName + '(string,uint256,uint256)'); - const statementHash = keccakhex('__StatementCoverage' + info.contractName + '(string,uint256)'); - const assertPreHash = keccakhex('__AssertPreCoverage' + info.contractName + '(string,uint256)'); - const assertPostHash = keccakhex('__AssertPostCoverage' + info.contractName + '(string,uint256)'); - - this.lineTopics.push(lineHash); - this.functionTopics.push(fnHash); - this.branchTopics.push(branchHash); - this.statementTopics.push(statementHash); - this.assertPreTopics.push(assertPreHash); - this.assertPostTopics.push(assertPostHash); - - const topics = `${lineHash}\n${fnHash}\n${branchHash}\n${statementHash}\n${assertPreHash}\n${assertPostHash}\n`; - fs.appendFileSync('./scTopics', topics); - } - - /** - * Populates an empty coverage map with values derived from an array of events - * fired by instrumented contracts as they are tested - * @param {Array} events - * @param {String} relative path to host contracts eg: './../contracts' - * @return {Object} coverage map. - */ - generate(events, pathPrefix) { - for (let idx = 0; idx < events.length; idx++) { - const event = JSON.parse(events[idx]); - - if (event.topics.filter(t => this.lineTopics.indexOf(t) >= 0).length > 0) { - const data = SolidityCoder.decodeParameters(['string', 'uint256'], `0x${event.data}`); - const canonicalContractPath = data[0]; - this.coverage[canonicalContractPath].l[parseInt(data[1], 10)] += 1; - } else if (event.topics.filter(t => this.functionTopics.indexOf(t) >= 0).length > 0) { - const data = SolidityCoder.decodeParameters(['string', 'uint256'], `0x${event.data}`); - const canonicalContractPath = data[0]; - this.coverage[canonicalContractPath].f[parseInt(data[1], 10)] += 1; - } else if (event.topics.filter(t => this.branchTopics.indexOf(t) >= 0).length > 0) { - const data = SolidityCoder.decodeParameters(['string', 'uint256', 'uint256'], `0x${event.data}`); - const canonicalContractPath = data[0]; - this.coverage[canonicalContractPath].b[parseInt(data[1], 10)][parseInt(data[2], 10)] += 1; - } else if (event.topics.filter(t => this.statementTopics.indexOf(t) >= 0).length > 0) { - const data = SolidityCoder.decodeParameters(['string', 'uint256'], `0x${event.data}`); - const canonicalContractPath = data[0]; - this.coverage[canonicalContractPath].s[parseInt(data[1], 10)] += 1; - } else if (event.topics.filter(t => this.assertPreTopics.indexOf(t) >= 0).length > 0) { - const data = SolidityCoder.decodeParameters(['string', 'uint256'], `0x${event.data}`); - const canonicalContractPath = data[0]; - this.assertCoverage[canonicalContractPath][parseInt(data[1], 10)].preEvents += 1; - } else if (event.topics.filter(t => this.assertPostTopics.indexOf(t) >= 0).length > 0) { - const data = SolidityCoder.decodeParameters(['string', 'uint256'], `0x${event.data}`); - const canonicalContractPath = data[0]; - this.assertCoverage[canonicalContractPath][parseInt(data[1], 10)].postEvents += 1; - } - } - // Finally, interpret the assert pre/post events - Object.keys(this.assertCoverage).forEach(contractPath => { - const contract = this.coverage[contractPath]; - for (let i = 1; i <= Object.keys(contract.b).length; i++) { - const branch = this.assertCoverage[contractPath][i]; - if (branch.preEvents > 0) { - // Then it was an assert branch. - this.coverage[contractPath].b[i] = [branch.postEvents, branch.preEvents - branch.postEvents]; - } - } - }); - return Object.assign({}, this.coverage); - } -}; diff --git a/lib/injector.js b/lib/injector.js index 6e7306f4..db1722fc 100644 --- a/lib/injector.js +++ b/lib/injector.js @@ -1,77 +1,184 @@ -const injector = {}; - -// These functions are used to actually inject the instrumentation events. - -injector.callEvent = function injectCallEvent(contract, fileName, injectionPoint) { - const linecount = (contract.instrumented.slice(0, injectionPoint).match(/\n/g) || []).length + 1; - contract.runnableLines.push(linecount); - contract.instrumented = contract.instrumented.slice(0, injectionPoint) + - 'emit __Coverage' + contract.contractName + '(\'' + fileName + '\',' + linecount + ');\n' + - contract.instrumented.slice(injectionPoint); -}; - -injector.callFunctionEvent = function injectCallFunctionEvent(contract, fileName, injectionPoint, injection) { - contract.instrumented = contract.instrumented.slice(0, injectionPoint) + - 'emit __FunctionCoverage' + contract.contractName + '(\'' + fileName + '\',' + injection.fnId + ');\n' + - contract.instrumented.slice(injectionPoint); -}; - -injector.callBranchEvent = function injectCallFunctionEvent(contract, fileName, injectionPoint, injection) { - contract.instrumented = contract.instrumented.slice(0, injectionPoint) + - (injection.openBracket ? '{' : '') + - 'emit __BranchCoverage' + contract.contractName + '(\'' + fileName + '\',' + injection.branchId + ',' + injection.locationIdx + ')' + - (injection.comma ? ',' : ';') + - contract.instrumented.slice(injectionPoint); -}; - -injector.callEmptyBranchEvent = function injectCallEmptyBranchEvent(contract, fileName, injectionPoint, injection) { - contract.instrumented = contract.instrumented.slice(0, injectionPoint) + - 'else { emit __BranchCoverage' + contract.contractName + '(\'' + fileName + '\',' + injection.branchId + ',' + injection.locationIdx + ');}\n' + - contract.instrumented.slice(injectionPoint); -}; - - -injector.callAssertPreEvent = function callAssertPreEvent(contract, fileName, injectionPoint, injection) { - contract.instrumented = contract.instrumented.slice(0, injectionPoint) + - 'emit __AssertPreCoverage' + contract.contractName + '(\'' + fileName + '\',' + injection.branchId + ');\n' + - contract.instrumented.slice(injectionPoint); -}; - -injector.callAssertPostEvent = function callAssertPostEvent(contract, fileName, injectionPoint, injection) { - contract.instrumented = contract.instrumented.slice(0, injectionPoint) + - 'emit __AssertPostCoverage' + contract.contractName + '(\'' + fileName + '\',' + injection.branchId + ');\n' + - contract.instrumented.slice(injectionPoint); +const sha1 = require("sha1"); +const web3Utils = require("web3-utils"); + +class Injector { + constructor(){ + this.hashCounter = 0; + this.definitionCounter = 0; + } + + /** + * Generates solidity statement to inject for line, stmt, branch, fn 'events' + * @param {String} memoryVariable + * @param {String} hash hash key to an instrumentationData entry (see _getHash) + * @param {String} type instrumentation type, e.g. line, statement + * @return {String} ex: _sc_82e0891[0] = bytes32(0xdc08...08ed1); // function + */ + _getInjectable(memoryVariable, hash, type){ + return `${memoryVariable}[0] = bytes32(${hash}); /* ${type} */ \n`; + } + + + _getHash(fileName) { + this.hashCounter++; + return web3Utils.keccak256(`${fileName}:${this.hashCounter}`); + } + + /** + * Generates a solidity statement injection. Declared once per fn. + * Definition is the same for every fn in file. + * @param {String} fileName + * @return {String} ex: bytes32[1] memory _sc_82e0891 + */ + _getMemoryVariableDefinition(fileName){ + this.definitionCounter++; + return `\nbytes32[1] memory _sc_${sha1(fileName).slice(0,7)};\n`; + } + + _getMemoryVariableAssignment(fileName){ + return `\n_sc_${sha1(fileName).slice(0,7)}`; + } + + + injectLine(contract, fileName, injectionPoint, injection, instrumentation){ + const type = 'line'; + const start = contract.instrumented.slice(0, injectionPoint); + const end = contract.instrumented.slice(injectionPoint); + + const newLines = start.match(/\n/g); + const linecount = ( newLines || []).length + 1; + contract.runnableLines.push(linecount); + + const hash = this._getHash(fileName); + const memoryVariable = this._getMemoryVariableAssignment(fileName); + const injectable = this._getInjectable(memoryVariable, hash , type) + + instrumentation[hash] = { + id: linecount, + type: type, + contractPath: fileName, + hits: 0 + } + + contract.instrumented = `${start}${injectable}${end}`; + } + + injectStatement(contract, fileName, injectionPoint, injection, instrumentation) { + const type = 'statement'; + const start = contract.instrumented.slice(0, injectionPoint); + const end = contract.instrumented.slice(injectionPoint); + + const hash = this._getHash(fileName); + const memoryVariable = this._getMemoryVariableAssignment(fileName); + const injectable = this._getInjectable(memoryVariable, hash, type) + + instrumentation[hash] = { + id: injection.statementId, + type: type, + contractPath: fileName, + hits: 0 + } + + contract.instrumented = `${start}${injectable}${end}`; + }; + + injectFunction(contract, fileName, injectionPoint, injection, instrumentation){ + const type = 'function'; + const start = contract.instrumented.slice(0, injectionPoint); + const end = contract.instrumented.slice(injectionPoint); + + const hash = this._getHash(fileName); + const memoryVariableDefinition = this._getMemoryVariableDefinition(fileName); + const memoryVariable = this._getMemoryVariableAssignment(fileName); + const injectable = this._getInjectable(memoryVariable, hash, type); + + instrumentation[hash] = { + id: injection.fnId, + type: type, + contractPath: fileName, + hits: 0 + } + + contract.instrumented = `${start}${memoryVariableDefinition}${injectable}${end}`; + } + + injectBranch(contract, fileName, injectionPoint, injection, instrumentation){ + const type = 'branch'; + const start = contract.instrumented.slice(0, injectionPoint); + const end = contract.instrumented.slice(injectionPoint); + + const hash = this._getHash(fileName); + const memoryVariable = this._getMemoryVariableAssignment(fileName); + const injectable = this._getInjectable(memoryVariable, hash, type); + + instrumentation[hash] = { + id: injection.branchId, + locationIdx: injection.locationIdx, + type: type, + contractPath: fileName, + hits: 0 + } + + contract.instrumented = `${start}${injectable}${end}`; + } + + injectEmptyBranch(contract, fileName, injectionPoint, injection, instrumentation) { + const type = 'branch'; + const start = contract.instrumented.slice(0, injectionPoint); + const end = contract.instrumented.slice(injectionPoint); + + const hash = this._getHash(fileName); + const memoryVariable = this._getMemoryVariableAssignment(fileName); + const injectable = this._getInjectable(memoryVariable, hash, type); + + instrumentation[hash] = { + id: injection.branchId, + locationIdx: injection.locationIdx, + type: type, + contractPath: fileName, + hits: 0 + } + + contract.instrumented = `${start}else { ${injectable}}${end}`; + } + + injectAssertPre(contract, fileName, injectionPoint, injection, instrumentation) { + const type = 'assertPre'; + const start = contract.instrumented.slice(0, injectionPoint); + const end = contract.instrumented.slice(injectionPoint); + + const hash = this._getHash(fileName); + const memoryVariable = this._getMemoryVariableAssignment(fileName); + const injectable = this._getInjectable(memoryVariable, hash, type); + + instrumentation[hash] = { + id: injection.branchId, + type: type, + contractPath: fileName, + hits: 0 + } + + contract.instrumented = `${start}${injectable}${end}`; + } + + injectAssertPost(contract, fileName, injectionPoint, injection, instrumentation) { + const type = 'assertPost'; + const start = contract.instrumented.slice(0, injectionPoint); + const end = contract.instrumented.slice(injectionPoint); + + const hash = this._getHash(fileName); + const memoryVariable = this._getMemoryVariableAssignment(fileName); + const injectable = this._getInjectable(memoryVariable, hash, type); + + instrumentation[hash] = { + id: injection.branchId, + type: type, + contractPath: fileName, + hits: 0 + } + + contract.instrumented = `${start}${injectable}${end}`; + } }; -injector.openParen = function injectOpenParen(contract, fileName, injectionPoint, injection) { - contract.instrumented = contract.instrumented.slice(0, injectionPoint) + '(' + contract.instrumented.slice(injectionPoint); -}; - -injector.closeParen = function injectCloseParen(contract, fileName, injectionPoint, injection) { - contract.instrumented = contract.instrumented.slice(0, injectionPoint) + ')' + contract.instrumented.slice(injectionPoint); -}; - -injector.literal = function injectLiteral(contract, fileName, injectionPoint, injection) { - contract.instrumented = contract.instrumented.slice(0, injectionPoint) + injection.string + contract.instrumented.slice(injectionPoint); -}; - -injector.statement = function injectStatement(contract, fileName, injectionPoint, injection) { - contract.instrumented = contract.instrumented.slice(0, injectionPoint) + - 'emit __StatementCoverage' + contract.contractName + '(\'' + fileName + '\',' + injection.statementId + ');\n' + - contract.instrumented.slice(injectionPoint); -}; - -injector.eventDefinition = function injectEventDefinition(contract, fileName, injectionPoint, injection) { - contract.instrumented = contract.instrumented.slice(0, injectionPoint) + - 'event __Coverage' + contract.contractName + '(string fileName, uint256 lineNumber);\n' + - 'event __FunctionCoverage' + contract.contractName + '(string fileName, uint256 fnId);\n' + - 'event __StatementCoverage' + contract.contractName + '(string fileName, uint256 statementId);\n' + - 'event __BranchCoverage' + contract.contractName + '(string fileName, uint256 branchId, uint256 locationIdx);\n' + - 'event __AssertPreCoverage' + contract.contractName + '(string fileName, uint256 branchId);\n' + - 'event __AssertPostCoverage' + contract.contractName + '(string fileName, uint256 branchId);\n' + - - contract.instrumented.slice(injectionPoint); -}; - - -module.exports = injector; +module.exports = Injector; diff --git a/lib/instrumentSolidity.js b/lib/instrumentSolidity.js deleted file mode 100644 index eae7ff88..00000000 --- a/lib/instrumentSolidity.js +++ /dev/null @@ -1,65 +0,0 @@ -const SolidityParser = require('solidity-parser-antlr'); -const preprocessor = require('./preprocessor'); -const injector = require('./injector'); -const parse = require('./parse'); - -const path = require('path'); - -module.exports = function instrumentSolidity(contractSource, fileName) { - const contract = {}; - contract.source = contractSource; - contract.instrumented = contractSource; - - contract.runnableLines = []; - contract.fnMap = {}; - contract.fnId = 0; - contract.branchMap = {}; - contract.branchId = 0; - contract.statementMap = {}; - contract.statementId = 0; - contract.injectionPoints = {}; - - // First, we run over the original contract to get the source mapping. - let ast = SolidityParser.parse(contract.source, {range: true}); - parse[ast.type](contract, ast); - const retValue = JSON.parse(JSON.stringify(contract)); - - // Now, we reset almost everything and use the preprocessor first to increase our effectiveness. - contract.runnableLines = []; - contract.fnMap = {}; - contract.fnId = 0; - contract.branchMap = {}; - contract.branchId = 0; - contract.statementMap = {}; - contract.statementId = 0; - contract.injectionPoints = {}; - - contract.preprocessed = preprocessor.run(contract.source); - contract.instrumented = contract.preprocessed; - ast = SolidityParser.parse(contract.preprocessed, {range: true}); - const contractStatement = ast.children.filter(node => (node.type === 'ContractDefinition' || - node.type === 'LibraryDefinition' || - node.type === 'InterfaceDefinition')); - contract.contractName = contractStatement[0].name; - - parse[ast.type](contract, ast); - - // We have to iterate through these injection points in descending order to not mess up - // the injection process. - const sortedPoints = Object.keys(contract.injectionPoints).sort((a, b) => b - a); - sortedPoints.forEach(injectionPoint => { - // Line instrumentation has to happen first - contract.injectionPoints[injectionPoint].sort((a, b) => { - const eventTypes = ['openParen', 'callBranchEvent', 'callEmptyBranchEvent', 'callEvent']; - return eventTypes.indexOf(b.type) - eventTypes.indexOf(a.type); - }); - contract.injectionPoints[injectionPoint].forEach(injection => { - injector[injection.type](contract, fileName, injectionPoint, injection); - }); - }); - retValue.runnableLines = contract.runnableLines; - retValue.contract = contract.instrumented; - retValue.contractName = contractStatement[0].name; - - return retValue; -}; diff --git a/lib/instrumenter.js b/lib/instrumenter.js index 93c98674..27c893f3 100644 --- a/lib/instrumenter.js +++ b/lib/instrumenter.js @@ -1,254 +1,106 @@ -const instrumenter = {}; - -// These functions work out where in an expression we can inject our -// instrumenation events. +const SolidityParser = require('solidity-parser-antlr'); +const path = require('path'); + +const Injector = require('./injector'); +const preprocess = require('./preprocessor'); +const parse = require('./parse'); + +/** + * Top level controller for the instrumentation sequence. Also hosts the instrumentation data map + * which the vm step listener writes its output to. This only needs to be instantiated once + * per coverage run. + */ +class Instrumenter { + + constructor(){ + this.instrumentationData = {}; + this.injector = new Injector(); + } -function createOrAppendInjectionPoint(contract, key, value) { - if (contract.injectionPoints[key]) { - contract.injectionPoints[key].push(value); - } else { - contract.injectionPoints[key] = [value]; + _isRootNode(node){ + return (node.type === 'ContractDefinition' || + node.type === 'LibraryDefinition' || + node.type === 'InterfaceDefinition'); } -} -instrumenter.prePosition = function prePosition(expression) { - if (expression.right.type === 'ConditionalExpression' && - expression.left.type === 'MemberExpression') { - expression.range[0] -= 2; + _initializeCoverageFields(contract){ + contract.runnableLines = []; + contract.fnMap = {}; + contract.fnId = 0; + contract.branchMap = {}; + contract.branchId = 0; + contract.statementMap = {}; + contract.statementId = 0; + contract.injectionPoints = {}; } -}; - -instrumenter.instrumentAssignmentExpression = function instrumentAssignmentExpression(contract, expression) { - - // This is suspended for 0.5.0 which tries to accomodate the new `emit` keyword. - // Solc is not allowing us to use the construction `emit SomeEvent()` within the parens :/ - return; - // -------------------------------------------------------------------------------------------- - - // The only time we instrument an assignment expression is if there's a conditional expression on - // the right - /*if (expression.right.type === 'ConditionalExpression') { - if (expression.left.type === 'DeclarativeExpression' || expression.left.type === 'Identifier') { - // Then we need to go from bytes32 varname = (conditional expression) - // to bytes32 varname; (,varname) = (conditional expression) - createOrAppendInjectionPoint(contract, expression.left.range[1], { - type: 'literal', string: '; (,' + expression.left.name + ')', - }); - instrumenter.instrumentConditionalExpression(contract, expression.right); - } else if (expression.left.type === 'MemberExpression') { - createOrAppendInjectionPoint(contract, expression.left.range[0], { - type: 'literal', string: '(,', + + + /** + * Per `contractSource`: + * - wraps any unbracketed singleton consequents of if, for, while stmts (preprocessor.js) + * - walks the file's AST, creating an instrumentation map (parse.js, registrar.js) + * - injects `instrumentation` solidity statements into the target solidity source (injector.js) + * + * @param {String} contractSource solidity source code + * @param {String} fileName absolute path to source file + * @return {Object} instrumented `contract` object + * { + * contract: instrumented solidity source code, + * contractName: contract name, + * runnableLines: integer + * } + * + */ + instrument(contractSource, fileName) { + const contract = {}; + + contract.source = contractSource; + contract.instrumented = contractSource; + + this._initializeCoverageFields(contract); + + // First, we run over the original contract to get the source mapping. + let ast = SolidityParser.parse(contract.source, {range: true}); + parse[ast.type](contract, ast); + const retValue = JSON.parse(JSON.stringify(contract)); // ????? + + // Now, we reset almost everything and use the preprocessor to increase our effectiveness. + this._initializeCoverageFields(contract); + contract.instrumented = preprocess(contract.source); + + // Walk the AST, recording injection points + ast = SolidityParser.parse(contract.instrumented, {range: true}); + contract.contractName = ast.children.filter(node => this._isRootNode(node))[0].name; + parse[ast.type](contract, ast); + + // We have to iterate through these points in descending order + const sortedPoints = Object.keys(contract.injectionPoints).sort((a, b) => b - a); + + sortedPoints.forEach(injectionPoint => { + + // Line instrumentation has to happen first + contract.injectionPoints[injectionPoint].sort((a, b) => { + const injections = ['injectBranch', 'injectEmptyBranch', 'injectLine']; + return injections.indexOf(b.type) - injections.indexOf(a.type); }); - createOrAppendInjectionPoint(contract, expression.left.range[1], { - type: 'literal', string: ')', + + contract.injectionPoints[injectionPoint].forEach(injection => { + this.injector[injection.type]( + contract, + fileName, + injectionPoint, + injection, + this.instrumentationData + ); }); - instrumenter.instrumentConditionalExpression(contract, expression.right); - } else { - const err = 'Error instrumenting assignment expression @ solidity-coverage/lib/instrumenter.js'; - console.log(err, contract, expression.left); - process.exit(); - } - }*/ -}; - -instrumenter.instrumentConditionalExpression = function instrumentConditionalExpression(contract, expression) { - // ---------------------------------------------------------------------------------------------- - // This is suspended for 0.5.0 which tries to accomodate the new `emit` keyword. - // Solc is not allowing us to use the construction `emit SomeEvent()` within the parens :/ - // Very sad, this is the coolest thing in here. - return; - // ---------------------------------------------------------------------------------------------- - - /*contract.branchId += 1; - - const startline = (contract.instrumented.slice(0, expression.range[0]).match(/\n/g) || []).length + 1; - const startcol = expression.range[0] - contract.instrumented.slice(0, expression.range[0]).lastIndexOf('\n') - 1; - const consequentStartCol = startcol + (contract, expression.trueBody.range[0] - expression.range[0]); - const consequentEndCol = consequentStartCol + (contract, expression.trueBody.range[1] - expression.trueBody.range[0]); - const alternateStartCol = startcol + (contract, expression.falseBody.range[0] - expression.range[0]); - const alternateEndCol = alternateStartCol + (contract, expression.falseBody.range[1] - expression.falseBody.range[0]); - // NB locations for conditional branches in istanbul are length 1 and associated with the : and ?. - contract.branchMap[contract.branchId] = { - line: startline, - type: 'cond-expr', - locations: [{ - start: { - line: startline, column: consequentStartCol, - }, - end: { - line: startline, column: consequentEndCol, - }, - }, { - start: { - line: startline, column: alternateStartCol, - }, - end: { - line: startline, column: alternateEndCol, - }, - }], - }; - // Right, this could be being used just by itself or as an assignment. In the case of the latter, because - // the comma operator doesn't exist, we're going to have to get funky. - // if we're on a line by ourselves, this is easier - // - // Now if we've got to wrap the expression it's being set equal to, do that... - - - // Wrap the consequent - createOrAppendInjectionPoint(contract, expression.trueBody.range[0], { - type: 'openParen', - }); - createOrAppendInjectionPoint(contract, expression.trueBody.range[0], { - type: 'callBranchEvent', comma: true, branchId: contract.branchId, locationIdx: 0, - }); - createOrAppendInjectionPoint(contract, expression.trueBody.range[1], { - type: 'closeParen', - }); - - // Wrap the alternate - createOrAppendInjectionPoint(contract, expression.falseBody.range[0], { - type: 'openParen', - }); - createOrAppendInjectionPoint(contract, expression.falseBody.range[0], { - type: 'callBranchEvent', comma: true, branchId: contract.branchId, locationIdx: 1, - }); - createOrAppendInjectionPoint(contract, expression.falseBody.range[1], { - type: 'closeParen', - });*/ -}; - -instrumenter.instrumentStatement = function instrumentStatement(contract, expression) { - contract.statementId += 1; - // We need to work out the lines and columns the expression starts and ends - const startline = (contract.instrumented.slice(0, expression.range[0]).match(/\n/g) || []).length + 1; - const startcol = expression.range[0] - contract.instrumented.slice(0, expression.range[0]).lastIndexOf('\n') - 1; - const expressionContent = contract.instrumented.slice(expression.range[0], expression.range[1] + 1); - - const endline = startline + (contract, expressionContent.match('/\n/g') || []).length; - let endcol; - if (expressionContent.lastIndexOf('\n') >= 0) { - endcol = contract.instrumented.slice(expressionContent.lastIndexOf('\n'), expression.range[1]).length; - } else { - endcol = startcol + (contract, expressionContent.length - 1); - } - contract.statementMap[contract.statementId] = { - start: { - line: startline, column: startcol, - }, - end: { - line: endline, column: endcol, - }, - }; - createOrAppendInjectionPoint(contract, expression.range[0], { - type: 'statement', statementId: contract.statementId, - }); -}; - -instrumenter.instrumentLine = function instrumentLine(contract, expression) { - // what's the position of the most recent newline? - const startchar = expression.range[0]; - const endchar = expression.range[1] + 1; - const lastNewLine = contract.instrumented.slice(0, startchar).lastIndexOf('\n'); - const nextNewLine = startchar + contract.instrumented.slice(startchar).indexOf('\n'); - const contractSnipped = contract.instrumented.slice(lastNewLine, nextNewLine); - const restOfLine = contract.instrumented.slice(endchar, nextNewLine); - - if (contract.instrumented.slice(lastNewLine, startchar).trim().length === 0 && - (restOfLine.replace(';', '').trim().length === 0 || restOfLine.replace(';', '').trim().substring(0, 2) === '//')) { - createOrAppendInjectionPoint(contract, lastNewLine + 1, { - type: 'callEvent', - }); - } else if (contract.instrumented.slice(lastNewLine, startchar).replace('{', '').trim().length === 0 && - contract.instrumented.slice(endchar, nextNewLine).replace(/[;}]/g, '').trim().length === 0) { - createOrAppendInjectionPoint(contract, expression.range[0], { - type: 'callEvent', - }); - } - // Is everything before us and after us on this line whitespace? -}; - -instrumenter.instrumentFunctionDeclaration = function instrumentFunctionDeclaration(contract, expression) { - contract.fnId += 1; - const startline = (contract.instrumented.slice(0, expression.range[0]).match(/\n/g) || []).length + 1; - // We need to work out the lines and columns the function declaration starts and ends - const startcol = expression.range[0] - contract.instrumented.slice(0, expression.range[0]).lastIndexOf('\n') - 1; - const endlineDelta = contract.instrumented.slice(expression.range[0]).indexOf('{'); - const functionDefinition = contract.instrumented.slice(expression.range[0], expression.range[0] + endlineDelta); - const endline = startline + (functionDefinition.match(/\n/g) || []).length; - const endcol = functionDefinition.length - functionDefinition.lastIndexOf('\n'); - contract.fnMap[contract.fnId] = { - name: expression.isConstructor ? 'constructor' : expression.name, - line: startline, - loc: { - start: { - line: startline, column: startcol, - }, - end: { - line: endline, column: endcol, - }, - }, - }; - createOrAppendInjectionPoint(contract, expression.range[0] + endlineDelta + 1, { - type: 'callFunctionEvent', fnId: contract.fnId, - }); -}; - -instrumenter.addNewBranch = function addNewBranch(contract, expression) { - contract.branchId += 1; - const startline = (contract.instrumented.slice(0, expression.range[0]).match(/\n/g) || []).length + 1; - const startcol = expression.range[0] - contract.instrumented.slice(0, expression.range[0]).lastIndexOf('\n') - 1; - // NB locations for if branches in istanbul are zero length and associated with the start of the if. - contract.branchMap[contract.branchId] = { - line: startline, - type: 'if', - locations: [{ - start: { - line: startline, column: startcol, - }, - end: { - line: startline, column: startcol, - }, - }, { - start: { - line: startline, column: startcol, - }, - end: { - line: startline, column: startcol, - }, - }], - }; -}; - -instrumenter.instrumentAssertOrRequire = function instrumentAssertOrRequire(contract, expression) { - instrumenter.addNewBranch(contract, expression); - createOrAppendInjectionPoint(contract, expression.range[0], { - type: 'callAssertPreEvent', branchId: contract.branchId, - }); - createOrAppendInjectionPoint(contract, expression.range[1] + 2, { - type: 'callAssertPostEvent', branchId: contract.branchId, - }); -}; - -instrumenter.instrumentIfStatement = function instrumentIfStatement(contract, expression) { - instrumenter.addNewBranch(contract, expression); - if (expression.trueBody.type === 'Block') { - createOrAppendInjectionPoint(contract, expression.trueBody.range[0] + 1, { - type: 'callBranchEvent', branchId: contract.branchId, locationIdx: 0, - }); - } - if (expression.falseBody && expression.falseBody.type === 'IfStatement') { - // Do nothing - we must be pre-preprocessor, so don't bother instrumenting - - // when we're actually instrumenting, this will never happen (we've wrapped it in - // a block statement) - } else if (expression.falseBody && expression.falseBody.type === 'Block') { - createOrAppendInjectionPoint(contract, expression.falseBody.range[0] + 1, { - type: 'callBranchEvent', branchId: contract.branchId, locationIdx: 1, - }); - } else { - createOrAppendInjectionPoint(contract, expression.trueBody.range[1] + 1, { - type: 'callEmptyBranchEvent', branchId: contract.branchId, locationIdx: 1, }); + + retValue.runnableLines = contract.runnableLines; + retValue.contract = contract.instrumented; + retValue.contractName = contract.contractName; + + return retValue; } -}; +} -module.exports = instrumenter; +module.exports = Instrumenter; diff --git a/lib/parse.js b/lib/parse.js index 8b9feb3c..5923f07a 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -1,39 +1,37 @@ -/* eslint no-unused-expressions: ["error", { "allowShortCircuit": true }] */ - /** * Methods in this file walk the AST and call the instrumenter * functions where appropriate, which determine where to inject events. * (Listed in alphabetical order) */ +const Registrar = require('./registrar'); +const register = new Registrar(); const parse = {}; -const instrumenter = require('./instrumenter'); -parse.AssignmentExpression = function parseAssignmentExpression(contract, expression) { - instrumenter.prePosition(expression); - instrumenter.instrumentStatement(contract, expression); - instrumenter.instrumentAssignmentExpression(contract, expression); +parse.AssignmentExpression = function(contract, expression) { + register.prePosition(expression); + register.statement(contract, expression); }; -parse.Block = function parseBlock(contract, expression) { +parse.Block = function(contract, expression) { for (let x = 0; x < expression.statements.length; x++) { - instrumenter.instrumentLine(contract, expression.statements[x]); + register.line(contract, expression.statements[x]); parse[expression.statements[x].type] && parse[expression.statements[x].type](contract, expression.statements[x]); } }; -parse.BinaryOperation = function parseBinaryOperation(contract, expression) { - instrumenter.instrumentStatement(contract, expression); +parse.BinaryOperation = function(contract, expression) { + register.statement(contract, expression); } -parse.FunctionCall = function parseCallExpression(contract, expression) { - // In any given chain of call expressions, only the last one will fail this check. This makes sure - // we don't instrument a chain of expressions multiple times. +parse.FunctionCall = function(contract, expression) { + // In any given chain of call expressions, only the last one will fail this check. + // This makes sure we don't instrument a chain of expressions multiple times. if (expression.expression.type !== 'FunctionCall') { - instrumenter.instrumentStatement(contract, expression); + register.statement(contract, expression); if (expression.expression.name === 'assert' || expression.expression.name === 'require') { - instrumenter.instrumentAssertOrRequire(contract, expression); + register.assertOrRequire(contract, expression); } parse[expression.expression.type] && parse[expression.expression.type](contract, expression.expression); @@ -43,28 +41,16 @@ parse.FunctionCall = function parseCallExpression(contract, expression) { } }; -parse.ConditionalExpression = function parseConditionalExpression(contract, expression) { - instrumenter.instrumentStatement(contract, expression); - instrumenter.instrumentConditionalExpression(contract, expression); +parse.ConditionalExpression = function(contract, expression) { + register.statement(contract, expression); + register.conditionalExpression(contract, expression); }; -parse.ContractDefinition = function ParseContractStatement(contract, expression) { +parse.ContractDefinition = function(contract, expression) { parse.ContractOrLibraryStatement(contract, expression); }; -parse.ContractOrLibraryStatement = function parseContractOrLibraryStatement(contract, expression) { - // From the start of this contract statement, find the first '{', and inject there. - const injectionPoint = expression.range[0] + contract.instrumented.slice(expression.range[0]).indexOf('{') + 1; - if (contract.injectionPoints[injectionPoint]) { - contract.injectionPoints[expression.range[0] + contract.instrumented.slice(expression.range[0]).indexOf('{') + 1].push({ - type: 'eventDefinition', - }); - } else { - contract.injectionPoints[expression.range[0] + contract.instrumented.slice(expression.range[0]).indexOf('{') + 1] = [{ - type: 'eventDefinition', - }]; - } - +parse.ContractOrLibraryStatement = function(contract, expression) { if (expression.subNodes) { expression.subNodes.forEach(construct => { parse[construct.type] && @@ -73,33 +59,33 @@ parse.ContractOrLibraryStatement = function parseContractOrLibraryStatement(cont } }; -parse.EmitStatement = function parseExpressionStatement(contract, expression){ - instrumenter.instrumentStatement(contract, expression); +parse.EmitStatement = function(contract, expression){ + register.statement(contract, expression); }; -parse.ExpressionStatement = function parseExpressionStatement(contract, content) { +parse.ExpressionStatement = function(contract, content) { parse[content.expression.type] && parse[content.expression.type](contract, content.expression); }; -parse.ForStatement = function parseForStatement(contract, expression) { - instrumenter.instrumentStatement(contract, expression); +parse.ForStatement = function(contract, expression) { + register.statement(contract, expression); parse[expression.body.type] && parse[expression.body.type](contract, expression.body); }; -parse.FunctionDefinition = function parseFunctionDefinition(contract, expression) { +parse.FunctionDefinition = function(contract, expression) { parse.Modifiers(contract, expression.modifiers); if (expression.body) { - instrumenter.instrumentFunctionDeclaration(contract, expression); + register.functionDeclaration(contract, expression); parse[expression.body.type] && parse[expression.body.type](contract, expression.body); } }; -parse.IfStatement = function parseIfStatement(contract, expression) { - instrumenter.instrumentStatement(contract, expression); - instrumenter.instrumentIfStatement(contract, expression); +parse.IfStatement = function(contract, expression) { + register.statement(contract, expression); + register.ifStatement(contract, expression); parse[expression.trueBody.type] && parse[expression.trueBody.type](contract, expression.trueBody); @@ -109,20 +95,20 @@ parse.IfStatement = function parseIfStatement(contract, expression) { } }; -parse.InterfaceStatement = function parseInterfaceStatement(contract, expression) { +parse.InterfaceStatement = function(contract, expression) { parse.ContractOrLibraryStatement(contract, expression); }; -parse.LibraryStatement = function parseLibraryStatement(contract, expression) { +parse.LibraryStatement = function(contract, expression) { parse.ContractOrLibraryStatement(contract, expression); }; -parse.MemberExpression = function parseMemberExpression(contract, expression) { +parse.MemberExpression = function(contract, expression) { parse[expression.object.type] && parse[expression.object.type](contract, expression.object); }; -parse.Modifiers = function parseModifier(contract, modifiers) { +parse.Modifiers = function(contract, modifiers) { if (modifiers) { modifiers.forEach(modifier => { parse[modifier.type] && parse[modifier.type](contract, modifier); @@ -130,52 +116,50 @@ parse.Modifiers = function parseModifier(contract, modifiers) { } }; -parse.ModifierDefinition = function parseModifierDefinition(contract, expression) { - instrumenter.instrumentFunctionDeclaration(contract, expression); +parse.ModifierDefinition = function(contract, expression) { + register.functionDeclaration(contract, expression); parse[expression.body.type] && parse[expression.body.type](contract, expression.body); }; -parse.NewExpression = function parseNewExpression(contract, expression) { +parse.NewExpression = function(contract, expression) { parse[expression.typeName.type] && parse[expression.typeName.type](contract, expression.typeName); }; -parse.SourceUnit = function parseSourceUnit(contract, expression) { +parse.SourceUnit = function(contract, expression) { expression.children.forEach(construct => { parse[construct.type] && parse[construct.type](contract, construct); }); }; -parse.ReturnStatement = function parseReturnStatement(contract, expression) { - instrumenter.instrumentStatement(contract, expression); +parse.ReturnStatement = function(contract, expression) { + register.statement(contract, expression); }; -parse.UnaryExpression = function parseUnaryExpression(contract, expression) { +parse.UnaryExpression = function(contract, expression) { parse[expression.argument.type] && parse[expression.argument.type](contract, expression.argument); }; -parse.UsingStatement = function parseUsingStatement(contract, expression) { +parse.UsingStatement = function (contract, expression) { parse[expression.for.type] && parse[expression.for.type](contract, expression.for); }; -parse.VariableDeclarationStatement = function parseVariableDeclarationStatement(contract, expression) { - instrumenter.instrumentStatement(contract, expression); - // parse[expression.declarations[0].id.type] && - // parse[expression.declarations[0].id.type](contract, expression.declarations[0].id); +parse.VariableDeclarationStatement = function (contract, expression) { + register.statement(contract, expression); }; -parse.VariableDeclarationTuple = function parseVariableDeclarationTuple(contract, expression) { - instrumenter.instrumentStatement(contract, expression); +parse.VariableDeclarationTuple = function (contract, expression) { + register.statement(contract, expression); parse[expression.declarations[0].id.type] && parse[expression.declarations[0].id.type](contract, expression.declarations[0].id); }; -parse.WhileStatement = function parseWhileStatement(contract, expression) { - instrumenter.instrumentStatement(contract, expression); +parse.WhileStatement = function (contract, expression) { + register.statement(contract, expression); parse[expression.body.type] && parse[expression.body.type](contract, expression.body); }; diff --git a/lib/preprocessor.js b/lib/preprocessor.js index 3ad34aab..b8463511 100644 --- a/lib/preprocessor.js +++ b/lib/preprocessor.js @@ -1,4 +1,3 @@ -const SolExplore = require('sol-explore'); const SolidityParser = require('solidity-parser-antlr'); const crRegex = /[\r\n ]+$/g; @@ -6,52 +5,31 @@ const OPEN = '{'; const CLOSE = '}'; /** - * Splices enclosing brackets into `contract` around `expression`; + * Inserts an open or close brace e.g. `{` or `}` at specified position in solidity source + * * @param {String} contract solidity source - * @param {Object} node AST node to bracket + * @param {Object} item AST node to bracket + * @param {Number} offset tracks the number of previously inserted braces * @return {String} contract */ function insertBrace(contract, item, offset) { return contract.slice(0,item.pos + offset) + item.type + contract.slice(item.pos + offset) } -/** Remove 'pure' and 'view' from the function declaration. - * @param {String} contract solidity source - * @param {Object} function AST node - * @return {String} contract with the modifiers removed from the given function. -*/ -function removePureView(contract, node){ - let fDefStart = node.range[0]; - if (node.body){ - fDefEnd = node.body.range[0]; - } else if (node.returnParameters) { - fDefEnd = node.returnParameters.range[0]; - } else { - fDefEnd = node.range[1]; - } - let fDef = contract.slice(fDefStart, fDefEnd + 1); - fDef = fDef.replace(/\bview\b/i, ' '); - fDef = fDef.replace(/\bpure\b/i, ' '); - return contract.slice(0, fDefStart) + fDef + contract.slice(fDefEnd + 1); -} - /** * Locates unbracketed singleton statements attached to if, else, for and while statements * and brackets them. Instrumenter needs to inject events at these locations and having - * them pre-bracketed simplifies the process. Each time a modification is made the contract - * is passed back to the parser and re-walked because all the starts and ends get shifted. - * - * Also removes pure and view modifiers. + * them pre-bracketed simplifies the process. * - * @param {String} contract solidity code - * @return {String} contract + * @param {String} contract solidity source code + * @return {String} modified solidity source code */ -module.exports.run = function r(contract) { +function preprocess(contract) { try { const ast = SolidityParser.parse(contract, { range: true }); insertions = []; - viewPureToRemove = []; + SolidityParser.visit(ast, { IfStatement: function(node) { if (node.trueBody.type !== 'Block') { @@ -74,23 +52,18 @@ module.exports.run = function r(contract) { insertions.push({type: OPEN, pos: node.body.range[0]}); insertions.push({type: CLOSE, pos: node.body.range[1] + 1}); } - }, - FunctionDefinition: function(node){ - if (node.stateMutability === 'view' || node.stateMutability === 'pure'){ - viewPureToRemove.push(node); - } } }) - // Firstly, remove pures and views. Note that we replace 'pure' and 'view' with spaces, so - // character counts remain the same, so we can do this in any order - viewPureToRemove.forEach(node => contract = removePureView(contract, node)); + // Sort the insertion points. insertions.sort((a,b) => a.pos - b.pos); insertions.forEach((item, idx) => contract = insertBrace(contract, item, idx)); } catch (err) { contract = err; - keepRunning = false; } return contract; }; + + +module.exports = preprocess; diff --git a/lib/registrar.js b/lib/registrar.js new file mode 100644 index 00000000..e4bc5bde --- /dev/null +++ b/lib/registrar.js @@ -0,0 +1,251 @@ +/** + * Registers injections points (e.g source location, type) and their associated data with + * a contract / instrumentation target. Run during the `parse` step. This data is + * consumed by the Injector as it modifies the source code in instrumentation's final step. + */ +class Registrar { + + constructor(){} + + /** + * Adds injection point to injection points map + * @param {Object} contract instrumentation target + * @param {String} key injection point `type` + * @param {Number} value injection point `id` + */ + _createInjectionPoint(contract, key, value) { + (contract.injectionPoints[key]) + ? contract.injectionPoints[key].push(value) + : contract.injectionPoints[key] = [value]; + } + + /** + * TODO - idk what this is anymore + * @param {Object} expression AST node + */ + prePosition(expression) { + if ( + expression.right.type === 'ConditionalExpression' && + expression.left.type === 'MemberExpression' + ) { + expression.range[0] -= 2; + } + } + + /** + * Registers injections for statement measurements + * @param {Object} contract instrumentation target + * @param {Object} expression AST node + */ + statement(contract, expression) { + const startContract = contract.instrumented.slice(0, expression.range[0]); + const startline = ( startContract.match(/\n/g) || [] ).length + 1; + const startcol = expression.range[0] - startContract.lastIndexOf('\n') - 1; + + const expressionContent = contract.instrumented.slice( + expression.range[0], + expression.range[1] + 1 + ); + + const endline = startline + (contract, expressionContent.match('/\n/g') || []).length; + + let endcol; + if (expressionContent.lastIndexOf('\n') >= 0) { + + endcol = contract.instrumented.slice( + expressionContent.lastIndexOf('\n'), + expression.range[1] + ).length; + + } else endcol = startcol + (contract, expressionContent.length - 1); + + contract.statementId += 1; + contract.statementMap[contract.statementId] = { + start: { line: startline, column: startcol }, + end: { line: endline, column: endcol }, + }; + + this._createInjectionPoint(contract, expression.range[0], { + type: 'injectStatement', statementId: contract.statementId, + }); + }; + + /** + * Registers injections for line measurements + * @param {Object} contract instrumentation target + * @param {Object} expression AST node + */ + line(contract, expression) { + const startchar = expression.range[0]; + const endchar = expression.range[1] + 1; + const lastNewLine = contract.instrumented.slice(0, startchar).lastIndexOf('\n'); + const nextNewLine = startchar + contract.instrumented.slice(startchar).indexOf('\n'); + const contractSnipped = contract.instrumented.slice(lastNewLine, nextNewLine); + const restOfLine = contract.instrumented.slice(endchar, nextNewLine); + + if ( + contract.instrumented.slice(lastNewLine, startchar).trim().length === 0 && + ( + restOfLine.replace(';', '').trim().length === 0 || + restOfLine.replace(';', '').trim().substring(0, 2) === '//' + ) + ) + { + this._createInjectionPoint(contract, lastNewLine + 1, { type: 'injectLine' }); + + } else if ( + contract.instrumented.slice(lastNewLine, startchar).replace('{', '').trim().length === 0 && + contract.instrumented.slice(endchar, nextNewLine).replace(/[;}]/g, '').trim().length === 0) + { + this._createInjectionPoint(contract, expression.range[0], { type: 'injectLine' }); + } + }; + + /** + * Registers injections for function measurements + * @param {Object} contract instrumentation target + * @param {Object} expression AST node + */ + functionDeclaration(contract, expression) { + const startContract = contract.instrumented.slice(0, expression.range[0]); + const startline = ( startContract.match(/\n/g) || [] ).length + 1; + const startcol = expression.range[0] - startContract.lastIndexOf('\n') - 1; + + const endlineDelta = contract.instrumented.slice(expression.range[0]).indexOf('{'); + const functionDefinition = contract.instrumented.slice( + expression.range[0], + expression.range[0] + endlineDelta + ); + const endline = startline + (functionDefinition.match(/\n/g) || []).length; + const endcol = functionDefinition.length - functionDefinition.lastIndexOf('\n'); + + contract.fnId += 1; + contract.fnMap[contract.fnId] = { + name: expression.isConstructor ? 'constructor' : expression.name, + line: startline, + loc: { + start: { line: startline, column: startcol }, + end: { line: endline, column: endcol }, + }, + }; + + this._createInjectionPoint( + contract, + expression.range[0] + endlineDelta + 1, + { + type: 'injectFunction', + fnId: contract.fnId, + } + ); + }; + + /** + * Registers injections for branch measurements. This generic is consumed by + * the `assert/require` and `if` registration methods. + * @param {Object} contract instrumentation target + * @param {Object} expression AST node + */ + addNewBranch(contract, expression) { + const startContract = contract.instrumented.slice(0, expression.range[0]); + const startline = ( startContract.match(/\n/g) || [] ).length + 1; + const startcol = expression.range[0] - startContract.lastIndexOf('\n') - 1; + + contract.branchId += 1; + + // NB locations for if branches in istanbul are zero + // length and associated with the start of the if. + contract.branchMap[contract.branchId] = { + line: startline, + type: 'if', + locations: [{ + start: { + line: startline, column: startcol, + }, + end: { + line: startline, column: startcol, + }, + }, { + start: { + line: startline, column: startcol, + }, + end: { + line: startline, column: startcol, + }, + }], + }; + }; + + /** + * Registers injections for assert/require statement measurements (branches) + * @param {Object} contract instrumentation target + * @param {Object} expression AST node + */ + assertOrRequire(contract, expression) { + this.addNewBranch(contract, expression); + this._createInjectionPoint( + contract, + expression.range[0], + { + type: 'injectAssertPre', + branchId: contract.branchId, + } + ); + this._createInjectionPoint( + contract, + expression.range[1] + 2, + { + type: 'injectAssertPost', + branchId: contract.branchId, + } + ); + }; + + /** + * Registers injections for if statement measurements (branches) + * @param {Object} contract instrumentation target + * @param {Object} expression AST node + */ + ifStatement(contract, expression) { + this.addNewBranch(contract, expression); + + if (expression.trueBody.type === 'Block') { + this._createInjectionPoint( + contract, + expression.trueBody.range[0] + 1, + { + type: 'injectBranch', + branchId: contract.branchId, + locationIdx: 0, + } + ); + } + + if (expression.falseBody && expression.falseBody.type === 'IfStatement') { + + // Do nothing - we must be pre-preprocessing + + } else if (expression.falseBody && expression.falseBody.type === 'Block') { + this._createInjectionPoint( + contract, + expression.falseBody.range[0] + 1, + { + type: 'injectBranch', + branchId: contract.branchId, + locationIdx: 1, + } + ); + } else { + this._createInjectionPoint( + contract, + expression.trueBody.range[1] + 1, + { + type: 'injectEmptyBranch', + branchId: contract.branchId, + locationIdx: 1, + } + ); + } + } +} + +module.exports = Registrar; diff --git a/test/conditional.js b/lib/ternary/conditional.js similarity index 85% rename from test/conditional.js rename to lib/ternary/conditional.js index c6995eae..bf011eae 100644 --- a/test/conditional.js +++ b/lib/ternary/conditional.js @@ -1,6 +1,6 @@ /* eslint-env node, mocha */ -const path = require('path'); +/*const path = require('path'); const getInstrumentedVersion = require('./../lib/instrumentSolidity.js'); const util = require('./util/util.js'); const CoverageMap = require('./../lib/coverageMap'); @@ -181,23 +181,5 @@ describe.skip('conditional statements', () => { }).catch(done); }); - // Solcover has trouble with this case. The conditional coverage strategy relies on being able to - // reference the left-hand variable before its value is assigned. Solidity doesn't allow this - // for 'var'. - - /* it('should cover a var decl assignment by conditional that reaches the alternate', (done) => { - const contract = util.getCode('conditional/variable-decl-assignment-alternate.sol'); - const info = getInstrumentedVersion(contract, filePath); - const coverage = new CoverageMap(); - coverage.addContract(info, filePath); - // Runs var z = (x) ? y = false : y = false; - vm.execute(info.contract, 'a', []).then(events => { - const mapping = coverage.generate(events, pathPrefix); - assert.deepEqual(mapping[filePath].l, {5: 1, 6: 1, 7: 1}); - assert.deepEqual(mapping[filePath].b, {'1': [0, 1]}); - assert.deepEqual(mapping[filePath].s, {1: 1, 2: 1, 3: 1}); - assert.deepEqual(mapping[filePath].f, {1: 1}); - done(); - }).catch(done); - }); */ }); +*/ diff --git a/lib/ternary/ternary.js b/lib/ternary/ternary.js new file mode 100644 index 00000000..82ff3048 --- /dev/null +++ b/lib/ternary/ternary.js @@ -0,0 +1,121 @@ +/** + * This is logic to instrument ternary conditional assignment statements. Preserving + * here for the time being, because instrumentation of these became impossible in + * solc >= 0.5.0 + */ + +function instrumentAssignmentExpression(contract, expression) { + + // This is suspended for 0.5.0 which tries to accomodate the new `emit` keyword. + // Solc is not allowing us to use the construction `emit SomeEvent()` within the parens :/ + return; + // -------------------------------------------------------------------------------------------- + + // The only time we instrument an assignment expression is if there's a conditional expression on + // the right + /*if (expression.right.type === 'ConditionalExpression') { + if (expression.left.type === 'DeclarativeExpression' || expression.left.type === 'Identifier') { + // Then we need to go from bytes32 varname = (conditional expression) + // to bytes32 varname; (,varname) = (conditional expression) + createOrAppendInjectionPoint(contract, expression.left.range[1], { + type: 'literal', string: '; (,' + expression.left.name + ')', + }); + instrumenter.instrumentConditionalExpression(contract, expression.right); + } else if (expression.left.type === 'MemberExpression') { + createOrAppendInjectionPoint(contract, expression.left.range[0], { + type: 'literal', string: '(,', + }); + createOrAppendInjectionPoint(contract, expression.left.range[1], { + type: 'literal', string: ')', + }); + instrumenter.instrumentConditionalExpression(contract, expression.right); + } else { + const err = 'Error instrumenting assignment expression @ solidity-coverage/lib/instrumenter.js'; + console.log(err, contract, expression.left); + process.exit(); + } + }*/ +}; + +function instrumentConditionalExpression(contract, expression) { + // ---------------------------------------------------------------------------------------------- + // This is suspended for 0.5.0 which tries to accomodate the new `emit` keyword. + // Solc is not allowing us to use the construction `emit SomeEvent()` within the parens :/ + // Very sad, this is the coolest thing in here. + return; + // ---------------------------------------------------------------------------------------------- + + /*contract.branchId += 1; + + const startline = (contract.instrumented.slice(0, expression.range[0]).match(/\n/g) || []).length + 1; + const startcol = expression.range[0] - contract.instrumented.slice(0, expression.range[0]).lastIndexOf('\n') - 1; + const consequentStartCol = startcol + (contract, expression.trueBody.range[0] - expression.range[0]); + const consequentEndCol = consequentStartCol + (contract, expression.trueBody.range[1] - expression.trueBody.range[0]); + const alternateStartCol = startcol + (contract, expression.falseBody.range[0] - expression.range[0]); + const alternateEndCol = alternateStartCol + (contract, expression.falseBody.range[1] - expression.falseBody.range[0]); + // NB locations for conditional branches in istanbul are length 1 and associated with the : and ?. + contract.branchMap[contract.branchId] = { + line: startline, + type: 'cond-expr', + locations: [{ + start: { + line: startline, column: consequentStartCol, + }, + end: { + line: startline, column: consequentEndCol, + }, + }, { + start: { + line: startline, column: alternateStartCol, + }, + end: { + line: startline, column: alternateEndCol, + }, + }], + }; + // Right, this could be being used just by itself or as an assignment. In the case of the latter, because + // the comma operator doesn't exist, we're going to have to get funky. + // if we're on a line by ourselves, this is easier + // + // Now if we've got to wrap the expression it's being set equal to, do that... + + + // Wrap the consequent + createOrAppendInjectionPoint(contract, expression.trueBody.range[0], { + type: 'openParen', + }); + createOrAppendInjectionPoint(contract, expression.trueBody.range[0], { + type: 'callBranchEvent', comma: true, branchId: contract.branchId, locationIdx: 0, + }); + createOrAppendInjectionPoint(contract, expression.trueBody.range[1], { + type: 'closeParen', + }); + + // Wrap the alternate + createOrAppendInjectionPoint(contract, expression.falseBody.range[0], { + type: 'openParen', + }); + createOrAppendInjectionPoint(contract, expression.falseBody.range[0], { + type: 'callBranchEvent', comma: true, branchId: contract.branchId, locationIdx: 1, + }); + createOrAppendInjectionPoint(contract, expression.falseBody.range[1], { + type: 'closeParen', + });*/ +}; + +// Paren / Literal injectors +/* + +injector.openParen = function injectOpenParen(contract, fileName, injectionPoint, injection) { + contract.instrumented = contract.instrumented.slice(0, injectionPoint) + '(' + contract.instrumented.slice(injectionPoint); +}; + +injector.closeParen = function injectCloseParen(contract, fileName, injectionPoint, injection) { + contract.instrumented = contract.instrumented.slice(0, injectionPoint) + ')' + contract.instrumented.slice(injectionPoint); +}; + +injector.literal = function injectLiteral(contract, fileName, injectionPoint, injection) { + contract.instrumented = contract.instrumented.slice(0, injectionPoint) + injection.string + contract.instrumented.slice(injectionPoint); +}; + +*/ \ No newline at end of file diff --git a/lib/truffleConfig.js b/lib/truffleConfig.js deleted file mode 100644 index d9113210..00000000 --- a/lib/truffleConfig.js +++ /dev/null @@ -1,14 +0,0 @@ -module.exports = function truffleConfig(port, gasLimit, gasPrice) { - return ` - module.exports = { - networks: { - development: { - host: "localhost", - network_id: "*", - port: ${port}, - gas: ${gasLimit}, - gasPrice: ${gasPrice} - } - } - };`; -}; \ No newline at end of file diff --git a/package.json b/package.json index 074effce..baca21e0 100644 --- a/package.json +++ b/package.json @@ -1,16 +1,15 @@ { "name": "solidity-coverage", - "version": "0.6.4", + "version": "0.7.0-beta.0", "description": "", - "bin": { - "solidity-coverage": "./bin/exec.js" - }, + "main": "index.js", + "buidler": "dist/buidler.coverage.js", "directories": { "test": "test" }, "scripts": { - "test": "mocha --timeout 60000", - "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --timeout 60000 --exit" + "test": "mocha test/units --timeout 70000 --no-warnings", + "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- test/units --timeout 70000 --exit" }, "homepage": "https://github.com/sc-forks/solidity-coverage", "repository": { @@ -21,27 +20,21 @@ "license": "ISC", "dependencies": { "death": "^1.1.0", - "ethereumjs-testrpc-sc": "^6.5.1-sc.0", + "ganache-cli": "^6.5.0", "istanbul": "^0.4.5", - "keccakjs": "^0.2.1", "req-cwd": "^1.0.1", + "sha1": "^1.1.1", "shelljs": "^0.8.3", - "sol-explore": "^1.6.2", "solidity-parser-antlr": "^0.4.7", - "tree-kill": "^1.2.0", - "web3": "1.0.0-beta.50", - "web3-eth-abi": "1.0.0-beta.50" + "web3-utils": "^1.0.0" }, "devDependencies": { - "crypto-js": "^3.1.9-1", - "ethereumjs-account": "~2.0.4", - "ethereumjs-tx": "^1.2.2", - "ethereumjs-util": "^5.0.1", - "ethereumjs-vm": "https://github.com/sc-forks/ethereumjs-vm-sc.git#336d8841ab2c37da079d290ea5c5af6b34f20495", - "merkle-patricia-tree": "~2.1.2", - "mocha": "^4.1.0", - "request": "^2.88.0", - "solc": "^0.5.3", - "truffle": "^5.0.30" + "@nomiclabs/buidler": "^1.0.0-beta.8", + "@nomiclabs/buidler-truffle5": "^1.0.0-beta.8", + "@nomiclabs/buidler-web3": "^1.0.0-beta.8", + "mocha": "5.2.0", + "solc": "^0.5.10", + "truffle": "^5.0.30", + "web3": "1.0.0-beta.37" } } diff --git a/test/app.js b/test/app.js deleted file mode 100644 index 3b5354ae..00000000 --- a/test/app.js +++ /dev/null @@ -1,468 +0,0 @@ -/* eslint-env node, mocha */ - -const assert = require('assert'); -const shell = require('shelljs'); -const fs = require('fs'); -const childprocess = require('child_process'); -const mock = require('./util/mockTruffle.js'); - -// shell.test alias for legibility -function pathExists(path) { return shell.test('-e', path); } - -// tests run out of memory in CI without this -function collectGarbage() { - if (global.gc) { global.gc(); } -} - -describe('app', () => { - let testrpcProcess = null; - const script = 'node ./bin/exec.js'; - const port = 8555; - - const config = { - dir: './mock', - port, - testing: true, - silent: true, // <-- Set to false to debug tests - norpc: true, - }; - - before(done => { - const command = `npx testrpc-sc --gasLimit 0xfffffffffff --port ${port}`; - testrpcProcess = childprocess.exec(command); - - testrpcProcess.stdout.on('data', data => { - if (data.includes('Listening')) { - done(); - } - }); - }); - - afterEach(() => { - mock.remove(); - }); - - after(() => { - testrpcProcess.kill(); - }); - - // #1: The 'config' tests ask exec.js to run testrpc on special ports, the subsequent tests use - // the testrpc launched in the before() block. For some reason config tests fail randomly - // unless they are at the top of the suite. Hard to debug since they pass if logging is turned - // on - there might be a timing issue around resource cleanup or something. - // - // #2: Creating repeated instances of testrpc hits the container memory limit on - // CI so these tests are disabled for that context - it('config with testrpc options string: should generate coverage, cleanup & exit(0)', () => { - if (!process.env.CI) { - const privateKey = '0x3af46c9ac38ee1f01b05f9915080133f644bf57443f504d339082cb5285ccae4'; - const balance = '0xfffffffffffffff'; - const testConfig = Object.assign({}, config); - - testConfig.testrpcOptions = `--account="${privateKey},${balance}" --port 8777`; - testConfig.dir = './mock'; - testConfig.norpc = false; - testConfig.port = 8777; - - // Installed test will process.exit(1) and crash truffle if the test isn't - // loaded with the account specified above - mock.install('Simple.sol', 'testrpc-options.js', testConfig); - shell.exec(script); - assert(shell.error() === null, 'script should not error'); - collectGarbage(); - } - }); - - it('config with test command options string: should run test', () => { - if (!process.env.CI) { - assert(pathExists('./allFiredEvents') === false, 'should start without: events log'); - const testConfig = Object.assign({}, config); - - testConfig.testCommand = 'mocha --timeout 5000'; - testConfig.dir = './mock'; - testConfig.norpc = false; - testConfig.port = 8888; - - // Installed test will write a fake allFiredEvents to ./ after 4000ms - // allowing test to pass - mock.install('Simple.sol', 'command-options.js', testConfig); - shell.exec(script); - assert(shell.error() === null, 'script should not error'); - collectGarbage(); - } - }); - - it('config racing test command: should run test after testrpc has started', () => { - if (!process.env.CI) { - assert(pathExists('./allFiredEvents') === false, 'should start without: events log'); - const testConfig = Object.assign({}, config); - - testConfig.testCommand = 'node ../test/util/mockTestCommand.js'; - testConfig.dir = './mock'; - testConfig.norpc = false; - testConfig.port = 8888; - - // Installed test will write a fake allFiredEvents to ./ after 4000ms - // allowing test to pass - mock.install('Simple.sol', 'command-options.js', testConfig); - shell.exec(script); - assert(shell.error() === null, 'script should not error'); - collectGarbage(); - } - }); - - it('contract tests events: tests should pass without errors', () => { - if (!process.env.CI) { - assert(pathExists('./coverage') === false, 'should start without: coverage'); - assert(pathExists('./coverage.json') === false, 'should start without: coverage.json'); - - const testConfig = Object.assign({}, config); - - testConfig.dir = './mock'; - testConfig.norpc = false; - testConfig.port = 8889; - - mock.install('Events.sol', 'events.js', testConfig); - shell.exec(script); - assert(shell.error() === null, 'script should not error'); - - // Directory should have coverage report - assert(pathExists('./coverage') === true, 'script should gen coverage folder'); - assert(pathExists('./coverage.json') === true, 'script should gen coverage.json'); - - // Coverage should be real. - // This test is tightly bound to the function names in Simple.sol - const produced = JSON.parse(fs.readFileSync('./coverage.json', 'utf8')); - const path = Object.keys(produced)[0]; - assert(produced[path].fnMap['1'].name === 'test', 'coverage.json should map "test"'); - assert(produced[path].fnMap['2'].name === 'getX', 'coverage.json should map "getX"'); - collectGarbage(); - } - }); - - it('trufflejs specifies coverage network: should generate coverage, cleanup and exit(0)', () => { - if (!process.env.CI) { - const trufflejs = - `module.exports = { - networks: { - development: { - host: "localhost", - port: 8545, - network_id: "*" - }, - coverage: { - host: "localhost", - port: 8999, - network_id: "*", - gas: 0xfffffffffff, - gasPrice: 0x01 - } - }, - compilers: { - solc: { - version: "0.5.3", - } - } - };`; - - const testConfig = Object.assign({}, config); - testConfig.dir = './mock'; - testConfig.norpc = false; - testConfig.port = 8555; // Manually inspect that port is actually set to 8999 - - // Directory should be clean - assert(pathExists('./coverage') === false, 'should start without: coverage'); - assert(pathExists('./coverage.json') === false, 'should start without: coverage.json'); - - // Run script (exits 0); - mock.install('Simple.sol', 'simple.js', testConfig, trufflejs); - shell.exec(script); - assert(shell.error() === null, 'script should not error'); - - // Directory should have coverage report - assert(pathExists('./coverage') === true, 'script should gen coverage folder'); - assert(pathExists('./coverage.json') === true, 'script should gen coverage.json'); - - // Coverage should be real. - // This test is tightly bound to the function names in Simple.sol - const produced = JSON.parse(fs.readFileSync('./coverage.json', 'utf8')); - const path = Object.keys(produced)[0]; - assert(produced[path].fnMap['1'].name === 'test', 'coverage.json should map "test"'); - assert(produced[path].fnMap['2'].name === 'getX', 'coverage.json should map "getX"'); - collectGarbage(); - } - }); - - it('large contract w/ many unbracketed statements (Oraclize)', () => { - const trufflejs = - `module.exports = { - networks: { - coverage: { - host: "localhost", - network_id: "*", - port: 8555, - gas: 0xfffffffffff, - gasPrice: 0x01 - }, - }, - compilers: { - solc: { - version: "0.4.24", - } - } - };`; - - // Directory should be clean - assert(pathExists('./coverage') === false, 'should start without: coverage'); - assert(pathExists('./coverage.json') === false, 'should start without: coverage.json'); - - // Run script (exits 0); - mock.install('Oraclize.sol', 'oraclize.js', config, trufflejs, null, true); - shell.exec(script); - assert(shell.error() === null, 'script should not error'); - - }); - - it('simple contract: should generate coverage, cleanup & exit(0)', () => { - // Directory should be clean - assert(pathExists('./coverage') === false, 'should start without: coverage'); - assert(pathExists('./coverage.json') === false, 'should start without: coverage.json'); - - // Run script (exits 0); - mock.install('Simple.sol', 'simple.js', config); - shell.exec(script); - assert(shell.error() === null, 'script should not error'); - - // Directory should have coverage report - assert(pathExists('./coverage') === true, 'script should gen coverage folder'); - assert(pathExists('./coverage.json') === true, 'script should gen coverage.json'); - - // Coverage should be real. - // This test is tightly bound to the function names in Simple.sol - const produced = JSON.parse(fs.readFileSync('./coverage.json', 'utf8')); - const path = Object.keys(produced)[0]; - assert(produced[path].fnMap['1'].name === 'test', 'coverage.json should map "test"'); - assert(produced[path].fnMap['2'].name === 'getX', 'coverage.json should map "getX"'); - collectGarbage(); - }); - - it('project uses truffle-config.js: should generate coverage, cleanup and exit(0)', () => { - // Directory should be clean - assert(pathExists('./coverage') === false, 'should start without: coverage'); - assert(pathExists('./coverage.json') === false, 'should start without: coverage.json'); - - // Run script (exits 0); - mock.install('Simple.sol', 'simple.js', config, null, 'truffle-config.js'); - shell.exec(script); - assert(shell.error() === null, 'script should not error'); - - // Directory should have coverage report - assert(pathExists('./coverage') === true, 'script should gen coverage folder'); - assert(pathExists('./coverage.json') === true, 'script should gen coverage.json'); - - // Coverage should be real. - // This test is tightly bound to the function names in Simple.sol - const produced = JSON.parse(fs.readFileSync('./coverage.json', 'utf8')); - const path = Object.keys(produced)[0]; - assert(produced[path].fnMap['1'].name === 'test', 'coverage.json should map "test"'); - assert(produced[path].fnMap['2'].name === 'getX', 'coverage.json should map "getX"'); - collectGarbage(); - }); - - it('testrpc-sc signs and recovers messages correctly', () => { - // sign.js signs and recovers - mock.install('Simple.sol', 'sign.js', config); - shell.exec(script); - assert(shell.error() === null, 'script should not error'); - collectGarbage(); - }); - - it('tests use pure and view modifiers, including with libraries', () => { - // Directory should be clean - assert(pathExists('./coverage') === false, 'should start without: coverage'); - assert(pathExists('./coverage.json') === false, 'should start without: coverage.json'); - - // Run script (exits 0); - mock.installLibraryTest(config); - shell.exec(script); - assert(shell.error() === null, 'script should not error'); - - // Directory should have coverage report - assert(pathExists('./coverage') === true, 'script should gen coverage folder'); - assert(pathExists('./coverage.json') === true, 'script should gen coverage.json'); - - // Coverage should be real. - // This test is tightly bound to the function names in TotallyPure.sol - const produced = JSON.parse(fs.readFileSync('./coverage.json', 'utf8')); - const path = Object.keys(produced)[0]; - assert(produced[path].fnMap['1'].name === 'usesThem', 'coverage.json should map "usesThem"'); - assert(produced[path].fnMap['2'].name === 'isPure', 'coverage.json should map "getX"'); - collectGarbage(); - }); - - it('tests require assets outside of test folder: should generate coverage, cleanup & exit(0)', () => { - // Directory should be clean - assert(pathExists('./coverage') === false, 'should start without: coverage'); - assert(pathExists('./coverage.json') === false, 'should start without: coverage.json'); - - // Run script (exits 0); - mock.install('Simple.sol', 'requires-externally.js', config); - shell.exec(script); - assert(shell.error() === null, 'script should not error'); - - // Directory should have coverage report - assert(pathExists('./coverage') === true, 'script should gen coverage folder'); - assert(pathExists('./coverage.json') === true, 'script should gen coverage.json'); - - // Coverage should be real. - // This test is tightly bound to the function names in Simple.sol - const produced = JSON.parse(fs.readFileSync('./coverage.json', 'utf8')); - const path = Object.keys(produced)[0]; - assert(produced[path].fnMap['1'].name === 'test', 'coverage.json should map "test"'); - assert(produced[path].fnMap['2'].name === 'getX', 'coverage.json should map "getX"'); - collectGarbage(); - }); - - it('contract only uses .call: should generate coverage, cleanup & exit(0)', () => { - // Run against contract that only uses method.call. - assert(pathExists('./coverage') === false, 'should start without: coverage'); - assert(pathExists('./coverage.json') === false, 'should start without: coverage.json'); - mock.install('OnlyCall.sol', 'only-call.js', config); - - shell.exec(script); - assert(shell.error() === null, 'script should not error'); - - assert(pathExists('./coverage') === true, 'script should gen coverage folder'); - assert(pathExists('./coverage.json') === true, 'script should gen coverage.json'); - - const produced = JSON.parse(fs.readFileSync('./coverage.json', 'utf8')); - const path = Object.keys(produced)[0]; - assert(produced[path].fnMap['1'].name === 'addTwo', 'coverage.json should map "addTwo"'); - collectGarbage(); - }); - - it('contract sends / transfers to instrumented fallback: coverage, cleanup & exit(0)', () => { - // Skipped due to https://github.com/sc-forks/solidity-coverage/issues/106 - // Validate ethereumjs-vm hack to remove gas constraints on transfer() and send() - assert(pathExists('./coverage') === false, 'should start without: coverage'); - assert(pathExists('./coverage.json') === false, 'should start without: coverage.json'); - - mock.install('Wallet.sol', 'wallet.js', config); - shell.exec(script); - assert(shell.error() === null, 'script should not error'); - - assert(pathExists('./coverage') === true, 'script should gen coverage folder'); - assert(pathExists('./coverage.json') === true, 'script should gen coverage.json'); - - const produced = JSON.parse(fs.readFileSync('./coverage.json', 'utf8')); - const path = Object.keys(produced)[0]; - assert(produced[path].fnMap['1'].name === 'transferPayment', 'should map "transferPayment"'); - collectGarbage(); - }); - - it('contract uses inheritance: should generate coverage, cleanup & exit(0)', () => { - // Run against a contract that 'is' another contract - assert(pathExists('./coverage') === false, 'should start without: coverage'); - assert(pathExists('./coverage.json') === false, 'should start without: coverage.json'); - mock.installInheritanceTest(config); - - shell.exec(script); - assert(shell.error() === null, 'script should not error'); - - assert(pathExists('./coverage') === true, 'script should gen coverage folder'); - assert(pathExists('./coverage.json') === true, 'script should gen coverage.json'); - - const produced = JSON.parse(fs.readFileSync('./coverage.json', 'utf8')); - const ownedPath = Object.keys(produced)[0]; - const proxyPath = Object.keys(produced)[1]; - assert(produced[ownedPath].fnMap['1'].name === 'constructor', 'coverage.json should map "constructor"'); - assert(produced[proxyPath].fnMap['1'].name === 'isOwner', 'coverage.json should map "isOwner"'); - collectGarbage(); - }); - - it('contracts are skipped: should generate coverage, cleanup & exit(0)', () => { - // Skip instrumentation of some contracts - assert(pathExists('./coverage') === false, 'should start without: coverage'); - assert(pathExists('./coverage.json') === false, 'should start without: coverage.json'); - const testConfig = Object.assign({}, config); - - testConfig.skipFiles = ['Owned.sol']; - mock.installInheritanceTest(testConfig); - - shell.exec(script); - assert(shell.error() === null, 'script should not error'); - - assert(pathExists('./coverage') === true, 'script should gen coverage folder'); - assert(pathExists('./coverage.json') === true, 'script should gen coverage.json'); - - const produced = JSON.parse(fs.readFileSync('./coverage.json', 'utf8')); - const firstKey = Object.keys(produced)[0]; - assert(Object.keys(produced).length === 1, 'coverage.json should only contain instrumentation for one contract'); - assert(firstKey.substr(firstKey.length - 9) === 'Proxy.sol', 'coverage.json should only contain instrumentation for Proxy.sol'); - collectGarbage(); - }); - - it('truffle tests failing: should generate coverage, cleanup & exit(1)', () => { - assert(pathExists('./coverage') === false, 'should start without: coverage'); - assert(pathExists('./coverage.json') === false, 'should start without: coverage.json'); - - // Run with Simple.sol and a failing assertion in a truffle test - mock.install('Simple.sol', 'truffle-test-fail.js', config); - shell.exec(script); - assert(shell.error() !== null, 'script should exit 1'); - assert(pathExists('./coverage') === true, 'script should gen coverage folder'); - assert(pathExists('./coverage.json') === true, 'script should gen coverage.json'); - - const produced = JSON.parse(fs.readFileSync('./coverage.json', 'utf8')); - const path = Object.keys(produced)[0]; - assert(produced[path].fnMap['1'].name === 'test', 'coverage.json should map "test"'); - assert(produced[path].fnMap['2'].name === 'getX', 'coverage.json should map "getX"'); - collectGarbage(); - }); - - it('deployment cost > block gasLimit: should generate coverage, cleanup & exit(0)', () => { - // Just making sure Expensive.sol compiles and deploys here. - mock.install('Expensive.sol', 'block-gas-limit.js', config); - shell.exec(script); - assert(shell.error() === null, 'script should not error'); - collectGarbage(); - }); - - it('truffle crashes: should generate NO coverage, cleanup and exit(1)', () => { - assert(pathExists('./coverage') === false, 'should start without: coverage'); - assert(pathExists('./coverage.json') === false, 'should start without: coverage.json'); - - // Run with Simple.sol and a syntax error in the truffle test - mock.install('Simple.sol', 'truffle-crash.js', config); - shell.exec(script); - assert(shell.error() !== null, 'script should error'); - assert(pathExists('./coverage') !== true, 'script should NOT gen coverage folder'); - assert(pathExists('./coverage.json') !== true, 'script should NOT gen coverage.json'); - collectGarbage(); - }); - - it('instrumentation errors: should generate NO coverage, cleanup and exit(1)', () => { - assert(pathExists('./coverage') === false, 'should start without: coverage'); - assert(pathExists('./coverage.json') === false, 'should start without: coverage.json'); - - // Run with SimpleError.sol (has syntax error) and working truffle test - mock.install('SimpleError.sol', 'simple.js', config); - shell.exec(script); - assert(shell.error() !== null, 'script should error'); - assert(pathExists('./coverage') !== true, 'script should NOT gen coverage folder'); - assert(pathExists('./coverage.json') !== true, 'script should NOT gen coverage.json'); - collectGarbage(); - }); - - it('no events log produced: should generate NO coverage, cleanup and exit(1)', () => { - // Run contract and test that pass but fire no events - assert(pathExists('./coverage') === false, 'should start without: coverage'); - assert(pathExists('./coverage.json') === false, 'should start without: coverage.json'); - mock.install('Empty.sol', 'empty.js', config); - shell.exec(script); - assert(shell.error() !== null, 'script should error'); - assert(pathExists('./coverage') !== true, 'script should NOT gen coverage folder'); - assert(pathExists('./coverage.json') !== true, 'script should NOT gen coverage.json'); - collectGarbage(); - }); -}); diff --git a/test/assembly.js b/test/assembly.js deleted file mode 100644 index a41c7b8b..00000000 --- a/test/assembly.js +++ /dev/null @@ -1,30 +0,0 @@ -/* eslint-env node, mocha */ - -const solc = require('solc'); -const getInstrumentedVersion = require('./../lib/instrumentSolidity.js'); -const util = require('./util/util.js'); -const path = require('path'); - -/** - * NB: passing '1' to solc as an option activates the optimiser - * NB: solc will throw if there is a compilation error, causing the test to fail - * and passing the error to mocha. - */ -describe('generic expressions', () => { - const filePath = path.resolve('./test.sol'); - - it('should compile after instrumenting an assembly function with spaces in parameters', () => { - const contract = util.getCode('assembly/spaces-in-function.sol'); - const info = getInstrumentedVersion(contract, filePath); - const output = JSON.parse(solc.compile(util.codeToCompilerInput(info.contract))); - util.report(output.errors); - }); - - it('should compile after instrumenting an assembly if statement', () => { - const contract = util.getCode('assembly/if.sol'); - const info = getInstrumentedVersion(contract, filePath); - const output = JSON.parse(solc.compile(util.codeToCompilerInput(info.contract))); - util.report(output.errors); - }); - -}); diff --git a/test/assert.js b/test/assert.js deleted file mode 100644 index 2f074c11..00000000 --- a/test/assert.js +++ /dev/null @@ -1,109 +0,0 @@ -/* eslint-env node, mocha */ - -const path = require('path'); -const getInstrumentedVersion = require('./../lib/instrumentSolidity.js'); -const util = require('./util/util.js'); -const CoverageMap = require('./../lib/coverageMap'); -const vm = require('./util/vm'); -const assert = require('assert'); - -describe('asserts and requires', () => { - const filePath = path.resolve('./test.sol'); - const pathPrefix = './'; - - it('should cover assert statements as if they are if statements when they pass', done => { - const contract = util.getCode('assert/Assert.sol'); - const info = getInstrumentedVersion(contract, filePath); - const coverage = new CoverageMap(); - coverage.addContract(info, filePath); - - vm.execute(info.contract, 'a', [true]).then(events => { - const mapping = coverage.generate(events, pathPrefix); - assert.deepEqual(mapping[filePath].l, { - 5: 1, - }); - assert.deepEqual(mapping[filePath].b, { - 1: [1, 0], - }); - assert.deepEqual(mapping[filePath].s, { - 1: 1, - }); - assert.deepEqual(mapping[filePath].f, { - 1: 1, - }); - done(); - }).catch(done); - }); - - it('should cover assert statements as if they are if statements when they fail', done => { - const contract = util.getCode('assert/Assert.sol'); - const info = getInstrumentedVersion(contract, filePath); - const coverage = new CoverageMap(); - coverage.addContract(info, filePath); - - vm.execute(info.contract, 'a', [false]).then(events => { - const mapping = coverage.generate(events, pathPrefix); - assert.deepEqual(mapping[filePath].l, { - 5: 1, - }); - assert.deepEqual(mapping[filePath].b, { - 1: [0, 1], - }); - assert.deepEqual(mapping[filePath].s, { - 1: 1, - }); - assert.deepEqual(mapping[filePath].f, { - 1: 1, - }); - done(); - }).catch(done); - }); - - it('should cover multi-line require statements as if they are if statements when they pass', done => { - const contract = util.getCode('assert/RequireMultiline.sol'); - const info = getInstrumentedVersion(contract, filePath); - const coverage = new CoverageMap(); - coverage.addContract(info, filePath); - - vm.execute(info.contract, 'a', [true, true, true]).then(events => { - const mapping = coverage.generate(events, pathPrefix); - assert.deepEqual(mapping[filePath].l, { - 5: 1, - }); - assert.deepEqual(mapping[filePath].b, { - 1: [1, 0], - }); - assert.deepEqual(mapping[filePath].s, { - 1: 1, - }); - assert.deepEqual(mapping[filePath].f, { - 1: 1, - }); - done(); - }).catch(done); - }); - - it('should cover multi-line require statements as if they are if statements when they fail', done => { - const contract = util.getCode('assert/RequireMultiline.sol'); - const info = getInstrumentedVersion(contract, filePath); - const coverage = new CoverageMap(); - coverage.addContract(info, filePath); - - vm.execute(info.contract, 'a', [true, true, false]).then(events => { - const mapping = coverage.generate(events, pathPrefix); - assert.deepEqual(mapping[filePath].l, { - 5: 1, - }); - assert.deepEqual(mapping[filePath].b, { - 1: [0, 1], - }); - assert.deepEqual(mapping[filePath].s, { - 1: 1, - }); - assert.deepEqual(mapping[filePath].f, { - 1: 1, - }); - done(); - }).catch(done); - }); -}); diff --git a/test/cli/command-options.js b/test/cli/command-options.js deleted file mode 100644 index 8dad7585..00000000 --- a/test/cli/command-options.js +++ /dev/null @@ -1,24 +0,0 @@ -/* eslint-env node, mocha */ - -const assert = require('assert'); -const fs = require('fs'); - -// Fake event for Simple.sol -const fakeEvent = {"address":"6d6cf716c2a7672047e15a255d4c9624db60f215","topics":["34b35f4b1a8c3eb2caa69f05fb5aadc827cedd2d8eb3bb3623b6c4bba3baec17"],"data":"00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000003a2f55736572732f757365722f53697465732f73632d666f726b732f6d657461636f696e2f636f6e7472616374732f4d657461436f696e2e736f6c000000000000"} - -/* { - address: '7c548f8a5ba3a37774440587743bb50f58c7e91c', - topics: ['1accf53d733f86cbefdf38d52682bc905cf6715eb3d860be0b5b052e58b0741d'], - data: '0', -};*/ -// Tests whether or not the testCommand option is invoked by exec.js -// Mocha's default timeout is 2000 - here we fake the creation of -// allFiredEvents at 4000. -describe('Test uses mocha', () => { - it('should run "mocha --timeout 5000" successfully', done => { - setTimeout(() => { - fs.writeFileSync('./../allFiredEvents', JSON.stringify(fakeEvent) + '\n'); - done(); - }, 4000); - }); -}); \ No newline at end of file diff --git a/test/cli/events.js b/test/cli/events.js deleted file mode 100644 index 53b15b0b..00000000 --- a/test/cli/events.js +++ /dev/null @@ -1,21 +0,0 @@ -/* eslint-env node, mocha */ -/* global artifacts, contract, assert */ - -const Events = artifacts.require('./Events.sol'); - -contract('Events', accounts => { - it('logs events correctly', done => { - const loggedEvents = []; - Events.deployed().then(instance => { - const allEvents = instance.allEvents(); - - allEvents.on("data", event => { loggedEvents.push(event); }); - - instance.test(5).then(() => { - const bad = loggedEvents.filter(e => e.event !== 'LogEventOne' && e.event !== 'LogEventTwo'); - assert(bad.length === 0, 'Did not filter events correctly'); - done(); - }); - }); - }); -}); \ No newline at end of file diff --git a/test/comments.js b/test/comments.js deleted file mode 100644 index 79ca305e..00000000 --- a/test/comments.js +++ /dev/null @@ -1,38 +0,0 @@ -/* eslint-env node, mocha */ - -const path = require('path'); -const getInstrumentedVersion = require('./../lib/instrumentSolidity.js'); -const util = require('./util/util.js'); -const solc = require('solc'); -const assert = require('assert'); - -describe('comments', () => { - const filePath = path.resolve('./test.sol'); - const pathPrefix = './'; - - it('should cover functions even if comments are present immediately after the opening {', () => { - const contract = util.getCode('comments/postFunctionDeclarationComment.sol'); - const info = getInstrumentedVersion(contract, filePath); - const output = JSON.parse(solc.compile(util.codeToCompilerInput(info.contract))); - util.report(output.errors); - }); - it('should cover lines even if comments are present', () => { - const contract = util.getCode('comments/postLineComment.sol'); - const info = getInstrumentedVersion(contract, filePath); - const output = JSON.parse(solc.compile(util.codeToCompilerInput(info.contract))); - assert.deepEqual([6, 5], info.runnableLines); - util.report(output.errors); - }); - it('should cover contracts even if comments are present', () => { - const contract = util.getCode('comments/postContractComment.sol'); - const info = getInstrumentedVersion(contract, filePath); - const output = JSON.parse(solc.compile(util.codeToCompilerInput(info.contract))); - util.report(output.errors); - }); - it('should cover if statements even if comments are present immediately after opening { ', () => { - const contract = util.getCode('comments/postIfStatementComment.sol'); - const info = getInstrumentedVersion(contract, filePath); - const output = JSON.parse(solc.compile(util.codeToCompilerInput(info.contract))); - util.report(output.errors); - }); -}); diff --git a/test/expressions.js b/test/expressions.js deleted file mode 100644 index 5723e22b..00000000 --- a/test/expressions.js +++ /dev/null @@ -1,29 +0,0 @@ -/* eslint-env node, mocha */ - -const solc = require('solc'); -const getInstrumentedVersion = require('./../lib/instrumentSolidity.js'); -const util = require('./util/util.js'); -const path = require('path'); - -/** - * NB: passing '1' to solc as an option activates the optimiser - * NB: solc will throw if there is a compilation error, causing the test to fail - * and passing the error to mocha. - */ -describe('generic expressions', () => { - const filePath = path.resolve('./test.sol'); - - it('should compile after instrumenting a single binary expression', () => { - const contract = util.getCode('expressions/single-binary-expression.sol'); - const info = getInstrumentedVersion(contract, filePath); - const output = JSON.parse(solc.compile(util.codeToCompilerInput(info.contract))); - util.report(output.errors); - }); - - it('should compile after instrumenting a new expression', () => { - const contract = util.getCode('expressions/new-expression.sol'); - const info = getInstrumentedVersion(contract, filePath); - const output = JSON.parse(solc.compile(util.codeToCompilerInput(info.contract))); - util.report(output.errors); - }); -}); diff --git a/test/function.js b/test/function.js deleted file mode 100644 index a5bb8651..00000000 --- a/test/function.js +++ /dev/null @@ -1,192 +0,0 @@ -/* eslint-env node, mocha */ - -const solc = require('solc'); -const getInstrumentedVersion = require('./../lib/instrumentSolidity.js'); -const util = require('./util/util.js'); -const path = require('path'); -const CoverageMap = require('./../lib/coverageMap'); -const vm = require('./util/vm'); -const assert = require('assert'); - -/** - * NB: passing '1' to solc as an option activates the optimiser - * NB: solc will throw if there is a compilation error, causing the test to fail - * and passing the error to mocha. - */ -describe('function declarations', () => { - const filePath = path.resolve('./test.sol'); - const pathPrefix = './'; - - it('should compile after instrumenting an ordinary function declaration', () => { - const contract = util.getCode('function/function.sol'); - const info = getInstrumentedVersion(contract, 'test.sol'); - const output = JSON.parse(solc.compile(util.codeToCompilerInput(info.contract))); - util.report(output.errors); - }); - - it('should compile after instrumenting an abstract function declaration', () => { - const contract = util.getCode('function/abstract.sol'); - const info = getInstrumentedVersion(contract, 'test.sol'); - const output = JSON.parse(solc.compile(util.codeToCompilerInput(info.contract))); - util.report(output.errors); - }); - - it('should compile after instrumenting a function declaration with an empty body', () => { - const contract = util.getCode('function/empty-body.sol'); - const info = getInstrumentedVersion(contract, 'test.sol'); - const output = JSON.parse(solc.compile(util.codeToCompilerInput(info.contract))); - util.report(output.errors); - }); - - it('should compile after instrumenting lots of declarations in row', () => { - const contract = util.getCode('function/multiple.sol'); - const info = getInstrumentedVersion(contract, 'test.sol'); - const output = JSON.parse(solc.compile(util.codeToCompilerInput(info.contract))); - util.report(output.errors); - }); - - it('should compile after instrumenting a new->constructor-->method chain', () => { - const contract = util.getCode('function/chainable-new.sol'); - const info = getInstrumentedVersion(contract, 'test.sol'); - const output = JSON.parse(solc.compile(util.codeToCompilerInput(info.contract))); - util.report(output.errors); - }); - - it('should compile after instrumenting a constructor call that chains to a method call', () => { - const contract = util.getCode('function/chainable.sol'); - const info = getInstrumentedVersion(contract, 'test.sol'); - const output = JSON.parse(solc.compile(util.codeToCompilerInput(info.contract))); - util.report(output.errors); - }); - - it('should compile after instrumenting a function with calldata keyword', () => { - const contract = util.getCode('function/calldata.sol'); - const info = getInstrumentedVersion(contract, 'test.sol'); - const output = JSON.parse(solc.compile(util.codeToCompilerInput(info.contract))); - util.report(output.errors); - }); - - it('should compile after instrumenting a constructor-->method-->value chain', () => { - const contract = util.getCode('function/chainable-value.sol'); - const info = getInstrumentedVersion(contract, 'test.sol'); - const output = JSON.parse(solc.compile(util.codeToCompilerInput(info.contract))); - util.report(output.errors); - }); - - it('should cover a simple invoked function call', done => { - const contract = util.getCode('function/function-call.sol'); - const info = getInstrumentedVersion(contract, filePath); - const coverage = new CoverageMap(); - coverage.addContract(info, filePath); - - vm.execute(info.contract, 'a', []).then(events => { - const mapping = coverage.generate(events, pathPrefix); - assert.deepEqual(mapping[filePath].l, { - 7: 1, - }); - assert.deepEqual(mapping[filePath].b, {}); - assert.deepEqual(mapping[filePath].s, { - 1: 1, - }); - assert.deepEqual(mapping[filePath].f, { - 1: 1, - 2: 1, - }); - done(); - }).catch(done); - }); - - it('should cover a modifier used on a function', done => { - const contract = util.getCode('function/modifier.sol'); - const info = getInstrumentedVersion(contract, filePath); - const coverage = new CoverageMap(); - coverage.addContract(info, filePath); - - vm.execute(info.contract, 'a', [0]).then(events => { - const mapping = coverage.generate(events, pathPrefix); - assert.deepEqual(mapping[filePath].l, { - 5: 1, 6: 1, 9: 1, - }); - assert.deepEqual(mapping[filePath].b, {}); - assert.deepEqual(mapping[filePath].s, { - 1: 1 - }); - assert.deepEqual(mapping[filePath].f, { - 1: 1, - 2: 1, - }); - done(); - }).catch(done); - }); - - it('should cover a constructor that uses the `constructor` keyword', done => { - const contract = util.getCode('function/constructor-keyword.sol'); - const info = getInstrumentedVersion(contract, filePath); - const coverage = new CoverageMap(); - coverage.addContract(info, filePath); - - vm.execute(info.contract, 'a', []).then(events => { - const mapping = coverage.generate(events, pathPrefix); - assert.deepEqual(mapping[filePath].l, { - 6: 1, 11: 1 - }); - assert.deepEqual(mapping[filePath].b, {}); - assert.deepEqual(mapping[filePath].s, { - 1: 1, 2: 1 - }); - assert.deepEqual(mapping[filePath].f, { - 1: 1, - 2: 1, - }); - done(); - }).catch(done); - }); - - it('should cover a constructor call that chains to a method call', done => { - const contract = util.getCode('function/chainable.sol'); - const info = getInstrumentedVersion(contract, filePath); - const coverage = new CoverageMap(); - coverage.addContract(info, filePath); - // We try and call a contract at an address where it doesn't exist and the VM - // throws, but we can verify line / statement / fn coverage is getting mapped. - vm.execute(info.contract, 'a', []).then(events => { - const mapping = coverage.generate(events, pathPrefix); - assert.deepEqual(mapping[filePath].l, { - 9: 1, - }); - assert.deepEqual(mapping[filePath].b, {}); - assert.deepEqual(mapping[filePath].s, { - 1: 1, - }); - assert.deepEqual(mapping[filePath].f, { - 1: 0, - 2: 1, - }); - done(); - }).catch(done); - }); - - it('should cover a constructor call that chains to a method call', done => { - const contract = util.getCode('function/chainable-value.sol'); - const info = getInstrumentedVersion(contract, filePath); - const coverage = new CoverageMap(); - coverage.addContract(info, filePath); - // The vm runs out of gas here - but we can verify line / statement / fn - // coverage is getting mapped. - vm.execute(info.contract, 'a', []).then(events => { - const mapping = coverage.generate(events, pathPrefix); - assert.deepEqual(mapping[filePath].l, { - 10: 1, - }); - assert.deepEqual(mapping[filePath].b, {}); - assert.deepEqual(mapping[filePath].s, { - 1: 1, - }); - assert.deepEqual(mapping[filePath].f, { - 1: 0, - 2: 1, - }); - done(); - }).catch(done); - }); -}); diff --git a/test/if.js b/test/if.js deleted file mode 100644 index 4ea0220a..00000000 --- a/test/if.js +++ /dev/null @@ -1,274 +0,0 @@ -/* eslint-env node, mocha */ - -const solc = require('solc'); -const path = require('path'); -const getInstrumentedVersion = require('./../lib/instrumentSolidity.js'); -const util = require('./util/util.js'); -const CoverageMap = require('./../lib/coverageMap'); -const vm = require('./util/vm'); -const assert = require('assert'); - -describe('if, else, and else if statements', () => { - const filePath = path.resolve('./test.sol'); - const pathPrefix = './'; - - it('should compile after instrumenting multiple if-elses', () => { - const contract = util.getCode('if/else-if-unbracketed-multi.sol'); - const info = getInstrumentedVersion(contract, filePath); - const output = JSON.parse(solc.compile(util.codeToCompilerInput(info.contract))); - util.report(output.errors); - }); - - it('should compile after instrumenting unbracketed if-elses', () => { - const contract = util.getCode('if/if-else-no-brackets.sol'); - const info = getInstrumentedVersion(contract, filePath); - const output = JSON.parse(solc.compile(util.codeToCompilerInput(info.contract))); - util.report(output.errors); - }); - - - it('should cover an if statement with a bracketed consequent', done => { - const contract = util.getCode('if/if-with-brackets.sol'); - const info = getInstrumentedVersion(contract, filePath); - const coverage = new CoverageMap(); - coverage.addContract(info, filePath); - - // Runs: a(1) => if (x == 1) { x = 3; } - vm.execute(info.contract, 'a', [1]).then(events => { - const mapping = coverage.generate(events, pathPrefix); - assert.deepEqual(mapping[filePath].l, { - 5: 1, - }); - assert.deepEqual(mapping[filePath].b, { - 1: [1, 0], - }); - assert.deepEqual(mapping[filePath].s, { - 1: 1, 2: 1, - }); - assert.deepEqual(mapping[filePath].f, { - 1: 1, - }); - done(); - }).catch(done); - }); - - // Runs: a(1) => if (x == 1) x = 2; - it('should cover an unbracketed if consequent (single line)', done => { - const contract = util.getCode('if/if-no-brackets.sol'); - const info = getInstrumentedVersion(contract, filePath); - const coverage = new CoverageMap(); - coverage.addContract(info, filePath); - - // Same results as previous test - vm.execute(info.contract, 'a', [1]).then(events => { - const mapping = coverage.generate(events, pathPrefix); - assert.deepEqual(mapping[filePath].l, { - 5: 1, - }); - assert.deepEqual(mapping[filePath].b, { - 1: [1, 0], - }); - assert.deepEqual(mapping[filePath].s, { - 1: 1, 2: 1, - }); - assert.deepEqual(mapping[filePath].f, { - 1: 1, - }); - done(); - }).catch(done); - }); - - it('should cover an if statement with multiline bracketed consequent', done => { - const contract = util.getCode('if/if-with-brackets-multiline.sol'); - const info = getInstrumentedVersion(contract, filePath); - const coverage = new CoverageMap(); - coverage.addContract(info, filePath); - - // Runs: a(1) => if (x == 1){\n x = 3; } - vm.execute(info.contract, 'a', [1]).then(events => { - const mapping = coverage.generate(events, pathPrefix); - assert.deepEqual(mapping[filePath].l, { - 5: 1, 6: 1, - }); - assert.deepEqual(mapping[filePath].b, { - 1: [1, 0], - }); - assert.deepEqual(mapping[filePath].s, { - 1: 1, 2: 1, - }); - assert.deepEqual(mapping[filePath].f, { - 1: 1, - }); - done(); - }).catch(done); - }); - - // Runs: a(1) => if (x == 1)\n x = 3; - it('should cover an unbracketed if consequent (multi-line)', done => { - const contract = util.getCode('if/if-no-brackets-multiline.sol'); - const info = getInstrumentedVersion(contract, filePath); - const coverage = new CoverageMap(); - coverage.addContract(info, filePath); - // Same results as previous test - vm.execute(info.contract, 'a', [1]).then(events => { - const mapping = coverage.generate(events, pathPrefix); - assert.deepEqual(mapping[filePath].l, { - 5: 1, 6: 1, - }); - assert.deepEqual(mapping[filePath].b, { - 1: [1, 0], - }); - assert.deepEqual(mapping[filePath].s, { - 1: 1, 2: 1, - }); - assert.deepEqual(mapping[filePath].f, { - 1: 1, - }); - done(); - }).catch(done); - }); - - it('should cover a simple if statement with a failing condition', done => { - const contract = util.getCode('if/if-with-brackets.sol'); - const info = getInstrumentedVersion(contract, filePath); - const coverage = new CoverageMap(); - coverage.addContract(info, filePath); - - // Runs: a(2) => if (x == 1) { x = 3; } - vm.execute(info.contract, 'a', [2]).then(events => { - const mapping = coverage.generate(events, pathPrefix); - assert.deepEqual(mapping[filePath].l, { - 5: 1, - }); - assert.deepEqual(mapping[filePath].b, { - 1: [0, 1], - }); - assert.deepEqual(mapping[filePath].s, { - 1: 1, 2: 0, - }); - assert.deepEqual(mapping[filePath].f, { - 1: 1, - }); - done(); - }).catch(done); - }); - - // Runs: a(2) => if (x == 1){\n throw;\n }else{\n x = 5; \n} - it('should cover an if statement with a bracketed alternate', done => { - const contract = util.getCode('if/else-with-brackets.sol'); - const info = getInstrumentedVersion(contract, filePath); - const coverage = new CoverageMap(); - coverage.addContract(info, filePath); - - vm.execute(info.contract, 'a', [2]).then(events => { - const mapping = coverage.generate(events, pathPrefix); - assert.deepEqual(mapping[filePath].l, { - 5: 1, 6: 0, 8: 1, - }); - assert.deepEqual(mapping[filePath].b, { - 1: [0, 1], - }); - assert.deepEqual(mapping[filePath].s, { - 1: 1, 2: 0, 3: 1, - }); - assert.deepEqual(mapping[filePath].f, { - 1: 1, - }); - done(); - }).catch(done); - }); - - it('should cover an if statement with an unbracketed alternate', done => { - const contract = util.getCode('if/else-without-brackets.sol'); - const info = getInstrumentedVersion(contract, filePath); - const coverage = new CoverageMap(); - coverage.addContract(info, filePath); - - vm.execute(info.contract, 'a', [2]).then(events => { - const mapping = coverage.generate(events, pathPrefix); - assert.deepEqual(mapping[filePath].l, { - 5: 1, 6: 0, 8: 1, - }); - assert.deepEqual(mapping[filePath].b, { - 1: [0, 1], - }); - assert.deepEqual(mapping[filePath].s, { - 1: 1, 2: 0, 3: 1, - }); - assert.deepEqual(mapping[filePath].f, { - 1: 1, - }); - done(); - }).catch(done); - }); - - it('should cover an else if statement with an unbracketed alternate', done => { - const contract = util.getCode('if/else-if-without-brackets.sol'); - const info = getInstrumentedVersion(contract, filePath); - const coverage = new CoverageMap(); - coverage.addContract(info, filePath); - - vm.execute(info.contract, 'a', [2]).then(events => { - const mapping = coverage.generate(events, pathPrefix); - assert.deepEqual(mapping[filePath].l, { - 5: 1, 6: 0, 8: 0, - }); - assert.deepEqual(mapping[filePath].b, { - 1: [0, 1], 2: [0, 1] - }); - assert.deepEqual(mapping[filePath].s, { - 1: 1, 2: 0, 3: 1, 4: 0 - }); - assert.deepEqual(mapping[filePath].f, { - 1: 1, - }); - done(); - }).catch(done); - }); - - it('should cover nested if statements with missing else statements', done => { - const contract = util.getCode('if/nested-if-missing-else.sol'); - const info = getInstrumentedVersion(contract, filePath); - const coverage = new CoverageMap(); - coverage.addContract(info, filePath); - vm.execute(info.contract, 'a', [2, 3, 3]).then(events => { - const mapping = coverage.generate(events, pathPrefix); - assert.deepEqual(mapping[filePath].l, { - 5: 1, 7: 1, - }); - assert.deepEqual(mapping[filePath].b, { - 1: [0, 1], 2: [1, 0], 3: [1, 0], - }); - assert.deepEqual(mapping[filePath].s, { - 1: 1, 2: 1, 3: 1, - }); - assert.deepEqual(mapping[filePath].f, { - 1: 1, - }); - done(); - }).catch(done); - }); - - it('should cover if-elseif-else statements that are at the same depth as each other', done => { - const contract = util.getCode('if/if-elseif-else.sol'); - const info = getInstrumentedVersion(contract, filePath); - const coverage = new CoverageMap(); - coverage.addContract(info, filePath); - vm.execute(info.contract, 'a', [2, 3, 3]).then(events => { - const mapping = coverage.generate(events, pathPrefix); - assert.deepEqual(mapping[filePath].l, { - 5: 1, 6: 0, 8: 1, 10: 0, 13: 1, 14: 0, 16: 1, 18: 0, - }); - assert.deepEqual(mapping[filePath].b, { - 1: [0, 1], 2: [1, 0], 3: [0, 1], 4: [1, 0] - }); - assert.deepEqual(mapping[filePath].s, { - 1: 1, 2: 0, 3: 1, 4: 1, 5: 0, 6: 1, 7: 0, 8: 1, 9: 1, 10: 0, - }); - assert.deepEqual(mapping[filePath].f, { - 1: 1, - }); - done(); - }).catch(done); - }); -}); diff --git a/test/cli/block-gas-limit.js b/test/jsSources/block-gas-limit.js similarity index 100% rename from test/cli/block-gas-limit.js rename to test/jsSources/block-gas-limit.js diff --git a/test/cli/empty.js b/test/jsSources/empty.js similarity index 100% rename from test/cli/empty.js rename to test/jsSources/empty.js diff --git a/test/cli/inheritance.js b/test/jsSources/inheritance.js similarity index 85% rename from test/cli/inheritance.js rename to test/jsSources/inheritance.js index 91fba754..d2546246 100644 --- a/test/cli/inheritance.js +++ b/test/jsSources/inheritance.js @@ -1,6 +1,3 @@ -/* eslint-env node, mocha */ -/* global artifacts, contract, assert */ - const Owned = artifacts.require('./Owned.sol'); const Proxy = artifacts.require('./Proxy.sol'); diff --git a/test/cli/only-call.js b/test/jsSources/only-call.js similarity index 100% rename from test/cli/only-call.js rename to test/jsSources/only-call.js diff --git a/test/cli/oraclize.js b/test/jsSources/oraclize.js similarity index 100% rename from test/cli/oraclize.js rename to test/jsSources/oraclize.js diff --git a/test/cli/pureview.js b/test/jsSources/pureview.js similarity index 100% rename from test/cli/pureview.js rename to test/jsSources/pureview.js diff --git a/test/cli/requires-externally.js b/test/jsSources/requires-externally.js similarity index 100% rename from test/cli/requires-externally.js rename to test/jsSources/requires-externally.js diff --git a/test/cli/sign.js b/test/jsSources/sign.js similarity index 100% rename from test/cli/sign.js rename to test/jsSources/sign.js diff --git a/test/cli/simple.js b/test/jsSources/simple.js similarity index 82% rename from test/cli/simple.js rename to test/jsSources/simple.js index 1fcf5501..86bdcb81 100644 --- a/test/cli/simple.js +++ b/test/jsSources/simple.js @@ -1,6 +1,3 @@ -/* eslint-env node, mocha */ -/* global artifacts, contract, assert */ - const Simple = artifacts.require('./Simple.sol'); contract('Simple', () => { diff --git a/test/cli/sol-parse-fail.js b/test/jsSources/sol-parse-fail.js similarity index 100% rename from test/cli/sol-parse-fail.js rename to test/jsSources/sol-parse-fail.js diff --git a/test/cli/testrpc-options.js b/test/jsSources/testrpc-options.js similarity index 100% rename from test/cli/testrpc-options.js rename to test/jsSources/testrpc-options.js diff --git a/test/cli/totallyPure.js b/test/jsSources/totallyPure.js similarity index 100% rename from test/cli/totallyPure.js rename to test/jsSources/totallyPure.js diff --git a/test/cli/truffle-crash.js b/test/jsSources/truffle-crash.js similarity index 100% rename from test/cli/truffle-crash.js rename to test/jsSources/truffle-crash.js diff --git a/test/cli/truffle-test-fail.js b/test/jsSources/truffle-test-fail.js similarity index 100% rename from test/cli/truffle-test-fail.js rename to test/jsSources/truffle-test-fail.js diff --git a/test/cli/wallet.js b/test/jsSources/wallet.js similarity index 76% rename from test/cli/wallet.js rename to test/jsSources/wallet.js index f9eb70bd..827a4001 100644 --- a/test/cli/wallet.js +++ b/test/jsSources/wallet.js @@ -1,6 +1,3 @@ -/* eslint-env node, mocha */ -/* global artifacts, contract, assert, web3 */ - const Wallet = artifacts.require('./Wallet.sol'); contract('Wallet', accounts => { @@ -11,15 +8,15 @@ contract('Wallet', accounts => { await walletA.sendTransaction({ value: web3.utils.toBN(500), from: accounts[0], }); - console.log('transaction done') + await walletA.sendPayment(50, walletB.address, { from: accounts[0], }); - console.log('transaction done') + await walletA.transferPayment(50, walletB.address, { from: accounts[0], }); - console.log('transaction done') + const balance = await walletB.getBalance(); assert.equal(balance.toNumber(), 100); }); diff --git a/test/loops.js b/test/loops.js deleted file mode 100644 index 6cba5e5b..00000000 --- a/test/loops.js +++ /dev/null @@ -1,105 +0,0 @@ -/* eslint-env node, mocha */ - -const path = require('path'); -const getInstrumentedVersion = require('./../lib/instrumentSolidity.js'); -const util = require('./util/util.js'); -const CoverageMap = require('./../lib/coverageMap'); -const vm = require('./util/vm'); -const assert = require('assert'); - -describe('for and while statements', () => { - const filePath = path.resolve('./test.sol'); - const pathPrefix = './'; - - it('should cover a for statement with a bracketed body (multiline)', done => { - const contract = util.getCode('loops/for-with-brackets.sol'); - const info = getInstrumentedVersion(contract, filePath); - const coverage = new CoverageMap(); - coverage.addContract(info, filePath); - - // Runs: a() => for(var x = 1; x < 10; x++){\n sha3(x);\n } - vm.execute(info.contract, 'a', []).then(events => { - const mapping = coverage.generate(events, pathPrefix); - assert.deepEqual(mapping[filePath].l, { - 5: 1, 6: 10, - }); - assert.deepEqual(mapping[filePath].b, {}); - assert.deepEqual(mapping[filePath].s, { - 1: 1, 2: 10, - }); - assert.deepEqual(mapping[filePath].f, { - 1: 1, - }); - done(); - }).catch(done); - }); - - it('should cover a for statement with an unbracketed body', done => { - const contract = util.getCode('loops/for-no-brackets.sol'); - const info = getInstrumentedVersion(contract, filePath); - const coverage = new CoverageMap(); - coverage.addContract(info, filePath); - - // Runs: a() => for(var x = 1; x < 10; x++)\n sha3(x);\n - vm.execute(info.contract, 'a', []).then(events => { - const mapping = coverage.generate(events, pathPrefix); - assert.deepEqual(mapping[filePath].l, { - 5: 1, 6: 10, - }); - assert.deepEqual(mapping[filePath].b, {}); - assert.deepEqual(mapping[filePath].s, { - 1: 1, 2: 10, - }); - assert.deepEqual(mapping[filePath].f, { - 1: 1, - }); - done(); - }).catch(done); - }); - - it('should cover a while statement with an bracketed body (multiline)', done => { - const contract = util.getCode('loops/while-with-brackets.sol'); - const info = getInstrumentedVersion(contract, filePath); - const coverage = new CoverageMap(); - coverage.addContract(info, filePath); - - // Runs: a() => var t = true;\n while(t){\n t = false;\n } - vm.execute(info.contract, 'a', []).then(events => { - const mapping = coverage.generate(events, pathPrefix); - assert.deepEqual(mapping[filePath].l, { - 5: 1, 6: 1, 7: 1, - }); - assert.deepEqual(mapping[filePath].b, {}); - assert.deepEqual(mapping[filePath].s, { - 1: 1, 2: 1, 3: 1, - }); - assert.deepEqual(mapping[filePath].f, { - 1: 1, - }); - done(); - }).catch(done); - }); - - it('should cover a while statement with an unbracketed body (multiline)', done => { - const contract = util.getCode('loops/while-no-brackets.sol'); - const info = getInstrumentedVersion(contract, filePath); - const coverage = new CoverageMap(); - coverage.addContract(info, filePath); - - // Runs: a() => var t = true;\n while(t)\n t = false;\n - vm.execute(info.contract, 'a', []).then(events => { - const mapping = coverage.generate(events, pathPrefix); - assert.deepEqual(mapping[filePath].l, { - 5: 1, 6: 1, 7: 1, - }); - assert.deepEqual(mapping[filePath].b, {}); - assert.deepEqual(mapping[filePath].s, { - 1: 1, 2: 1, 3: 1, - }); - assert.deepEqual(mapping[filePath].f, { - 1: 1, - }); - done(); - }).catch(done); - }); -}); diff --git a/test/return.js b/test/return.js deleted file mode 100644 index 3df788a5..00000000 --- a/test/return.js +++ /dev/null @@ -1,14 +0,0 @@ -/* eslint-env node, mocha */ - -const solc = require('solc'); -const getInstrumentedVersion = require('./../lib/instrumentSolidity.js'); -const util = require('./util/util.js'); - -describe('return statements', () => { - it('should compile after instrumenting function that returns true', () => { - const contract = util.getCode('return/return.sol'); - const info = getInstrumentedVersion(contract, 'test.sol'); - const output = JSON.parse(solc.compile(util.codeToCompilerInput(info.contract))); - util.report(output.errors); - }); -}); diff --git a/test/sources/assembly/if.sol b/test/soliditySources/contracts/assembly/if.sol similarity index 100% rename from test/sources/assembly/if.sol rename to test/soliditySources/contracts/assembly/if.sol diff --git a/test/sources/assembly/spaces-in-function.sol b/test/soliditySources/contracts/assembly/spaces-in-function.sol similarity index 100% rename from test/sources/assembly/spaces-in-function.sol rename to test/soliditySources/contracts/assembly/spaces-in-function.sol diff --git a/test/sources/assert/Assert.sol b/test/soliditySources/contracts/assert/Assert.sol similarity index 100% rename from test/sources/assert/Assert.sol rename to test/soliditySources/contracts/assert/Assert.sol diff --git a/test/soliditySources/contracts/assert/RequireMultiline.sol b/test/soliditySources/contracts/assert/RequireMultiline.sol new file mode 100644 index 00000000..2f7dc51c --- /dev/null +++ b/test/soliditySources/contracts/assert/RequireMultiline.sol @@ -0,0 +1,9 @@ +pragma solidity ^0.5.0; + +contract Test { + function a(bool _a, bool _b, bool _c) public { + require(_a && + _b && + _c); + } +} \ No newline at end of file diff --git a/test/sources/cli/CLibrary.sol b/test/soliditySources/contracts/cli/CLibrary.sol similarity index 100% rename from test/sources/cli/CLibrary.sol rename to test/soliditySources/contracts/cli/CLibrary.sol diff --git a/test/sources/cli/Empty.sol b/test/soliditySources/contracts/cli/Empty.sol similarity index 100% rename from test/sources/cli/Empty.sol rename to test/soliditySources/contracts/cli/Empty.sol diff --git a/test/sources/cli/Events.sol b/test/soliditySources/contracts/cli/Events.sol similarity index 100% rename from test/sources/cli/Events.sol rename to test/soliditySources/contracts/cli/Events.sol diff --git a/test/sources/cli/Expensive.sol b/test/soliditySources/contracts/cli/Expensive.sol similarity index 100% rename from test/sources/cli/Expensive.sol rename to test/soliditySources/contracts/cli/Expensive.sol diff --git a/test/sources/cli/Face.sol b/test/soliditySources/contracts/cli/Face.sol similarity index 100% rename from test/sources/cli/Face.sol rename to test/soliditySources/contracts/cli/Face.sol diff --git a/test/sources/cli/Migrations.sol b/test/soliditySources/contracts/cli/Migrations.sol similarity index 100% rename from test/sources/cli/Migrations.sol rename to test/soliditySources/contracts/cli/Migrations.sol diff --git a/test/sources/cli/OnlyCall.sol b/test/soliditySources/contracts/cli/OnlyCall.sol similarity index 100% rename from test/sources/cli/OnlyCall.sol rename to test/soliditySources/contracts/cli/OnlyCall.sol diff --git a/test/sources/cli/Owned.sol b/test/soliditySources/contracts/cli/Owned.sol similarity index 100% rename from test/sources/cli/Owned.sol rename to test/soliditySources/contracts/cli/Owned.sol diff --git a/test/sources/cli/Proxy.sol b/test/soliditySources/contracts/cli/Proxy.sol similarity index 100% rename from test/sources/cli/Proxy.sol rename to test/soliditySources/contracts/cli/Proxy.sol diff --git a/test/sources/cli/PureView.sol b/test/soliditySources/contracts/cli/PureView.sol similarity index 100% rename from test/sources/cli/PureView.sol rename to test/soliditySources/contracts/cli/PureView.sol diff --git a/test/sources/cli/Simple.sol b/test/soliditySources/contracts/cli/Simple.sol similarity index 100% rename from test/sources/cli/Simple.sol rename to test/soliditySources/contracts/cli/Simple.sol diff --git a/test/sources/cli/TotallyPure.sol b/test/soliditySources/contracts/cli/TotallyPure.sol similarity index 87% rename from test/sources/cli/TotallyPure.sol rename to test/soliditySources/contracts/cli/TotallyPure.sol index 008271cb..5c6c826b 100644 --- a/test/sources/cli/TotallyPure.sol +++ b/test/soliditySources/contracts/cli/TotallyPure.sol @@ -1,8 +1,8 @@ pragma solidity ^0.5.0; -import "./../assets/Face.sol"; -import "./../assets/PureView.sol"; -import "./../assets/CLibrary.sol"; +import "./../../externalSources/Face.sol"; +import "./../../externalSources/PureView.sol"; +import "./../../externalSources/CLibrary.sol"; contract TotallyPure is PureView, Face { uint onehundred = 99; diff --git a/test/sources/cli/Wallet.sol b/test/soliditySources/contracts/cli/Wallet.sol similarity index 100% rename from test/sources/cli/Wallet.sol rename to test/soliditySources/contracts/cli/Wallet.sol diff --git a/test/sources/comments/postContractComment.sol b/test/soliditySources/contracts/comments/postContractComment.sol similarity index 100% rename from test/sources/comments/postContractComment.sol rename to test/soliditySources/contracts/comments/postContractComment.sol diff --git a/test/sources/comments/postFunctionDeclarationComment.sol b/test/soliditySources/contracts/comments/postFunctionDeclarationComment.sol similarity index 57% rename from test/sources/comments/postFunctionDeclarationComment.sol rename to test/soliditySources/contracts/comments/postFunctionDeclarationComment.sol index 4c6fdcae..b14c774a 100644 --- a/test/sources/comments/postFunctionDeclarationComment.sol +++ b/test/soliditySources/contracts/comments/postFunctionDeclarationComment.sol @@ -3,5 +3,7 @@ pragma solidity ^0.5.0; contract Test { function a(bool test) public {//Comment immediately after function declaration } - function b(bool test) public {uint8 x=1;}//Comment immediately after function closes + function b(bool test) public { + uint8 x=1; + }//Comment immediately after function closes } diff --git a/test/sources/comments/postIfStatementComment.sol b/test/soliditySources/contracts/comments/postIfStatementComment.sol similarity index 100% rename from test/sources/comments/postIfStatementComment.sol rename to test/soliditySources/contracts/comments/postIfStatementComment.sol diff --git a/test/sources/comments/postLineComment.sol b/test/soliditySources/contracts/comments/postLineComment.sol similarity index 100% rename from test/sources/comments/postLineComment.sol rename to test/soliditySources/contracts/comments/postLineComment.sol diff --git a/test/sources/conditional/declarative-exp-assignment-alternate.sol b/test/soliditySources/contracts/conditional/declarative-exp-assignment-alternate.sol similarity index 100% rename from test/sources/conditional/declarative-exp-assignment-alternate.sol rename to test/soliditySources/contracts/conditional/declarative-exp-assignment-alternate.sol diff --git a/test/sources/conditional/identifier-assignment-alternate.sol b/test/soliditySources/contracts/conditional/identifier-assignment-alternate.sol similarity index 100% rename from test/sources/conditional/identifier-assignment-alternate.sol rename to test/soliditySources/contracts/conditional/identifier-assignment-alternate.sol diff --git a/test/sources/conditional/mapping-assignment.sol b/test/soliditySources/contracts/conditional/mapping-assignment.sol similarity index 88% rename from test/sources/conditional/mapping-assignment.sol rename to test/soliditySources/contracts/conditional/mapping-assignment.sol index c8100a0b..7e0faf61 100644 --- a/test/sources/conditional/mapping-assignment.sol +++ b/test/soliditySources/contracts/conditional/mapping-assignment.sol @@ -8,7 +8,7 @@ contract Test { Vote vote; function a() public { - var isYay = false; + bool isYay = false; vote.voted[msg.sender] = isYay ? 1 : 2; } } \ No newline at end of file diff --git a/test/sources/conditional/multiline-alternate.sol b/test/soliditySources/contracts/conditional/multiline-alternate.sol similarity index 100% rename from test/sources/conditional/multiline-alternate.sol rename to test/soliditySources/contracts/conditional/multiline-alternate.sol diff --git a/test/sources/conditional/multiline-consequent.sol b/test/soliditySources/contracts/conditional/multiline-consequent.sol similarity index 100% rename from test/sources/conditional/multiline-consequent.sol rename to test/soliditySources/contracts/conditional/multiline-consequent.sol diff --git a/test/sources/conditional/sameline-alternate.sol b/test/soliditySources/contracts/conditional/sameline-alternate.sol similarity index 100% rename from test/sources/conditional/sameline-alternate.sol rename to test/soliditySources/contracts/conditional/sameline-alternate.sol diff --git a/test/sources/conditional/sameline-consequent.sol b/test/soliditySources/contracts/conditional/sameline-consequent.sol similarity index 100% rename from test/sources/conditional/sameline-consequent.sol rename to test/soliditySources/contracts/conditional/sameline-consequent.sol diff --git a/test/sources/conditional/variable-decl-assignment-alternate.sol b/test/soliditySources/contracts/conditional/variable-decl-assignment-alternate.sol similarity index 100% rename from test/sources/conditional/variable-decl-assignment-alternate.sol rename to test/soliditySources/contracts/conditional/variable-decl-assignment-alternate.sol diff --git a/test/sources/expressions/new-expression.sol b/test/soliditySources/contracts/expressions/new-expression.sol similarity index 100% rename from test/sources/expressions/new-expression.sol rename to test/soliditySources/contracts/expressions/new-expression.sol diff --git a/test/sources/expressions/single-binary-expression.sol b/test/soliditySources/contracts/expressions/single-binary-expression.sol similarity index 100% rename from test/sources/expressions/single-binary-expression.sol rename to test/soliditySources/contracts/expressions/single-binary-expression.sol diff --git a/test/sources/function/abstract.sol b/test/soliditySources/contracts/function/abstract.sol similarity index 100% rename from test/sources/function/abstract.sol rename to test/soliditySources/contracts/function/abstract.sol diff --git a/test/sources/function/calldata.sol b/test/soliditySources/contracts/function/calldata.sol similarity index 100% rename from test/sources/function/calldata.sol rename to test/soliditySources/contracts/function/calldata.sol diff --git a/test/sources/function/chainable-new.sol b/test/soliditySources/contracts/function/chainable-new.sol similarity index 100% rename from test/sources/function/chainable-new.sol rename to test/soliditySources/contracts/function/chainable-new.sol diff --git a/test/sources/function/chainable-value.sol b/test/soliditySources/contracts/function/chainable-value.sol similarity index 100% rename from test/sources/function/chainable-value.sol rename to test/soliditySources/contracts/function/chainable-value.sol diff --git a/test/sources/function/chainable.sol b/test/soliditySources/contracts/function/chainable.sol similarity index 100% rename from test/sources/function/chainable.sol rename to test/soliditySources/contracts/function/chainable.sol diff --git a/test/sources/function/constructor-keyword.sol b/test/soliditySources/contracts/function/constructor-keyword.sol similarity index 100% rename from test/sources/function/constructor-keyword.sol rename to test/soliditySources/contracts/function/constructor-keyword.sol diff --git a/test/sources/function/empty-body.sol b/test/soliditySources/contracts/function/empty-body.sol similarity index 100% rename from test/sources/function/empty-body.sol rename to test/soliditySources/contracts/function/empty-body.sol diff --git a/test/sources/function/function-call.sol b/test/soliditySources/contracts/function/function-call.sol similarity index 100% rename from test/sources/function/function-call.sol rename to test/soliditySources/contracts/function/function-call.sol diff --git a/test/sources/function/function.sol b/test/soliditySources/contracts/function/function.sol similarity index 100% rename from test/sources/function/function.sol rename to test/soliditySources/contracts/function/function.sol diff --git a/test/sources/function/modifier.sol b/test/soliditySources/contracts/function/modifier.sol similarity index 100% rename from test/sources/function/modifier.sol rename to test/soliditySources/contracts/function/modifier.sol diff --git a/test/sources/function/multiple.sol b/test/soliditySources/contracts/function/multiple.sol similarity index 100% rename from test/sources/function/multiple.sol rename to test/soliditySources/contracts/function/multiple.sol diff --git a/test/sources/if/else-if-unbracketed-multi.sol b/test/soliditySources/contracts/if/else-if-unbracketed-multi.sol similarity index 100% rename from test/sources/if/else-if-unbracketed-multi.sol rename to test/soliditySources/contracts/if/else-if-unbracketed-multi.sol diff --git a/test/sources/if/else-if-without-brackets.sol b/test/soliditySources/contracts/if/else-if-without-brackets.sol similarity index 100% rename from test/sources/if/else-if-without-brackets.sol rename to test/soliditySources/contracts/if/else-if-without-brackets.sol diff --git a/test/sources/if/else-with-brackets.sol b/test/soliditySources/contracts/if/else-with-brackets.sol similarity index 100% rename from test/sources/if/else-with-brackets.sol rename to test/soliditySources/contracts/if/else-with-brackets.sol diff --git a/test/sources/if/else-without-brackets.sol b/test/soliditySources/contracts/if/else-without-brackets.sol similarity index 100% rename from test/sources/if/else-without-brackets.sol rename to test/soliditySources/contracts/if/else-without-brackets.sol diff --git a/test/sources/if/if-else-no-brackets.sol b/test/soliditySources/contracts/if/if-else-no-brackets.sol similarity index 100% rename from test/sources/if/if-else-no-brackets.sol rename to test/soliditySources/contracts/if/if-else-no-brackets.sol diff --git a/test/sources/if/if-elseif-else.sol b/test/soliditySources/contracts/if/if-elseif-else.sol similarity index 100% rename from test/sources/if/if-elseif-else.sol rename to test/soliditySources/contracts/if/if-elseif-else.sol diff --git a/test/sources/if/if-no-brackets-multiline.sol b/test/soliditySources/contracts/if/if-no-brackets-multiline.sol similarity index 100% rename from test/sources/if/if-no-brackets-multiline.sol rename to test/soliditySources/contracts/if/if-no-brackets-multiline.sol diff --git a/test/sources/if/if-no-brackets.sol b/test/soliditySources/contracts/if/if-no-brackets.sol similarity index 100% rename from test/sources/if/if-no-brackets.sol rename to test/soliditySources/contracts/if/if-no-brackets.sol diff --git a/test/sources/if/if-with-brackets-multiline.sol b/test/soliditySources/contracts/if/if-with-brackets-multiline.sol similarity index 100% rename from test/sources/if/if-with-brackets-multiline.sol rename to test/soliditySources/contracts/if/if-with-brackets-multiline.sol diff --git a/test/sources/if/if-with-brackets.sol b/test/soliditySources/contracts/if/if-with-brackets.sol similarity index 100% rename from test/sources/if/if-with-brackets.sol rename to test/soliditySources/contracts/if/if-with-brackets.sol diff --git a/test/sources/if/nested-if-missing-else.sol b/test/soliditySources/contracts/if/nested-if-missing-else.sol similarity index 100% rename from test/sources/if/nested-if-missing-else.sol rename to test/soliditySources/contracts/if/nested-if-missing-else.sol diff --git a/test/sources/loops/for-no-brackets.sol b/test/soliditySources/contracts/loops/for-no-brackets.sol similarity index 100% rename from test/sources/loops/for-no-brackets.sol rename to test/soliditySources/contracts/loops/for-no-brackets.sol diff --git a/test/sources/loops/for-with-brackets.sol b/test/soliditySources/contracts/loops/for-with-brackets.sol similarity index 100% rename from test/sources/loops/for-with-brackets.sol rename to test/soliditySources/contracts/loops/for-with-brackets.sol diff --git a/test/sources/loops/while-no-brackets.sol b/test/soliditySources/contracts/loops/while-no-brackets.sol similarity index 100% rename from test/sources/loops/while-no-brackets.sol rename to test/soliditySources/contracts/loops/while-no-brackets.sol diff --git a/test/sources/loops/while-with-brackets.sol b/test/soliditySources/contracts/loops/while-with-brackets.sol similarity index 100% rename from test/sources/loops/while-with-brackets.sol rename to test/soliditySources/contracts/loops/while-with-brackets.sol diff --git a/test/sources/return/return.sol b/test/soliditySources/contracts/return/return.sol similarity index 100% rename from test/sources/return/return.sol rename to test/soliditySources/contracts/return/return.sol diff --git a/test/sources/statements/emit-coverage.sol b/test/soliditySources/contracts/statements/emit-coverage.sol similarity index 100% rename from test/sources/statements/emit-coverage.sol rename to test/soliditySources/contracts/statements/emit-coverage.sol diff --git a/test/sources/statements/emit-instrument.sol b/test/soliditySources/contracts/statements/emit-instrument.sol similarity index 100% rename from test/sources/statements/emit-instrument.sol rename to test/soliditySources/contracts/statements/emit-instrument.sol diff --git a/test/sources/statements/empty-contract-ala-melonport.sol b/test/soliditySources/contracts/statements/empty-contract-ala-melonport.sol similarity index 100% rename from test/sources/statements/empty-contract-ala-melonport.sol rename to test/soliditySources/contracts/statements/empty-contract-ala-melonport.sol diff --git a/test/sources/statements/empty-contract-body.sol b/test/soliditySources/contracts/statements/empty-contract-body.sol similarity index 100% rename from test/sources/statements/empty-contract-body.sol rename to test/soliditySources/contracts/statements/empty-contract-body.sol diff --git a/test/sources/statements/fn-argument-multiline.sol b/test/soliditySources/contracts/statements/fn-argument-multiline.sol similarity index 100% rename from test/sources/statements/fn-argument-multiline.sol rename to test/soliditySources/contracts/statements/fn-argument-multiline.sol diff --git a/test/sources/statements/fn-argument.sol b/test/soliditySources/contracts/statements/fn-argument.sol similarity index 100% rename from test/sources/statements/fn-argument.sol rename to test/soliditySources/contracts/statements/fn-argument.sol diff --git a/test/sources/statements/fn-struct.sol b/test/soliditySources/contracts/statements/fn-struct.sol similarity index 86% rename from test/sources/statements/fn-struct.sol rename to test/soliditySources/contracts/statements/fn-struct.sol index 5af1f83e..51487cde 100644 --- a/test/sources/statements/fn-struct.sol +++ b/test/soliditySources/contracts/statements/fn-struct.sol @@ -1,3 +1,5 @@ +pragma solidity ^0.5.0; + contract Test { struct Fn { function(bytes32) internal view returns(bool) startConditions; diff --git a/test/sources/statements/library.sol b/test/soliditySources/contracts/statements/library.sol similarity index 100% rename from test/sources/statements/library.sol rename to test/soliditySources/contracts/statements/library.sol diff --git a/test/sources/statements/multiple.sol b/test/soliditySources/contracts/statements/multiple.sol similarity index 100% rename from test/sources/statements/multiple.sol rename to test/soliditySources/contracts/statements/multiple.sol diff --git a/test/sources/statements/post-close-brace.sol b/test/soliditySources/contracts/statements/post-close-brace.sol similarity index 100% rename from test/sources/statements/post-close-brace.sol rename to test/soliditySources/contracts/statements/post-close-brace.sol diff --git a/test/sources/statements/single.sol b/test/soliditySources/contracts/statements/single.sol similarity index 100% rename from test/sources/statements/single.sol rename to test/soliditySources/contracts/statements/single.sol diff --git a/test/sources/statements/tuple.sol b/test/soliditySources/contracts/statements/tuple.sol similarity index 63% rename from test/sources/statements/tuple.sol rename to test/soliditySources/contracts/statements/tuple.sol index 54ff373e..9912e658 100644 --- a/test/sources/statements/tuple.sol +++ b/test/soliditySources/contracts/statements/tuple.sol @@ -1,13 +1,13 @@ pragma solidity ^0.5.0; -contract Test { +contract Test { function returnTuple() public returns (uint x, uint y) { return (10, 20); } function a() public { - (uint a, uint b) = (10, 20); - (a, b) = returnTuple(); + (uint _a, uint _b) = (10, 20); + (_a, _b) = returnTuple(); } } \ No newline at end of file diff --git a/test/sources/statements/type-keyword.sol b/test/soliditySources/contracts/statements/type-keyword.sol similarity index 100% rename from test/sources/statements/type-keyword.sol rename to test/soliditySources/contracts/statements/type-keyword.sol diff --git a/test/sources/cli/Oraclize.sol b/test/soliditySources/errors/Oraclize.sol similarity index 100% rename from test/sources/cli/Oraclize.sol rename to test/soliditySources/errors/Oraclize.sol diff --git a/test/sources/cli/SimpleError.sol b/test/soliditySources/errors/SimpleError.sol similarity index 100% rename from test/sources/cli/SimpleError.sol rename to test/soliditySources/errors/SimpleError.sol diff --git a/test/sources/statements/compilation-error.sol b/test/soliditySources/errors/compilation-error.sol similarity index 100% rename from test/sources/statements/compilation-error.sol rename to test/soliditySources/errors/compilation-error.sol diff --git a/test/soliditySources/external/CLibrary.sol b/test/soliditySources/external/CLibrary.sol new file mode 100644 index 00000000..3a341115 --- /dev/null +++ b/test/soliditySources/external/CLibrary.sol @@ -0,0 +1,8 @@ +pragma solidity ^0.5.0; + +library CLibrary { + uint constant x = 1; + function a() public view returns (uint) { + return x; + } +} \ No newline at end of file diff --git a/test/soliditySources/external/Face.sol b/test/soliditySources/external/Face.sol new file mode 100644 index 00000000..2e9d2a45 --- /dev/null +++ b/test/soliditySources/external/Face.sol @@ -0,0 +1,6 @@ +pragma solidity ^0.5.0; + +interface Face { + function stare(uint a, uint b) external; + function cry() external; +} \ No newline at end of file diff --git a/test/soliditySources/external/PureView.sol b/test/soliditySources/external/PureView.sol new file mode 100644 index 00000000..a66773f1 --- /dev/null +++ b/test/soliditySources/external/PureView.sol @@ -0,0 +1,19 @@ +pragma solidity ^0.5.0; + +contract PureView { + + // Make sure we aren't corrupting anything with the replace + uint notpureview = 5; + + // Abstract functions to inherit from an uninstrumented, imported file. + function bePure(uint a, uint b) public pure returns (uint); + function beView() public view returns (uint); + + function inheritedPure(uint a, uint b) public pure returns(uint){ + return a + b; + } + + function inheritedView() public view returns (uint){ + return notpureview; + } +} \ No newline at end of file diff --git a/test/sources/assert/RequireMultiline.sol b/test/sources/assert/RequireMultiline.sol deleted file mode 100644 index de1aead6..00000000 --- a/test/sources/assert/RequireMultiline.sol +++ /dev/null @@ -1,9 +0,0 @@ -pragma solidity ^0.5.0; - -contract Test { - function a(bool a, bool b, bool c) public { - require(a && - b && - c); - } -} \ No newline at end of file diff --git a/test/statements.js b/test/statements.js deleted file mode 100644 index 20746751..00000000 --- a/test/statements.js +++ /dev/null @@ -1,193 +0,0 @@ -/* eslint-env node, mocha */ - -const solc = require('solc'); -const getInstrumentedVersion = require('./../lib/instrumentSolidity.js'); -const util = require('./util/util.js'); -const CoverageMap = require('./../lib/coverageMap'); -const path = require('path'); -const vm = require('./util/vm'); -const assert = require('assert'); - -/** - * NB: passing '1' to solc as an option activates the optimiser - * NB: solc will throw if there is a compilation error, causing the test to fail - * and passing the error to mocha. - */ -describe('generic statements', () => { - const filePath = path.resolve('./test.sol'); - const pathPrefix = './'; - - it('should compile function defined in a struct', () => { - const contract = util.getCode('statements/fn-struct.sol'); - const info = getInstrumentedVersion(contract, filePath); - const output = JSON.parse(solc.compile(util.codeToCompilerInput(info.contract))); - util.report(output.errors); - }) - - it('should compile when using the type keyword', () => { - const contract = util.getCode('statements/type-keyword.sol'); - const info = getInstrumentedVersion(contract, filePath); - const output = JSON.parse(solc.compile(util.codeToCompilerInput(info.contract))); - util.report(output.errors); - }) - - it('should compile after instrumenting a single statement (first line of function)', () => { - const contract = util.getCode('statements/single.sol'); - const info = getInstrumentedVersion(contract, filePath); - const output = JSON.parse(solc.compile(util.codeToCompilerInput(info.contract))); - util.report(output.errors); - }); - - it('should compile after instrumenting multiple statements', () => { - const contract = util.getCode('statements/multiple.sol'); - const info = getInstrumentedVersion(contract, filePath); - const output = JSON.parse(solc.compile(util.codeToCompilerInput(info.contract))); - util.report(output.errors); - }); - - it('should compile after instrumenting a statement that is a function argument (single line)', () => { - const contract = util.getCode('statements/fn-argument.sol'); - const info = getInstrumentedVersion(contract, filePath); - const output = JSON.parse(solc.compile(util.codeToCompilerInput(info.contract))); - util.report(output.errors); - }); - - it('should compile after instrumenting a statement that is a function argument (multi-line)', () => { - const contract = util.getCode('statements/fn-argument-multiline.sol'); - const info = getInstrumentedVersion(contract, filePath); - const output = JSON.parse(solc.compile(util.codeToCompilerInput(info.contract))); - util.report(output.errors); - }); - - it('should compile after instrumenting an empty-contract-body', () => { - const contract = util.getCode('statements/empty-contract-ala-melonport.sol'); - const info = getInstrumentedVersion(contract, filePath); - const output = JSON.parse(solc.compile(util.codeToCompilerInput(info.contract))); - util.report(output.errors); - }); - - it('should NOT pass tests if the contract has a compilation error', () => { - const contract = util.getCode('statements/compilation-error.sol'); - const info = getInstrumentedVersion(contract, filePath); - const output = JSON.parse(solc.compile(util.codeToCompilerInput(info.contract))); - try { - util.report(output.errors); - assert.fail('WRONG'); // We shouldn't hit this. - } catch (err) { - (err.actual === 'WRONG') ? assert(false) : assert(true); - } - }); - - it('should compile after instrumenting an emit statement after an un-enclosed if statement', () => { - const contract = util.getCode('statements/emit-instrument.sol'); - const info = getInstrumentedVersion(contract, filePath); - const output = JSON.parse(solc.compile(util.codeToCompilerInput(info.contract))); - util.report(output.errors); - }); - - it('should cover an emitted event statement', done => { - const contract = util.getCode('statements/emit-coverage.sol'); - const info = getInstrumentedVersion(contract, filePath); - const coverage = new CoverageMap(); - coverage.addContract(info, filePath); - - vm.execute(info.contract, 'a', [0]).then(events => { - const mapping = coverage.generate(events, pathPrefix); - assert.deepEqual(mapping[filePath].l, { - 6: 1 - }); - assert.deepEqual(mapping[filePath].b, {}); - assert.deepEqual(mapping[filePath].s, { - 1: 1 - }); - assert.deepEqual(mapping[filePath].f, { - 1: 1, - }); - done(); - }).catch(done); - }); - - it('should cover a statement following a close brace', done => { - const contract = util.getCode('statements/post-close-brace.sol'); - const info = getInstrumentedVersion(contract, filePath); - const coverage = new CoverageMap(); - coverage.addContract(info, filePath); - - vm.execute(info.contract, 'a', [1]).then(events => { - const mapping = coverage.generate(events, pathPrefix); - assert.deepEqual(mapping[filePath].l, { - 5: 1, 6: 0, 8: 1, - }); - assert.deepEqual(mapping[filePath].b, { - 1: [0, 1], - }); - assert.deepEqual(mapping[filePath].s, { - 1: 1, 2: 0, 3: 1, - }); - assert.deepEqual(mapping[filePath].f, { - 1: 1, - }); - done(); - }).catch(done); - }); - - it('should cover a library statement and an invoked library method', done => { - const contract = util.getCode('statements/library.sol'); - const info = getInstrumentedVersion(contract, filePath); - const coverage = new CoverageMap(); - coverage.addContract(info, filePath); - - vm.execute(info.contract, 'not', []).then(events => { - const mapping = coverage.generate(events, pathPrefix); - assert.deepEqual(mapping[filePath].l, { - 9: 1, 10: 1, 19: 1, - }); - assert.deepEqual(mapping[filePath].b, {}); - assert.deepEqual(mapping[filePath].s, { - 1: 1, 2: 1, 3: 1, - }); - assert.deepEqual(mapping[filePath].f, { - 1: 1, 2: 1, - }); - done(); - }).catch(done); - }); - - it('should cover a tuple statement', done => { - const contract = util.getCode('statements/tuple.sol'); - const info = getInstrumentedVersion(contract, filePath); - const coverage = new CoverageMap(); - coverage.addContract(info, filePath); - - vm.execute(info.contract, 'a', []).then(events => { - const mapping = coverage.generate(events, pathPrefix); - assert.deepEqual(mapping[filePath].l, { - 6: 1, 10: 1, 11: 1 - }); - assert.deepEqual(mapping[filePath].b, {}); - assert.deepEqual(mapping[filePath].s, { - 1: 1, 2: 1, 3: 1, - }); - assert.deepEqual(mapping[filePath].f, { - 1: 1, 2: 1, - }); - done(); - }).catch(done); - }); - - it('should cover an empty bodied contract statement', done => { - const contract = util.getCode('statements/empty-contract-body.sol'); - const info = getInstrumentedVersion(contract, filePath); - const coverage = new CoverageMap(); - coverage.addContract(info, filePath); - - vm.execute(info.contract, null, []).then(events => { - const mapping = coverage.generate(events, pathPrefix); - assert.deepEqual(mapping[filePath].l, {}); - assert.deepEqual(mapping[filePath].b, {}); - assert.deepEqual(mapping[filePath].s, {}); - assert.deepEqual(mapping[filePath].f, {}); - done(); - }).catch(done); - }); -}); diff --git a/test/units/app.js b/test/units/app.js new file mode 100644 index 00000000..b519f157 --- /dev/null +++ b/test/units/app.js @@ -0,0 +1,271 @@ +/* eslint-env node, mocha */ + +const assert = require('assert'); +const shell = require('shelljs'); +const fs = require('fs'); +const childprocess = require('child_process'); +const mock = require('../util/mockTruffle.js'); + +// shell.test alias for legibility +function pathExists(path) { return shell.test('-e', path); } + +function assertCleanInitialState(){ + assert(pathExists('./coverage') === false, 'should start without: coverage'); + assert(pathExists('./coverage.json') === false, 'should start without: coverage.json'); +} + +function assertCoverageGenerated(){ + assert(pathExists('./coverage') === true, 'script should gen coverage folder'); + assert(pathExists('./coverage.json') === true, 'script should gen coverage.json'); +} + +function assertCoverageNotGenerated(){ + assert(pathExists('./coverage') !== true, 'script should NOT gen coverage folder'); + assert(pathExists('./coverage.json') !== true, 'script should NOT gen coverage.json'); +} + +function assertExecutionSucceeds(){ + +} + +function assertExecutionFails(){ + +} + +describe.skip('app', function() { + afterEach(() => mock.remove()); + + it('config with testrpc options string: should generate coverage, cleanup & exit(0)', () => { + + const privateKey = '0x3af46c9ac38ee1f01b05f9915080133f644bf57443f504d339082cb5285ccae4'; + const balance = '0xfffffffffffffff'; + const testConfig = Object.assign({}, config); + + testConfig.testrpcOptions = `--account="${privateKey},${balance}" --port 8777`; + testConfig.dir = './mock'; + testConfig.norpc = false; + testConfig.port = 8777; + + // Installed test will process.exit(1) and crash truffle if the test isn't + // loaded with the account specified above + mock.install('Simple.sol', 'testrpc-options.js', testConfig); + shell.exec(script); + assert(shell.error() === null, 'script should not error'); + + }); + + it('config with test command options string: should run test', () => { + assert(pathExists('./allFiredEvents') === false, 'should start without: events log'); + const testConfig = Object.assign({}, config); + + testConfig.testCommand = 'mocha --timeout 5000'; + testConfig.dir = './mock'; + testConfig.norpc = false; + testConfig.port = 8888; + + // Installed test will write a fake allFiredEvents to ./ after 4000ms + // allowing test to pass + mock.install('Simple.sol', 'command-options.js', testConfig); + shell.exec(script); + assert(shell.error() === null, 'script should not error'); + + }); + + it('simple contract: should generate coverage, cleanup & exit(0)', () => { + assertCleanInitialState(); + + // Run script (exits 0); + mock.install('Simple.sol', 'simple.js', config); + shell.exec(script); + assert(shell.error() === null, 'script should not error'); + + assertCoverageGenerated(); + + // Coverage should be real. + // This test is tightly bound to the function names in Simple.sol + const produced = JSON.parse(fs.readFileSync('./coverage.json', 'utf8')); + const path = Object.keys(produced)[0]; + assert(produced[path].fnMap['1'].name === 'test', 'coverage.json should map "test"'); + assert(produced[path].fnMap['2'].name === 'getX', 'coverage.json should map "getX"'); + + }); + + it('Oraclize @ solc v.0.4.24 (large, many unbracketed statements)', () => { + const trufflejs = + `module.exports = { + networks: { + coverage: { + host: "localhost", + network_id: "*", + port: 8555, + gas: 0xfffffffffff, + gasPrice: 0x01 + }, + }, + compilers: { + solc: { + version: "0.4.24", + } + } + };`; + + assertCleanInitialState(); + + // Run script (exits 0); + mock.install('Oraclize.sol', 'oraclize.js', config, trufflejs, null, true); + shell.exec(script); + assert(shell.error() === null, 'script should not error'); + + }); + + it('tests use pure and view modifiers, including with libraries', () => { + assertCleanInitialState(); + + // Run script (exits 0); + mock.installLibraryTest(config); + shell.exec(script); + assert(shell.error() === null, 'script should not error'); + + assertCoverageGenerated(); + + // Coverage should be real. + // This test is tightly bound to the function names in TotallyPure.sol + const produced = JSON.parse(fs.readFileSync('./coverage.json', 'utf8')); + const path = Object.keys(produced)[0]; + assert(produced[path].fnMap['1'].name === 'usesThem', 'coverage.json should map "usesThem"'); + assert(produced[path].fnMap['2'].name === 'isPure', 'coverage.json should map "getX"'); + + }); + + it('tests require assets outside of test folder: should generate coverage, cleanup & exit(0)', () => { + assertCleanInitialState(); + + // Run script (exits 0); + mock.install('Simple.sol', 'requires-externally.js', config); + shell.exec(script); + assert(shell.error() === null, 'script should not error'); + + assertCoverageGenerated(); + + // Coverage should be real. + // This test is tightly bound to the function names in Simple.sol + const produced = JSON.parse(fs.readFileSync('./coverage.json', 'utf8')); + const path = Object.keys(produced)[0]; + assert(produced[path].fnMap['1'].name === 'test', 'coverage.json should map "test"'); + assert(produced[path].fnMap['2'].name === 'getX', 'coverage.json should map "getX"'); + + }); + + it('contract only uses .call: should generate coverage, cleanup & exit(0)', () => { + assertCleanInitialState(); + + mock.install('OnlyCall.sol', 'only-call.js', config); + + shell.exec(script); + assert(shell.error() === null, 'script should not error'); + + assertCoverageGenerated(); + + const produced = JSON.parse(fs.readFileSync('./coverage.json', 'utf8')); + const path = Object.keys(produced)[0]; + assert(produced[path].fnMap['1'].name === 'addTwo', 'coverage.json should map "addTwo"'); + + }); + + it('contract sends / transfers to instrumented fallback: coverage, cleanup & exit(0)', () => { + assertCleanInitialState(); + + mock.install('Wallet.sol', 'wallet.js', config); + shell.exec(script); + assert(shell.error() === null, 'script should not error'); + + assertCoverageGenerated(); + + const produced = JSON.parse(fs.readFileSync('./coverage.json', 'utf8')); + const path = Object.keys(produced)[0]; + assert(produced[path].fnMap['1'].name === 'transferPayment', 'should map "transferPayment"'); + + }); + + it('contract uses inheritance: should generate coverage, cleanup & exit(0)', () => { + assertCleanInitialState(); + + mock.installInheritanceTest(config); + shell.exec(script); + assert(shell.error() === null, 'script should not error'); + + assertCoverageGenerated(); + + const produced = JSON.parse(fs.readFileSync('./coverage.json', 'utf8')); + const ownedPath = Object.keys(produced)[0]; + const proxyPath = Object.keys(produced)[1]; + assert(produced[ownedPath].fnMap['1'].name === 'constructor', 'coverage.json should map "constructor"'); + assert(produced[proxyPath].fnMap['1'].name === 'isOwner', 'coverage.json should map "isOwner"'); + }); + + it('contracts are skipped: should generate coverage, cleanup & exit(0)', () => { + assertCleanInitialState(); + + const testConfig = Object.assign({}, config); + + testConfig.skipFiles = ['Owned.sol']; + mock.installInheritanceTest(testConfig); + + shell.exec(script); + assert(shell.error() === null, 'script should not error'); + + assertCoverageGenerated(); + + const produced = JSON.parse(fs.readFileSync('./coverage.json', 'utf8')); + const firstKey = Object.keys(produced)[0]; + assert(Object.keys(produced).length === 1, 'coverage.json should only contain instrumentation for one contract'); + assert(firstKey.substr(firstKey.length - 9) === 'Proxy.sol', 'coverage.json should only contain instrumentation for Proxy.sol'); + + }); + + it('truffle tests failing: should generate coverage, cleanup & exit(1)', () => { + assertCleanInitialState(); + + // Run with Simple.sol and a failing assertion in a truffle test + mock.install('Simple.sol', 'truffle-test-fail.js', config); + shell.exec(script); + assert(shell.error() !== null, 'script should exit 1'); + + assertCoverageGenerated(); + + const produced = JSON.parse(fs.readFileSync('./coverage.json', 'utf8')); + const path = Object.keys(produced)[0]; + assert(produced[path].fnMap['1'].name === 'test', 'coverage.json should map "test"'); + assert(produced[path].fnMap['2'].name === 'getX', 'coverage.json should map "getX"'); + + }); + + it('deployment cost > block gasLimit: should generate coverage, cleanup & exit(0)', () => { + // Just making sure Expensive.sol compiles and deploys here. + mock.install('Expensive.sol', 'block-gas-limit.js', config); + shell.exec(script); + assert(shell.error() === null, 'script should not error'); + + }); + + it('truffle crashes: should generate NO coverage, cleanup and exit(1)', () => { + assertCleanInitialState(); + + // Run with Simple.sol and a syntax error in the truffle test + mock.install('Simple.sol', 'truffle-crash.js', config); + shell.exec(script); + assert(shell.error() !== null, 'script should error'); + assertCoverageNotGenerated(); + }); + + it('instrumentation errors: should generate NO coverage, cleanup and exit(1)', () => { + assertCleanInitialState(); + + // Run with SimpleError.sol (has syntax error) and working truffle test + mock.install('SimpleError.sol', 'simple.js', config); + shell.exec(script); + assert(shell.error() !== null, 'script should error'); + assertCoverageNotGenerated(); + }); + +}); diff --git a/test/units/assembly.js b/test/units/assembly.js new file mode 100644 index 00000000..6418775a --- /dev/null +++ b/test/units/assembly.js @@ -0,0 +1,16 @@ +const assert = require('assert'); +const util = require('./../util/util.js'); + +describe('assembly expressions', () => { + + it('should compile after instrumenting an assembly function with spaces in parameters', () => { + const info = util.instrumentAndCompile('assembly/spaces-in-function'); + util.report(info.solcOutput.errors); + }); + + it('should compile after instrumenting an assembly if statement', () => { + const info = util.instrumentAndCompile('assembly/if'); + util.report(info.solcOutput.errors); + }); + +}); diff --git a/test/units/assert.js b/test/units/assert.js new file mode 100644 index 00000000..dfe9dfed --- /dev/null +++ b/test/units/assert.js @@ -0,0 +1,99 @@ +const assert = require('assert'); +const util = require('./../util/util.js'); + +const ganache = require('ganache-cli'); +const Coverage = require('./../../lib/coverage'); + +describe('asserts and requires', () => { + let coverage; + let provider; + let collector; + + before(async () => ({ provider, collector } = await util.initializeProvider(ganache))); + beforeEach(() => coverage = new Coverage()); + after((done) => provider.close(done)); + + it('should cover assert statements as `if` statements when they pass', async function() { + const contract = await util.bootstrapCoverage('assert/Assert', provider, collector); + coverage.addContract(contract.instrumented, util.filePath); + await contract.instance.a(true); + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 5: 1, + }); + assert.deepEqual(mapping[util.filePath].b, { + 1: [1, 0], + }); + assert.deepEqual(mapping[util.filePath].s, { + 1: 1, + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 1, + }); + }); + + it('should cover assert statements as `if` statements when they fail', async function() { + const contract = await util.bootstrapCoverage('assert/Assert', provider, collector); + coverage.addContract(contract.instrumented, util.filePath); + + try { await contract.instance.a(false) } catch(err) { /* Invalid opcode */ } + + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 5: 1, + }); + assert.deepEqual(mapping[util.filePath].b, { + 1: [0, 1], + }); + assert.deepEqual(mapping[util.filePath].s, { + 1: 1, + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 1, + }); + }); + + it('should cover multi-line require stmts as `if` statements when they pass', async function() { + const contract = await util.bootstrapCoverage('assert/RequireMultiline', provider, collector); + coverage.addContract(contract.instrumented, util.filePath); + await contract.instance.a(true, true, true); + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 5: 1, + }); + assert.deepEqual(mapping[util.filePath].b, { + 1: [1, 0], + }); + assert.deepEqual(mapping[util.filePath].s, { + 1: 1, + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 1, + }); + }); + + it('should cover multi-line require stmts as `if` statements when they fail', async function() { + const contract = await util.bootstrapCoverage('assert/RequireMultiline', provider, collector); + coverage.addContract(contract.instrumented, util.filePath); + + try { await contract.instance.a(true, true, false) } catch(err) { /* Revert */ } + + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 5: 1, + }); + assert.deepEqual(mapping[util.filePath].b, { + 1: [0, 1], + }); + assert.deepEqual(mapping[util.filePath].s, { + 1: 1, + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 1, + }); + }); +}); diff --git a/test/units/comments.js b/test/units/comments.js new file mode 100644 index 00000000..d1e6e3e2 --- /dev/null +++ b/test/units/comments.js @@ -0,0 +1,26 @@ +const assert = require('assert'); +const util = require('./../util/util.js'); + +describe('comments', () => { + + it('should cover functions even if comments are present immediately after the opening {', () => { + const info = util.instrumentAndCompile('comments/postFunctionDeclarationComment'); + util.report(info.solcOutput.errors); + }); + + it('should cover lines even if comments are present', () => { + const info = util.instrumentAndCompile('comments/postLineComment'); + assert.deepEqual([6, 5], info.instrumented.runnableLines); + util.report(info.solcOutput.errors); + }); + + it('should cover contracts even if comments are present', () => { + const info = util.instrumentAndCompile('comments/postContractComment'); + util.report(info.solcOutput.errors); + }); + + it('should cover if statements even if comments are present immediately after opening { ', () => { + const info = util.instrumentAndCompile('comments/postIfStatementComment'); + util.report(info.solcOutput.errors); + }); +}); diff --git a/test/units/expressions.js b/test/units/expressions.js new file mode 100644 index 00000000..b007c294 --- /dev/null +++ b/test/units/expressions.js @@ -0,0 +1,19 @@ +const assert = require('assert'); +const util = require('./../util/util.js'); + +describe('generic expressions / misc', () => { + it('should compile after instrumenting a single binary expression', () => { + const info = util.instrumentAndCompile('expressions/single-binary-expression'); + util.report(info.solcOutput.errors); + }); + + it('should compile after instrumenting a new expression', () => { + const info = util.instrumentAndCompile('expressions/new-expression'); + util.report(info.solcOutput.errors); + }); + + it('should compile after instrumenting function that returns true', () => { + const info = util.instrumentAndCompile('return/return'); + util.report(info.solcOutput.errors); + }); +}); diff --git a/test/units/function.js b/test/units/function.js new file mode 100644 index 00000000..6e3fe1d9 --- /dev/null +++ b/test/units/function.js @@ -0,0 +1,159 @@ +const assert = require('assert'); +const util = require('./../util/util.js'); + +const ganache = require('ganache-cli'); +const Coverage = require('./../../lib/coverage'); + +describe('function declarations', () => { + let coverage; + let provider; + let collector; + + before(async () => ({ provider, collector } = await util.initializeProvider(ganache))); + beforeEach(() => coverage = new Coverage()); + after((done) => provider.close(done)); + + it('should compile after instrumenting an ordinary function declaration', () => { + const info = util.instrumentAndCompile('function/function'); + util.report(info.solcOutput.errors); + }); + + it('should compile after instrumenting an abstract function declaration', () => { + const info = util.instrumentAndCompile('function/abstract'); + util.report(info.solcOutput.errors); + }); + + it('should compile after instrumenting a function declaration with an empty body', () => { + const info = util.instrumentAndCompile('function/empty-body'); + util.report(info.solcOutput.errors); + }); + + it('should compile after instrumenting lots of declarations in row', () => { + const info = util.instrumentAndCompile('function/multiple'); + util.report(info.solcOutput.errors); + }); + + it('should compile after instrumenting a new->constructor-->method chain', () => { + const info = util.instrumentAndCompile('function/chainable-new'); + util.report(info.solcOutput.errors); + }); + + it('should compile after instrumenting a constructor call that chains to a method call', () => { + const info = util.instrumentAndCompile('function/chainable'); + util.report(info.solcOutput.errors); + }); + + it('should compile after instrumenting a function with calldata keyword', () => { + const info = util.instrumentAndCompile('function/calldata'); + util.report(info.solcOutput.errors); + }); + + it('should compile after instrumenting a constructor-->method-->value chain', () => { + const info = util.instrumentAndCompile('function/chainable-value'); + util.report(info.solcOutput.errors); + }); + + it('should cover a simple invoked function call', async function() { + const contract = await util.bootstrapCoverage('function/function-call', provider, collector); + coverage.addContract(contract.instrumented, util.filePath); + await contract.instance.a(); + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 7: 1, + }); + assert.deepEqual(mapping[util.filePath].b, {}); + assert.deepEqual(mapping[util.filePath].s, { + 1: 1, + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 1, + 2: 1, + }); + }); + + it('should cover a modifier used on a function', async function() { + const contract = await util.bootstrapCoverage('function/modifier', provider, collector); + coverage.addContract(contract.instrumented, util.filePath); + await contract.instance.a(0); + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 5: 1, 6: 1, 9: 1, + }); + assert.deepEqual(mapping[util.filePath].b, {}); + assert.deepEqual(mapping[util.filePath].s, { + 1: 1 + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 1, + 2: 1, + }); + }); + + it('should cover a constructor that uses the `constructor` keyword', async function() { + const contract = await util.bootstrapCoverage('function/constructor-keyword', provider, collector); + coverage.addContract(contract.instrumented, util.filePath); + await contract.instance.a(); + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 6: 1, 11: 1 + }); + assert.deepEqual(mapping[util.filePath].b, {}); + assert.deepEqual(mapping[util.filePath].s, { + 1: 1, 2: 1 + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 1, + 2: 1, + }); + }); + + // We try and call a contract at an address where it doesn't exist and the VM + // throws, but we can verify line / statement / fn coverage is getting mapped. + it('should cover a constructor call that chains to a method call', async function() { + const contract = await util.bootstrapCoverage('function/chainable', provider, collector); + coverage.addContract(contract.instrumented, util.filePath); + + try { await contract.instance.a() } catch(err){} + + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 9: 1, + }); + assert.deepEqual(mapping[util.filePath].b, {}); + assert.deepEqual(mapping[util.filePath].s, { + 1: 1, + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 0, + 2: 1, + }); + }); + + // The vm runs out of gas here - but we can verify line / statement / fn + // coverage is getting mapped. + it('should cover a constructor call that chains to a method call', async function() { + const contract = await util.bootstrapCoverage('function/chainable-value', provider, collector); + coverage.addContract(contract.instrumented, util.filePath); + + try { await contract.instance.a() } catch(err){} + + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 10: 1, + }); + assert.deepEqual(mapping[util.filePath].b, {}); + assert.deepEqual(mapping[util.filePath].s, { + 1: 1, + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 0, + 2: 1, + }); + }); +}); + diff --git a/test/units/if.js b/test/units/if.js new file mode 100644 index 00000000..5ad033f6 --- /dev/null +++ b/test/units/if.js @@ -0,0 +1,241 @@ +const assert = require('assert'); +const util = require('./../util/util.js'); + +const ganache = require('ganache-cli'); +const Coverage = require('./../../lib/coverage'); + +describe('if, else, and else if statements', () => { + let coverage; + let provider; + let collector; + + before(async () => ({ provider, collector } = await util.initializeProvider(ganache))); + beforeEach(() => coverage = new Coverage()); + after((done) => provider.close(done)); + + it('should compile after instrumenting unbracketed if-elses', () => { + const info = util.instrumentAndCompile('if/if-else-no-brackets'); + util.report(info.solcOutput.errors); + }); + + it('should compile after instrumenting multiple unbracketed if-elses', () => { + const info = util.instrumentAndCompile('if/else-if-unbracketed-multi'); + util.report(info.solcOutput.errors); + }); + + it('should cover an if statement with a bracketed consequent', async function() { + const contract = await util.bootstrapCoverage('if/if-with-brackets', provider, collector); + coverage.addContract(contract.instrumented, util.filePath); + await contract.instance.a(1); + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 5: 1, + }); + assert.deepEqual(mapping[util.filePath].b, { + 1: [1, 0], + }); + assert.deepEqual(mapping[util.filePath].s, { + 1: 1, 2: 1, + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 1, + }); + }); + + // Runs: a(1) => if (x == 1) x = 2; + it('should cover an unbracketed if consequent (single line)', async function(){ + const contract = await util.bootstrapCoverage('if/if-no-brackets', provider, collector); + coverage.addContract(contract.instrumented, util.filePath); + await contract.instance.a(1); + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 5: 1, + }); + assert.deepEqual(mapping[util.filePath].b, { + 1: [1, 0], + }); + assert.deepEqual(mapping[util.filePath].s, { + 1: 1, 2: 1, + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 1, + }); + }); + + // Runs: a(1) => if (x == 1){\n x = 3; } + it('should cover an if statement with multiline bracketed consequent', async function() { + const contract = await util.bootstrapCoverage('if/if-with-brackets-multiline',provider,collector); + + coverage.addContract(contract.instrumented, util.filePath); + await contract.instance.a(1); + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 5: 1, 6: 1, + }); + assert.deepEqual(mapping[util.filePath].b, { + 1: [1, 0], + }); + assert.deepEqual(mapping[util.filePath].s, { + 1: 1, 2: 1, + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 1, + }); + + }); + + // Runs: a(1) => if (x == 1)\n x = 3; + it('should cover an unbracketed if consequent (multi-line)', async function() { + const contract = await util.bootstrapCoverage('if/if-no-brackets-multiline',provider,collector); + + coverage.addContract(contract.instrumented, util.filePath); + await contract.instance.a(1); + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 5: 1, 6: 1, + }); + assert.deepEqual(mapping[util.filePath].b, { + 1: [1, 0], + }); + assert.deepEqual(mapping[util.filePath].s, { + 1: 1, 2: 1, + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 1, + }); + }); + + // Runs: a(2) => if (x == 1) { x = 3; } + it('should cover a simple if statement with a failing condition', async function() { + const contract = await util.bootstrapCoverage('if/if-with-brackets',provider,collector); + + coverage.addContract(contract.instrumented, util.filePath); + await contract.instance.a(2); + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 5: 1, + }); + assert.deepEqual(mapping[util.filePath].b, { + 1: [0, 1], + }); + assert.deepEqual(mapping[util.filePath].s, { + 1: 1, 2: 0, + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 1, + }); + }); + + // Runs: a(2) => if (x == 1){\n throw;\n }else{\n x = 5; \n} + it('should cover an if statement with a bracketed alternate', async function() { + const contract = await util.bootstrapCoverage('if/else-with-brackets',provider,collector); + + coverage.addContract(contract.instrumented, util.filePath); + await contract.instance.a(2); + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 5: 1, 6: 0, 8: 1, + }); + assert.deepEqual(mapping[util.filePath].b, { + 1: [0, 1], + }); + assert.deepEqual(mapping[util.filePath].s, { + 1: 1, 2: 0, 3: 1, + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 1, + }); + }); + + it('should cover an if statement with an unbracketed alternate', async function() { + const contract = await util.bootstrapCoverage('if/else-without-brackets',provider,collector); + + coverage.addContract(contract.instrumented, util.filePath); + await contract.instance.a(2); + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 5: 1, 6: 0, 8: 1, + }); + assert.deepEqual(mapping[util.filePath].b, { + 1: [0, 1], + }); + assert.deepEqual(mapping[util.filePath].s, { + 1: 1, 2: 0, 3: 1, + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 1, + }); + + }); + + it('should cover an else if statement with an unbracketed alternate', async function() { + const contract = await util.bootstrapCoverage('if/else-if-without-brackets',provider,collector); + + coverage.addContract(contract.instrumented, util.filePath); + await contract.instance.a(2); + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 5: 1, 6: 0, 8: 0, + }); + assert.deepEqual(mapping[util.filePath].b, { + 1: [0, 1], 2: [0, 1] + }); + assert.deepEqual(mapping[util.filePath].s, { + 1: 1, 2: 0, 3: 1, 4: 0 + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 1, + }); + }); + + it('should cover nested if statements with missing else statements', async function() { + const contract = await util.bootstrapCoverage('if/nested-if-missing-else',provider,collector); + + coverage.addContract(contract.instrumented, util.filePath); + await contract.instance.a(2,3,3); + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 5: 1, 7: 1, + }); + assert.deepEqual(mapping[util.filePath].b, { + 1: [0, 1], 2: [1, 0], 3: [1, 0], + }); + assert.deepEqual(mapping[util.filePath].s, { + 1: 1, 2: 1, 3: 1, + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 1, + }); + + }); + + it('should cover if-elseif-else statements that are at the same depth as each other', async function() { + const contract = await util.bootstrapCoverage('if/if-elseif-else',provider,collector); + + coverage.addContract(contract.instrumented, util.filePath); + await contract.instance.a(2,3,3); + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 5: 1, 6: 0, 8: 1, 10: 0, 13: 1, 14: 0, 16: 1, 18: 0, + }); + assert.deepEqual(mapping[util.filePath].b, { + 1: [0, 1], 2: [1, 0], 3: [0, 1], 4: [1, 0] + }); + assert.deepEqual(mapping[util.filePath].s, { + 1: 1, 2: 0, 3: 1, 4: 1, 5: 0, 6: 1, 7: 0, 8: 1, 9: 1, 10: 0, + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 1, + }); + }); +}); diff --git a/test/units/loops.js b/test/units/loops.js new file mode 100644 index 00000000..c87248cf --- /dev/null +++ b/test/units/loops.js @@ -0,0 +1,91 @@ +const assert = require('assert'); +const util = require('./../util/util.js'); + +const ganache = require('ganache-cli'); +const Coverage = require('./../../lib/coverage'); + +describe('for and while statements', () => { + let coverage; + let provider; + let collector; + + before(async () => ({ provider, collector } = await util.initializeProvider(ganache))); + beforeEach(() => coverage = new Coverage()); + after((done) => provider.close(done)); + + // Runs: a() => for(var x = 1; x < 10; x++){\n sha3(x);\n } + it('should cover a for statement with a bracketed body (multiline)', async function() { + const contract = await util.bootstrapCoverage('loops/for-with-brackets', provider, collector); + coverage.addContract(contract.instrumented, util.filePath); + await contract.instance.a(); + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 5: 1, 6: 10, + }); + assert.deepEqual(mapping[util.filePath].b, {}); + assert.deepEqual(mapping[util.filePath].s, { + 1: 1, 2: 10, + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 1, + }); + }); + + // Runs: a() => for(var x = 1; x < 10; x++)\n sha3(x);\n + it('should cover a for statement with an unbracketed body', async function() { + const contract = await util.bootstrapCoverage('loops/for-no-brackets', provider, collector); + coverage.addContract(contract.instrumented, util.filePath); + await contract.instance.a(); + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 5: 1, 6: 10, + }); + assert.deepEqual(mapping[util.filePath].b, {}); + assert.deepEqual(mapping[util.filePath].s, { + 1: 1, 2: 10, + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 1, + }); + }); + + // Runs: a() => var t = true;\n while(t){\n t = false;\n } + it('should cover a while statement with an bracketed body (multiline)', async function() { + const contract = await util.bootstrapCoverage('loops/while-with-brackets', provider, collector); + coverage.addContract(contract.instrumented, util.filePath); + await contract.instance.a(); + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 5: 1, 6: 1, 7: 1, + }); + assert.deepEqual(mapping[util.filePath].b, {}); + assert.deepEqual(mapping[util.filePath].s, { + 1: 1, 2: 1, 3: 1, + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 1, + }); + }); + + // Runs: a() => var t = true;\n while(t)\n t = false;\n + it('should cover a while statement with an unbracketed body (multiline)', async function() { + const contract = await util.bootstrapCoverage('loops/while-no-brackets', provider, collector); + coverage.addContract(contract.instrumented, util.filePath); + await contract.instance.a(); + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 5: 1, 6: 1, 7: 1, + }); + assert.deepEqual(mapping[util.filePath].b, {}); + assert.deepEqual(mapping[util.filePath].s, { + 1: 1, 2: 1, 3: 1, + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 1, + }); + }); +}); diff --git a/test/units/statements.js b/test/units/statements.js new file mode 100644 index 00000000..5e962dd0 --- /dev/null +++ b/test/units/statements.js @@ -0,0 +1,150 @@ +const assert = require('assert'); +const util = require('./../util/util.js'); + +const ganache = require('ganache-cli'); +const Coverage = require('./../../lib/coverage'); + +describe('generic statements', () => { + let coverage; + let provider; + let collector; + + before(async () => ({ provider, collector } = await util.initializeProvider(ganache))); + beforeEach(() => coverage = new Coverage()); + after((done) => provider.close(done)); + + it('should compile function defined in a struct', () => { + const info = util.instrumentAndCompile('statements/fn-struct'); + util.report(info.solcOutput.errors); + }) + + it('should compile when using the type keyword', () => { + const info = util.instrumentAndCompile('statements/type-keyword'); + util.report(info.solcOutput.errors); + }) + + it('should instrument a single statement (first line of function)', () => { + const info = util.instrumentAndCompile('statements/single'); + util.report(info.solcOutput.errors); + }); + + it('should instrument multiple statements', () => { + const info = util.instrumentAndCompile('statements/multiple'); + util.report(info.solcOutput.errors); + }); + + it('should instrument a statement that is a function argument (single line)', () => { + const info = util.instrumentAndCompile('statements/fn-argument'); + util.report(info.solcOutput.errors); + }); + + it('should instrument a statement that is a function argument (multi-line)', () => { + const info = util.instrumentAndCompile('statements/fn-argument-multiline'); + util.report(info.solcOutput.errors); + }); + + it('should instrument an empty-contract-body', () => { + const info = util.instrumentAndCompile('statements/empty-contract-ala-melonport'); + util.report(info.solcOutput.errors); + }); + + it('should NOT pass tests if the contract has a compilation error', () => { + const info = util.instrumentAndCompile('../errors/compilation-error'); + try { + util.report(output.errors); + assert.fail('failure'); // We shouldn't hit this. + } catch (err) { + (err.actual === 'failure') ? assert(false) : assert(true); + } + }); + + it('should instrument an emit statement after an un-enclosed if statement', () => { + const info = util.instrumentAndCompile('statements/emit-instrument'); + util.report(info.solcOutput.errors); + }); + + it('should cover an emitted event statement', async function() { + const contract = await util.bootstrapCoverage('statements/emit-coverage', provider, collector); + coverage.addContract(contract.instrumented, util.filePath); + await contract.instance.a(0); + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 6: 1 + }); + assert.deepEqual(mapping[util.filePath].b, {}); + assert.deepEqual(mapping[util.filePath].s, { + 1: 1 + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 1, + }); + }); + + it('should cover a statement following a close brace', async function() { + const contract = await util.bootstrapCoverage('statements/post-close-brace', provider, collector); + coverage.addContract(contract.instrumented, util.filePath); + await contract.instance.a(1); + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 5: 1, 6: 0, 8: 1, + }); + assert.deepEqual(mapping[util.filePath].b, { + 1: [0, 1], + }); + assert.deepEqual(mapping[util.filePath].s, { + 1: 1, 2: 0, 3: 1, + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 1, + }); + }); + + it('should cover a library statement and an invoked library method', async function() { + const contract = await util.bootstrapCoverage('statements/library', provider, collector); + coverage.addContract(contract.instrumented, util.filePath); + await contract.instance.not(); + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 9: 1, 10: 1, 19: 1, + }); + assert.deepEqual(mapping[util.filePath].b, {}); + assert.deepEqual(mapping[util.filePath].s, { + 1: 1, 2: 1, 3: 1, + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 1, 2: 1, + }); + }); + + it('should cover a tuple statement', async function() { + const contract = await util.bootstrapCoverage('statements/tuple', provider, collector); + coverage.addContract(contract.instrumented, util.filePath); + await contract.instance.a(); + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 6: 1, 10: 1, 11: 1 + }); + assert.deepEqual(mapping[util.filePath].b, {}); + assert.deepEqual(mapping[util.filePath].s, { + 1: 1, 2: 1, 3: 1, + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 1, 2: 1, + }); + }); + + it('should cover an empty bodied contract statement', async function() { + const contract = await util.bootstrapCoverage('statements/empty-contract-body', provider, collector); + coverage.addContract(contract.instrumented, util.filePath); + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, {}); + assert.deepEqual(mapping[util.filePath].b, {}); + assert.deepEqual(mapping[util.filePath].s, {}); + assert.deepEqual(mapping[util.filePath].f, {}); + }); +}); diff --git a/test/util/mockTestCommand.js b/test/util/mockTestCommand.js deleted file mode 100644 index d0abb345..00000000 --- a/test/util/mockTestCommand.js +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env node - -const fs = require('fs'); -const request = require('request'); -const fakeEvent = {"address":"6d6cf716c2a7672047e15a255d4c9624db60f215","topics":["34b35f4b1a8c3eb2caa69f05fb5aadc827cedd2d8eb3bb3623b6c4bba3baec17"],"data":"00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000003a2f55736572732f757365722f53697465732f73632d666f726b732f6d657461636f696e2f636f6e7472616374732f4d657461436f696e2e736f6c000000000000"} - -request({ - uri: 'http://localhost:8888', - body: { - jsonrpc: '2.0', - method: 'web3_clientVersion', - params: [], - id: 0, - }, - json: true, -}, (error, response, body) => { - if (error) { - console.error(error); - process.exit(1); - } - fs.writeFileSync('../allFiredEvents', JSON.stringify(fakeEvent) + '\n'); - process.exit(0); -}); diff --git a/test/util/util.js b/test/util/util.js index 921940f6..1faa8d4f 100644 --- a/test/util/util.js +++ b/test/util/util.js @@ -1,39 +1,111 @@ const fs = require('fs'); const path = require('path'); +const solc = require('solc'); +const TruffleContract = require('truffle-contract'); -/** - * Retrieves code at source//.sol - * @param {String} _path path relative to `./source` - * @return {String} contents of a .sol file - */ -module.exports.getCode = function getCode(_path) { - return fs.readFileSync(path.join(__dirname, `./../sources/${_path}`), 'utf8'); +const Instrumenter = require('./../../lib/instrumenter'); +const DataCollector = require('./../../lib/collector') + +const filePath = path.resolve('./test.sol'); +const pathPrefix = './'; + +function getCode(_path) { + const pathToSources = `./../soliditySources/contracts/${_path}`; + return fs.readFileSync(path.join(__dirname, pathToSources), 'utf8'); }; -module.exports.report = function report(errors) { - if (errors) { - errors.forEach(error => { - if (error.severity === 'error') { - throw new Error(`Instrumented solidity invalid: ${JSON.stringify(errors)}`); - } - }); +function getABI(solcOutput, testFile="test.sol", testName="Test"){ + return solcOutput.contracts[testFile][testName].abi; +} + +function getBytecode(solcOutput, testFile="test.sol", testName="Test"){ + return `0x${solcOutput.contracts[testFile][testName].evm.bytecode.object}`; +} + +async function getDeployedContractInstance(info, provider){ + + const contract = TruffleContract({ + abi: getABI(info.solcOutput), + bytecode: getBytecode(info.solcOutput) + }) + + contract.setProvider(provider); + + const accounts = await contract.web3.eth.getAccounts(); + contract.defaults({ + gas: 5500000, + gasPrice: 1, + from: accounts[0] + }); + + return contract.new(); +} + +function compile(source){ + const compilerInput = codeToCompilerInput(source); + return JSON.parse(solc.compile(compilerInput)); +} + +function report(output=[]) { + output.forEach(item => { + if (item.severity === 'error') { + const errors = JSON.stringify(output, null, ' '); + throw new Error(`Instrumentation fault: ${errors}`); + } + }); +} + +function instrumentAndCompile(sourceName) { + const contract = getCode(`${sourceName}.sol`) + const instrumenter = new Instrumenter(); + const instrumented = instrumenter.instrument(contract, filePath); + + return { + contract: contract, + instrumented: instrumented, + solcOutput: compile(instrumented.contract), + data: instrumenter.instrumentationData } -}; +} -module.exports.codeToCompilerInput = function codeToCompilerInput(code) { +function codeToCompilerInput(code) { return JSON.stringify({ language: 'Solidity', - sources: { - 'test.sol': { - content: code - } - }, - settings: { - outputSelection: { - '*': { - '*': [ '*' ] - } - } - } + sources: { 'test.sol': { content: code } }, + settings: { outputSelection: {'*': { '*': [ '*' ] }} } }); } + +async function bootstrapCoverage(file, provider, collector){ + const info = instrumentAndCompile(file); + info.instance = await getDeployedContractInstance(info, provider); + collector._setInstrumentationData(info.data); + return info; +} + +async function initializeProvider(ganache){ + const provider = ganache.provider(); + + return new Promise(resolve => { + const interval = setInterval(() => { + + if (provider.engine.manager.state.blockchain.vm !== undefined){ + clearInterval(interval); + + resolve({ + provider: provider, + collector: new DataCollector({provider: provider}) + }); + } + }); + }) +} + +module.exports = { + pathPrefix: pathPrefix, + filePath: filePath, + report: report, + instrumentAndCompile: instrumentAndCompile, + bootstrapCoverage: bootstrapCoverage, + initializeProvider: initializeProvider, +} diff --git a/test/util/vm.js b/test/util/vm.js deleted file mode 100644 index 46ef9399..00000000 --- a/test/util/vm.js +++ /dev/null @@ -1,157 +0,0 @@ -const solc = require('solc'); -const shell = require('shelljs'); -const fs = require('fs'); -const VM = require('ethereumjs-vm'); -const Account = require('ethereumjs-account'); -const Transaction = require('ethereumjs-tx'); -const utils = require('ethereumjs-util'); -const CryptoJS = require('crypto-js'); -const Trie = require('merkle-patricia-tree'); -const { AbiCoder } = require('web3-eth-abi'); -const SolidityCoder = AbiCoder(); - -const codeToCompilerInput = require('./util').codeToCompilerInput; - -// Don't use this address for anything, obviously! -const secretKey = 'e81cb653c260ee12c72ec8750e6bfd8a4dc2c3d7e3ede68dd2f150d0a67263d8'; -const accountAddress = new Buffer('7caf6f9bc8b3ba5c7824f934c826bd6dc38c8467', 'hex'); - -/** - * Encodes function data - * Source: consensys/eth-lightwallet/lib/txutils.js (line 18) - */ -function encodeFunctionTxData(functionName, types, args) { - const fullName = `${functionName}(${types.join()})`; - const signature = CryptoJS.SHA3(fullName, { - outputLength: 256, - }).toString(CryptoJS.enc.Hex).slice(0, 8); - const dataHex = signature + SolidityCoder.encodeParameters(types, args).slice(2); - return `0x${dataHex}`; -} - -/** - * Extracts types from abi - * Source: consensys/eth-lightwallet/lib/txutils.js (line 27) - */ -function getTypesFromAbi(abi, functionName) { - function matchesFunctionName(json) { - return (json.name === functionName && json.type === 'function'); - } - function getTypes(json) { - return json.type; - } - const funcJson = abi.filter(matchesFunctionName)[0]; - - return funcJson ? (funcJson.inputs).map(getTypes) : []; -} - -/** - * Retrieves abi for contract - * Source: raineorshine/eth-new-contract/src/index.js (line 8) - * @param {String} source solidity contract - * @param {Object} compilation compiled `source` - * @return {Object} abi - */ -function getAbi(source, compilation) { - const contractNameMatch = source.match(/(?:contract)\s([^\s]*)\s*{/); - if (!contractNameMatch) { - throw new Error('Could not parse contract name from source.'); - } - const contractName = contractNameMatch[1]; - return compilation.contracts['test.sol'][contractName].abi; -} - -/** - * Creates, funds and publishes account to Trie - */ -function createAccount(trie) { - const account = new Account(); - account.balance = 'f00000000000000000'; - trie.put(accountAddress, account.serialize()); -} - -/** - * Deploys contract represented by `code` - * @param {String} code contract bytecode - */ - -function deploy(vm, code) { - const tx = new Transaction({ - gasPrice: '1', gasLimit: 'ffffff', data: code, - }); - tx.sign(new Buffer(secretKey, 'hex')); - - return new Promise((resolve, reject) => { - vm.runTx({ - tx, - }, (err, results) => { - if (err) { - reject(err); - } else { - resolve(results.createdAddress); - } - }); - }); -} - -/** - * Invokes `functionName` with `args` on contract at `address`. Tx construction logic - * is poached from consensys/eth-lightwallet/lib/txutils:functionTx - * @param {Array} abi contract abi - * @param {String} address deployed contract to invoke method on - * @param {String} functionName method to invoke - * @param {Array} args functionName's arguments - * @return {Promise} resolves array of logged events - */ -function callMethod(vm, abi, address, functionName, args) { - const types = getTypesFromAbi(abi, functionName); - const txData = encodeFunctionTxData(functionName, types, args); - const options = { - gasPrice: '0x1', - gasLimit: '0xffffff', - to: utils.bufferToHex(address), - data: txData, - nonce: '0x1', - }; - - const tx = new Transaction(options); - tx.sign(new Buffer(secretKey, 'hex')); - - return new Promise(resolve => { - vm.runTx({ - tx, - }, (err, results) => { - try { - const events = fs.readFileSync('./allFiredEvents').toString().split('\n'); - events.pop(); - shell.rm('./allFiredEvents'); - resolve(events); - } catch (e) { - resolve([]); - } - }); - }); -} - -/** - * Runs method `functionName` with parameters `args` on contract. Resolves a - * CR delimited list of logged events. - * @param {String} contract solidity to compile - * @param {String} functionName method to invoke on contract - * @param {Array} args parameter values to pass to method - * @return {Promise} resolves array of logged events. - */ -module.exports.execute = function ex(contract, functionName, args) { - const input = codeToCompilerInput(contract); - const output = JSON.parse(solc.compile(input)); - const code = new Buffer(output.contracts['test.sol']['Test'].evm.bytecode.object, 'hex'); - const abi = getAbi(contract, output); - const stateTrie = new Trie(); - const vm = new VM({ - state: stateTrie, - hardfork: "constantinople" - }); - - createAccount(stateTrie); - return deploy(vm, code).then(address => callMethod(vm, abi, address, functionName, args)); -}; diff --git a/yarn.lock b/yarn.lock index 5929714b..8d02ad7f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,18 +2,65 @@ # yarn lockfile v1 -"@babel/runtime@^7.3.1": - version "7.5.2" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.2.tgz#98f584f4d03be5d8142c77107ffaedee4d5956f1" - integrity sha512-9M29wrrP7//JBGX70+IrDuD1w4iOYhUGpJNMQJVNAXue+cFeFlMTqBECouIziXPUphlgrfjcfiEpGX4t0WGK4g== - dependencies: - regenerator-runtime "^0.13.2" +"@nomiclabs/buidler-truffle5@^1.0.0-beta.8": + version "1.0.0-beta.9" + resolved "https://registry.yarnpkg.com/@nomiclabs/buidler-truffle5/-/buidler-truffle5-1.0.0-beta.9.tgz#935fb0e04b77f138ad913ede7feae108ccbd248d" + integrity sha512-lzBQifJ+bEw1HlXnpKVWxliTg/2IGxU+tv56wuoOqWXN2dFnL9xQ/rYCkc1uVA8iqO2Zx+jSlkbC02vR6q2tDA== + dependencies: + chai "^4.2.0" + truffle-contract "^4.0.27" + +"@nomiclabs/buidler-web3@^1.0.0-beta.8": + version "1.0.0-beta.9" + resolved "https://registry.yarnpkg.com/@nomiclabs/buidler-web3/-/buidler-web3-1.0.0-beta.9.tgz#f1cab65a26abd455dded4bbcfd955012476af1c9" + integrity sha512-pNwLu/sl/2bXxpSNey73HxxFXgei1F19UaPTlM0W6I6AZgeq1/ZvXzWW2P9MwUZAJUnnZj4q7KC4wZ+uhe32Mw== + +"@nomiclabs/buidler@^1.0.0-beta.8": + version "1.0.0-beta.9" + resolved "https://registry.yarnpkg.com/@nomiclabs/buidler/-/buidler-1.0.0-beta.9.tgz#3bd63b1a291fbae55161cf91528210f28bb3f8d2" + integrity sha512-3HIvkrKUcPMmjObO8/I/nuMV5SMCAjMHyadN0lzCKSAS2T9x43J5B6mSARJfzR2nDT0+0mpBXzuQb2rdzNLEzQ== + dependencies: + "@types/bn.js" "^4.11.5" + abort-controller "^3.0.0" + bip32 "^2.0.3" + bip39 "^3.0.2" + chalk "^2.4.2" + ci-info "^2.0.0" + debug "^4.1.1" + deepmerge "^2.1.0" + download "^7.1.0" + enquirer "^2.3.0" + ethereumjs-common "^1.3.0" + ethereumjs-tx "^2.0.0" + ethereumjs-util "^6.1.0" + find-up "^2.1.0" + fp-ts "1.19.3" + fs-extra "^7.0.1" + glob "^7.1.3" + io-ts "1.10.4" + is-installed-globally "^0.2.0" + lodash "^4.17.11" + mocha "^5.2.0" + node-fetch "^2.6.0" + qs "^6.7.0" + semver "^5.6.0" + solc "0.5.8" + solidity-parser-antlr "^0.4.2" + source-map-support "^0.5.12" + ts-essentials "^2.0.7" + tsort "0.0.1" + uuid "^3.3.2" "@sindresorhus/is@^0.14.0": version "0.14.0" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== +"@sindresorhus/is@^0.7.0": + version "0.7.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd" + integrity sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow== + "@szmarczak/http-timer@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" @@ -21,7 +68,7 @@ dependencies: defer-to-connect "^1.0.1" -"@types/bn.js@^4.11.4": +"@types/bn.js@^4.11.5": version "4.11.5" resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.5.tgz#40e36197433f78f807524ec623afcf0169ac81dc" integrity sha512-AEAZcIZga0JgVMHNtl1CprA/hXX7/wPt79AgR4XqaDt7jyj3QWYw6LPoOiznPtugDmlubUnAahMs2PFxGcQrng== @@ -29,14 +76,24 @@ "@types/node" "*" "@types/node@*": - version "12.6.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.6.1.tgz#d5544f6de0aae03eefbb63d5120f6c8be0691946" - integrity sha512-rp7La3m845mSESCgsJePNL/JQyhkOJA6G4vcwvVgkDAwHhGdq5GCumxmPjEk1MZf+8p5ZQAUE7tqgQRQTXN7uQ== + version "12.6.9" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.6.9.tgz#ffeee23afdc19ab16e979338e7b536fdebbbaeaf" + integrity sha512-+YB9FtyxXGyD54p8rXwWaN1EWEyar5L58GlGWgtH2I9rGmLGBQcw63+0jw+ujqVavNuO47S1ByAjm9zdHMnskw== + +"@types/node@10.12.18": + version "10.12.18" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67" + integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ== -"@types/node@^10.12.18", "@types/node@^10.3.2": - version "10.14.12" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.12.tgz#0eec3155a46e6c4db1f27c3e588a205f767d622f" - integrity sha512-QcAKpaO6nhHLlxWBvpc4WeLrTvPqlHOvaj0s5GriKkA1zq+bsFBPpfYCvQhLqLgYlIko8A9YrPdaMHCo5mBcpg== +"@types/node@11.11.6": + version "11.11.6" + resolved "https://registry.yarnpkg.com/@types/node/-/node-11.11.6.tgz#df929d1bb2eee5afdda598a41930fe50b43eaa6a" + integrity sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ== + +"@types/node@^10.3.2": + version "10.14.14" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.14.tgz#a47955df2acf76ba7f0ac3b205d325da193dc9ad" + integrity sha512-xXD08vZsvpv4xptQXj1+ky22f7ZoKu5ZNI/4l+/BXG3X+XaeZsmaFbbTKuhSE3NjjvRuZFxFf9sQBMXIcZNFMQ== JSONStream@^1.3.4: version "1.3.5" @@ -56,26 +113,12 @@ abbrev@1.0.x: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" integrity sha1-kbR5JYinc4wl813W9jdSovh3YTU= -abstract-leveldown@^5.0.0, abstract-leveldown@~5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-5.0.0.tgz#f7128e1f86ccabf7d2893077ce5d06d798e386c6" - integrity sha512-5mU5P1gXtsMIXg65/rsYGsi93+MlogXZ9FA8JnwKurHQg64bfXwGYVdVdijNTVNOlAsuIiOwHdvFFD5JqCJQ7A== - dependencies: - xtend "~4.0.0" - -abstract-leveldown@~2.6.0: - version "2.6.3" - resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz#1c5e8c6a5ef965ae8c35dfb3a8770c476b82c4b8" - integrity sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA== - dependencies: - xtend "~4.0.0" - -abstract-leveldown@~2.7.1: - version "2.7.2" - resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-2.7.2.tgz#87a44d7ebebc341d59665204834c8b7e0932cc93" - integrity sha512-+OVvxH2rHVEhWLdbudP6p0+dNMXu8JA1CbhP19T8paTYAcX7oJ4OVjT+ZUVpv7mITxXHqDMej+GdqXBmXkw09w== +abort-controller@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" + integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== dependencies: - xtend "~4.0.0" + event-target-shim "^5.0.0" accepts@~1.3.7: version "1.3.7" @@ -111,10 +154,10 @@ agentkeepalive@^3.4.1: dependencies: humanize-ms "^1.2.1" -ajv@^6.5.5: - version "6.10.1" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.1.tgz#ebf8d3af22552df9dd049bfbe50cc2390e823593" - integrity sha512-w1YQaVGNC6t2UCPjEawK/vo/dG8OOrVtUmhBT1uJJYxbl5kU2Tj3v6LGqBcsysN1yhuCStJCCA3GqdvKY8sqXQ== +ajv@^6.10.0, ajv@^6.5.5: + version "6.10.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52" + integrity sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw== dependencies: fast-deep-equal "^2.0.1" fast-json-stable-stringify "^2.0.0" @@ -133,6 +176,11 @@ ansi-align@^3.0.0: dependencies: string-width "^3.0.0" +ansi-colors@^3.2.1: + version "3.2.4" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" + integrity sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA== + ansi-regex@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" @@ -160,6 +208,11 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1: dependencies: color-convert "^1.9.0" +any-promise@1.3.0, any-promise@^1.0.0, any-promise@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + integrity sha1-q8av7tzqUugJzcA3au0845Y10X8= + app-module-path@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/app-module-path/-/app-module-path-2.2.0.tgz#641aa55dfb7d6a6f0a8141c4b9c0aa50b6c24dd5" @@ -170,6 +223,13 @@ aproba@^1.1.1: resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== +archive-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/archive-type/-/archive-type-4.0.0.tgz#f92e72233056dfc6969472749c267bdb046b1d70" + integrity sha1-+S5yIzBW38aWlHJ0nCZ72wRrHXA= + dependencies: + file-type "^4.2.0" + argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -203,30 +263,21 @@ assert-plus@1.0.0, assert-plus@^1.0.0: resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= -async-eventemitter@^0.2.2: - version "0.2.4" - resolved "https://registry.yarnpkg.com/async-eventemitter/-/async-eventemitter-0.2.4.tgz#f5e7c8ca7d3e46aab9ec40a292baf686a0bafaca" - integrity sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw== - dependencies: - async "^2.4.0" +assertion-error@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" + integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== async-limiter@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" - integrity sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg== + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" + integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== -async@1.x, async@^1.4.2: +async@1.x: version "1.5.2" resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= -async@^2.0.1, async@^2.1.2, async@^2.4.0, async@^2.6.1: - version "2.6.3" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" - integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== - dependencies: - lodash "^4.17.14" - asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" @@ -247,6 +298,13 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= +base-x@^3.0.2: + version "3.0.6" + resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.6.tgz#de047ec95f5f7b99ae63d830a2a894c96538b2cd" + integrity sha512-4PaF8u2+AlViJxRVjurkLTxpp7CaFRD/jo5rPT9ONnKxyhQ8f59yzamEvq7EkriG56yn5On4ONyaG75HLqr46w== + dependencies: + safe-buffer "^5.0.1" + base64-js@^1.0.2: version "1.3.0" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3" @@ -259,13 +317,41 @@ bcrypt-pbkdf@^1.0.0: dependencies: tweetnacl "^0.14.3" -bindings@^1.2.1, bindings@^1.5.0: +bignumber.js@^7.2.1: + version "7.2.1" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-7.2.1.tgz#80c048759d826800807c4bfd521e50edbba57a5f" + integrity sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ== + +bindings@^1.2.1, bindings@^1.3.0, bindings@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== dependencies: file-uri-to-path "1.0.0" +bip32@^2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/bip32/-/bip32-2.0.4.tgz#b662bd28710d4676fb351ba8a13be45cb4d85d01" + integrity sha512-ioPytarPDIrWckWMuK4RNUtvwhvWEc2fvuhnO0WEwu732k5OLjUXv4rXi2c/KJHw9ZMNQMkYRJrBw81RujShGQ== + dependencies: + "@types/node" "10.12.18" + bs58check "^2.1.1" + create-hash "^1.2.0" + create-hmac "^1.1.7" + tiny-secp256k1 "^1.1.0" + typeforce "^1.11.5" + wif "^2.0.6" + +bip39@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/bip39/-/bip39-3.0.2.tgz#2baf42ff3071fc9ddd5103de92e8f80d9257ee32" + integrity sha512-J4E1r2N0tUylTKt07ibXvhpT2c5pyAFgvuA5q1H9uDy6dEGpjV8jmymh3MTYJDLCNbIVClSB9FbND49I6N24MQ== + dependencies: + "@types/node" "11.11.6" + create-hash "^1.1.0" + pbkdf2 "^3.0.9" + randombytes "^2.0.1" + bip66@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/bip66/-/bip66-1.1.5.tgz#01fa8748785ca70955d5011217d1b3139969ca22" @@ -281,6 +367,18 @@ bl@^1.0.0: readable-stream "^2.3.5" safe-buffer "^5.1.1" +block-stream@*: + version "0.0.9" + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + integrity sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo= + dependencies: + inherits "~2.0.0" + +bluebird@^2.9.34: + version "2.11.0" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1" + integrity sha1-U0uQM8AiyVecVro7Plpcqvu2UOE= + bluebird@^3.5.0, bluebird@^3.5.1, bluebird@^3.5.3, bluebird@^3.5.5: version "3.5.5" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.5.tgz#a8d0afd73251effbbd5fe384a77d73003c17a71f" @@ -291,7 +389,7 @@ bn.js@4.11.6: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215" integrity sha1-UzRK2xRhehP26N0s4okF0cC6MhU= -bn.js@4.11.8, bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.11.0, bn.js@^4.11.1, bn.js@^4.11.6, bn.js@^4.11.8, bn.js@^4.4.0, bn.js@^4.8.0: +bn.js@4.11.8, bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.11.0, bn.js@^4.11.1, bn.js@^4.11.6, bn.js@^4.11.8, bn.js@^4.4.0: version "4.11.8" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== @@ -339,11 +437,6 @@ brorand@^1.0.1: resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= -browser-stdout@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f" - integrity sha1-81HTKWnTL6XXpVZxVCY9korjvR8= - browser-stdout@1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" @@ -409,6 +502,22 @@ browserify-sign@^4.0.0: inherits "^2.0.1" parse-asn1 "^5.0.0" +bs58@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" + integrity sha1-vhYedsNU9veIrkBx9j806MTwpCo= + dependencies: + base-x "^3.0.2" + +bs58check@<3.0.0, bs58check@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" + integrity sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA== + dependencies: + bs58 "^4.0.0" + create-hash "^1.1.0" + safe-buffer "^5.1.2" + buffer-alloc-unsafe@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" @@ -466,15 +575,16 @@ bytes@3.1.0: integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== cacache@^12.0.0: - version "12.0.0" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.0.tgz#1ed91cc306312a53ad688b1563ce4c416faec564" - integrity sha512-0baf1FhCp16LhN+xDJsOrSiaPDCTD3JegZptVmLDoEbFcT5aT+BeFGt3wcDU3olCP5tpTCXU5sv0+TsKWT9WGQ== + version "12.0.2" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.2.tgz#8db03205e36089a3df6954c66ce92541441ac46c" + integrity sha512-ifKgxH2CKhJEg6tNdAwziu6Q33EvuG26tYcda6PT3WKisZcYDXsnEdnRv67Po3yCzFfaSoMjGZzJyD2c3DT1dg== dependencies: bluebird "^3.5.5" chownr "^1.1.1" figgy-pudding "^3.5.1" glob "^7.1.4" graceful-fs "^4.1.15" + infer-owner "^1.0.3" lru-cache "^5.1.1" mississippi "^3.0.0" mkdirp "^0.5.1" @@ -485,6 +595,19 @@ cacache@^12.0.0: unique-filename "^1.1.1" y18n "^4.0.0" +cacheable-request@^2.1.1: + version "2.1.4" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-2.1.4.tgz#0d808801b6342ad33c91df9d0b44dc09b91e5c3d" + integrity sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0= + dependencies: + clone-response "1.0.2" + get-stream "3.0.0" + http-cache-semantics "3.8.1" + keyv "3.0.0" + lowercase-keys "1.0.0" + normalize-url "2.0.1" + responselike "1.0.2" + cacheable-request@^6.0.0: version "6.1.0" resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" @@ -513,6 +636,28 @@ caseless@~0.12.0: resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= +caw@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/caw/-/caw-2.0.1.tgz#6c3ca071fc194720883c2dc5da9b074bfc7e9e95" + integrity sha512-Cg8/ZSBEa8ZVY9HspcGUYaK63d/bN7rqS3CYCzEGUxuYv6UlmcjzDUz2fCFFHyTvUW5Pk0I+3hkA3iXlIj6guA== + dependencies: + get-proxy "^2.0.0" + isurl "^1.0.0-alpha5" + tunnel-agent "^0.6.0" + url-to-options "^1.0.1" + +chai@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/chai/-/chai-4.2.0.tgz#760aa72cf20e3795e84b12877ce0e83737aa29e5" + integrity sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw== + dependencies: + assertion-error "^1.1.0" + check-error "^1.0.2" + deep-eql "^3.0.1" + get-func-name "^2.0.0" + pathval "^1.1.0" + type-detect "^4.0.5" + chalk@^1.1.1: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" @@ -533,12 +678,15 @@ chalk@^2.0.1, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -checkpoint-store@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/checkpoint-store/-/checkpoint-store-1.1.0.tgz#04e4cb516b91433893581e6d4601a78e9552ea06" - integrity sha1-BOTLUWuRQziTWB5tRgGnjpVS6gY= - dependencies: - functional-red-black-tree "^1.0.1" +"charenc@>= 0.0.1": + version "0.0.2" + resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" + integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc= + +check-error@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" + integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= chownr@^1.1.1: version "1.1.2" @@ -593,7 +741,7 @@ cliui@^5.0.0: strip-ansi "^5.2.0" wrap-ansi "^5.1.0" -clone-response@^1.0.2: +clone-response@1.0.2, clone-response@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= @@ -634,17 +782,12 @@ command-exists@^1.2.8: resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.8.tgz#715acefdd1223b9c9b37110a149c6392c2852291" integrity sha512-PM54PkseWbiiD/mMsbvW351/u+dafwTJ0ye2qB60G1aGQP9j3xK2gmMDc+R34L3nDtx4qMCitXT75mkbkGJDLw== -commander@2.11.0: - version "2.11.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" - integrity sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ== - commander@2.15.1: version "2.15.1" resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag== -commander@^2.20.0, commander@~2.20.0: +commander@^2.20.0, commander@^2.8.1, commander@~2.20.0: version "2.20.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== @@ -671,6 +814,14 @@ concat-stream@^1.5.0: readable-stream "^2.2.2" typedarray "^0.0.6" +config-chain@^1.1.11: + version "1.1.12" + resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.12.tgz#0fde8d091200eb5e808caf25fe618c02f48e4efa" + integrity sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA== + dependencies: + ini "^1.3.4" + proto-list "~1.2.1" + configstore@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/configstore/-/configstore-4.0.0.tgz#5933311e95d3687efb592c528b922d9262d227e7" @@ -683,7 +834,7 @@ configstore@^4.0.0: write-file-atomic "^2.0.0" xdg-basedir "^3.0.0" -content-disposition@0.5.3: +content-disposition@0.5.3, content-disposition@^0.5.2: version "0.5.3" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== @@ -754,7 +905,7 @@ create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: ripemd160 "^2.0.1" sha.js "^2.4.0" -create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: +create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4, create-hmac@^1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== @@ -786,6 +937,11 @@ cross-spawn@^6.0.0: shebang-command "^1.2.0" which "^1.2.9" +"crypt@>= 0.0.1": + version "0.0.2" + resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" + integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs= + crypto-browserify@3.12.0: version "3.12.0" resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" @@ -851,7 +1007,7 @@ debug@^3.1.0: dependencies: ms "^2.1.1" -debug@^4.1.1: +debug@^4.1.0, debug@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== @@ -914,7 +1070,7 @@ decompress-unzip@^4.0.1: pify "^2.3.0" yauzl "^2.4.2" -decompress@^4.0.0: +decompress@^4.0.0, decompress@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/decompress/-/decompress-4.2.0.tgz#7aedd85427e5a92dacfe55674a7c505e96d01f9d" integrity sha1-eu3YVCflqS2s/lVnSnxQXpbQH50= @@ -928,6 +1084,13 @@ decompress@^4.0.0: pify "^2.3.0" strip-dirs "^2.0.0" +deep-eql@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" + integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== + dependencies: + type-detect "^4.0.0" + deep-extend@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" @@ -938,27 +1101,17 @@ deep-is@~0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= +deepmerge@^2.1.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-2.2.1.tgz#5d3ff22a01c00f645405a2fbc17d0778a1801170" + integrity sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA== + defer-to-connect@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.0.2.tgz#4bae758a314b034ae33902b5aac25a8dd6a8633e" integrity sha512-k09hcQcTDY+cwgiwa6PYKLm3jlagNzQ+RSvhjzESOGOx+MNOuXkxTfEvPrO1IOQ81tArCFYQgi631clB70RpQw== -deferred-leveldown@~1.2.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz#3acd2e0b75d1669924bc0a4b642851131173e1eb" - integrity sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA== - dependencies: - abstract-leveldown "~2.6.0" - -deferred-leveldown@~4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-4.0.2.tgz#0b0570087827bf480a23494b398f04c128c19a20" - integrity sha512-5fMC8ek8alH16QiV0lTCis610D1Zt1+LA4MS4d63JgS32lrCjTFDUFz2ao09/j2I4Bqb5jL4FZYwu7Jz0XO1ww== - dependencies: - abstract-leveldown "~5.0.0" - inherits "^2.0.3" - -define-properties@^1.1.2: +define-properties@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== @@ -988,11 +1141,6 @@ destroy@~1.0.4: resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= -diff@3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.3.1.tgz#aa8567a6eed03c531fc89d3f711cd0e5259dec75" - integrity sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww== - diff@3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" @@ -1019,6 +1167,24 @@ dot-prop@^4.1.0: dependencies: is-obj "^1.0.0" +download@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/download/-/download-7.1.0.tgz#9059aa9d70b503ee76a132897be6dec8e5587233" + integrity sha512-xqnBTVd/E+GxJVrX5/eUJiLYjCGPwMpdL+jGhGU57BvtcA7wwhtHVbXBeUk51kOpW3S7Jn3BQbN9Q1R1Km2qDQ== + dependencies: + archive-type "^4.0.0" + caw "^2.0.1" + content-disposition "^0.5.2" + decompress "^4.2.0" + ext-name "^5.0.0" + file-type "^8.1.0" + filenamify "^2.0.0" + get-stream "^3.0.0" + got "^8.3.1" + make-dir "^1.2.0" + p-event "^2.1.0" + pify "^3.0.0" + drbg.js@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/drbg.js/-/drbg.js-1.0.1.tgz#3e36b6c42b37043823cdbc332d58f31e2445480b" @@ -1089,17 +1255,6 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= -encoding-down@~5.0.0: - version "5.0.4" - resolved "https://registry.yarnpkg.com/encoding-down/-/encoding-down-5.0.4.tgz#1e477da8e9e9d0f7c8293d320044f8b2cd8e9614" - integrity sha512-8CIZLDcSKxgzT+zX8ZVfgNbu8Md2wq/iqa1Y7zyVR18QBEAc0Nmzuvj/N5ykSKpfGzjM8qxbaFntLPwnVoUhZw== - dependencies: - abstract-leveldown "^5.0.0" - inherits "^2.0.3" - level-codec "^9.0.0" - level-errors "^2.0.0" - xtend "^4.0.1" - encoding@^0.1.11: version "0.1.12" resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" @@ -1114,19 +1269,19 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0: dependencies: once "^1.4.0" +enquirer@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.1.tgz#f1bf52ea38470525f41412d723a62ba6868559c6" + integrity sha512-7slmHsJY+mvnIrzD0Z0FfTFLmVJuIzRNCW72X9s35BshOoC+MI4jLJ8aPyAC/BelAirXBZB+Mu1wSqP0wpW4Kg== + dependencies: + ansi-colors "^3.2.1" + err-code@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/err-code/-/err-code-1.1.2.tgz#06e0116d3028f6aef4806849eb0ea6a748ae6960" integrity sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA= -errno@~0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" - integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== - dependencies: - prr "~1.0.1" - -es-abstract@^1.5.0: +es-abstract@^1.13.0: version "1.13.0" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.13.0.tgz#ac86145fdd5099d8dd49558ccba2eaf9b88e24e9" integrity sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg== @@ -1197,9 +1352,9 @@ estraverse@^1.9.1: integrity sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q= esutils@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" - integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs= + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== etag@~1.8.1: version "1.8.1" @@ -1214,16 +1369,7 @@ eth-ens-namehash@2.0.8: idna-uts46-hx "^2.3.1" js-sha3 "^0.5.7" -eth-lib@0.2.8: - version "0.2.8" - resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.2.8.tgz#b194058bef4b220ad12ea497431d6cb6aa0623c8" - integrity sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw== - dependencies: - bn.js "^4.11.6" - elliptic "^6.4.0" - xhr-request-promise "^0.1.2" - -eth-lib@^0.1.26: +eth-lib@0.1.27, eth-lib@^0.1.26: version "0.1.27" resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.1.27.tgz#f0b0fd144f865d2d6bf8257a40004f2e75ca1dd6" integrity sha512-B8czsfkJYzn2UIEMwjc7Mbj+Cy72V+/OXH/tb44LV8jhrjizQJJ325xMOMyk3+ETa6r6oi0jsUY14+om8mQMWA== @@ -1236,80 +1382,29 @@ eth-lib@^0.1.26: ws "^3.0.0" xhr-request-promise "^0.1.2" -ethashjs@~0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/ethashjs/-/ethashjs-0.0.7.tgz#30bfe4196726690a0c59d3b8272e70d4d0c34bae" - integrity sha1-ML/kGWcmaQoMWdO4Jy5w1NDDS64= - dependencies: - async "^1.4.2" - buffer-xor "^1.0.3" - ethereumjs-util "^4.0.1" - miller-rabin "^4.0.0" - -ethereum-common@^0.0.18: - version "0.0.18" - resolved "https://registry.yarnpkg.com/ethereum-common/-/ethereum-common-0.0.18.tgz#2fdc3576f232903358976eb39da783213ff9523f" - integrity sha1-L9w1dvIykDNYl26znaeDIT/5Uj8= - -ethereumjs-account@^2.0.3, ethereumjs-account@~2.0.4: - version "2.0.5" - resolved "https://registry.yarnpkg.com/ethereumjs-account/-/ethereumjs-account-2.0.5.tgz#eeafc62de544cb07b0ee44b10f572c9c49e00a84" - integrity sha512-bgDojnXGjhMwo6eXQC0bY6UK2liSFUSMwwylOmQvZbSl/D7NXQ3+vrGO46ZeOgjGfxXmgIeVNDIiHw7fNZM4VA== +eth-lib@0.2.7: + version "0.2.7" + resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.2.7.tgz#2f93f17b1e23aec3759cd4a3fe20c1286a3fc1ca" + integrity sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco= dependencies: - ethereumjs-util "^5.0.0" - rlp "^2.0.0" - safe-buffer "^5.1.1" - -ethereumjs-block@~2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/ethereumjs-block/-/ethereumjs-block-2.2.0.tgz#8c6c3ab4a5eff0a16d9785fbeedbe643f4dbcbef" - integrity sha512-Ye+uG/L2wrp364Zihdlr/GfC3ft+zG8PdHcRtsBFNNH1CkOhxOwdB8friBU85n89uRZ9eIMAywCq0F4CwT1wAw== - dependencies: - async "^2.0.1" - ethereumjs-common "^1.1.0" - ethereumjs-tx "^1.2.2" - ethereumjs-util "^5.0.0" - merkle-patricia-tree "^2.1.2" - -ethereumjs-blockchain@^3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/ethereumjs-blockchain/-/ethereumjs-blockchain-3.4.0.tgz#92240da6ecd86b3d8d324df69510b381f26c966b" - integrity sha512-wxPSmt6EQjhbywkFbftKcb0qRFIZWocHMuDa8/AB4eWL/UPYalNcDyLaxYbrDytmhHid3Uu8G/tA3C/TxZBuOQ== - dependencies: - async "^2.6.1" - ethashjs "~0.0.7" - ethereumjs-block "~2.2.0" - ethereumjs-common "^1.1.0" - ethereumjs-util "~6.0.0" - flow-stoplight "^1.0.0" - level-mem "^3.0.1" - lru-cache "^5.1.1" - safe-buffer "^5.1.2" - semaphore "^1.1.0" + bn.js "^4.11.6" + elliptic "^6.4.0" + xhr-request-promise "^0.1.2" -ethereumjs-common@^1.1.0: +ethereumjs-common@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/ethereumjs-common/-/ethereumjs-common-1.3.0.tgz#ca7d152b615d5e1851fcf184d062bf14c62c18e6" integrity sha512-/jdFHyHOIS3FiAnunwRZ+oNulFtNNSHyWii3PaNHReOUmBAxij7KMyZLKh0tE16JEsJtXOVz1ceYuq++ILzv+g== -ethereumjs-testrpc-sc@^6.5.1-sc.0: - version "6.5.1-sc.0" - resolved "https://registry.yarnpkg.com/ethereumjs-testrpc-sc/-/ethereumjs-testrpc-sc-6.5.1-sc.0.tgz#c5986af4548776ebea35581ae6ae2518afb72faa" - integrity sha512-ZWhg3Rd64hAWSMM7DygDs7wITH9hDYPCvFypHkiLTiKu42wfl6QVJtkouelhtdyufzv2TFe7Lo0uOWS9NEiOqw== - dependencies: - ethereumjs-util "6.1.0" - source-map-support "0.5.12" - yargs "13.2.4" - -ethereumjs-tx@^1.2.2: - version "1.3.7" - resolved "https://registry.yarnpkg.com/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz#88323a2d875b10549b8347e09f4862b546f3d89a" - integrity sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA== +ethereumjs-tx@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ethereumjs-tx/-/ethereumjs-tx-2.1.0.tgz#36b9e6a46383b18941644ba5264e1b506115c002" + integrity sha512-q1PFhR5i93OjcoE0G3GGz7XvnpLiddcUSKr28hmMUzVHvvc/+PHmQTx4NrGQUUny7qBq9tEIcvMivdB7uphKtA== dependencies: - ethereum-common "^0.0.18" - ethereumjs-util "^5.0.0" + ethereumjs-common "^1.3.0" + ethereumjs-util "^6.0.0" -ethereumjs-util@6.1.0, ethereumjs-util@^6.0.0: +ethereumjs-util@6.1.0, ethereumjs-util@^6.0.0, ethereumjs-util@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.1.0.tgz#e9c51e5549e8ebd757a339cc00f5380507e799c8" integrity sha512-URESKMFbDeJxnAxPppnk2fN6Y3BIatn9fwn76Lm8bQlt+s52TpG8dN9M66MLPuRAiAOIqL3dfwqWJf0sd0fL0Q== @@ -1322,64 +1417,42 @@ ethereumjs-util@6.1.0, ethereumjs-util@^6.0.0: safe-buffer "^5.1.1" secp256k1 "^3.0.1" -ethereumjs-util@^4.0.0, ethereumjs-util@^4.0.1: - version "4.5.0" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-4.5.0.tgz#3e9428b317eebda3d7260d854fddda954b1f1bc6" - integrity sha1-PpQosxfuvaPXJg2FT93alUsfG8Y= - dependencies: - bn.js "^4.8.0" - create-hash "^1.1.2" - keccakjs "^0.2.0" - rlp "^2.0.0" - secp256k1 "^3.0.1" - -ethereumjs-util@^5.0.0, ethereumjs-util@^5.0.1: - version "5.2.0" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz#3e0c0d1741471acf1036052d048623dee54ad642" - integrity sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA== +ethers@4.0.0-beta.1: + version "4.0.0-beta.1" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.0-beta.1.tgz#0648268b83e0e91a961b1af971c662cdf8cbab6d" + integrity sha512-SoYhktEbLxf+fiux5SfCEwdzWENMvgIbMZD90I62s4GZD9nEjgEWy8ZboI3hck193Vs0bDoTohDISx84f2H2tw== dependencies: - bn.js "^4.11.0" - create-hash "^1.1.2" - ethjs-util "^0.1.3" - keccak "^1.0.2" - rlp "^2.0.0" - safe-buffer "^5.1.1" - secp256k1 "^3.0.1" + "@types/node" "^10.3.2" + aes-js "3.0.0" + bn.js "^4.4.0" + elliptic "6.3.3" + hash.js "1.1.3" + js-sha3 "0.5.7" + scrypt-js "2.0.3" + setimmediate "1.0.4" + uuid "2.0.1" + xmlhttprequest "1.8.0" -ethereumjs-util@~6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.0.0.tgz#f14841c182b918615afefd744207c7932c8536c0" - integrity sha512-E3yKUyl0Fs95nvTFQZe/ZSNcofhDzUsDlA5y2uoRmf1+Ec7gpGhNCsgKkZBRh7Br5op8mJcYF/jFbmjj909+nQ== +ethers@4.0.0-beta.3: + version "4.0.0-beta.3" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.0-beta.3.tgz#15bef14e57e94ecbeb7f9b39dd0a4bd435bc9066" + integrity sha512-YYPogooSknTwvHg3+Mv71gM/3Wcrx+ZpCzarBj3mqs9njjRkrOo2/eufzhHloOCo3JSoNI4TQJJ6yU5ABm3Uog== dependencies: - bn.js "^4.11.0" - create-hash "^1.1.2" - ethjs-util "^0.1.6" - keccak "^1.0.2" - rlp "^2.0.0" - safe-buffer "^5.1.1" - secp256k1 "^3.0.1" - -"ethereumjs-vm@https://github.com/sc-forks/ethereumjs-vm-sc.git#336d8841ab2c37da079d290ea5c5af6b34f20495": - version "3.0.0" - resolved "https://github.com/sc-forks/ethereumjs-vm-sc.git#336d8841ab2c37da079d290ea5c5af6b34f20495" - dependencies: - async "^2.1.2" - async-eventemitter "^0.2.2" - ethereumjs-account "^2.0.3" - ethereumjs-block "~2.2.0" - ethereumjs-blockchain "^3.4.0" - ethereumjs-common "^1.1.0" - ethereumjs-util "^6.0.0" - fake-merkle-patricia-tree "^1.0.1" - functional-red-black-tree "^1.0.1" - merkle-patricia-tree "^2.3.2" - rustbn.js "~0.2.0" - safe-buffer "^5.1.1" + "@types/node" "^10.3.2" + aes-js "3.0.0" + bn.js "^4.4.0" + elliptic "6.3.3" + hash.js "1.1.3" + js-sha3 "0.5.7" + scrypt-js "2.0.3" + setimmediate "1.0.4" + uuid "2.0.1" + xmlhttprequest "1.8.0" -ethers@^4.0.27: - version "4.0.32" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.32.tgz#46378864cb3bf29b57c2effd17508b560743abf6" - integrity sha512-r0k2tBNF6MYEsvwmINeP3VPppD/7eAZyiOk/ifDDawXGCKqr3iEQkPq6OZSDVD+4Jie38WPteS9thXzpn2+A5Q== +ethers@^4.0.0-beta.1, ethers@^4.0.32: + version "4.0.33" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.33.tgz#f7b88d2419d731a39aefc37843a3f293e396f918" + integrity sha512-lAHkSPzBe0Vj+JrhmkEHLtUEKEheVktIjGDyE9gbzF4zf1vibjYgB57LraDHu4/ItqWVkztgsm8GWqcDMN+6vQ== dependencies: "@types/node" "^10.3.2" aes-js "3.0.0" @@ -1392,7 +1465,7 @@ ethers@^4.0.27: uuid "2.0.1" xmlhttprequest "1.8.0" -ethjs-unit@^0.1.6: +ethjs-unit@0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/ethjs-unit/-/ethjs-unit-0.1.6.tgz#c665921e476e87bce2a9d588a6fe0405b2c41699" integrity sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk= @@ -1400,7 +1473,7 @@ ethjs-unit@^0.1.6: bn.js "4.11.6" number-to-bn "1.7.0" -ethjs-util@0.1.6, ethjs-util@^0.1.3, ethjs-util@^0.1.6: +ethjs-util@0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/ethjs-util/-/ethjs-util-0.1.6.tgz#f308b62f185f9fe6237132fb2a9818866a5cd536" integrity sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w== @@ -1408,12 +1481,17 @@ ethjs-util@0.1.6, ethjs-util@^0.1.3, ethjs-util@^0.1.6: is-hex-prefixed "1.0.0" strip-hex-prefix "1.0.0" -eventemitter3@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.0.tgz#090b4d6cdbd645ed10bf750d4b5407942d7ba163" - integrity sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA== +event-target-shim@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" + integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== + +eventemitter3@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-1.1.1.tgz#47786bdaa087caf7b1b75e73abc5c7d540158cd0" + integrity sha1-R3hr2qCHyvext15zq8XH1UAVjNA= -eventemitter3@^3.1.0: +eventemitter3@3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7" integrity sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q== @@ -1488,6 +1566,21 @@ express@^4.14.0: utils-merge "1.0.1" vary "~1.1.2" +ext-list@^2.0.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/ext-list/-/ext-list-2.2.2.tgz#0b98e64ed82f5acf0f2931babf69212ef52ddd37" + integrity sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA== + dependencies: + mime-db "^1.28.0" + +ext-name@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ext-name/-/ext-name-5.0.0.tgz#70781981d183ee15d13993c8822045c506c8f0a6" + integrity sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ== + dependencies: + ext-list "^2.0.0" + sort-keys-length "^1.0.0" + extend@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" @@ -1503,13 +1596,6 @@ extsprintf@^1.2.0: resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= -fake-merkle-patricia-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/fake-merkle-patricia-tree/-/fake-merkle-patricia-tree-1.0.1.tgz#4b8c3acfb520afadf9860b1f14cd8ce3402cddd3" - integrity sha1-S4w6z7Ugr635hgsfFM2M40As3dM= - dependencies: - checkpoint-store "^1.1.0" - fast-deep-equal@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" @@ -1547,6 +1633,11 @@ file-type@^3.8.0: resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9" integrity sha1-JXoHg4TR24CHvESdEH1SpSZyuek= +file-type@^4.2.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-4.4.0.tgz#1b600e5fca1fbdc6e80c0a70c71c8dba5f7906c5" + integrity sha1-G2AOX8ofvcboDApwxxyNul95BsU= + file-type@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/file-type/-/file-type-5.2.0.tgz#2ddbea7c73ffe36368dfae49dc338c058c2b8ad6" @@ -1557,11 +1648,30 @@ file-type@^6.1.0: resolved "https://registry.yarnpkg.com/file-type/-/file-type-6.2.0.tgz#e50cd75d356ffed4e306dc4f5bcf52a79903a919" integrity sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg== +file-type@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-8.1.0.tgz#244f3b7ef641bbe0cca196c7276e4b332399f68c" + integrity sha512-qyQ0pzAy78gVoJsmYeNgl8uH8yKhr1lVhW7JbzJmnlRi0I4R2eEDEJZVKG8agpDnLpacwNbDhLNG/LMdxHD2YQ== + file-uri-to-path@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== +filename-reserved-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz#abf73dfab735d045440abfea2d91f389ebbfa229" + integrity sha1-q/c9+rc10EVECr/qLZHzieu/oik= + +filenamify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/filenamify/-/filenamify-2.1.0.tgz#88faf495fb1b47abfd612300002a16228c677ee9" + integrity sha512-ICw7NTT6RsDp2rnYKVd8Fu4cr6ITzGy3+u4vUujPkabyaz+03F24NWEX7fs5fp+kBonlaqPH8fAO2NM+SXt/JA== + dependencies: + filename-reserved-regex "^2.0.0" + strip-outer "^1.0.0" + trim-repeated "^1.0.0" + finalhandler@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" @@ -1597,11 +1707,6 @@ find-up@^3.0.0: dependencies: locate-path "^3.0.0" -flow-stoplight@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/flow-stoplight/-/flow-stoplight-1.0.0.tgz#4a292c5bcff8b39fa6cc0cb1a853d86f27eeff7b" - integrity sha1-SiksW8/4s5+mzAyxqFPYbyfu/3s= - flush-write-stream@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" @@ -1636,12 +1741,22 @@ forwarded@~0.1.2: resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= +fp-ts@1.19.3: + version "1.19.3" + resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.3.tgz#261a60d1088fbff01f91256f91d21d0caaaaa96f" + integrity sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg== + +fp-ts@^1.0.0: + version "1.19.5" + resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.5.tgz#3da865e585dfa1fdfd51785417357ac50afc520a" + integrity sha512-wDNqTimnzs8QqpldiId9OavWK2NptormjXnRJTQecNjzwfyp6P/8s/zG8e4h3ja3oqkKaY72UlTjQYt/1yXf9A== + fresh@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= -from2@^2.1.0: +from2@^2.1.0, from2@^2.1.1: version "2.3.0" resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= @@ -1665,6 +1780,14 @@ fs-extra@^0.30.0: path-is-absolute "^1.0.0" rimraf "^2.2.8" +fs-extra@^2.0.0, fs-extra@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-2.1.2.tgz#046c70163cef9aad46b0e4a7fa467fb22d71de35" + integrity sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU= + dependencies: + graceful-fs "^4.1.2" + jsonfile "^2.1.0" + fs-extra@^4.0.2: version "4.0.3" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" @@ -1674,6 +1797,15 @@ fs-extra@^4.0.2: jsonfile "^4.0.0" universalify "^0.1.0" +fs-extra@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" + integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + fs-minipass@^1.2.5: version "1.2.6" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.6.tgz#2c5cc30ded81282bfe8a0d7c7c1853ddeb102c07" @@ -1681,6 +1813,16 @@ fs-minipass@^1.2.5: dependencies: minipass "^2.2.1" +fs-promise@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/fs-promise/-/fs-promise-2.0.3.tgz#f64e4f854bcf689aa8bddcba268916db3db46854" + integrity sha1-9k5PhUvPaJqovdy6JokW2z20aFQ= + dependencies: + any-promise "^1.3.0" + fs-extra "^2.0.0" + mz "^2.6.0" + thenify-all "^1.6.0" + fs-write-stream-atomic@^1.0.8: version "1.0.10" resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" @@ -1696,15 +1838,29 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -function-bind@^1.0.2, function-bind@^1.1.1: +fstream@^1.0.12, fstream@^1.0.8: + version "1.0.12" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045" + integrity sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg== + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + +function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== -functional-red-black-tree@^1.0.1, functional-red-black-tree@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= +ganache-cli@^6.5.0: + version "6.5.1" + resolved "https://registry.yarnpkg.com/ganache-cli/-/ganache-cli-6.5.1.tgz#aaa1feaaa3d58f8ba488edd321a5c5522d1176bf" + integrity sha512-0+BoZmA/lrYVektfBTtn8CY/laEptrCl1LMtISLcNEEaLugxOrq0saXAtJTqvSpxdkCNdaTA92Dk8NKANyIuzw== + dependencies: + ethereumjs-util "6.1.0" + source-map-support "0.5.12" + yargs "13.2.4" genfun@^5.0.0: version "5.0.0" @@ -1721,11 +1877,28 @@ get-caller-file@^2.0.1: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== +get-func-name@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" + integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= + +get-proxy@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/get-proxy/-/get-proxy-2.1.0.tgz#349f2b4d91d44c4d4d4e9cba2ad90143fac5ef93" + integrity sha512-zmZIaQTWnNQb4R4fJUEp/FC51eZsc6EkErspy3xtIYStaq8EB/hDIWipxsal+E8rz0qD7f2sL/NA9Xee4RInJw== + dependencies: + npm-conf "^1.1.0" + get-stdin@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-7.0.0.tgz#8d5de98f15171a125c5e516643c7a6d0ea8a96f6" integrity sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ== +get-stream@3.0.0, get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= + get-stream@^2.2.0: version "2.3.1" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de" @@ -1734,11 +1907,6 @@ get-stream@^2.2.0: object-assign "^4.0.1" pinkie-promise "^2.0.0" -get-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" - integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= - get-stream@^4.0.0, get-stream@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" @@ -1795,7 +1963,7 @@ glob@^7.0.0, glob@^7.1.3, glob@^7.1.4: once "^1.3.0" path-is-absolute "^1.0.0" -global-dirs@^0.1.0: +global-dirs@^0.1.0, global-dirs@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" integrity sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU= @@ -1810,7 +1978,7 @@ global@~4.3.0: min-document "^2.19.0" process "~0.5.1" -got@^7.1.0: +got@7.1.0, got@^7.1.0: version "7.1.0" resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a" integrity sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw== @@ -1830,7 +1998,7 @@ got@^7.1.0: url-parse-lax "^1.0.0" url-to-options "^1.0.1" -got@^9.6.0: +got@9.6.0, got@^9.6.0: version "9.6.0" resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== @@ -1847,6 +2015,29 @@ got@^9.6.0: to-readable-stream "^1.0.0" url-parse-lax "^3.0.0" +got@^8.3.1: + version "8.3.2" + resolved "https://registry.yarnpkg.com/got/-/got-8.3.2.tgz#1d23f64390e97f776cac52e5b936e5f514d2e937" + integrity sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw== + dependencies: + "@sindresorhus/is" "^0.7.0" + cacheable-request "^2.1.1" + decompress-response "^3.3.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + into-stream "^3.1.0" + is-retry-allowed "^1.1.0" + isurl "^1.0.0-alpha5" + lowercase-keys "^1.0.0" + mimic-response "^1.0.0" + p-cancelable "^0.4.0" + p-timeout "^2.0.1" + pify "^3.0.0" + safe-buffer "^5.1.1" + timed-out "^4.0.1" + url-parse-lax "^3.0.0" + url-to-options "^1.0.1" + graceful-fs@^4.1.10, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9: version "4.2.0" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.0.tgz#8d8fdc73977cb04104721cb53666c1ca64cd328b" @@ -1857,11 +2048,6 @@ graceful-fs@^4.1.10, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1. resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU= -growl@1.10.3: - version "1.10.3" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.3.tgz#1926ba90cf3edfe2adb4927f5880bc22c66c790f" - integrity sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q== - growl@1.10.5: version "1.10.5" resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" @@ -1903,11 +2089,6 @@ has-flag@^1.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo= -has-flag@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" - integrity sha1-6CB68cx7MNRGzHC3NLXovhj4jVE= - has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -1985,7 +2166,7 @@ hosted-git-info@^2.1.4, hosted-git-info@^2.6.0: resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" integrity sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w== -http-cache-semantics@^3.8.1: +http-cache-semantics@3.8.1, http-cache-semantics@^3.8.1: version "3.8.1" resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w== @@ -2017,7 +2198,12 @@ http-errors@~1.7.2: statuses ">= 1.5.0 < 2" toidentifier "1.0.0" -http-proxy-agent@^2.1.0: +http-https@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/http-https/-/http-https-1.0.0.tgz#2f908dd5f1db4068c058cd6e6d4ce392c913389b" + integrity sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs= + +http-proxy-agent@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405" integrity sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg== @@ -2080,11 +2266,6 @@ ignore-walk@^3.0.1: dependencies: minimatch "^3.0.4" -immediate@^3.2.3, immediate@~3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.2.3.tgz#d140fa8f614659bd6541233097ddaac25cdd991c" - integrity sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw= - import-lazy@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" @@ -2095,6 +2276,11 @@ imurmurhash@^0.1.4: resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= +infer-owner@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" + integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== + inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -2103,7 +2289,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -2123,6 +2309,14 @@ interpret@^1.0.0: resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296" integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw== +into-stream@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-3.1.0.tgz#96fb0a936c12babd6ff1752a17d05616abd094c6" + integrity sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY= + dependencies: + from2 "^2.1.1" + p-is-promise "^1.1.0" + invert-kv@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" @@ -2133,6 +2327,13 @@ invert-kv@^2.0.0: resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== +io-ts@1.10.4: + version "1.10.4" + resolved "https://registry.yarnpkg.com/io-ts/-/io-ts-1.10.4.tgz#cd5401b138de88e4f920adbcb7026e2d1967e6e2" + integrity sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g== + dependencies: + fp-ts "^1.0.0" + ip@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" @@ -2190,6 +2391,14 @@ is-installed-globally@^0.1.0: global-dirs "^0.1.0" is-path-inside "^1.0.0" +is-installed-globally@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.2.0.tgz#8cde07ade508458b51f14bcda315ffaf4898de30" + integrity sha512-g3TzWCnR/eO4Q3abCwgFjOFw7uVOfxG4m8hMr/39Jcf2YvE5mHrFKqpyuraWV4zwx9XhjnVO4nY0ZI4llzl0Pg== + dependencies: + global-dirs "^0.1.1" + is-path-inside "^2.1.0" + is-natural-number@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/is-natural-number/-/is-natural-number-4.0.1.tgz#ab9d76e1db4ced51e35de0c72ebecf09f734cde8" @@ -2217,7 +2426,14 @@ is-path-inside@^1.0.0: dependencies: path-is-inside "^1.0.1" -is-plain-obj@^1.1.0: +is-path-inside@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-2.1.0.tgz#7c9810587d659a40d27bcdb4d5616eab059494b2" + integrity sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg== + dependencies: + path-is-inside "^1.0.2" + +is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= @@ -2229,7 +2445,7 @@ is-regex@^1.0.4: dependencies: has "^1.0.1" -is-retry-allowed@^1.0.0: +is-retry-allowed@^1.0.0, is-retry-allowed@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" integrity sha1-EaBgVotnM5REAz0BJaYaINVk+zQ= @@ -2256,11 +2472,6 @@ is-yarn-global@^0.3.0: resolved "https://registry.yarnpkg.com/is-yarn-global/-/is-yarn-global-0.3.0.tgz#d502d3382590ea3004893746754c89139973e232" integrity sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw== -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= - isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -2410,7 +2621,7 @@ keccak@^1.0.2: nan "^2.2.1" safe-buffer "^5.1.0" -keccakjs@^0.2.0, keccakjs@^0.2.1: +keccakjs@^0.2.1: version "0.2.3" resolved "https://registry.yarnpkg.com/keccakjs/-/keccakjs-0.2.3.tgz#5e4e969ce39689a3861f445d7752ee3477f9fe72" integrity sha512-BjLkNDcfaZ6l8HBG9tH0tpmDv3sS2mA7FNQxFHpCdzP3Gb2MVruXBSuoM66SnVxKJpAr5dKGdkHD+bDokt8fTg== @@ -2418,6 +2629,13 @@ keccakjs@^0.2.0, keccakjs@^0.2.1: browserify-sha3 "^0.0.4" sha3 "^1.2.2" +keyv@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.0.0.tgz#44923ba39e68b12a7cec7df6c3268c031f2ef373" + integrity sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA== + dependencies: + json-buffer "3.0.0" + keyv@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" @@ -2458,103 +2676,6 @@ lcid@^2.0.0: dependencies: invert-kv "^2.0.0" -level-codec@^9.0.0: - version "9.0.1" - resolved "https://registry.yarnpkg.com/level-codec/-/level-codec-9.0.1.tgz#042f4aa85e56d4328ace368c950811ba802b7247" - integrity sha512-ajFP0kJ+nyq4i6kptSM+mAvJKLOg1X5FiFPtLG9M5gCEZyBmgDi3FkDrvlMkEzrUn1cWxtvVmrvoS4ASyO/q+Q== - -level-codec@~7.0.0: - version "7.0.1" - resolved "https://registry.yarnpkg.com/level-codec/-/level-codec-7.0.1.tgz#341f22f907ce0f16763f24bddd681e395a0fb8a7" - integrity sha512-Ua/R9B9r3RasXdRmOtd+t9TCOEIIlts+TN/7XTT2unhDaL6sJn83S3rUyljbr6lVtw49N3/yA0HHjpV6Kzb2aQ== - -level-errors@^1.0.3: - version "1.1.2" - resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-1.1.2.tgz#4399c2f3d3ab87d0625f7e3676e2d807deff404d" - integrity sha512-Sw/IJwWbPKF5Ai4Wz60B52yj0zYeqzObLh8k1Tk88jVmD51cJSKWSYpRyhVIvFzZdvsPqlH5wfhp/yxdsaQH4w== - dependencies: - errno "~0.1.1" - -level-errors@^2.0.0, level-errors@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-2.0.1.tgz#2132a677bf4e679ce029f517c2f17432800c05c8" - integrity sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw== - dependencies: - errno "~0.1.1" - -level-errors@~1.0.3: - version "1.0.5" - resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-1.0.5.tgz#83dbfb12f0b8a2516bdc9a31c4876038e227b859" - integrity sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig== - dependencies: - errno "~0.1.1" - -level-iterator-stream@~1.3.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz#e43b78b1a8143e6fa97a4f485eb8ea530352f2ed" - integrity sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0= - dependencies: - inherits "^2.0.1" - level-errors "^1.0.3" - readable-stream "^1.0.33" - xtend "^4.0.0" - -level-iterator-stream@~3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-3.0.1.tgz#2c98a4f8820d87cdacab3132506815419077c730" - integrity sha512-nEIQvxEED9yRThxvOrq8Aqziy4EGzrxSZK+QzEFAVuJvQ8glfyZ96GB6BoI4sBbLfjMXm2w4vu3Tkcm9obcY0g== - dependencies: - inherits "^2.0.1" - readable-stream "^2.3.6" - xtend "^4.0.0" - -level-mem@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/level-mem/-/level-mem-3.0.1.tgz#7ce8cf256eac40f716eb6489654726247f5a89e5" - integrity sha512-LbtfK9+3Ug1UmvvhR2DqLqXiPW1OJ5jEh0a3m9ZgAipiwpSxGj/qaVVy54RG5vAQN1nCuXqjvprCuKSCxcJHBg== - dependencies: - level-packager "~4.0.0" - memdown "~3.0.0" - -level-packager@~4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/level-packager/-/level-packager-4.0.1.tgz#7e7d3016af005be0869bc5fa8de93d2a7f56ffe6" - integrity sha512-svCRKfYLn9/4CoFfi+d8krOtrp6RoX8+xm0Na5cgXMqSyRru0AnDYdLl+YI8u1FyS6gGZ94ILLZDE5dh2but3Q== - dependencies: - encoding-down "~5.0.0" - levelup "^3.0.0" - -level-ws@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/level-ws/-/level-ws-0.0.0.tgz#372e512177924a00424b0b43aef2bb42496d228b" - integrity sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos= - dependencies: - readable-stream "~1.0.15" - xtend "~2.1.1" - -levelup@^1.2.1: - version "1.3.9" - resolved "https://registry.yarnpkg.com/levelup/-/levelup-1.3.9.tgz#2dbcae845b2bb2b6bea84df334c475533bbd82ab" - integrity sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ== - dependencies: - deferred-leveldown "~1.2.1" - level-codec "~7.0.0" - level-errors "~1.0.3" - level-iterator-stream "~1.3.0" - prr "~1.0.1" - semver "~5.4.1" - xtend "~4.0.0" - -levelup@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/levelup/-/levelup-3.1.1.tgz#c2c0b3be2b4dc316647c53b42e2f559e232d2189" - integrity sha512-9N10xRkUU4dShSRRFTBdNaBxofz+PGaIZO962ckboJZiNmLuhVT6FZ6ZKAsICKfUBO76ySaYU6fJWX/jnj3Lcg== - dependencies: - deferred-leveldown "~4.0.0" - level-errors "~2.0.0" - level-iterator-stream "~3.0.0" - xtend "~4.0.0" - levn@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" @@ -2595,21 +2716,16 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" -lodash@^4.17.11: - version "4.17.11" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" - integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== - -lodash@^4.17.13, lodash@^4.2.0: - version "4.17.14" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.14.tgz#9ce487ae66c96254fe20b599f21b6816028078ba" - integrity sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw== - -lodash@^4.17.14: +lodash@^4.17.11, lodash@^4.17.13, lodash@^4.2.0: version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== +lowercase-keys@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" + integrity sha1-TjNms55/VFfjXxMkvfb4jQv8cwY= + lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" @@ -2635,12 +2751,7 @@ lru-cache@^5.1.1: dependencies: yallist "^3.0.2" -ltgt@~2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.2.1.tgz#f35ca91c493f7b73da0e07495304f17b31f87ee5" - integrity sha1-81ypHEk/e3PaDgdJUwTxezH4fuU= - -make-dir@^1.0.0: +make-dir@^1.0.0, make-dir@^1.2.0: version "1.3.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== @@ -2701,30 +2812,6 @@ mem@^4.0.0: mimic-fn "^2.0.0" p-is-promise "^2.0.0" -memdown@^1.0.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/memdown/-/memdown-1.4.1.tgz#b4e4e192174664ffbae41361aa500f3119efe215" - integrity sha1-tOThkhdGZP+65BNhqlAPMRnv4hU= - dependencies: - abstract-leveldown "~2.7.1" - functional-red-black-tree "^1.0.1" - immediate "^3.2.3" - inherits "~2.0.1" - ltgt "~2.2.0" - safe-buffer "~5.1.1" - -memdown@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/memdown/-/memdown-3.0.0.tgz#93aca055d743b20efc37492e9e399784f2958309" - integrity sha512-tbV02LfZMWLcHcq4tw++NuqMO+FZX8tNJEiD2aNRm48ZZusVg5N8NART+dmBkepJVye986oixErf7jfXboMGMA== - dependencies: - abstract-leveldown "~5.0.0" - functional-red-black-tree "~1.0.1" - immediate "~3.2.3" - inherits "~2.0.1" - ltgt "~2.2.0" - safe-buffer "~5.1.1" - memorystream@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" @@ -2735,34 +2822,6 @@ merge-descriptors@1.0.1: resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= -merkle-patricia-tree@^2.1.2, merkle-patricia-tree@^2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz#982ca1b5a0fde00eed2f6aeed1f9152860b8208a" - integrity sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g== - dependencies: - async "^1.4.2" - ethereumjs-util "^5.0.0" - level-ws "0.0.0" - levelup "^1.2.1" - memdown "^1.0.0" - readable-stream "^2.0.0" - rlp "^2.0.0" - semaphore ">=1.0.1" - -merkle-patricia-tree@~2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-2.1.2.tgz#724483d54b75631a48fedda55e114051706a7291" - integrity sha1-ckSD1Ut1YxpI/t2lXhFAUXBqcpE= - dependencies: - async "^1.4.2" - ethereumjs-util "^4.0.0" - level-ws "0.0.0" - levelup "^1.2.1" - memdown "^1.0.0" - readable-stream "^2.0.0" - rlp "^2.0.0" - semaphore ">=1.0.1" - methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" @@ -2776,7 +2835,7 @@ miller-rabin@^4.0.0: bn.js "^4.0.0" brorand "^1.0.1" -mime-db@1.40.0: +mime-db@1.40.0, mime-db@^1.28.0: version "1.40.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.40.0.tgz#a65057e998db090f732a68f6c276d387d4126c32" integrity sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA== @@ -2885,14 +2944,14 @@ mkdirp-promise@^5.0.1: dependencies: mkdirp "*" -mkdirp@*, mkdirp@0.5.1, mkdirp@0.5.x, mkdirp@^0.5.0, mkdirp@^0.5.1: +mkdirp@*, mkdirp@0.5.1, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= dependencies: minimist "0.0.8" -mocha@5.2.0: +mocha@5.2.0, mocha@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.2.0.tgz#6d8ae508f59167f940f2b5b3c4a612ae50c90ae6" integrity sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ== @@ -2909,27 +2968,16 @@ mocha@5.2.0: mkdirp "0.5.1" supports-color "5.4.0" -mocha@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-4.1.0.tgz#7d86cfbcf35cb829e2754c32e17355ec05338794" - integrity sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA== - dependencies: - browser-stdout "1.3.0" - commander "2.11.0" - debug "3.1.0" - diff "3.3.1" - escape-string-regexp "1.0.5" - glob "7.1.2" - growl "1.10.3" - he "1.1.1" - mkdirp "0.5.1" - supports-color "4.4.0" - mock-fs@^4.1.0: version "4.10.1" resolved "https://registry.yarnpkg.com/mock-fs/-/mock-fs-4.10.1.tgz#50a07a20114a6cdb119f35762f61f46266a1e323" integrity sha512-w22rOL5ZYu6HbUehB5deurghGM0hS/xBVyHMGKOuQctkk93J9z9VEOhDsiWrXOprVNQpP9uzGKdl8v9mFspKuw== +mout@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/mout/-/mout-0.11.1.tgz#ba3611df5f0e5b1ffbfd01166b8f02d1f5fa2b99" + integrity sha1-ujYR318OWx/7/QEWa48C0fX6K5k= + move-concurrently@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" @@ -2957,12 +3005,21 @@ ms@^2.0.0, ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +mz@^2.6.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" + integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== + dependencies: + any-promise "^1.0.0" + object-assign "^4.0.1" + thenify-all "^1.0.0" + nan@2.13.2: version "2.13.2" resolved "https://registry.yarnpkg.com/nan/-/nan-2.13.2.tgz#f51dc7ae66ba7d5d55e1e6d4d8092e802c9aefe7" integrity sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw== -nan@^2.0.8, nan@^2.14.0, nan@^2.2.1, nan@^2.3.3: +nan@^2.0.8, nan@^2.13.2, nan@^2.14.0, nan@^2.2.1, nan@^2.3.3: version "2.14.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== @@ -3009,6 +3066,11 @@ node-fetch-npm@^2.0.2: json-parse-better-errors "^1.0.0" safe-buffer "^5.1.1" +node-fetch@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd" + integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA== + nopt@3.x: version "3.0.6" resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" @@ -3026,6 +3088,15 @@ normalize-package-data@^2.4.0: semver "2 || 3 || 4 || 5" validate-npm-package-license "^3.0.1" +normalize-url@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-2.0.1.tgz#835a9da1551fa26f70e92329069a23aa6574d7e6" + integrity sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw== + dependencies: + prepend-http "^2.0.0" + query-string "^5.0.1" + sort-keys "^2.0.0" + normalize-url@^4.1.0: version "4.3.0" resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.3.0.tgz#9c49e10fc1876aeb76dba88bf1b2b5d9fa57b2ee" @@ -3062,6 +3133,14 @@ npm-check-updates@^3.1.11: spawn-please "^0.3.0" update-notifier "^3.0.1" +npm-conf@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/npm-conf/-/npm-conf-1.1.3.tgz#256cc47bd0e218c259c4e9550bf413bc2192aff9" + integrity sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw== + dependencies: + config-chain "^1.1.11" + pify "^3.0.0" + npm-package-arg@^6.0.0, npm-package-arg@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-6.1.0.tgz#15ae1e2758a5027efb4c250554b85a737db7fcc1" @@ -3136,10 +3215,19 @@ object-keys@^1.0.12: resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== -object-keys@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.4.0.tgz#28a6aae7428dd2c3a92f3d95f21335dd204e0336" - integrity sha1-KKaq50KN0sOpLz2V8hM13SBOAzY= +oboe@2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/oboe/-/oboe-2.1.3.tgz#2b4865dbd46be81225713f4e9bfe4bcf4f680a4f" + integrity sha1-K0hl29Rr6BIlcT9Om/5Lz09oCk8= + dependencies: + http-https "^1.0.0" + +oboe@2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/oboe/-/oboe-2.1.4.tgz#20c88cdb0c15371bb04119257d4fdd34b0aa49f6" + integrity sha1-IMiM2wwVNxuwQRklfU/dNLCqSfY= + dependencies: + http-https "^1.0.0" on-finished@~2.3.0: version "2.3.0" @@ -3221,6 +3309,11 @@ p-cancelable@^0.3.0: resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa" integrity sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw== +p-cancelable@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.4.1.tgz#35f363d67d52081c8d9585e37bcceb7e0bbcb2a0" + integrity sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ== + p-cancelable@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" @@ -3231,11 +3324,23 @@ p-defer@^1.0.0: resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= +p-event@^2.1.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/p-event/-/p-event-2.3.1.tgz#596279ef169ab2c3e0cae88c1cfbb08079993ef6" + integrity sha512-NQCqOFhbpVTMX4qMe8PF8lbGtzZ+LCiN7pcNrb/413Na7+TRoe1xkKUzuWa/YEJdGQ0FvKtj35EEbDoVPO2kbA== + dependencies: + p-timeout "^2.0.1" + p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= +p-is-promise@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e" + integrity sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4= + p-is-promise@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" @@ -3283,6 +3388,13 @@ p-timeout@^1.1.1: dependencies: p-finally "^1.0.0" +p-timeout@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-2.0.1.tgz#d8dd1979595d2dc0139e1fe46b8b646cb3cdf038" + integrity sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA== + dependencies: + p-finally "^1.0.0" + p-try@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" @@ -3294,14 +3406,14 @@ p-try@^2.0.0: integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== package-json@^6.3.0: - version "6.4.0" - resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.4.0.tgz#4f626976604f4a9a41723ce1792b204a60b1b61e" - integrity sha512-bd1T8OBG7hcvMd9c/udgv6u5v9wISP3Oyl9Cm7Weop8EFwrtcQDnS2sb6zhwqus2WslSr5wSTIPiTTpxxmPm7Q== + version "6.5.0" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0" + integrity sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ== dependencies: got "^9.6.0" - registry-auth-token "^3.4.0" + registry-auth-token "^4.0.0" registry-url "^5.0.0" - semver "^6.1.1" + semver "^6.2.0" pacote@^9.5.1: version "9.5.4" @@ -3385,7 +3497,7 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= -path-is-inside@^1.0.1: +path-is-inside@^1.0.1, path-is-inside@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= @@ -3405,7 +3517,12 @@ path-to-regexp@0.1.7: resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= -pbkdf2@^3.0.3: +pathval@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0" + integrity sha1-uULm1L3mUwBe9rcTYd74cn0GReA= + +pbkdf2@^3.0.3, pbkdf2@^3.0.9: version "3.0.17" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA== @@ -3499,6 +3616,11 @@ prompts@^2.1.0: kleur "^3.0.2" sisteransi "^1.0.0" +proto-list@~1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" + integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= + protoduck@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/protoduck/-/protoduck-5.0.1.tgz#03c3659ca18007b69a50fd82a7ebcc516261151f" @@ -3514,20 +3636,15 @@ proxy-addr@~2.0.5: forwarded "~0.1.2" ipaddr.js "1.9.0" -prr@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" - integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= - pseudomap@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= psl@^1.1.24: - version "1.2.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.2.0.tgz#df12b5b1b3a30f51c329eacbdef98f3a6e136dc6" - integrity sha512-GEn74ZffufCmkDDLNcl3uuyF/aSD6exEyh1v/ZSdAomB82t6G9hzJVRx0jBmLDW+VfZqks3aScmMw9DszwUalA== + version "1.3.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.3.0.tgz#e1ebf6a3b5564fa8376f3da2275da76d875ca1bd" + integrity sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag== public-encrypt@^4.0.0: version "4.0.3" @@ -3581,7 +3698,7 @@ punycode@^2.1.0: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== -qs@6.7.0: +qs@6.7.0, qs@^6.7.0: version "6.7.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== @@ -3600,11 +3717,6 @@ query-string@^5.0.1: object-assign "^4.1.0" strict-uri-encode "^1.0.0" -querystringify@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.1.tgz#60e5a5fd64a7f8bfa4d2ab2ed6fdf4c85bad154e" - integrity sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA== - randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" @@ -3653,7 +3765,7 @@ rc-config-loader@^2.0.4: path-exists "^3.0.0" require-from-string "^2.0.2" -rc@^1.1.6, rc@^1.2.8, rc@~1.2.7: +rc@^1.2.8, rc@~1.2.7: version "1.2.8" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== @@ -3676,26 +3788,6 @@ rc@^1.1.6, rc@^1.2.8, rc@~1.2.7: string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@^1.0.33: - version "1.1.14" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" - integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - -readable-stream@~1.0.15: - version "1.0.34" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" - integrity sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw= - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - rechoir@^0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" @@ -3703,17 +3795,12 @@ rechoir@^0.6.2: dependencies: resolve "^1.1.6" -regenerator-runtime@^0.13.2: - version "0.13.2" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz#32e59c9a6fb9b1a4aff09b4930ca2d4477343447" - integrity sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA== - -registry-auth-token@^3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.4.0.tgz#d7446815433f5d5ed6431cd5dca21048f66b397e" - integrity sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A== +registry-auth-token@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.0.0.tgz#30e55961eec77379da551ea5c4cf43cbf03522be" + integrity sha512-lpQkHxd9UL6tb3k/aHAVfnVtn+Bcs9ob5InuFLLEDqSqeq+AljB8GZW9xY0x7F+xYwEcjKe07nyoxzEYz6yvkw== dependencies: - rc "^1.1.6" + rc "^1.2.8" safe-buffer "^5.0.1" registry-url@^5.0.0: @@ -3737,7 +3824,7 @@ req-from@^1.0.1: dependencies: resolve-from "^2.0.0" -request@^2.79.0, request@^2.88.0: +request@^2.79.0: version "2.88.0" resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== @@ -3792,11 +3879,6 @@ requireg@^0.2.2: rc "~1.2.7" resolve "~1.7.1" -requires-port@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" - integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= - resolve-from@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57" @@ -3808,9 +3890,9 @@ resolve@1.1.x: integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= resolve@^1.1.6, resolve@^1.10.0: - version "1.11.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.11.1.tgz#ea10d8110376982fef578df8fc30b9ac30a07a3e" - integrity sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw== + version "1.12.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.12.0.tgz#3fc644a35c84a48554609ff26ec52b66fa577df6" + integrity sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w== dependencies: path-parse "^1.0.6" @@ -3821,7 +3903,7 @@ resolve@~1.7.1: dependencies: path-parse "^1.0.5" -responselike@^1.0.2: +responselike@1.0.2, responselike@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= @@ -3833,7 +3915,7 @@ retry@^0.10.0: resolved "https://registry.yarnpkg.com/retry/-/retry-0.10.1.tgz#e76388d217992c252750241d3d3956fed98d8ff4" integrity sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q= -rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.2, rimraf@^2.6.3: +rimraf@2, rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.2, rimraf@^2.6.3: version "2.6.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== @@ -3863,18 +3945,6 @@ run-queue@^1.0.0, run-queue@^1.0.3: dependencies: aproba "^1.1.1" -rustbn.js@~0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/rustbn.js/-/rustbn.js-0.2.0.tgz#8082cb886e707155fd1cb6f23bd591ab8d55d0ca" - integrity sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA== - -rxjs@^6.4.0: - version "6.5.2" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.2.tgz#2e35ce815cd46d84d02a209fb4e5921e051dbec7" - integrity sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg== - dependencies: - tslib "^1.9.0" - safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" @@ -3890,6 +3960,11 @@ safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== +scrypt-js@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-2.0.3.tgz#bb0040be03043da9a012a2cea9fc9f852cfc87d4" + integrity sha1-uwBAvgMEPamgEqLOqfyfhSz8h9Q= + scrypt-js@2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-2.0.4.tgz#32f8c5149f0797672e551c07e230f834b6af5f16" @@ -3903,6 +3978,15 @@ scrypt.js@0.2.0: scrypt "^6.0.2" scryptsy "^1.2.1" +scrypt.js@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/scrypt.js/-/scrypt.js-0.3.0.tgz#6c62d61728ad533c8c376a2e5e3e86d41a95c4c0" + integrity sha512-42LTc1nyFsyv/o0gcHtDztrn+aqpkaCNt5Qh7ATBZfhEZU7IC/0oT/qbBH+uRNoAPvs2fwiOId68FDEoSRA8/A== + dependencies: + scryptsy "^1.2.1" + optionalDependencies: + scrypt "^6.0.2" + scrypt@^6.0.2: version "6.0.3" resolved "https://registry.yarnpkg.com/scrypt/-/scrypt-6.0.3.tgz#04e014a5682b53fa50c2d5cce167d719c06d870d" @@ -3938,11 +4022,6 @@ seek-bzip@^1.0.5: dependencies: commander "~2.8.1" -semaphore@>=1.0.1, semaphore@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/semaphore/-/semaphore-1.1.0.tgz#aaad8b86b20fe8e9b32b16dc2ee682a8cd26a8aa" - integrity sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA== - semver-diff@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" @@ -3960,15 +4039,10 @@ semver-utils@^1.1.4: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA== -semver@^6.1.1, semver@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.2.0.tgz#4d813d9590aaf8a9192693d6c85b9344de5901db" - integrity sha512-jdFC1VdUGT/2Scgbimf7FSx9iJLXoqfglSF+gJeuNWVpiE37OIbc1jywR/GJyFdz3mnkz2/id0L0J/cr0izR5A== - -semver@~5.4.1: - version "5.4.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" - integrity sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg== +semver@^6.2.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== send@0.17.1: version "0.17.1" @@ -4038,6 +4112,14 @@ sha.js@^2.4.0, sha.js@^2.4.8: inherits "^2.0.1" safe-buffer "^5.0.1" +sha1@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/sha1/-/sha1-1.1.1.tgz#addaa7a93168f393f19eb2b15091618e2700f848" + integrity sha1-rdqnqTFo85PxnrKxUJFhjicA+Eg= + dependencies: + charenc ">= 0.0.1" + crypt ">= 0.0.1" + sha3@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/sha3/-/sha3-1.2.3.tgz#ed5958fa8331df1b1b8529ca9fdf225a340c5418" @@ -4111,12 +4193,21 @@ socks@~2.3.2: ip "^1.1.5" smart-buffer "4.0.2" -sol-explore@^1.6.2: - version "1.6.2" - resolved "https://registry.yarnpkg.com/sol-explore/-/sol-explore-1.6.2.tgz#43ae8c419fd3ac056a05f8a9d1fb1022cd41ecc2" - integrity sha1-Q66MQZ/TrAVqBfip0fsQIs1B7MI= +solc@0.5.8: + version "0.5.8" + resolved "https://registry.yarnpkg.com/solc/-/solc-0.5.8.tgz#a0aa2714082fc406926f5cb384376d7408080611" + integrity sha512-RQ2SlwPBOBSV7ktNQJkvbiQks3t+3V9dsqD014EdstxnJzSxBuOvbt3P5QXpNPYW1DsEmF7dhOaT3JL7yEae/A== + dependencies: + command-exists "^1.2.8" + fs-extra "^0.30.0" + keccak "^1.0.2" + memorystream "^0.3.1" + require-from-string "^2.0.0" + semver "^5.5.0" + tmp "0.0.33" + yargs "^11.0.0" -solc@^0.5.3: +solc@^0.5.10: version "0.5.10" resolved "https://registry.yarnpkg.com/solc/-/solc-0.5.10.tgz#e57d789b1028f3d35f7989e5134d6ddc0e3b32aa" integrity sha512-Stdrh/MDkopsXYPRzPehTNYuV80Grr2CnQMuFvWj+EeRVbe3piGHxW47KebWn1sGdmK8FLaMfUehccqJP0KovQ== @@ -4130,13 +4221,34 @@ solc@^0.5.3: tmp "0.0.33" yargs "^11.0.0" -solidity-parser-antlr@^0.4.7: - version "0.4.7" - resolved "https://registry.yarnpkg.com/solidity-parser-antlr/-/solidity-parser-antlr-0.4.7.tgz#8e18867c95a956958ed008371e43f9e571dee6af" - integrity sha512-iVjNhgqkXw+o+0E+xoLcji+3KuXLe8Rm8omUuVGhsV14+ZsTwQ70nhBRXg8O3t9xwdS0iST1q9NJ5IqHnqpWkA== +solidity-parser-antlr@^0.4.2, solidity-parser-antlr@^0.4.7: + version "0.4.8" + resolved "https://registry.yarnpkg.com/solidity-parser-antlr/-/solidity-parser-antlr-0.4.8.tgz#69f77a56ed5596458ee42f7240e80f23b8eb75b9" + integrity sha512-HkAAvzLfw2OPmkuGLcy8M5yVaO4PWagmV4t7DSKYi3pXQZG7TPQ2dWl1c0QTp56snX08FeKsBAsPhXY43yjZUQ== dependencies: npm-check-updates "^3.1.11" +sort-keys-length@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sort-keys-length/-/sort-keys-length-1.0.1.tgz#9cb6f4f4e9e48155a6aa0671edd336ff1479a188" + integrity sha1-nLb09OnkgVWmqgZx7dM2/xR5oYg= + dependencies: + sort-keys "^1.0.0" + +sort-keys@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" + integrity sha1-RBttTTRnmPG05J6JIK37oOVD+a0= + dependencies: + is-plain-obj "^1.0.0" + +sort-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" + integrity sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg= + dependencies: + is-plain-obj "^1.0.0" + source-map-support@0.5.12: version "0.5.12" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.12.tgz#b4f3b10d51857a5af0138d3ce8003b201613d599" @@ -4145,6 +4257,14 @@ source-map-support@0.5.12: buffer-from "^1.0.0" source-map "^0.6.0" +source-map-support@^0.5.12: + version "0.5.13" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" + integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" @@ -4265,18 +4385,13 @@ string-width@^3.0.0, string-width@^3.1.0: strip-ansi "^5.1.0" string.prototype.trim@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz#d04de2c89e137f4d7d206f086b5ed2fae6be8cea" - integrity sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo= + version "1.2.0" + resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.0.tgz#75a729b10cfc1be439543dae442129459ce61e3d" + integrity sha512-9EIjYD/WdlvLpn987+ctkLf0FfvBefOCuiEr2henD8X+7jfwPnyvTdmW8OJhj5p+M0/96mBdynLWkxUr+rHlpg== dependencies: - define-properties "^1.1.2" - es-abstract "^1.5.0" - function-bind "^1.0.2" - -string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" - integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= + define-properties "^1.1.3" + es-abstract "^1.13.0" + function-bind "^1.1.1" string_decoder@~1.1.1: version "1.1.1" @@ -4330,12 +4445,12 @@ strip-json-comments@~2.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= -supports-color@4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.4.0.tgz#883f7ddabc165142b2a61427f3352ded195d1a3e" - integrity sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ== +strip-outer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-outer/-/strip-outer-1.0.1.tgz#b2fd2abf6604b9d1e6013057195df836b8a9d631" + integrity sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg== dependencies: - has-flag "^2.0.0" + escape-string-regexp "^1.0.2" supports-color@5.4.0: version "5.4.0" @@ -4363,7 +4478,26 @@ supports-color@^5.3.0: dependencies: has-flag "^3.0.0" -swarm-js@^0.1.39: +swarm-js@0.1.37: + version "0.1.37" + resolved "https://registry.yarnpkg.com/swarm-js/-/swarm-js-0.1.37.tgz#27d485317a340bbeec40292af783cc10acfa4663" + integrity sha512-G8gi5fcXP/2upwiuOShJ258sIufBVztekgobr3cVgYXObZwJ5AXLqZn52AI+/ffft29pJexF9WNdUxjlkVehoQ== + dependencies: + bluebird "^3.5.0" + buffer "^5.0.5" + decompress "^4.0.0" + eth-lib "^0.1.26" + fs-extra "^2.1.2" + fs-promise "^2.0.0" + got "^7.1.0" + mime-types "^2.1.16" + mkdirp-promise "^5.0.1" + mock-fs "^4.1.0" + setimmediate "^1.0.5" + tar.gz "^1.0.5" + xhr-request-promise "^0.1.2" + +swarm-js@0.1.39: version "0.1.39" resolved "https://registry.yarnpkg.com/swarm-js/-/swarm-js-0.1.39.tgz#79becb07f291d4b2a178c50fee7aa6e10342c0e8" integrity sha512-QLMqL2rzF6n5s50BptyD6Oi0R1aWlJC5Y17SRIVXRj6OR1DRIPM7nepvrxxkjA1zNzFz6mUOMjfeqeDaWB7OOg== @@ -4394,6 +4528,26 @@ tar-stream@^1.5.2: to-buffer "^1.1.1" xtend "^4.0.0" +tar.gz@^1.0.5: + version "1.0.7" + resolved "https://registry.yarnpkg.com/tar.gz/-/tar.gz-1.0.7.tgz#577ef2c595faaa73452ef0415fed41113212257b" + integrity sha512-uhGatJvds/3diZrETqMj4RxBR779LKlIE74SsMcn5JProZsfs9j0QBwWO1RW+IWNJxS2x8Zzra1+AW6OQHWphg== + dependencies: + bluebird "^2.9.34" + commander "^2.8.1" + fstream "^1.0.8" + mout "^0.11.0" + tar "^2.1.1" + +tar@^2.1.1: + version "2.2.2" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.2.tgz#0ca8848562c7299b8b446ff6a4d60cdbb23edc40" + integrity sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA== + dependencies: + block-stream "*" + fstream "^1.0.12" + inherits "2" + tar@^4.0.2, tar@^4.4.8: version "4.4.10" resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.10.tgz#946b2810b9a5e0b26140cf78bea6b0b0d689eba1" @@ -4414,6 +4568,20 @@ term-size@^1.2.0: dependencies: execa "^0.7.0" +thenify-all@^1.0.0, thenify-all@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" + integrity sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY= + dependencies: + thenify ">= 3.1.0 < 4" + +"thenify@>= 3.1.0 < 4": + version "3.3.0" + resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.0.tgz#e69e38a1babe969b0108207978b9f62b88604839" + integrity sha1-5p44obq+lpsBCCB5eLn2K4hgSDk= + dependencies: + any-promise "^1.0.0" + through2@^2.0.0: version "2.0.5" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" @@ -4432,6 +4600,17 @@ timed-out@^4.0.0, timed-out@^4.0.1: resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= +tiny-secp256k1@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/tiny-secp256k1/-/tiny-secp256k1-1.1.3.tgz#e93b1e1bf62e9bd1ad3ab24af27ff6127ce0e077" + integrity sha512-ZpobrhOtHP98VYEN51IYQH1YcrbFpnxFhI6ceWa3OEbJn7eHvSd8YFjGPxbedGCy7PNYU1v/+BRsdvyr5uRd4g== + dependencies: + bindings "^1.3.0" + bn.js "^4.11.8" + create-hmac "^1.1.7" + elliptic "^6.4.0" + nan "^2.13.2" + tmp@0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" @@ -4462,10 +4641,57 @@ tough-cookie@~2.4.3: psl "^1.1.24" punycode "^1.4.1" -tree-kill@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.1.tgz#5398f374e2f292b9dcc7b2e71e30a5c3bb6c743a" - integrity sha512-4hjqbObwlh2dLyW4tcz0Ymw0ggoaVDMveUB9w8kFSQScdRLo0gxO9J7WFcUBo+W3C1TLdFIEwNOWebgZZ0RH9Q== +trim-repeated@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-repeated/-/trim-repeated-1.0.0.tgz#e3646a2ea4e891312bf7eace6cfb05380bc01c21" + integrity sha1-42RqLqTokTEr9+rObPsFOAvAHCE= + dependencies: + escape-string-regexp "^1.0.2" + +truffle-blockchain-utils@^0.0.10: + version "0.0.10" + resolved "https://registry.yarnpkg.com/truffle-blockchain-utils/-/truffle-blockchain-utils-0.0.10.tgz#18b772673635a95a893f7083f7be6bd62227462b" + integrity sha512-gVvagLCvYD0QXfnkxy6I48P6O+d7TEY0smc2VFuwldl1/clLVWE+KfBO/jFMaAz+nupTQeKvPhNTeyh3JAsCeA== + +truffle-contract-schema@^3.0.11: + version "3.0.11" + resolved "https://registry.yarnpkg.com/truffle-contract-schema/-/truffle-contract-schema-3.0.11.tgz#202f6982b51bcad032b7ff2a8d5837853fb69301" + integrity sha512-YcgSOlrufi6VtnXg8LU5Ma7JHzHpnZQxzB1PSWnb+JOTc1nL02XRoCWTgEO7PkJnFgf6yrwOpW0ajSwHk3zQ7Q== + dependencies: + ajv "^6.10.0" + crypto-js "^3.1.9-1" + debug "^4.1.0" + +truffle-contract@^4.0.27: + version "4.0.27" + resolved "https://registry.yarnpkg.com/truffle-contract/-/truffle-contract-4.0.27.tgz#fe12ff5c71d0b301a37ca86a0021966d45b0a900" + integrity sha512-/UwsAm8tHN6sGCRbM/sarp/eR5ST3aj45wvmKWh680H3H60ur66xzrDgKJ0xPCpnAZhBOaNIhTY2bGj3jZz/ZQ== + dependencies: + bignumber.js "^7.2.1" + ethers "^4.0.0-beta.1" + truffle-blockchain-utils "^0.0.10" + truffle-contract-schema "^3.0.11" + truffle-error "^0.0.5" + truffle-interface-adapter "^0.2.2" + web3 "^1.2.0" + web3-core-promievent "^1.2.0" + web3-eth-abi "^1.2.0" + web3-utils "^1.2.0" + +truffle-error@^0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/truffle-error/-/truffle-error-0.0.5.tgz#6b5740c9f3aac74f47b85d654fff7fe2c1fc5e0e" + integrity sha512-JpzPLMPSCE0vaZ3vH5NO5u42GpMj/Y1SRBkQ6b69PSw3xMSH1umApN32cEcg1nnh8q5FNYc5FnKu0m4tiBffyQ== + +truffle-interface-adapter@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/truffle-interface-adapter/-/truffle-interface-adapter-0.2.2.tgz#f2ca897b4769b2190e3fb03f09fb98a178362126" + integrity sha512-dAKN+mSOlQV/+PlzUhBH90RAWrbp0Avm8nQcALoTwKa35PkS5RyB2ir1Y0AVoZvKVFYOmRDt884KHpZe8YgJRA== + dependencies: + bn.js "^4.11.8" + ethers "^4.0.32" + lodash "^4.17.13" + web3 "^1.2.0" truffle@^5.0.30: version "5.0.30" @@ -4476,10 +4702,15 @@ truffle@^5.0.30: mocha "5.2.0" original-require "1.0.1" -tslib@^1.9.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" - integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== +ts-essentials@^2.0.7: + version "2.0.12" + resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-2.0.12.tgz#c9303f3d74f75fa7528c3d49b80e089ab09d8745" + integrity sha512-3IVX4nI6B5cc31/GFFE+i8ey/N2eA0CZDbo6n0yrz0zDX8ZJ8djmU1p+XRz7G3is0F3bB3pu2pAroFdAWQKU3w== + +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= tunnel-agent@^0.6.0: version "0.6.0" @@ -4500,6 +4731,11 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" +type-detect@^4.0.0, type-detect@^4.0.5: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + type-fest@^0.3.0: version "0.3.1" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.3.1.tgz#63d00d204e059474fe5e1b7c011112bbd1dc29e1" @@ -4525,6 +4761,11 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= +typeforce@^1.11.5: + version "1.18.0" + resolved "https://registry.yarnpkg.com/typeforce/-/typeforce-1.18.0.tgz#d7416a2c5845e085034d70fcc5b6cc4a90edbfdc" + integrity sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g== + uglify-js@^3.1.4: version "3.6.0" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.0.tgz#704681345c53a8b2079fb6cec294b05ead242ff5" @@ -4546,6 +4787,16 @@ unbzip2-stream@^1.0.9: buffer "^5.2.1" through "^2.3.8" +underscore@1.8.3: + version "1.8.3" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.8.3.tgz#4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022" + integrity sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI= + +underscore@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.9.1.tgz#06dce34a0e68a7babc29b365b8e74b8925203961" + integrity sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg== + unique-filename@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" @@ -4616,14 +4867,6 @@ url-parse-lax@^3.0.0: dependencies: prepend-http "^2.0.0" -url-parse@1.4.4: - version "1.4.4" - resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.4.tgz#cac1556e95faa0303691fec5cf9d5a1bc34648f8" - integrity sha512-/92DTTorg4JjktLNLe6GPS2/RvAd/RGr6LuktmWSMLEOa6rjnlrFXNgSbSmkNvCoL2T028A0a1JaJLzRMlFoHg== - dependencies: - querystringify "^2.0.0" - requires-port "^1.0.0" - url-set-query@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/url-set-query/-/url-set-query-1.0.0.tgz#016e8cfd7c20ee05cafe7795e892bd0702faa339" @@ -4639,6 +4882,11 @@ utf8@2.1.1: resolved "https://registry.yarnpkg.com/utf8/-/utf8-2.1.1.tgz#2e01db02f7d8d0944f77104f1609eb0c304cf768" integrity sha1-LgHbAvfY0JRPdxBPFgnrDDBM92g= +utf8@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1" + integrity sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ== + util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" @@ -4688,234 +4936,467 @@ verror@1.10.0: core-util-is "1.0.2" extsprintf "^1.2.0" -web3-bzz@1.0.0-beta.50: - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.0.0-beta.50.tgz#5e234eecf427b33f773c78c00e34d370b542f6b0" - integrity sha512-0jD4/g+apH7t87cA9gXoZpvvVW7OqQtbu+X+olFKPrS9pKbkwfaKPdRwc1BNbjqvrRYN0K7koT9xV+Lzvyah6w== +web3-bzz@1.0.0-beta.37: + version "1.0.0-beta.37" + resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.0.0-beta.37.tgz#59e3e4f5a9d732731008fe9165c3ec8bf85d502f" + integrity sha512-E+dho49Nsm/QpQvYWOF35YDsQrMvLB19AApENxhlQsu6HpWQt534DQul0t3Y/aAh8rlKD6Kanxt8LhHDG3vejQ== dependencies: - "@babel/runtime" "^7.3.1" - "@types/node" "^10.12.18" - lodash "^4.17.11" - swarm-js "^0.1.39" + got "7.1.0" + swarm-js "0.1.37" + underscore "1.8.3" -web3-core-helpers@1.0.0-beta.50: - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.0.0-beta.50.tgz#0de88656ffa5f13659141cc443ff8529f109deac" - integrity sha512-B1LMrlC9c5HEJYmBWUhsxHdJ78w5YGop/ptF1cFL8cHLwTCQqCFFKLgYUg+dax/554TP1xgJ2w/ArLpnPJ8dBg== +web3-bzz@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.2.0.tgz#eab70a2cf6c437223f40fc069499fe70ff53feb0" + integrity sha512-QEIdvguSEpqBK9b815nzx4yvpfKv/SAvaFeCMjQ0vjIVqFhAwBHDxd+f+X3nWGVRGVeOTP7864tau26CPBtQ8Q== dependencies: - "@babel/runtime" "^7.3.1" - lodash "^4.17.11" - web3-eth-iban "1.0.0-beta.50" - web3-utils "1.0.0-beta.50" + got "9.6.0" + swarm-js "0.1.39" + underscore "1.9.1" -web3-core-method@1.0.0-beta.50: - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.0.0-beta.50.tgz#4f9b55699f6e46f49dc8ac6bde204f9ae877b513" - integrity sha512-0+L37KDT90DD1fcTye/ZWMyGOLiw0ZxX2vaC8qDSFvAV3scTEuZyEQuR+tCM2aGyUVihy8LdmZwioRwnTXgLwg== +web3-core-helpers@1.0.0-beta.37: + version "1.0.0-beta.37" + resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.0.0-beta.37.tgz#04ec354b7f5c57234c309eea2bda9bf1f2fe68ba" + integrity sha512-efaLOzN28RMnbugnyelgLwPWWaSwElQzcAJ/x3PZu+uPloM/lE5x0YuBKvIh7/PoSMlHqtRWj1B8CpuQOUQ5Ew== dependencies: - "@babel/runtime" "^7.3.1" - eventemitter3 "3.1.0" - lodash "^4.17.11" + underscore "1.8.3" + web3-eth-iban "1.0.0-beta.37" + web3-utils "1.0.0-beta.37" -web3-core-subscriptions@1.0.0-beta.50: - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.0.0-beta.50.tgz#73df7143062f915e02b153239af10974e350e20f" - integrity sha512-q2Jmuy/BCwcKCFjR6kc03hPbdC6sR0n3IhPVg98Sk7ewgRLur/v3lLDz0fQpY4xE6U0XOqrjxwzlqISkOcP5Kw== +web3-core-helpers@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.2.0.tgz#023947323cebd021e43a67145a5087627ce87fb3" + integrity sha512-KLCCP2FS1cMz23Y9l3ZaEDzaUky+GpsNavl4Hn1xX8lNaKcfgGEF+DgtAY/TfPQYAxLjLrSbIFUDzo9H/W1WAQ== dependencies: - "@babel/runtime" "^7.3.1" - eventemitter3 "^3.1.0" - lodash "^4.17.11" + underscore "1.9.1" + web3-eth-iban "1.2.0" + web3-utils "1.2.0" -web3-core@1.0.0-beta.50: - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.0.0-beta.50.tgz#385137b8c34257db2679e925dfe41b98a0f7fe37" - integrity sha512-edOHdSnkRREi0vUXXNUsrbkTvXftCDroiF2tEvbPVyiBv0U6/VDYClFdHuZKdrrTRUcn/rUbvBqw8qCt3xgcuQ== +web3-core-method@1.0.0-beta.37: + version "1.0.0-beta.37" + resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.0.0-beta.37.tgz#53d148e63f818b23461b26307afdfbdaa9457744" + integrity sha512-pKWFUeqnVmzx3VrZg+CseSdrl/Yrk2ioid/HzolNXZE6zdoITZL0uRjnsbqXGEzgRRd1Oe/pFndpTlRsnxXloA== dependencies: - "@babel/runtime" "^7.3.1" - "@types/node" "^10.12.18" - lodash "^4.17.11" - web3-utils "1.0.0-beta.50" + underscore "1.8.3" + web3-core-helpers "1.0.0-beta.37" + web3-core-promievent "1.0.0-beta.37" + web3-core-subscriptions "1.0.0-beta.37" + web3-utils "1.0.0-beta.37" -web3-eth-abi@1.0.0-beta.50: - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.0.0-beta.50.tgz#52ca509257648c6088aa9d8874d6ea5f249c6de7" - integrity sha512-Nwm1HL3xBbrs43j/9V3gH1CJWWR7jyTDSE7PIkjYVjwgygAjlHPMHzuzGffoFMp2tSQ2DywCGmXAY5I5+vznZw== +web3-core-method@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.2.0.tgz#9f6a6939d15f53bc74d086f280fbd62461546cd3" + integrity sha512-Iff5rCL+sgHe6zZVZijp818aRixKQf3ZAyQsT6ewER1r9yqXsH89DJtX33Xw8xiaYSwUFcpNs2j+Kluhv/eVAw== dependencies: - "@babel/runtime" "^7.3.1" - ethers "^4.0.27" - lodash "^4.17.11" - web3-utils "1.0.0-beta.50" + underscore "1.9.1" + web3-core-helpers "1.2.0" + web3-core-promievent "1.2.0" + web3-core-subscriptions "1.2.0" + web3-utils "1.2.0" -web3-eth-accounts@1.0.0-beta.50: - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.0.0-beta.50.tgz#e405979db8d4dc0caccff576fa746cea3d87e3d1" - integrity sha512-cUuYxKhymob87zCUYgw7ieZY6aVStMhClocblI3FKNdI1I8dczhdhZ97qMj5iavOganN7/OxLzeji7ksAoNAhg== +web3-core-promievent@1.0.0-beta.37: + version "1.0.0-beta.37" + resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.0.0-beta.37.tgz#4e51c469d0a7ac0a969885a4dbcde8504abe5b02" + integrity sha512-GTF2r1lP8nJBeA5Gxq5yZpJy9l8Fb9CXGZPfF8jHvaRdQHtm2Z+NDhqYmF833lcdkokRSyfPcXlz1mlWeClFpg== dependencies: - "@babel/runtime" "^7.3.1" + any-promise "1.3.0" + eventemitter3 "1.1.1" + +web3-core-promievent@1.2.0, web3-core-promievent@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.2.0.tgz#d6454837a307da5b453fe3077743fe25801a07a1" + integrity sha512-9THNYsZka91AX4LZGZvka5hio9+QlOY22hNgCiagmCmYytyKk3cXftL6CWefnNF7XgW8sy/ew5lzWLVsQW61Lw== + dependencies: + any-promise "1.3.0" + eventemitter3 "3.1.2" + +web3-core-requestmanager@1.0.0-beta.37: + version "1.0.0-beta.37" + resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.0.0-beta.37.tgz#721a75df5920621bff42d9d74f7a64413675d56b" + integrity sha512-66VUqye5BGp1Zz1r8psCxdNH+GtTjaFwroum2Osx+wbC5oRjAiXkkadiitf6wRb+edodjEMPn49u7B6WGNuewQ== + dependencies: + underscore "1.8.3" + web3-core-helpers "1.0.0-beta.37" + web3-providers-http "1.0.0-beta.37" + web3-providers-ipc "1.0.0-beta.37" + web3-providers-ws "1.0.0-beta.37" + +web3-core-requestmanager@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.2.0.tgz#a7f9995495340037e7ac72792c1885c35c1e7616" + integrity sha512-hPe1jyESodXAiE7qJglu7ySo4GINCn5CgG+9G1ATLQbriZsir83QMSeKQekv/hckKFIf4SvZJRPEBhtAle+Dhw== + dependencies: + underscore "1.9.1" + web3-core-helpers "1.2.0" + web3-providers-http "1.2.0" + web3-providers-ipc "1.2.0" + web3-providers-ws "1.2.0" + +web3-core-subscriptions@1.0.0-beta.37: + version "1.0.0-beta.37" + resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.0.0-beta.37.tgz#40de5e2490cc05b15faa8f935c97fd48d670cd9a" + integrity sha512-FdXl8so9kwkRRWziuCSpFsAuAdg9KvpXa1fQlT16uoGcYYfxwFO/nkwyBGQzkZt7emShI2IRugcazyPCZDwkOA== + dependencies: + eventemitter3 "1.1.1" + underscore "1.8.3" + web3-core-helpers "1.0.0-beta.37" + +web3-core-subscriptions@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.2.0.tgz#d359b9b5fb6f6a700f1b383be11de7925cb7549f" + integrity sha512-DHipGH8It5E4HxxvymhkudcYhBVgGx6MwGWobIVKFgp6JRxtuvAbqwrMbuD/+78J6yXOa4y9zVXBk12dm2NXGg== + dependencies: + eventemitter3 "3.1.2" + underscore "1.9.1" + web3-core-helpers "1.2.0" + +web3-core@1.0.0-beta.37: + version "1.0.0-beta.37" + resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.0.0-beta.37.tgz#66c2c7000772c9db36d737ada31607ace09b7e90" + integrity sha512-cIwEqCj7OJyefQNauI0HOgW4sSaOQ98V99H2/HEIlnCZylsDzfw7gtQUdwnRFiIyIxjbWy3iWsjwDPoXNPZBYg== + dependencies: + web3-core-helpers "1.0.0-beta.37" + web3-core-method "1.0.0-beta.37" + web3-core-requestmanager "1.0.0-beta.37" + web3-utils "1.0.0-beta.37" + +web3-core@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.2.0.tgz#6f3c59f84b2af9ab0ee7617d3c5208a814d3953c" + integrity sha512-Vy+fargzx94COdihE79zIM5lb/XAl/LJlgGdmz2a6QhgGZrSL8K6DKKNS+OuORAcLJN2PWNMc4IdfknkOw1PhQ== + dependencies: + web3-core-helpers "1.2.0" + web3-core-method "1.2.0" + web3-core-requestmanager "1.2.0" + web3-utils "1.2.0" + +web3-eth-abi@1.0.0-beta.37: + version "1.0.0-beta.37" + resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.0.0-beta.37.tgz#55592fa9cd2427d9f0441d78f3b8d0c1359a2a24" + integrity sha512-g9DKZGM2OqwKp/tX3W/yihcj7mQCtJ6CXyZXEIZfuDyRBED/iSEIFfieDOd+yo16sokLMig6FG7ADhhu+19hdA== + dependencies: + ethers "4.0.0-beta.1" + underscore "1.8.3" + web3-utils "1.0.0-beta.37" + +web3-eth-abi@1.2.0, web3-eth-abi@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.2.0.tgz#26b22261756ffbb3363bc37c1a6f5143bebb6469" + integrity sha512-FDuPq/tFeMg/D/f7cNSmvVYkMYb1z379gUUzSL8ZFtZrdHPkezq+lq/TmWmbCOMLYNXlhGJBzjGdLXRS4Upprg== + dependencies: + ethers "4.0.0-beta.3" + underscore "1.9.1" + web3-utils "1.2.0" + +web3-eth-accounts@1.0.0-beta.37: + version "1.0.0-beta.37" + resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.0.0-beta.37.tgz#0a5a9f14a6c3bd285e001c15eb3bb38ffa4b5204" + integrity sha512-uvbHL62/zwo4GDmwKdqH9c/EgYd8QVnAfpVw8D3epSISpgbONNY7Hr4MRMSd/CqAP12l2Ls9JVQGLhhC83bW6g== + dependencies: + any-promise "1.3.0" crypto-browserify "3.12.0" - eth-lib "0.2.8" - lodash "^4.17.11" + eth-lib "0.2.7" scrypt.js "0.2.0" + underscore "1.8.3" + uuid "2.0.1" + web3-core "1.0.0-beta.37" + web3-core-helpers "1.0.0-beta.37" + web3-core-method "1.0.0-beta.37" + web3-utils "1.0.0-beta.37" + +web3-eth-accounts@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.2.0.tgz#bb26d5446017700a13b75fc69a2b1226fe44f6bb" + integrity sha512-d/fUAL3F6HqstvEiBnZ1RwZ77/DytgF9d6A3mWVvPOUk2Pqi77PM0adRvsKvIWUaQ/k6OoCk/oXtbzaO7CyGpg== + dependencies: + any-promise "1.3.0" + crypto-browserify "3.12.0" + eth-lib "0.2.7" + scrypt.js "^0.3.0" + underscore "1.9.1" uuid "3.3.2" - web3-core "1.0.0-beta.50" - web3-core-helpers "1.0.0-beta.50" - web3-core-method "1.0.0-beta.50" - web3-providers "1.0.0-beta.50" - web3-utils "1.0.0-beta.50" - -web3-eth-contract@1.0.0-beta.50: - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.0.0-beta.50.tgz#bc6d4523347e113c74c5e1c6c78219eeb61d9182" - integrity sha512-X8R1+qIeD4Dbz1RmQa5m3K1suVFigNgd7EFMp6vVC3ULDjt4R6T0cRmFw/x51v3MQoT7s6Yd1KiEWIAt9IYG6w== - dependencies: - "@babel/runtime" "^7.3.1" - lodash "^4.17.11" - web3-core "1.0.0-beta.50" - web3-core-helpers "1.0.0-beta.50" - web3-core-method "1.0.0-beta.50" - web3-core-subscriptions "1.0.0-beta.50" - web3-eth-abi "1.0.0-beta.50" - web3-eth-accounts "1.0.0-beta.50" - web3-providers "1.0.0-beta.50" - web3-utils "1.0.0-beta.50" - -web3-eth-ens@1.0.0-beta.50: - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.0.0-beta.50.tgz#29304e42e2671ea755a19ab3f1011ad197f115da" - integrity sha512-UnhYcNuSNRBOBcbD5y8cTyRh5ENn65/GfZkxCDXAKBY6sD4GzMZNkD7kq+37/34cnZEzzQPPGd9jLZNLXOklyg== - dependencies: - "@babel/runtime" "^7.3.1" + web3-core "1.2.0" + web3-core-helpers "1.2.0" + web3-core-method "1.2.0" + web3-utils "1.2.0" + +web3-eth-contract@1.0.0-beta.37: + version "1.0.0-beta.37" + resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.0.0-beta.37.tgz#87f93c95ed16f320ba54943b7886890de6766013" + integrity sha512-h1B3A8Z/C7BlnTCHkrWbXZQTViDxfR12lKMeTkT8Sqj5phFmxrBlPE4ORy4lf1Dk5b23mZYE0r/IRACx4ThCrQ== + dependencies: + underscore "1.8.3" + web3-core "1.0.0-beta.37" + web3-core-helpers "1.0.0-beta.37" + web3-core-method "1.0.0-beta.37" + web3-core-promievent "1.0.0-beta.37" + web3-core-subscriptions "1.0.0-beta.37" + web3-eth-abi "1.0.0-beta.37" + web3-utils "1.0.0-beta.37" + +web3-eth-contract@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.2.0.tgz#8d1c235c6624b5df428969ea2e9c26337095f6f0" + integrity sha512-hfjozNbfsoMeR3QklfkwU0Mqcw6YRD4y1Cb1ghGWNhFy2+/sbvKcQNPPJDKFTde22PRzGQBWyh/nb422Sux4bQ== + dependencies: + underscore "1.9.1" + web3-core "1.2.0" + web3-core-helpers "1.2.0" + web3-core-method "1.2.0" + web3-core-promievent "1.2.0" + web3-core-subscriptions "1.2.0" + web3-eth-abi "1.2.0" + web3-utils "1.2.0" + +web3-eth-ens@1.0.0-beta.37: + version "1.0.0-beta.37" + resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.0.0-beta.37.tgz#714ecb01eb447ee3eb39b2b20a10ae96edb1f01f" + integrity sha512-dR3UkrVzdRrJhfP57xBPx0CMiVnCcYFvh+u2XMkGydrhHgupSUkjqGr89xry/j1T0BkuN9mikpbyhdCVMXqMbg== + dependencies: eth-ens-namehash "2.0.8" - lodash "^4.17.11" - web3-core "1.0.0-beta.50" - web3-core-helpers "1.0.0-beta.50" - web3-core-method "1.0.0-beta.50" - web3-eth-abi "1.0.0-beta.50" - web3-eth-contract "1.0.0-beta.50" - web3-net "1.0.0-beta.50" - web3-providers "1.0.0-beta.50" - web3-utils "1.0.0-beta.50" - -web3-eth-iban@1.0.0-beta.50: - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.0.0-beta.50.tgz#311ea9422369ecbde6316e10a34de9fb07994cd6" - integrity sha512-rW5fpUUW3WaToPxBXNnqTfj5dh2BJ+9uognYAfThh2WWR1+EwWZethsKS/PyU6Jn9uA5p/kQoUIP0JKaeBm80Q== - dependencies: - "@babel/runtime" "^7.3.1" + underscore "1.8.3" + web3-core "1.0.0-beta.37" + web3-core-helpers "1.0.0-beta.37" + web3-core-promievent "1.0.0-beta.37" + web3-eth-abi "1.0.0-beta.37" + web3-eth-contract "1.0.0-beta.37" + web3-utils "1.0.0-beta.37" + +web3-eth-ens@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.2.0.tgz#af66308542f4acfa09ccd3ce370e3ad2de20ec30" + integrity sha512-kE6uHMLwH9dv+MZSKT7BcKXcQ6CcLP5m5mM44s2zg2e9Rl20F3J6R3Ik6sLc/w2ywdCwTe/Z22yEstHXQwu5ig== + dependencies: + eth-ens-namehash "2.0.8" + underscore "1.9.1" + web3-core "1.2.0" + web3-core-helpers "1.2.0" + web3-core-promievent "1.2.0" + web3-eth-abi "1.2.0" + web3-eth-contract "1.2.0" + web3-utils "1.2.0" + +web3-eth-iban@1.0.0-beta.37: + version "1.0.0-beta.37" + resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.0.0-beta.37.tgz#313a3f18ae2ab00ba98678ea1156b09ef32a3655" + integrity sha512-WQRniGJFxH/XCbd7miO6+jnUG+6bvuzfeufPIiOtCbeIC1ypp1kSqER8YVBDrTyinU1xnf1U5v0KBZ2yiWBJxQ== + dependencies: + bn.js "4.11.6" + web3-utils "1.0.0-beta.37" + +web3-eth-iban@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.2.0.tgz#1bece9cebf817dca82fa03230203351f4f263866" + integrity sha512-6DzTx/cvIgEvxadhJjLGpsuDUARA4RKskNOuwWYUsUODcPb50rsfMmRkHhGtLss/sNXVE5gNjbT9rX3TDqy2tg== + dependencies: bn.js "4.11.8" - web3-utils "1.0.0-beta.50" - -web3-eth-personal@1.0.0-beta.50: - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.0.0-beta.50.tgz#891f55bb93c2e38918be085dcb295634a59b31b1" - integrity sha512-52dS24YfJxx/Uy21RKj2m5rjag1kktdy5rY/R9vDwWZRrJkxfDf058CvtRF+QsD7A6QVxkHCZ9YwEWnLCLW9Cw== - dependencies: - "@babel/runtime" "^7.3.1" - web3-core "1.0.0-beta.50" - web3-core-helpers "1.0.0-beta.50" - web3-core-method "1.0.0-beta.50" - web3-net "1.0.0-beta.50" - web3-providers "1.0.0-beta.50" - web3-utils "1.0.0-beta.50" - -web3-eth@1.0.0-beta.50: - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.0.0-beta.50.tgz#6da9246d36d65ba7ff03209419c571359eda0e0a" - integrity sha512-ojsddEclIdu+C3hfRrLVJK0rcxt2O+Yj7c3b4YEzZQ9+Kd/HaSZfeSpUgKojgmFhUUiCCRTEc2holWtQ+Lx4gQ== - dependencies: - "@babel/runtime" "^7.3.1" - eth-lib "0.2.8" - rxjs "^6.4.0" - web3-core "1.0.0-beta.50" - web3-core-helpers "1.0.0-beta.50" - web3-core-method "1.0.0-beta.50" - web3-core-subscriptions "1.0.0-beta.50" - web3-eth-abi "1.0.0-beta.50" - web3-eth-accounts "1.0.0-beta.50" - web3-eth-contract "1.0.0-beta.50" - web3-eth-ens "1.0.0-beta.50" - web3-eth-iban "1.0.0-beta.50" - web3-eth-personal "1.0.0-beta.50" - web3-net "1.0.0-beta.50" - web3-providers "1.0.0-beta.50" - web3-utils "1.0.0-beta.50" - -web3-net@1.0.0-beta.50: - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.0.0-beta.50.tgz#1ca188b9210da6ae560bbd35a2b6dea1d2e68da7" - integrity sha512-T9aBrWYzCeqZTTJlljonTm8x1tEjHT1uBqcdvEYZoyCS1Xxc+zCNBqP4SBfdcfwCeGohhI7bRx9qX1JjYH3cRA== - dependencies: - "@babel/runtime" "^7.3.1" - lodash "^4.17.11" - web3-core "1.0.0-beta.50" - web3-core-helpers "1.0.0-beta.50" - web3-core-method "1.0.0-beta.50" - web3-providers "1.0.0-beta.50" - web3-utils "1.0.0-beta.50" - -web3-providers@1.0.0-beta.50: - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/web3-providers/-/web3-providers-1.0.0-beta.50.tgz#41d7cd3c38f3b12f721c115fea1972a3d1904d25" - integrity sha512-p2xtr6N72pdXvND5dLdK1G9T/9qCQiKC2EYDPmimnqvoHWixmM3tlBl042swkHspHHVL60vXPKxB4UDaQE2hWQ== - dependencies: - "@babel/runtime" "^7.3.1" - "@types/node" "^10.12.18" - eventemitter3 "3.1.0" - lodash "^4.17.11" - url-parse "1.4.4" - websocket "git://github.com/frozeman/WebSocket-Node.git#browserifyCompatible" + web3-utils "1.2.0" + +web3-eth-personal@1.0.0-beta.37: + version "1.0.0-beta.37" + resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.0.0-beta.37.tgz#187472f51861e2b6d45da43411801bc91a859f9a" + integrity sha512-B4dZpGbD+nGnn48i6nJBqrQ+HB7oDmd+Q3wGRKOsHSK5HRWO/KwYeA7wgwamMAElkut50lIsT9EJl4Apfk3G5Q== + dependencies: + web3-core "1.0.0-beta.37" + web3-core-helpers "1.0.0-beta.37" + web3-core-method "1.0.0-beta.37" + web3-net "1.0.0-beta.37" + web3-utils "1.0.0-beta.37" + +web3-eth-personal@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.2.0.tgz#7194f519c870d720eee1349d867408004f0f78af" + integrity sha512-8QdcaT6dbdiMC8zEqvDuij8XeI34r2GGdQYGvYBP2UgCm15EZBHgewxO30A+O+j2oIW1/Hu60zP5upnhCuA1Dw== + dependencies: + web3-core "1.2.0" + web3-core-helpers "1.2.0" + web3-core-method "1.2.0" + web3-net "1.2.0" + web3-utils "1.2.0" + +web3-eth@1.0.0-beta.37: + version "1.0.0-beta.37" + resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.0.0-beta.37.tgz#0e8ffcd857a5f85ae4b5f052ad831ca5c56f4f74" + integrity sha512-Eb3aGtkz3G9q+Z9DKgSQNbn/u8RtcZQQ0R4sW9hy5KK47GoT6vab5c6DiD3QWzI0BzitHzR5Ji+3VHf/hPUGgw== + dependencies: + underscore "1.8.3" + web3-core "1.0.0-beta.37" + web3-core-helpers "1.0.0-beta.37" + web3-core-method "1.0.0-beta.37" + web3-core-subscriptions "1.0.0-beta.37" + web3-eth-abi "1.0.0-beta.37" + web3-eth-accounts "1.0.0-beta.37" + web3-eth-contract "1.0.0-beta.37" + web3-eth-ens "1.0.0-beta.37" + web3-eth-iban "1.0.0-beta.37" + web3-eth-personal "1.0.0-beta.37" + web3-net "1.0.0-beta.37" + web3-utils "1.0.0-beta.37" + +web3-eth@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.2.0.tgz#ac8d3409356538d2fe1cb6151036b724eace76f6" + integrity sha512-GP1+hHS/IVW1tAOIDS44PxCpvSl9PBU/KAB40WgP27UMvSy43LjHxGlP6hQQOdIfmBLBTvGvn2n+Z5kW2gzAzg== + dependencies: + underscore "1.9.1" + web3-core "1.2.0" + web3-core-helpers "1.2.0" + web3-core-method "1.2.0" + web3-core-subscriptions "1.2.0" + web3-eth-abi "1.2.0" + web3-eth-accounts "1.2.0" + web3-eth-contract "1.2.0" + web3-eth-ens "1.2.0" + web3-eth-iban "1.2.0" + web3-eth-personal "1.2.0" + web3-net "1.2.0" + web3-utils "1.2.0" + +web3-net@1.0.0-beta.37: + version "1.0.0-beta.37" + resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.0.0-beta.37.tgz#b494136043f3c6ba84fe4a47d4c028c2a63c9a8e" + integrity sha512-xG/uBtMdDa1UMXw9KjDUgf3fXA/fDEJUYUS0TDn+U9PMgngA+UVECHNNvQTrVVDxEky38V3sahwIDiopNsQdsw== + dependencies: + web3-core "1.0.0-beta.37" + web3-core-method "1.0.0-beta.37" + web3-utils "1.0.0-beta.37" + +web3-net@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.2.0.tgz#9e99c4326a28712451dc4d45f3acf26c1d4b3219" + integrity sha512-7iD8C6vvx8APXPMmlpPLGWjn4bsXHzd3BTdFzKjkoYjiiVFJdVAbY3j1BwN/6tVQu8Ay7sDpV2EdTNub7GKbyw== + dependencies: + web3-core "1.2.0" + web3-core-method "1.2.0" + web3-utils "1.2.0" + +web3-providers-http@1.0.0-beta.37: + version "1.0.0-beta.37" + resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.0.0-beta.37.tgz#c06efd60e16e329e25bd268d2eefc68d82d13651" + integrity sha512-FM/1YDB1jtZuTo78habFj7S9tNHoqt0UipdyoQV29b8LkGKZV9Vs3is8L24hzuj1j/tbwkcAH+ewIseHwu0DTg== + dependencies: + web3-core-helpers "1.0.0-beta.37" xhr2-cookies "1.1.0" -web3-shh@1.0.0-beta.50: - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.0.0-beta.50.tgz#e5a4a64b2308267b1635858e4adcc92eeee147f1" - integrity sha512-a46Gz/YQdF3HJ4XK7rZh6bJiP3IEq+BDAvdxD1jW54yKM2k3RGarOY8hanC1crxKE7E9Q1UUkrp1Vjrj8XSQuQ== - dependencies: - "@babel/runtime" "^7.3.1" - web3-core "1.0.0-beta.50" - web3-core-helpers "1.0.0-beta.50" - web3-core-method "1.0.0-beta.50" - web3-core-subscriptions "1.0.0-beta.50" - web3-net "1.0.0-beta.50" - web3-providers "1.0.0-beta.50" - web3-utils "1.0.0-beta.50" - -web3-utils@1.0.0-beta.50: - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.0.0-beta.50.tgz#ed12454d3d2727d3b77695c1899ad3abbef303af" - integrity sha512-xGhM/YkepK2x0iMYUl/sws58LzTbodjMGlhZxrCZLZxJ0DoaDyk3UdmZ6aCSCwVTFg4hlVj3doaIhWnwGfhhpQ== - dependencies: - "@babel/runtime" "^7.3.1" - "@types/bn.js" "^4.11.4" - "@types/node" "^10.12.18" - bn.js "4.11.8" - eth-lib "0.2.8" - ethjs-unit "^0.1.6" - lodash "^4.17.11" +web3-providers-http@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.2.0.tgz#c6ebf9b6a23564439fa3c4a431cd6b405cc1ec0f" + integrity sha512-UrUn6JSz7NVCZ+0nZZtC4cmbl5JIi57w1flL1jN8jgkfdWDdErNvTkSwCt/QYdTQscMaUtWXDDOSAsVO6YC64g== + dependencies: + web3-core-helpers "1.2.0" + xhr2-cookies "1.1.0" + +web3-providers-ipc@1.0.0-beta.37: + version "1.0.0-beta.37" + resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.0.0-beta.37.tgz#55d247e7197257ca0c3e4f4b0fe1561311b9d5b9" + integrity sha512-NdRPRxYMIU0C3u18NI8u4bwbhI9pCg5nRgDGYcmSAx5uOBxiYcQy+hb0WkJRRhBoyIXJmy+s26FoH8904+UnPg== + dependencies: + oboe "2.1.3" + underscore "1.8.3" + web3-core-helpers "1.0.0-beta.37" + +web3-providers-ipc@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.2.0.tgz#98b8b8c9e77935dabfcf6d16e66c783f2429eac8" + integrity sha512-T2OSbiqu7+dahbGG5YFEQM5+FXdLVvaTCKmHXaQpw8IuL5hw7HELtyFOtHVudgDRyw0tJKxIfAiX/v2F1IL1fQ== + dependencies: + oboe "2.1.4" + underscore "1.9.1" + web3-core-helpers "1.2.0" + +web3-providers-ws@1.0.0-beta.37: + version "1.0.0-beta.37" + resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.0.0-beta.37.tgz#77c15aebc00b75d760d22d063ac2e415bdbef72f" + integrity sha512-8p6ZLv+1JYa5Vs8oBn33Nn3VGFBbF+wVfO+b78RJS1Qf1uIOzjFVDk3XwYDD7rlz9G5BKpxhaQw+6EGQ7L02aw== + dependencies: + underscore "1.8.3" + web3-core-helpers "1.0.0-beta.37" + websocket "git://github.com/frozeman/WebSocket-Node.git#browserifyCompatible" + +web3-providers-ws@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.2.0.tgz#c45929f0d1e1743301372e6e604aab63e83f66e3" + integrity sha512-rnwGcCe6cev5A6eG5UBCQqPmkJVZMCrK+HN1AvUCco0OHD/0asGc9LuLbtkQIyznA6Lzetq/OOcaTOM4KeT11g== + dependencies: + underscore "1.9.1" + web3-core-helpers "1.2.0" + websocket "github:frozeman/WebSocket-Node#browserifyCompatible" + +web3-shh@1.0.0-beta.37: + version "1.0.0-beta.37" + resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.0.0-beta.37.tgz#3246ce5229601b525020828a56ee283307057105" + integrity sha512-h5STG/xqZNQWtCLYOu7NiMqwqPea8SfkKQUPUFxXKIPVCFVKpHuQEwW1qcPQRJMLhlQIv17xuoUe1A+RzDNbrw== + dependencies: + web3-core "1.0.0-beta.37" + web3-core-method "1.0.0-beta.37" + web3-core-subscriptions "1.0.0-beta.37" + web3-net "1.0.0-beta.37" + +web3-shh@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.2.0.tgz#c07c306d761f70782c64e2b5b119db54e16f301f" + integrity sha512-VFjS8kvsQBodudFmIoVJWvDNZosONJZZnhvktngD3POu5dwbJmSCl6lzbLJ2C5XjR15dF+JvSstAkWbM+2sdPg== + dependencies: + web3-core "1.2.0" + web3-core-method "1.2.0" + web3-core-subscriptions "1.2.0" + web3-net "1.2.0" + +web3-utils@1.0.0-beta.37: + version "1.0.0-beta.37" + resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.0.0-beta.37.tgz#ab868a90fe5e649337e38bdaf72133fcbf4d414d" + integrity sha512-kA1fyhO8nKgU21wi30oJQ/ssvu+9srMdjOTKbHYbQe4ATPcr5YNwwrxG3Bcpbu1bEwRUVKHCkqi+wTvcAWBdlQ== + dependencies: + bn.js "4.11.6" + eth-lib "0.1.27" + ethjs-unit "0.1.6" number-to-bn "1.7.0" randomhex "0.1.5" + underscore "1.8.3" utf8 "2.1.1" -web3@1.0.0-beta.50: - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/web3/-/web3-1.0.0-beta.50.tgz#a82db1ac519e68696363eee46d9b233f52f37eed" - integrity sha512-N4YqT1jl2tZYNWiLk5gA5BMchHJaG76d65z899DT9UTR4iI6mfqe1QIE+1YLII1x+uE8ohFzBq/aaZ8praLeoA== - dependencies: - "@babel/runtime" "^7.3.1" - "@types/node" "^10.12.18" - web3-bzz "1.0.0-beta.50" - web3-core "1.0.0-beta.50" - web3-core-helpers "1.0.0-beta.50" - web3-core-method "1.0.0-beta.50" - web3-eth "1.0.0-beta.50" - web3-eth-personal "1.0.0-beta.50" - web3-net "1.0.0-beta.50" - web3-providers "1.0.0-beta.50" - web3-shh "1.0.0-beta.50" - web3-utils "1.0.0-beta.50" +web3-utils@1.2.0, web3-utils@^1.0.0, web3-utils@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.2.0.tgz#1f11b05d173b757d3f5ba32cb90b375a487d3bf0" + integrity sha512-tI1low8ICoaWU2c53cikH0rsksKuIskI2nycH5E5sEXxxl9/BOD3CeDDBFbxgNPQ+bpDevbR7gXNEDB7Ud4G9g== + dependencies: + bn.js "4.11.8" + eth-lib "0.2.7" + ethjs-unit "0.1.6" + number-to-bn "1.7.0" + randomhex "0.1.5" + underscore "1.9.1" + utf8 "3.0.0" + +web3@1.0.0-beta.37: + version "1.0.0-beta.37" + resolved "https://registry.yarnpkg.com/web3/-/web3-1.0.0-beta.37.tgz#b42c30e67195f816cd19d048fda872f70eca7083" + integrity sha512-8XLgUspdzicC/xHG82TLrcF/Fxzj2XYNJ1KTYnepOI77bj5rvpsxxwHYBWQ6/JOjk0HkZqoBfnXWgcIHCDhZhQ== + dependencies: + web3-bzz "1.0.0-beta.37" + web3-core "1.0.0-beta.37" + web3-eth "1.0.0-beta.37" + web3-eth-personal "1.0.0-beta.37" + web3-net "1.0.0-beta.37" + web3-shh "1.0.0-beta.37" + web3-utils "1.0.0-beta.37" + +web3@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/web3/-/web3-1.2.0.tgz#ef9c43a99eac348a85c09179690290d45a96a5f2" + integrity sha512-iFrVAexsopX97x0ofBU/7HrCxzovf624qBkjBUeHZDf/G3Sb4tMQtjkCRc5lgVvzureq5SCqDiFDcqnw7eJ0bA== + dependencies: + web3-bzz "1.2.0" + web3-core "1.2.0" + web3-eth "1.2.0" + web3-eth-personal "1.2.0" + web3-net "1.2.0" + web3-shh "1.2.0" + web3-utils "1.2.0" "websocket@git://github.com/frozeman/WebSocket-Node.git#browserifyCompatible": version "1.0.26" + uid "6c72925e3f8aaaea8dc8450f97627e85263999f2" resolved "git://github.com/frozeman/WebSocket-Node.git#6c72925e3f8aaaea8dc8450f97627e85263999f2" dependencies: debug "^2.2.0" @@ -4923,6 +5404,15 @@ web3@1.0.0-beta.50: typedarray-to-buffer "^3.1.2" yaeti "^0.0.6" +"websocket@github:frozeman/WebSocket-Node#browserifyCompatible": + version "1.0.26" + resolved "https://codeload.github.com/frozeman/WebSocket-Node/tar.gz/6c72925e3f8aaaea8dc8450f97627e85263999f2" + dependencies: + debug "^2.2.0" + nan "^2.3.3" + typedarray-to-buffer "^3.1.2" + yaeti "^0.0.6" + which-module@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" @@ -4942,6 +5432,13 @@ widest-line@^2.0.0: dependencies: string-width "^2.1.1" +wif@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/wif/-/wif-2.0.6.tgz#08d3f52056c66679299726fade0d432ae74b4704" + integrity sha1-CNP1IFbGZnkplyb63g1DKudLRwQ= + dependencies: + bs58check "<3.0.0" + wordwrap@^1.0.0, wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" @@ -5039,18 +5536,11 @@ xmlhttprequest@1.8.0: resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc" integrity sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw= -xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.0, xtend@~4.0.1: +xtend@^4.0.0, xtend@~4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== -xtend@~2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-2.1.2.tgz#6efecc2a4dad8e6962c4901b337ce7ba87b5d28b" - integrity sha1-bv7MKk2tjmlixJAbM3znuoe10os= - dependencies: - object-keys "~0.4.0" - y18n@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41"