From 1c09954998843e30c1c38b602b5cbfda6506bef9 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Mon, 10 Dec 2018 17:49:20 +0530 Subject: [PATCH 01/83] Initial circleci script --- .circleci/config.yml | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 .circleci/config.yml diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 000000000..86bb215de --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,39 @@ +version: 2 +jobs: + test: + docker: + - image: circleci/node:8 + steps: + - checkout + - restore_cache: + key: dependency-cache-{{ checksum "package.json" }} + - run: + - yarn + - node --version + - truffle version + - npm run test + - save_cache: + key: dependency-cache-{{ checksum "package.json" }} + paths: + - node_modules + docs: + docker: + - image: circleci/node:8 + steps: + - checkout + - restore_cache: + key: dependency-cache-{{ checksum "package.json" }} + - run: + - yarn + - npm run docs + - save_cache: + key: dependency-cache-{{ checksum "package.json" }} + paths: + - node_modules +workflows: + version: 2 + test_and_docs: + jobs: + - test + - docs + \ No newline at end of file From cd83c01871b84ef99e0e1b122014515923469092 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Mon, 10 Dec 2018 17:56:30 +0530 Subject: [PATCH 02/83] circle ci run fixed --- .circleci/config.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 86bb215de..41ac6838b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -7,11 +7,10 @@ jobs: - checkout - restore_cache: key: dependency-cache-{{ checksum "package.json" }} - - run: - - yarn - - node --version - - truffle version - - npm run test + - run: yarn + - run: node --version + - run: truffle version + - run: npm run test - save_cache: key: dependency-cache-{{ checksum "package.json" }} paths: @@ -23,9 +22,10 @@ jobs: - checkout - restore_cache: key: dependency-cache-{{ checksum "package.json" }} - - run: - - yarn - - npm run docs + - run: yarn + - run: node --version + - run: truffle version + - run: npm run docs - save_cache: key: dependency-cache-{{ checksum "package.json" }} paths: From 1dba68c91b5f24c274d6f4557bfda06f29eba8da Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Mon, 10 Dec 2018 18:00:25 +0530 Subject: [PATCH 03/83] Added global truffle installation --- .circleci/config.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 41ac6838b..feb53b66e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -8,6 +8,7 @@ jobs: - restore_cache: key: dependency-cache-{{ checksum "package.json" }} - run: yarn + - run: npm i truffle -g - run: node --version - run: truffle version - run: npm run test @@ -23,6 +24,7 @@ jobs: - restore_cache: key: dependency-cache-{{ checksum "package.json" }} - run: yarn + - run: npm i truffle -g - run: node --version - run: truffle version - run: npm run docs From e2605859ffae129e2b1e0a862a95492315a5e6d9 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Mon, 10 Dec 2018 18:03:13 +0530 Subject: [PATCH 04/83] Added sudo to global install --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index feb53b66e..f69a20ced 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -8,7 +8,7 @@ jobs: - restore_cache: key: dependency-cache-{{ checksum "package.json" }} - run: yarn - - run: npm i truffle -g + - run: sudo npm i truffle -g - run: node --version - run: truffle version - run: npm run test @@ -24,7 +24,7 @@ jobs: - restore_cache: key: dependency-cache-{{ checksum "package.json" }} - run: yarn - - run: npm i truffle -g + - run: sudo npm i truffle -g - run: node --version - run: truffle version - run: npm run docs From e157e399694c52487d570c716a1f53717f8dca18 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Mon, 10 Dec 2018 18:23:20 +0530 Subject: [PATCH 05/83] Added coverage, parallelism --- .circleci/config.yml | 49 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f69a20ced..00b97d3ce 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,8 +1,26 @@ version: 2 jobs: + build: + docker: + - image: circleci/node:8 + parallelism: 4 + steps: + - checkout + - restore_cache: + key: dependency-cache-{{ checksum "package.json" }} + - run: yarn + - run: sudo npm i truffle -g + - run: node --version + - run: truffle version + - run: truffle compile + - save_cache: + key: dependency-cache-{{ checksum "package.json" }} + paths: + - node_modules test: docker: - image: circleci/node:8 + parallelism: 4 steps: - checkout - restore_cache: @@ -16,6 +34,23 @@ jobs: key: dependency-cache-{{ checksum "package.json" }} paths: - node_modules + coverage: + docker: + - image: circleci/node:8 + parallelism: 4 + steps: + - checkout + - restore_cache: + key: dependency-cache-{{ checksum "package.json" }} + - run: yarn + - run: sudo npm i truffle -g + - run: node --version + - run: truffle version + - run: npm run coverage + - save_cache: + key: dependency-cache-{{ checksum "package.json" }} + paths: + - node_modules docs: docker: - image: circleci/node:8 @@ -34,8 +69,16 @@ jobs: - node_modules workflows: version: 2 - test_and_docs: + build-test-coverage-docs: jobs: - - test - - docs + - build + - test: + - requires: + - build + - coverage: + - requires: + - test + - docs: + - requires: + - coverage \ No newline at end of file From 3df37ca6e471f6a52599980f93677bcccd818fd7 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Mon, 10 Dec 2018 18:27:16 +0530 Subject: [PATCH 06/83] Workflow fixed --- .circleci/config.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 00b97d3ce..2714ad01e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -73,12 +73,12 @@ workflows: jobs: - build - test: - - requires: - - build + requires: + - build - coverage: - - requires: - - test + requires: + - test - docs: - - requires: - - coverage + requires: + - coverage \ No newline at end of file From 2a3a8592e09b198a9e2c28853bfc8eb769001ad1 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Mon, 10 Dec 2018 18:41:25 +0530 Subject: [PATCH 07/83] Removed parallelism --- .circleci/config.yml | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 2714ad01e..26383b3bd 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3,7 +3,6 @@ jobs: build: docker: - image: circleci/node:8 - parallelism: 4 steps: - checkout - restore_cache: @@ -20,7 +19,6 @@ jobs: test: docker: - image: circleci/node:8 - parallelism: 4 steps: - checkout - restore_cache: @@ -37,7 +35,6 @@ jobs: coverage: docker: - image: circleci/node:8 - parallelism: 4 steps: - checkout - restore_cache: @@ -72,13 +69,6 @@ workflows: build-test-coverage-docs: jobs: - build - - test: - requires: - - build - - coverage: - requires: - - test - - docs: - requires: - - coverage - \ No newline at end of file + - test + - coverage + - docs \ No newline at end of file From 30a8c5d624c025dc6f35f27971caafb4d491f7d4 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Thu, 13 Dec 2018 13:13:02 +0530 Subject: [PATCH 08/83] WIP --- .circleci/config.yml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 26383b3bd..fe65e9fca 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -7,7 +7,7 @@ jobs: - checkout - restore_cache: key: dependency-cache-{{ checksum "package.json" }} - - run: yarn + - run: yarn install - run: sudo npm i truffle -g - run: node --version - run: truffle version @@ -23,7 +23,7 @@ jobs: - checkout - restore_cache: key: dependency-cache-{{ checksum "package.json" }} - - run: yarn + - run: yarn install - run: sudo npm i truffle -g - run: node --version - run: truffle version @@ -39,7 +39,7 @@ jobs: - checkout - restore_cache: key: dependency-cache-{{ checksum "package.json" }} - - run: yarn + - run: yarn install - run: sudo npm i truffle -g - run: node --version - run: truffle version @@ -55,7 +55,7 @@ jobs: - checkout - restore_cache: key: dependency-cache-{{ checksum "package.json" }} - - run: yarn + - run: yarn install - run: sudo npm i truffle -g - run: node --version - run: truffle version @@ -68,7 +68,5 @@ workflows: version: 2 build-test-coverage-docs: jobs: - - build - test - - coverage - - docs \ No newline at end of file + - coverage \ No newline at end of file From 6e14dafd84c749810547762e9953d6d3b91ec5d8 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Thu, 13 Dec 2018 13:30:49 +0530 Subject: [PATCH 09/83] CircleCI changes --- .circleci/config.yml | 17 +++++++++++++++-- scripts/coverage.sh | 2 +- scripts/test.sh | 25 ++++++++++--------------- 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index fe65e9fca..cff30c3ee 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -66,7 +66,20 @@ jobs: - node_modules workflows: version: 2 - build-test-coverage-docs: + commit: jobs: + - build - test - - coverage \ No newline at end of file + daily-coverage: + triggers: + - schedule: + cron: "0 0 * * *" + jobs: + - coverage + docs: + filters: + branches: + only: + - master + jobs: + - docs \ No newline at end of file diff --git a/scripts/coverage.sh b/scripts/coverage.sh index e42ed6a84..5d1e2a24e 100755 --- a/scripts/coverage.sh +++ b/scripts/coverage.sh @@ -2,4 +2,4 @@ rm -rf flat -TRAVIS_PULL_REQUEST=true scripts/test.sh \ No newline at end of file +COVERAGE=true scripts/test.sh \ No newline at end of file diff --git a/scripts/test.sh b/scripts/test.sh index 6dd3ce95a..fa569144f 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -19,11 +19,7 @@ cleanup() { fi } -if ! [ -z "${TRAVIS_PULL_REQUEST+x}" ] && [ "$TRAVIS_PULL_REQUEST" != false ]; then - testrpc_port=8545 -else - testrpc_port=8545 -fi +testrpc_port=8545 testrpc_running() { nc -z localhost "$testrpc_port" @@ -60,20 +56,19 @@ start_testrpc() { --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501209,1000000000000000000000000" ) - if ! [ -z "${TRAVIS_PULL_REQUEST+x}" ] && [ "$TRAVIS_PULL_REQUEST" != false ]; then + if [ "$COVERAGE" = true ]; then node_modules/.bin/testrpc-sc --gasLimit 0xfffffffffff --port "$testrpc_port" "${accounts[@]}" > /dev/null & else node_modules/.bin/ganache-cli --gasLimit 8000000 "${accounts[@]}" > /dev/null & fi - testrpc_pid=$! } if testrpc_running; then echo "Using existing testrpc instance" - # Do not start ethereum bridge unless it is a cron job from travis - if [ "$TRAVIS_EVENT_TYPE" = "cron" ]; then + # Do not start ethereum bridge unless it is a cron job + if [ "$CIRCLE_CI_CRON" = true ]; then bridge_running if bridge_running; then echo "Using existing ethereum-bridge instance" @@ -85,23 +80,23 @@ if testrpc_running; then else echo "Starting our own testrpc instance" start_testrpc - # Do not start ethereum bridge unless it is a cron job from travis - if [ "$TRAVIS_EVENT_TYPE" = "cron" ]; then + # Do not start ethereum bridge unless it is a cron job + if [ "$CIRCLE_CI_CRON" = true ]; then echo "Starting our own ethereum-bridge instance" sleep 10 start_bridge fi fi -if ! [ -z "${TRAVIS_PULL_REQUEST+x}" ] && [ "$TRAVIS_PULL_REQUEST" != false ]; then +if [ "$COVERAGE" = true ]; then curl -o node_modules/solidity-coverage/lib/app.js https://raw.githubusercontent.com/maxsam4/solidity-coverage/relative-path/lib/app.js node_modules/.bin/solidity-coverage - if [ "$CONTINUOUS_INTEGRATION" = true ]; then + if [ "$CI" = true ]; then cat coverage/lcov.info | node_modules/.bin/coveralls fi else - # Do not run a_poly_oracle,js tests unless it is a cron job from travis - if [ "$TRAVIS_EVENT_TYPE" = "cron" ]; then + # Do not run a_poly_oracle,js tests unless it is a cron job + if [ "$CIRCLE_CI_CRON" = true ]; then node_modules/.bin/truffle test `ls test/*.js` else node_modules/.bin/truffle test `find test/*.js ! -name a_poly_oracle.js -and ! -name s_v130_to_v140_upgrade.js` From 646952006030fa847b4e1b65be70df8052aa6dc2 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Thu, 13 Dec 2018 13:33:29 +0530 Subject: [PATCH 10/83] CircleCI changes --- .circleci/config.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index cff30c3ee..450b659a2 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -74,6 +74,12 @@ workflows: triggers: - schedule: cron: "0 0 * * *" + filters: + branches: + only: + - master + - development-2.1.0 + - development-3.0.0 jobs: - coverage docs: From 65441f51f012592e937e1c3560f62a143841175a Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Thu, 13 Dec 2018 13:36:04 +0530 Subject: [PATCH 11/83] CircleCI changes --- .circleci/config.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 450b659a2..d74a38924 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -83,9 +83,9 @@ workflows: jobs: - coverage docs: - filters: - branches: - only: - - master jobs: - - docs \ No newline at end of file + - docs: + filters: + branches: + only: + - master \ No newline at end of file From 1c0fd7ca405a4b7277f31baa0c9e2963f81f44e8 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Thu, 13 Dec 2018 13:47:32 +0530 Subject: [PATCH 12/83] Badge --- .circleci/config.yml | 1 + README.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index d74a38924..421f32002 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -70,6 +70,7 @@ workflows: jobs: - build - test + - coverage daily-coverage: triggers: - schedule: diff --git a/README.md b/README.md index 51610e9d4..81f754148 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Build Status](https://travis-ci.org/PolymathNetwork/polymath-core.svg?branch=master)](https://travis-ci.org/PolymathNetwork/polymath-core) +[![CircleCI](https://circleci.com/gh/maxsam4/polymath-core.svg?style=svg)](https://circleci.com/gh/maxsam4/polymath-core) [![Coverage Status](https://coveralls.io/repos/github/PolymathNetwork/polymath-core/badge.svg?branch=master)](https://coveralls.io/github/PolymathNetwork/polymath-core?branch=master) [![Gitter](https://img.shields.io/badge/chat-gitter-green.svg)](https://gitter.im/PolymathNetwork/Lobby) [![Telegram](https://img.shields.io/badge/50k+-telegram-blue.svg)](https://gitter.im/PolymathNetwork/Lobby) [![Greenkeeper badge](https://badges.greenkeeper.io/PolymathNetwork/polymath-core.svg)](https://greenkeeper.io/) From 8f81424d66cd0209dae75649860b21c2adcc2cd8 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Thu, 13 Dec 2018 14:18:02 +0530 Subject: [PATCH 13/83] Store test results --- .circleci/config.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 421f32002..105d4b9aa 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -32,6 +32,8 @@ jobs: key: dependency-cache-{{ checksum "package.json" }} paths: - node_modules + - store_test_results: + path: test-results coverage: docker: - image: circleci/node:8 @@ -48,6 +50,9 @@ jobs: key: dependency-cache-{{ checksum "package.json" }} paths: - node_modules + - store_test_results: + path: test-results + docs: docker: - image: circleci/node:8 From 57db7a93596869b6ae4653df1b9c2d4340669e21 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Thu, 13 Dec 2018 14:35:04 +0530 Subject: [PATCH 14/83] Removed coverage from commit workflow --- .circleci/config.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 105d4b9aa..de4dcba6b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -75,7 +75,6 @@ workflows: jobs: - build - test - - coverage daily-coverage: triggers: - schedule: From 23bf3a83c816e266bcc52c6ff0b623c1d25e1d60 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Thu, 13 Dec 2018 17:07:52 +0530 Subject: [PATCH 15/83] Fix merge conflict --- .circleci/config.yml | 8 +++----- .gitignore | 6 +++++- package.json | 1 + scripts/test.sh | 6 ++++++ truffle-ci.js | 33 +++++++++++++++++++++++++++++++++ yarn.lock | 41 ++++++++++++++++++++++++++++++++++++++++- 6 files changed, 88 insertions(+), 7 deletions(-) create mode 100644 truffle-ci.js diff --git a/.circleci/config.yml b/.circleci/config.yml index de4dcba6b..47f5344f1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -50,9 +50,6 @@ jobs: key: dependency-cache-{{ checksum "package.json" }} paths: - node_modules - - store_test_results: - path: test-results - docs: docker: - image: circleci/node:8 @@ -73,9 +70,9 @@ workflows: version: 2 commit: jobs: - - build - test - daily-coverage: + - coverage + daily-builds: triggers: - schedule: cron: "0 0 * * *" @@ -86,6 +83,7 @@ workflows: - development-2.1.0 - development-3.0.0 jobs: + - test - coverage docs: jobs: diff --git a/.gitignore b/.gitignore index 1693ab75c..f1aed51ad 100644 --- a/.gitignore +++ b/.gitignore @@ -19,4 +19,8 @@ package-lock.json bridge.log .node-xml* .solcover.js.bk -allFiredEvents \ No newline at end of file +allFiredEvents +extract/ +extract.py +extract.zip +/test-results \ No newline at end of file diff --git a/package.json b/package.json index fcf504ea0..57713a060 100644 --- a/package.json +++ b/package.json @@ -89,6 +89,7 @@ "ethereumjs-abi": "^0.6.5", "fast-csv": "^2.4.1", "ganache-cli": "^6.1.8", + "mocha-junit-reporter": "^1.18.0", "prettier": "^1.14.3", "sol-merger": "^0.1.2", "solidity-coverage": "^0.5.11", diff --git a/scripts/test.sh b/scripts/test.sh index fa569144f..12a3704c5 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -95,6 +95,12 @@ if [ "$COVERAGE" = true ]; then cat coverage/lcov.info | node_modules/.bin/coveralls fi else + if [ "$CI" = true ]; then + mkdir test-results + mkdir test-results/mocha + rm truffle-config.js + mv truffle-ci.js truffle-config.js + fi # Do not run a_poly_oracle,js tests unless it is a cron job if [ "$CIRCLE_CI_CRON" = true ]; then node_modules/.bin/truffle test `ls test/*.js` diff --git a/truffle-ci.js b/truffle-ci.js new file mode 100644 index 000000000..f427eb332 --- /dev/null +++ b/truffle-ci.js @@ -0,0 +1,33 @@ +require('babel-register'); +require('babel-polyfill'); + +module.exports = { + networks: { + development: { + host: 'localhost', + port: 8545, + network_id: '*', // Match any network id + gas: 7900000, + }, + coverage: { + host: "localhost", + network_id: "*", + port: 8545, // <-- If you change this, also set the port option in .solcover.js. + gas: 0xfffffffffff, // <-- Use this high gas value + gasPrice: 0x01 // <-- Use this low gas price + } + }, + solc: { + optimizer: { + enabled: true, + runs: 200, + }, + }, + mocha: { + enableTimeouts: false, + reporter: "mocha-junit-reporter", + reporterOptions: { + mochaFile: './test-results/mocha/results.xml' + } + } +}; diff --git a/yarn.lock b/yarn.lock index aba68e85b..c31bbb848 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1373,6 +1373,11 @@ chardet@^0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" +charenc@~0.0.1: + version "0.0.2" + resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" + integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc= + checkpoint-store@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/checkpoint-store/-/checkpoint-store-1.1.0.tgz#04e4cb516b91433893581e6d4601a78e9552ea06" @@ -1708,6 +1713,11 @@ cross-spawn@^6.0.5: semver "^5.5.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, crypto-browserify@^3.11.0: version "3.12.0" @@ -3545,7 +3555,7 @@ is-binary-path@^1.0.0: dependencies: binary-extensions "^1.0.0" -is-buffer@^1.1.5: +is-buffer@^1.1.5, is-buffer@~1.1.1: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" @@ -4207,6 +4217,15 @@ md5.js@^1.3.4: inherits "^2.0.1" safe-buffer "^5.1.2" +md5@^2.1.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/md5/-/md5-2.2.1.tgz#53ab38d5fe3c8891ba465329ea23fac0540126f9" + integrity sha1-U6s41f48iJG6RlMp6iP6wFQBJvk= + dependencies: + charenc "~0.0.1" + crypt "~0.0.1" + is-buffer "~1.1.1" + media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" @@ -4406,12 +4425,27 @@ mkdirp-promise@^5.0.1: dependencies: mkdirp "*" +<<<<<<< HEAD mkdirp@*, mkdirp@0.5.1, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0: +======= +mkdirp@*, mkdirp@0.5.1, mkdirp@0.5.x, mkdirp@0.x.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: +>>>>>>> e543061f... Added test reporter version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" dependencies: minimist "0.0.8" +mocha-junit-reporter@^1.18.0: + version "1.18.0" + resolved "https://registry.yarnpkg.com/mocha-junit-reporter/-/mocha-junit-reporter-1.18.0.tgz#9209a3fba30025ae3ae5e6bfe7f9c5bc3c2e8ee2" + integrity sha512-y3XuqKa2+HRYtg0wYyhW/XsLm2Ps+pqf9HaTAt7+MVUAKFJaNAHOrNseTZo9KCxjfIbxUWwckP5qCDDPUmjSWA== + dependencies: + debug "^2.2.0" + md5 "^2.1.0" + mkdirp "~0.5.1" + strip-ansi "^4.0.0" + xml "^1.0.0" + mocha@^4.0.1, mocha@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/mocha/-/mocha-4.1.0.tgz#7d86cfbcf35cb829e2754c32e17355ec05338794" @@ -7124,6 +7158,11 @@ xhr@^2.0.4, xhr@^2.2.0, xhr@^2.3.3: parse-headers "^2.0.0" xtend "^4.0.0" +xml@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5" + integrity sha1-eLpyAgApxbyHuKgaPPzXS0ovweU= + xmlhttprequest@*, xmlhttprequest@1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc" From edbd4b139db1878e6a993c2f71dbbe50e1a87e99 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Thu, 13 Dec 2018 17:19:47 +0530 Subject: [PATCH 16/83] Addded artifact collection --- .circleci/config.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 47f5344f1..c17f9010e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -34,6 +34,8 @@ jobs: - node_modules - store_test_results: path: test-results + - store_artifacts: + path: ./test-results/mocha/results.xml coverage: docker: - image: circleci/node:8 @@ -50,6 +52,8 @@ jobs: key: dependency-cache-{{ checksum "package.json" }} paths: - node_modules + - store_artifacts: + path: ./coverage/lcov.info docs: docker: - image: circleci/node:8 From 88607d61434cf4e44dfa8629b680a7c86a0afa88 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Thu, 13 Dec 2018 17:34:11 +0530 Subject: [PATCH 17/83] Added parallelism --- .circleci/config.yml | 1 + scripts/test.sh | 9 +++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c17f9010e..1dff7a561 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -19,6 +19,7 @@ jobs: test: docker: - image: circleci/node:8 + parallelism: 2 steps: - checkout - restore_cache: diff --git a/scripts/test.sh b/scripts/test.sh index 12a3704c5..b0b99dd34 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -100,10 +100,11 @@ else mkdir test-results/mocha rm truffle-config.js mv truffle-ci.js truffle-config.js - fi - # Do not run a_poly_oracle,js tests unless it is a cron job - if [ "$CIRCLE_CI_CRON" = true ]; then - node_modules/.bin/truffle test `ls test/*.js` + if [ "$CIRCLE_CI_CRON" = true ]; then + node_modules/.bin/truffle test `ls test/*.js | circleci tests split --split-by=timings` + else + node_modules/.bin/truffle test `find test/*.js ! -name a_poly_oracle.js -and ! -name s_v130_to_v140_upgrade.js | circleci tests split --split-by=timings` + fi else node_modules/.bin/truffle test `find test/*.js ! -name a_poly_oracle.js -and ! -name s_v130_to_v140_upgrade.js` fi From a2ef395857446289641f43232a120451faf7632a Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Thu, 13 Dec 2018 17:44:34 +0530 Subject: [PATCH 18/83] Comment --- scripts/test.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/test.sh b/scripts/test.sh index b0b99dd34..2f4e5b057 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -100,6 +100,7 @@ else mkdir test-results/mocha rm truffle-config.js mv truffle-ci.js truffle-config.js + # only run poly oracle and upgrade tests if cron job by CI if [ "$CIRCLE_CI_CRON" = true ]; then node_modules/.bin/truffle test `ls test/*.js | circleci tests split --split-by=timings` else From f5c1d87afc650cb843abc47903ce0271d270f4f4 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Thu, 13 Dec 2018 17:46:08 +0530 Subject: [PATCH 19/83] Bumped parallelism to 3 --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 1dff7a561..e55982c40 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -19,7 +19,7 @@ jobs: test: docker: - image: circleci/node:8 - parallelism: 2 + parallelism: 3 steps: - checkout - restore_cache: From d84e09dc74990f8ce4f37c16f28bb1bf32bd71ed Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Thu, 13 Dec 2018 17:51:23 +0530 Subject: [PATCH 20/83] Coverage requires approval --- .circleci/config.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index e55982c40..78530ce94 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -76,7 +76,8 @@ workflows: commit: jobs: - test - - coverage + - coverage: + type: approval daily-builds: triggers: - schedule: From e5d28e4472b6d1814560e331cb6d8cb9702c696e Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Thu, 13 Dec 2018 18:06:20 +0530 Subject: [PATCH 21/83] Bumped parallelism to 4 --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 78530ce94..d73bda085 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -19,7 +19,7 @@ jobs: test: docker: - image: circleci/node:8 - parallelism: 3 + parallelism: 4 steps: - checkout - restore_cache: From c8d4b72559558aaef023700a1ae3eb87db9f0c5d Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Thu, 13 Dec 2018 18:12:49 +0530 Subject: [PATCH 22/83] Removed manual approval --- .circleci/config.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index d73bda085..e55982c40 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -19,7 +19,7 @@ jobs: test: docker: - image: circleci/node:8 - parallelism: 4 + parallelism: 3 steps: - checkout - restore_cache: @@ -76,8 +76,7 @@ workflows: commit: jobs: - test - - coverage: - type: approval + - coverage daily-builds: triggers: - schedule: From 97c7b6fe44a8845781dffc842f3e24bf1de3acc1 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Thu, 13 Dec 2018 20:09:16 +0530 Subject: [PATCH 23/83] Combine travis and CircleCI --- .circleci/config.yml | 9 ++++----- .travis.yml | 15 +-------------- README.md | 2 +- 3 files changed, 6 insertions(+), 20 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index e55982c40..986c13c2d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -19,7 +19,7 @@ jobs: test: docker: - image: circleci/node:8 - parallelism: 3 + parallelism: 2 steps: - checkout - restore_cache: @@ -75,7 +75,6 @@ workflows: version: 2 commit: jobs: - - test - coverage daily-builds: triggers: @@ -85,10 +84,10 @@ workflows: branches: only: - master - - development-2.1.0 - - development-3.0.0 + - dev-2.1.0 + - dev-2.2.0 + - dev-3.0.0 jobs: - - test - coverage docs: jobs: diff --git a/.travis.yml b/.travis.yml index 2265b2d88..b676c5840 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,24 +4,11 @@ node_js: cache: directories: - node_modules -matrix: - fast_finish: true - allow_failures: - - env: 'TASK=docs' jobs: include: - - stage: Tests and Coverage - after_install: wget -O node_modules/solidity-coverage/lib/app.js https://raw.githubusercontent.com/maxsam4/solidity-coverage/relative-path/lib/app.js + - stage: test before_script: truffle version script: npm run test - - stage: Docs - env: 'TASK=docs' - before_install: - - echo -ne '\n' | sudo apt-add-repository -y ppa:hvr/z3 - - sudo apt-get -y update - - sudo apt-get -y install libz3-dev - before_script: wget -O node_modules/solidity-docgen/lib/index.js https://raw.githubusercontent.com/maxsam4/solidity-docgen/buffer-size/lib/index.js - script: npm run docs notifications: slack: secure: W4FZSabLrzF74f317hutolEHnlq2GBlQxU6b85L5XymrjgLEhlgE16c5Qz7Emoyt6le6PXL+sfG2ujJc3XYys/6hppgrHSAasuJnKCdQNpmMZ9BNyMs6WGkmB3enIf3K/FLXb26AQdwpQdIXuOeJUTf879u+YoiZV0eZH8d3+fsIOyovq9N6X5pKOpDM9iT8gGB4t7fie7xf51s+iUaHxyO9G7jDginZ4rBXHcU7mxCub9z+Z1H8+kCTnPWaF+KKVEXx4Z0nI3+urboD7E4OIP02LwrThQls2CppA3X0EoesTcdvj/HLErY/JvsXIFiFEEHZzB1Wi+k2TiOeLcYwEuHIVij+HPxxlJNX/j8uy01Uk8s4rd+0EhvfdKHJqUKqxH4YN2npcKfHEss7bU3y7dUinXQfYShW5ZewHdvc7pnnxBTfhvmdi64HdNrXAPq+s1rhciH7MmnU+tsm4lhrpr+FBuHzUMA9fOCr7b0SQytZEgWpiUls88gdbh3yG8TjyZxmZJGx09cwEP0q7VoH0UwFh7mIu5XmYdd5tWUhavTiO7YV8cUPn7MvwMsTltB3YBpF/fB26L7ka8zBhCsjm9prW6SVYU/dyO3m91VeZtO/zJFHRDA6Q58JGVW2rgzO39z193qC1EGRXqTie96VwAAtNg8+hRb+bI/CWDVzSPc= \ No newline at end of file diff --git a/README.md b/README.md index 81f754148..51610e9d4 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![CircleCI](https://circleci.com/gh/maxsam4/polymath-core.svg?style=svg)](https://circleci.com/gh/maxsam4/polymath-core) +[![Build Status](https://travis-ci.org/PolymathNetwork/polymath-core.svg?branch=master)](https://travis-ci.org/PolymathNetwork/polymath-core) [![Coverage Status](https://coveralls.io/repos/github/PolymathNetwork/polymath-core/badge.svg?branch=master)](https://coveralls.io/github/PolymathNetwork/polymath-core?branch=master) [![Gitter](https://img.shields.io/badge/chat-gitter-green.svg)](https://gitter.im/PolymathNetwork/Lobby) [![Telegram](https://img.shields.io/badge/50k+-telegram-blue.svg)](https://gitter.im/PolymathNetwork/Lobby) [![Greenkeeper badge](https://badges.greenkeeper.io/PolymathNetwork/polymath-core.svg)](https://greenkeeper.io/) From 731f1e8ad0a5e67e4aea1a857da371b3df651c87 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Thu, 13 Dec 2018 20:55:37 +0530 Subject: [PATCH 24/83] env var changes --- scripts/test.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/test.sh b/scripts/test.sh index 2f4e5b057..f23df2845 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -91,11 +91,11 @@ fi if [ "$COVERAGE" = true ]; then curl -o node_modules/solidity-coverage/lib/app.js https://raw.githubusercontent.com/maxsam4/solidity-coverage/relative-path/lib/app.js node_modules/.bin/solidity-coverage - if [ "$CI" = true ]; then + if [ "$CIRCLECI" = true ]; then cat coverage/lcov.info | node_modules/.bin/coveralls fi else - if [ "$CI" = true ]; then + if [ "$CIRCLECI" = true ]; then mkdir test-results mkdir test-results/mocha rm truffle-config.js From e20c91a19af0636c3b09928f36946f315af2912a Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Thu, 13 Dec 2018 21:01:27 +0530 Subject: [PATCH 25/83] comment --- scripts/test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/test.sh b/scripts/test.sh index f23df2845..9f595d0ba 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -95,7 +95,7 @@ if [ "$COVERAGE" = true ]; then cat coverage/lcov.info | node_modules/.bin/coveralls fi else - if [ "$CIRCLECI" = true ]; then + if [ "$CIRCLECI" = true ]; then # using mocha junit reporter for parallelism in CircleCI mkdir test-results mkdir test-results/mocha rm truffle-config.js From 896816648e99e52ccdfeb2426c57eaca7df30b32 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Fri, 14 Dec 2018 20:20:15 +0530 Subject: [PATCH 26/83] Increased no o/p timeout --- .circleci/config.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 986c13c2d..a39d287a0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -48,7 +48,9 @@ jobs: - run: sudo npm i truffle -g - run: node --version - run: truffle version - - run: npm run coverage + - run: + command: npm run coverage + no_output_timeout: 1h - save_cache: key: dependency-cache-{{ checksum "package.json" }} paths: @@ -95,4 +97,4 @@ workflows: filters: branches: only: - - master \ No newline at end of file + - master From bf2cca9b4e8acc316422b9bff66bdcb3ab4ca2a9 Mon Sep 17 00:00:00 2001 From: "Charles Plant St.Louis" <32653033+CPSTL@users.noreply.github.com> Date: Mon, 7 Jan 2019 10:41:37 -0500 Subject: [PATCH 27/83] update contributing.md (#486) --- CONTRIBUTING.md | 48 ++++++++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3dadf0761..fc1a6d701 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,12 +1,28 @@ -# Contributing Guidelines +# Contributing to Polymath -## Do you have a question? +🎉 First off, thanks for taking the time to contribute! 🎉 + +The following is a set of guidelines for contributing to Polymath-Core. Use your best judgment, and feel free to propose changes to this document in a pull request. + +## Table of Contents + +1. Do you have a question about Polymath's codebase? +2. Please Report bugs! +3. Contributing +4. Code Styleguide +5. Code of Conduct +6. Scope + + +## 1. Do you have a question about Polymath's codebase? [Check out our Gitter](https://gitter.im/PolymathNetwork/Lobby) -See also frequently asked questions tagged with Polymath on Stack Exchange and Reddit. +You can also check out our frequently asked questions tagged with Polymath on Stack Exchange and Reddit. + +For questions about the dApp, please visit our [Zendesk](https://polymath.zendesk.com/hc/en-us) -# Please Report bugs! +# 2. Please Report bugs! Do not open an issue on Github if you think your discovered bug could be a security-relevant vulnerability. In the case of the discovery of high security venerabilities, pleasse email us the issue privately at team@polymath.network. @@ -15,32 +31,28 @@ Otherwise, just create a new issue in our repository and follow the template bel [Issue template to make things easier for you](https://github.com/PolymathNetwork/polymath-core/blob/master/.github/ISSUE_TEMPLATE/feature_request.md) -# Contribute! +# 3. Contributing Process -If you would like to contribute to Polymath-core, please fork it, fix bugs or implement features, and propose a [pull request](https://github.com/PolymathNetwork/polymath-core/blob/master/PULL_REQUEST_TEMPLATE.md) +When contributing to this repository, please first discuss the change you wish to make via issue, email, or any other method with the owners of this repository before making a change. The process to contribute to Polymath-core is the following: -Please, refer to the Coding Guide on our [Developer Portal](https://developers.polymath.network/) for more details about hacking on Polymath. - -# Contributing - -When contributing to this repository, please first discuss the change you wish to make via issue, email, or any other method with the owners of this repository before making a change. +1. To get started, please fork the most recent development branch [here](https://github.com/PolymathNetwork/polymath-core/tree/dev-2.1.0) +2. Fix bugs or implement features. Please make sure to take extra steps to highlight the changes you are implementing by putting comments in your code. +3. Propose a [pull request](https://github.com/PolymathNetwork/polymath-core/blob/master/PULL_REQUEST_TEMPLATE.md) -Please note we have a code of conduct, please follow it in all your interactions with the project. - -# Pull Request Process +Please, refer to the Coding Guide on our [Developer Portal](https://developers.polymath.network/) for more details about hacking on Polymath. -[Template](https://github.com/PolymathNetwork/polymath-core/blob/master/PULL_REQUEST_TEMPLATE.md) +Please note we have a code of conduct, please follow it. -# Code Styleguide +# 4. Code Styleguide The polymath-core repo follows the [Solidity style guide](https://solidity.readthedocs.io/en/v0.4.24/style-guide.html) -# Code of Conduct +# 5. Code of Conduct [Community Standards](https://github.com/PolymathNetwork/polymath-core/blob/master/CODE_OF_CONDUCT.md) In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community feel safe and respected. -# Scope +# 6. Scope This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. From 3c4531c44996acf319c9a9de0511dd0fb9c3923a Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Thu, 7 Feb 2019 10:01:34 +0530 Subject: [PATCH 28/83] Initial auto deploy --- .circleci/config.yml | 29 +++++++++++++++++++++++++++++ truffle-ci.js | 7 +++++++ 2 files changed, 36 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 841b807b6..71a6bc1ba 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -57,6 +57,24 @@ jobs: - node_modules - store_artifacts: path: ./coverage/lcov.info + deploy_kovan: + docker: + - image: maxsam4/solidity-kit:0.4.24 + steps: + - checkout + - restore_cache: + key: dependency-cache-{{ checksum "package.json" }} + - run: yarn install + - run: node --version + - run: truffle version + - run: mv truffle-ci.js truffle-config.js + - run: + command: truffle deploy --network kovan + no_output_timeout: 1h + - save_cache: + key: dependency-cache-{{ checksum "package.json" }} + paths: + - node_modules docs: docker: - image: circleci/node:8 @@ -78,6 +96,7 @@ workflows: commit: jobs: - coverage + - deploy_kovan daily-builds: triggers: - schedule: @@ -98,3 +117,13 @@ workflows: branches: only: - master + deploy: + jobs: + - deploy_kovan: + filters: + branches: + only: + - master + - dev-2.1.0 + - dev-2.2.0 + - dev-3.0.0 diff --git a/truffle-ci.js b/truffle-ci.js index 049deb0c6..0a5157c33 100644 --- a/truffle-ci.js +++ b/truffle-ci.js @@ -9,6 +9,13 @@ module.exports = { network_id: '*', // Match any network id gas: 7900000, }, + kovan: { + provider: () => { + return new HDWalletProvider(process.env.PRIVATE_KEY, "https://kovan.mudit.blog/"); + }, + network_id: '42', + gasPrice: 2000000000 + }, coverage: { host: "localhost", network_id: "*", From e6fb8bfd3c59e45d8189916e3644aa2a71dca5ee Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Thu, 7 Feb 2019 10:08:33 +0530 Subject: [PATCH 29/83] HDWalletProvider --- package.json | 1 + truffle-ci.js | 2 ++ yarn.lock | 45 ++++++++++++++++++++++++++++++++++++++------- 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index ac5e5b0f9..9641338b9 100644 --- a/package.json +++ b/package.json @@ -91,6 +91,7 @@ "solidity-docgen": "^0.1.0", "solium": "^1.1.8", "truffle": "4.1.14", + "truffle-hdwallet-provider": "^1.0.3", "truffle-wallet-provider": "0.0.5" }, "greenkeeper": { diff --git a/truffle-ci.js b/truffle-ci.js index 0a5157c33..f6d2bf7ae 100644 --- a/truffle-ci.js +++ b/truffle-ci.js @@ -1,6 +1,8 @@ require('babel-register'); require('babel-polyfill'); +let HDWalletProvider = require("truffle-hdwallet-provider"); + module.exports = { networks: { development: { diff --git a/yarn.lock b/yarn.lock index 39e3b7bb3..99f339018 100644 --- a/yarn.lock +++ b/yarn.lock @@ -253,7 +253,7 @@ async-eventemitter@^0.2.2: dependencies: async "^2.4.0" -"async-eventemitter@github:ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c": +async-eventemitter@ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c: version "0.2.3" resolved "https://codeload.github.com/ahultgren/async-eventemitter/tar.gz/fa06e39e56786ba541c180061dbf2c0a5bbf951c" dependencies: @@ -1024,13 +1024,13 @@ bignumber.js@^8.0.1: resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-8.0.1.tgz#5d419191370fb558c64e3e5f70d68e5947138832" integrity sha512-zAySveTJXkgLYCBi0b14xzfnOs+f3G6x36I8w2a1+PFQpWk/dp0mI0F+ZZK2bu+3ELewDcSyP+Cfq++NcHX7sg== -"bignumber.js@git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2": +"bignumber.js@git+https://github.com/debris/bignumber.js#master": version "2.0.7" - resolved "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2" + resolved "git+https://github.com/debris/bignumber.js#c7a38de919ed75e6fb6ba38051986e294b328df9" -"bignumber.js@git+https://github.com/debris/bignumber.js.git#master": +"bignumber.js@git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2": version "2.0.7" - resolved "git+https://github.com/debris/bignumber.js.git#c7a38de919ed75e6fb6ba38051986e294b328df9" + resolved "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2" "bignumber.js@git+https://github.com/frozeman/bignumber.js-nolookahead.git": version "2.0.7" @@ -1046,6 +1046,13 @@ bindings@^1.2.1: resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.3.1.tgz#21fc7c6d67c18516ec5aaa2815b145ff77b26ea5" integrity sha512-i47mqjF9UbjxJhxGf+pZ6kSxrnI3wBLlnGI2ArWJ4r0VrvDS7ZYXkprq/pLaBWYq4GM0r4zdHY+NNRqEMU7uew== +bindings@^1.3.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.4.0.tgz#909efa49f2ebe07ecd3cb136778f665052040127" + integrity sha512-7znEVX22Djn+nYjxCWKDne0RRloa9XfYa84yk3s+HkE3LpDYZmhArYr9O9huBoHY3/oXispx5LorIX7Sl2CgSQ== + dependencies: + file-uri-to-path "1.0.0" + bip66@^1.1.3: version "1.1.5" resolved "https://registry.yarnpkg.com/bip66/-/bip66-1.1.5.tgz#01fa8748785ca70955d5011217d1b3139969ca22" @@ -3030,6 +3037,11 @@ 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-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-regex@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" @@ -4810,7 +4822,7 @@ nan@2.10.0: resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f" integrity sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA== -nan@^2.0.8, nan@^2.2.1, nan@^2.3.3, nan@^2.9.2: +nan@^2.0.8, nan@^2.11.0, nan@^2.2.1, nan@^2.3.3, nan@^2.9.2: version "2.12.1" resolved "https://registry.yarnpkg.com/nan/-/nan-2.12.1.tgz#7b1aa193e9aa86057e3c7bbd0ac448e770925552" integrity sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw== @@ -6871,6 +6883,15 @@ truffle-hdwallet-provider-privkey@0.3.0: web3 "^0.20.6" web3-provider-engine "^13.8.0" +truffle-hdwallet-provider@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/truffle-hdwallet-provider/-/truffle-hdwallet-provider-1.0.3.tgz#4ae845f9b2de23f47c4f0fbc6ef2d4b13b494604" + integrity sha512-Lm4MrXHnWg8wHNUoumUBc8AhlCBg05x7wZA81JOFfO0j3QU53A/hhSfV7v8gANbRsvpF5Su0s3SNQGJjewtnYw== + dependencies: + any-promise "^1.3.0" + bindings "^1.3.1" + websocket "^1.0.28" + truffle-wallet-provider@0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/truffle-wallet-provider/-/truffle-wallet-provider-0.0.5.tgz#db59ce6fa1c558766011137509a94dfca8d1408e" @@ -6943,7 +6964,7 @@ typechecker@~2.0.1: resolved "https://registry.yarnpkg.com/typechecker/-/typechecker-2.0.8.tgz#e83da84bb64c584ccb345838576c40b0337db82e" integrity sha1-6D2oS7ZMWEzLNFg4V2xAsDN9uC4= -typedarray-to-buffer@^3.1.2: +typedarray-to-buffer@^3.1.2, typedarray-to-buffer@^3.1.5: version "3.1.5" resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== @@ -7450,6 +7471,16 @@ web3@^0.20.6: xhr2-cookies "^1.1.0" xmlhttprequest "*" +websocket@^1.0.28: + version "1.0.28" + resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.28.tgz#9e5f6fdc8a3fe01d4422647ef93abdd8d45a78d3" + integrity sha512-00y/20/80P7H4bCYkzuuvvfDvh+dgtXi5kzDf3UcZwN6boTYaKvsrtZ5lIYm1Gsg48siMErd9M4zjSYfYFHTrA== + dependencies: + debug "^2.2.0" + nan "^2.11.0" + typedarray-to-buffer "^3.1.5" + yaeti "^0.0.6" + "websocket@git://github.com/frozeman/WebSocket-Node.git#browserifyCompatible": version "1.0.26" resolved "git://github.com/frozeman/WebSocket-Node.git#6c72925e3f8aaaea8dc8450f97627e85263999f2" From ad72cc226ceedcd2b29cd424863a8ca1663e438f Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Thu, 7 Feb 2019 10:14:22 +0530 Subject: [PATCH 30/83] Use local truffle --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 71a6bc1ba..ef877b4db 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -69,7 +69,7 @@ jobs: - run: truffle version - run: mv truffle-ci.js truffle-config.js - run: - command: truffle deploy --network kovan + command: node_modules/.bin/truffle deploy --network kovan no_output_timeout: 1h - save_cache: key: dependency-cache-{{ checksum "package.json" }} From 5c10dfbebf8b4506886ea71868803d2f8caddf5c Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Thu, 7 Feb 2019 10:30:39 +0530 Subject: [PATCH 31/83] Deploy only on dev and master branches --- .circleci/config.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ef877b4db..2935ae4af 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -96,7 +96,6 @@ workflows: commit: jobs: - coverage - - deploy_kovan daily-builds: triggers: - schedule: From f775272bc507cd9367088414bf55880d53715b46 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Sat, 9 Feb 2019 12:06:36 +0530 Subject: [PATCH 32/83] Added deploy script --- scripts/deploy.sh | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100755 scripts/deploy.sh diff --git a/scripts/deploy.sh b/scripts/deploy.sh new file mode 100755 index 000000000..f961fb5fd --- /dev/null +++ b/scripts/deploy.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +node_modules/.bin/truffle deploy --network kovan +address=$(grep build/contracts/PolymathRegistry.json -e "\"address\":" | grep -o "0[0-9a-z]*") +commitId=$(git rev-parse HEAD) +branchName=$(git rev-parse --abbrev-ref HEAD) +commitName=$(git log -1 --pretty=%B) +data='{"text":"Somebody merged a new pull request!\nBranch Name: '$branchName'\nCommit Name: '$commitName'\nCommit ID: '$commitId'\nPolymath Registry Address(Kovan): '$address'"}' +curl -X POST -H 'Content-type: application/json' --data "$data" ${SLACK_DEVNOTIFACTIONS_WH} \ No newline at end of file From 287fe50e4d64b1addcde3b29719c045f7ab67c7b Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Sat, 9 Feb 2019 12:10:44 +0530 Subject: [PATCH 33/83] Enabled deployment on commit --- .circleci/config.yml | 5 ++--- package.json | 1 + 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 2935ae4af..b3e81a7e7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -68,9 +68,7 @@ jobs: - run: node --version - run: truffle version - run: mv truffle-ci.js truffle-config.js - - run: - command: node_modules/.bin/truffle deploy --network kovan - no_output_timeout: 1h + - run: npm run deploy-kovan - save_cache: key: dependency-cache-{{ checksum "package.json" }} paths: @@ -96,6 +94,7 @@ workflows: commit: jobs: - coverage + - deploy_kovan daily-builds: triggers: - schedule: diff --git a/package.json b/package.json index 9641338b9..fbaf43ed0 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ }, "scripts": { "test": "scripts/test.sh 2> /dev/null", + "deploy-kovan": "scripts/deploy.sh", "wintest": "scripts\\wintest.cmd", "wincov": "scripts\\wincov.cmd", "docs": "scripts/docs.sh", From 2967a6cb492f4c318bccc15e929c957630d5b285 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Sat, 9 Feb 2019 12:22:56 +0530 Subject: [PATCH 34/83] Deploy only on dev/master branches --- .circleci/config.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b3e81a7e7..da2111136 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -94,7 +94,6 @@ workflows: commit: jobs: - coverage - - deploy_kovan daily-builds: triggers: - schedule: From 411e8741e243f0e4bec54d7ee31d21a53f68c121 Mon Sep 17 00:00:00 2001 From: Pablo Ruiz Date: Fri, 1 Mar 2019 12:59:26 -0300 Subject: [PATCH 35/83] Add files via upload --- ...olymath DividendCheckpoint Audit Report.pdf | Bin 0 -> 175032 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 audit reports/Polymath DividendCheckpoint Audit Report.pdf diff --git a/audit reports/Polymath DividendCheckpoint Audit Report.pdf b/audit reports/Polymath DividendCheckpoint Audit Report.pdf new file mode 100644 index 0000000000000000000000000000000000000000..ecbdfcec18ad631717fa82980b348ff785e0ec2a GIT binary patch literal 175032 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,LF!yYL@ly9k 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 Date: Wed, 6 Mar 2019 17:10:38 +0530 Subject: [PATCH 36/83] Force overrite existing solc --- scripts/docs.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/docs.sh b/scripts/docs.sh index af7f6e395..fc09d7556 100755 --- a/scripts/docs.sh +++ b/scripts/docs.sh @@ -33,8 +33,9 @@ create_docs() { fi echo "Fetching solc binary" + rm -f solidity-ubuntu-trusty.zip curl -L -o solidity-ubuntu-trusty.zip https://github.com/ethereum/solidity/releases/download/v0.4.24/solidity-ubuntu-trusty.zip - unzip solidity-ubuntu-trusty.zip + unzip -o solidity-ubuntu-trusty.zip CWD=$(pwd) OLD_SOLC_PATH=$SOLC_PATH export SOLC_PATH=$CWD/solc From 577dd46139214ad0ffa4af1f3c439ab6136cbcf3 Mon Sep 17 00:00:00 2001 From: Victor Date: Wed, 6 Mar 2019 12:20:11 -0300 Subject: [PATCH 37/83] Fix reading factory address from module registry for dividends modules --- CLI/commands/dividends_manager.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/CLI/commands/dividends_manager.js b/CLI/commands/dividends_manager.js index 0b4dd8f39..9f091d7dc 100644 --- a/CLI/commands/dividends_manager.js +++ b/CLI/commands/dividends_manager.js @@ -586,14 +586,18 @@ to account ${ event._claimer} ` async function addDividendsModule() { let availableModules = await moduleRegistry.methods.getModulesByTypeAndToken(gbl.constants.MODULES_TYPES.DIVIDENDS, securityToken.options.address).call(); - let options = await Promise.all(availableModules.map(async function (m) { + let moduleList = await Promise.all(availableModules.map(async function (m) { let moduleFactoryABI = abis.moduleFactory(); let moduleFactory = new web3.eth.Contract(moduleFactoryABI, m); - return web3.utils.hexToUtf8(await moduleFactory.methods.name().call()); + let moduleName = web3.utils.hexToUtf8(await moduleFactory.methods.name().call()); + let moduleVersion = await moduleFactory.methods.version().call(); + return { name: moduleName, version: moduleVersion, factoryAddress: m }; })); + let options = moduleList.map(m => `${m.name} - ${m.version} (${m.factoryAddress})`); + let index = readlineSync.keyInSelect(options, 'Which dividends module do you want to add? ', { cancel: 'Return' }); - if (index != -1 && readlineSync.keyInYNStrict(`Are you sure you want to add ${options[index]} module? `)) { + if (index != -1 && readlineSync.keyInYNStrict(`Are you sure you want to add ${options[index]}? `)) { let wallet = readlineSync.question('Enter the account address to receive reclaimed dividends and tax: ', { limit: function (input) { return web3.utils.isAddress(input); @@ -603,7 +607,7 @@ async function addDividendsModule() { let configureFunction = abis.erc20DividendCheckpoint().find(o => o.name === 'configure' && o.type === 'function'); let bytes = web3.eth.abi.encodeFunctionCall(configureFunction, [wallet]); - let selectedDividendFactoryAddress = await contracts.getModuleFactoryAddressByName(securityToken.options.address, gbl.constants.MODULES_TYPES.DIVIDENDS, options[index]); + let selectedDividendFactoryAddress = moduleList[index].factoryAddress; let addModuleAction = securityToken.methods.addModule(selectedDividendFactoryAddress, bytes, 0, 0); let receipt = await common.sendTransaction(addModuleAction); let event = common.getEventFromLogs(securityToken._jsonInterface, receipt.logs, 'ModuleAdded'); From fb7bfd3d86278a792ba4e681dcafbf6504f5b113 Mon Sep 17 00:00:00 2001 From: Victor Date: Wed, 6 Mar 2019 15:51:54 -0300 Subject: [PATCH 38/83] Alternative symbol() ABI for ERC20 tokens --- CLI/commands/dividends_manager.js | 31 ++++++++++++++++++++------- CLI/commands/helpers/contract_abis.js | 12 +++++++++++ 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/CLI/commands/dividends_manager.js b/CLI/commands/dividends_manager.js index 9f091d7dc..f4aca926e 100644 --- a/CLI/commands/dividends_manager.js +++ b/CLI/commands/dividends_manager.js @@ -240,8 +240,7 @@ async function manageExistingDividend(dividendIndex) { let dividendTokenSymbol = 'ETH'; if (dividendsType === 'ERC20') { dividendTokenAddress = await currentDividendsModule.methods.dividendTokens(dividendIndex).call(); - let erc20token = new web3.eth.Contract(abis.erc20(), dividendTokenAddress); - dividendTokenSymbol = await erc20token.methods.symbol().call(); + dividendTokenSymbol = await getERC20TokenSymbol(dividendTokenAddress); } let progress = await currentDividendsModule.methods.getDividendProgress(dividendIndex).call(); let investorArray = progress[0]; @@ -387,10 +386,11 @@ async function createDividends() { limitMessage: "Must be a valid ERC20 address", defaultInput: polyToken.options.address }); - token = new web3.eth.Contract(abis.erc20(), dividendToken); - try { - dividendSymbol = await token.methods.symbol().call(); - } catch (err) { + let erc20Symbol = await getERC20TokenSymbol(dividendToken); + if (erc20Symbol != null) { + token = new web3.eth.Contract(abis.erc20(), dividendToken); + dividendSymbol = erc20Symbol; + } else { console.log(chalk.red(`${dividendToken} is not a valid ERC20 token address!!`)); } } while (dividendSymbol === 'ETH'); @@ -738,8 +738,7 @@ async function getDividends() { let tokenSymbol = 'ETH'; if (dividendsType === 'ERC20') { let tokenAddress = await currentDividendsModule.methods.dividendTokens(i).call(); - let erc20token = new web3.eth.Contract(abis.erc20(), tokenAddress); - tokenSymbol = await erc20token.methods.symbol().call(); + tokenSymbol = await getERC20TokenSymbol(tokenAddress); } dividends.push( new DividendData( @@ -885,6 +884,22 @@ async function selectToken() { return result; } +async function getERC20TokenSymbol(tokenAddress) { + let tokenSymbol = null; + try { + let erc20token = new web3.eth.Contract(abis.erc20(), tokenAddress); + tokenSymbol = await erc20token.methods.symbol().call(); + } catch (err) { + try { + // Some ERC20 tokens use bytes32 for symbol instead of string + let erc20token = new web3.eth.Contract(abis.alternativeErc20(), tokenAddress); + tokenSymbol = web3.utils.hexToUtf8(await erc20token.methods.symbol().call()); + } catch (err) { + } + } + return tokenSymbol; +} + module.exports = { executeApp: async function (_tokenSymbol) { await initialize(_tokenSymbol); diff --git a/CLI/commands/helpers/contract_abis.js b/CLI/commands/helpers/contract_abis.js index 67dc43244..f5d8064a6 100644 --- a/CLI/commands/helpers/contract_abis.js +++ b/CLI/commands/helpers/contract_abis.js @@ -140,5 +140,17 @@ module.exports = { }, erc20: function () { return erc20ABI; + }, + alternativeErc20: function () { + let alternativeErc20 = [{ + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [{ "name": "", "type": "bytes32" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }]; + return alternativeErc20; } } \ No newline at end of file From fd51e7abaad3d01bbf4697349e0a827fa64e356e Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Thu, 7 Mar 2019 21:45:43 +0530 Subject: [PATCH 39/83] STO fixes (#583) * Minor STO changes * typo fix * Added STO interface * Typo fixed * Refund remaining amount in last cappedsto tx --- contracts/interfaces/ISTO.sol | 11 +++++ contracts/modules/STO/CappedSTO.sol | 47 ++++++------------- contracts/modules/STO/DummySTO.sol | 4 +- contracts/modules/STO/PreSaleSTO.sol | 4 +- contracts/modules/STO/{ISTO.sol => STO.sol} | 14 ++---- .../STO/{ISTOStorage.sol => STOStorage.sol} | 6 +-- contracts/modules/STO/USDTieredSTO.sol | 32 ++++++------- contracts/proxy/USDTieredSTOProxy.sol | 4 +- contracts/storage/USDTieredSTOStorage.sol | 3 -- test/p_usd_tiered_sto.js | 3 +- 10 files changed, 57 insertions(+), 71 deletions(-) create mode 100644 contracts/interfaces/ISTO.sol rename contracts/modules/STO/{ISTO.sol => STO.sol} (87%) rename contracts/modules/STO/{ISTOStorage.sol => STOStorage.sol} (88%) diff --git a/contracts/interfaces/ISTO.sol b/contracts/interfaces/ISTO.sol new file mode 100644 index 000000000..dd5ce3f16 --- /dev/null +++ b/contracts/interfaces/ISTO.sol @@ -0,0 +1,11 @@ +pragma solidity ^0.4.24; + +/** + * @title Interface to be implemented by all STO modules + */ +interface ISTO { + /** + * @notice Returns the total no. of tokens sold + */ + function getTokensSold() external view returns (uint256); +} diff --git a/contracts/modules/STO/CappedSTO.sol b/contracts/modules/STO/CappedSTO.sol index af091dacf..3245aa3f5 100644 --- a/contracts/modules/STO/CappedSTO.sol +++ b/contracts/modules/STO/CappedSTO.sol @@ -1,6 +1,6 @@ pragma solidity ^0.4.24; -import "./ISTO.sol"; +import "./STO.sol"; import "../../interfaces/ISecurityToken.sol"; import "openzeppelin-solidity/contracts/ReentrancyGuard.sol"; import "openzeppelin-solidity/contracts/math/SafeMath.sol"; @@ -8,7 +8,7 @@ import "openzeppelin-solidity/contracts/math/SafeMath.sol"; /** * @title STO module for standard capped crowdsale */ -contract CappedSTO is ISTO, ReentrancyGuard { +contract CappedSTO is STO, ReentrancyGuard { using SafeMath for uint256; // Determine whether users can invest on behalf of a beneficiary @@ -51,7 +51,7 @@ contract CappedSTO is ISTO, ReentrancyGuard { * @param _startTime Unix timestamp at which offering get started * @param _endTime Unix timestamp at which offering get ended * @param _cap Maximum No. of token base units for sale - * @param _rate Token units a buyer gets multiplied by 10^18 per wei / base unit of POLY + * @param _rate Token units a buyer gets multiplied by 10^18 per wei / base unit of POLY * @param _fundRaiseTypes Type of currency used to collect the funds * @param _fundsReceiver Ethereum account address to hold the funds */ @@ -115,7 +115,6 @@ contract CappedSTO is ISTO, ReentrancyGuard { weiAmount = weiAmount.sub(refund); _forwardFunds(refund); - _postValidatePurchase(_beneficiary, weiAmount); } /** @@ -127,7 +126,6 @@ contract CappedSTO is ISTO, ReentrancyGuard { require(fundRaiseTypes[uint8(FundRaiseType.POLY)], "Mode of investment is not POLY"); uint256 refund = _processTx(msg.sender, _investedPOLY); _forwardPoly(msg.sender, wallet, _investedPOLY.sub(refund)); - _postValidatePurchase(msg.sender, _investedPOLY.sub(refund)); } /** @@ -161,7 +159,7 @@ contract CappedSTO is ISTO, ReentrancyGuard { * @return Token units a buyer gets(multiplied by 10^18) per wei / base unit of POLY * @return Amount of funds raised * @return Number of individual investors this STO have. - * @return Amount of tokens get sold. + * @return Amount of tokens get sold. * @return Boolean value to justify whether the fund raise type is POLY or not, i.e true for POLY. */ function getSTODetails() public view returns(uint256, uint256, uint256, uint256, uint256, uint256, uint256, bool) { @@ -203,8 +201,6 @@ contract CappedSTO is ISTO, ReentrancyGuard { _processPurchase(_beneficiary, tokens); emit TokenPurchase(msg.sender, _beneficiary, _investedAmount, tokens); - - _updatePurchasingState(_beneficiary, _investedAmount); } /** @@ -216,21 +212,10 @@ contract CappedSTO is ISTO, ReentrancyGuard { function _preValidatePurchase(address _beneficiary, uint256 _investedAmount) internal view { require(_beneficiary != address(0), "Beneficiary address should not be 0x"); require(_investedAmount != 0, "Amount invested should not be equal to 0"); - uint256 tokens; - (tokens, ) = _getTokenAmount(_investedAmount); - require(totalTokensSold.add(tokens) <= cap, "Investment more than cap is not allowed"); /*solium-disable-next-line security/no-block-members*/ require(now >= startTime && now <= endTime, "Offering is closed/Not yet started"); } - /** - * @notice Validation of an executed purchase. - Observe state and use revert statements to undo rollback when valid conditions are not met. - */ - function _postValidatePurchase(address /*_beneficiary*/, uint256 /*_investedAmount*/) internal pure { - // optional override - } - /** * @notice Source of tokens. Override this method to modify the way in which the crowdsale ultimately gets and sends its tokens. @@ -255,27 +240,23 @@ contract CappedSTO is ISTO, ReentrancyGuard { _deliverTokens(_beneficiary, _tokenAmount); } - /** - * @notice Overrides for extensions that require an internal state to check for validity - (current user contributions, etc.) - */ - function _updatePurchasingState(address /*_beneficiary*/, uint256 /*_investedAmount*/) internal pure { - // optional override - } - /** * @notice Overrides to extend the way in which ether is converted to tokens. * @param _investedAmount Value in wei to be converted into tokens * @return Number of tokens that can be purchased with the specified _investedAmount * @return Remaining amount that should be refunded to the investor */ - function _getTokenAmount(uint256 _investedAmount) internal view returns (uint256 _tokens, uint256 _refund) { - _tokens = _investedAmount.mul(rate); - _tokens = _tokens.div(uint256(10) ** 18); + function _getTokenAmount(uint256 _investedAmount) internal view returns (uint256 tokens, uint256 refund) { + tokens = _investedAmount.mul(rate); + tokens = tokens.div(uint256(10) ** 18); + if (totalTokensSold.add(tokens) > cap) { + tokens = cap.sub(totalTokensSold); + } uint256 granularity = ISecurityToken(securityToken).granularity(); - _tokens = _tokens.div(granularity); - _tokens = _tokens.mul(granularity); - _refund = _investedAmount.sub((_tokens.mul(uint256(10) ** 18)).div(rate)); + tokens = tokens.div(granularity); + tokens = tokens.mul(granularity); + require(tokens > 0, "Cap reached"); + refund = _investedAmount.sub((tokens.mul(uint256(10) ** 18)).div(rate)); } /** diff --git a/contracts/modules/STO/DummySTO.sol b/contracts/modules/STO/DummySTO.sol index 1b44d2e9b..fafc6c1c4 100644 --- a/contracts/modules/STO/DummySTO.sol +++ b/contracts/modules/STO/DummySTO.sol @@ -1,12 +1,12 @@ pragma solidity ^0.4.24; -import "./ISTO.sol"; +import "./STO.sol"; import "../../interfaces/ISecurityToken.sol"; /** * @title STO module for sample implementation of a different crowdsale module */ -contract DummySTO is ISTO { +contract DummySTO is STO { bytes32 public constant ADMIN = "ADMIN"; diff --git a/contracts/modules/STO/PreSaleSTO.sol b/contracts/modules/STO/PreSaleSTO.sol index 7378fb06b..4dacaa2d7 100644 --- a/contracts/modules/STO/PreSaleSTO.sol +++ b/contracts/modules/STO/PreSaleSTO.sol @@ -1,13 +1,13 @@ pragma solidity ^0.4.24; -import "./ISTO.sol"; +import "./STO.sol"; import "../../interfaces/ISecurityToken.sol"; import "openzeppelin-solidity/contracts/math/SafeMath.sol"; /** * @title STO module for private presales */ -contract PreSaleSTO is ISTO { +contract PreSaleSTO is STO { using SafeMath for uint256; bytes32 public constant PRE_SALE_ADMIN = "PRE_SALE_ADMIN"; diff --git a/contracts/modules/STO/ISTO.sol b/contracts/modules/STO/STO.sol similarity index 87% rename from contracts/modules/STO/ISTO.sol rename to contracts/modules/STO/STO.sol index 6fb216566..5f9a6e9e3 100644 --- a/contracts/modules/STO/ISTO.sol +++ b/contracts/modules/STO/STO.sol @@ -3,17 +3,18 @@ pragma solidity ^0.4.24; import "../../Pausable.sol"; import "../Module.sol"; import "../../interfaces/IERC20.sol"; -import "./ISTOStorage.sol"; +import "../../interfaces/ISTO.sol"; +import "./STOStorage.sol"; import "openzeppelin-solidity/contracts/math/SafeMath.sol"; /** * @title Interface to be implemented by all STO modules */ -contract ISTO is ISTOStorage, Module, Pausable { +contract STO is ISTO, STOStorage, Module, Pausable { using SafeMath for uint256; enum FundRaiseType { ETH, POLY, SC } - + // Event event SetFundRaiseTypes(FundRaiseType[] _fundRaiseTypes); @@ -36,11 +37,6 @@ contract ISTO is ISTOStorage, Module, Pausable { return fundsRaised[uint8(_fundRaiseType)]; } - /** - * @notice Returns the total no. of tokens sold - */ - function getTokensSold() public view returns (uint256); - /** * @notice Pause (overridden function) */ @@ -59,7 +55,7 @@ contract ISTO is ISTOStorage, Module, Pausable { function _setFundRaiseType(FundRaiseType[] _fundRaiseTypes) internal { // FundRaiseType[] parameter type ensures only valid values for _fundRaiseTypes - require(_fundRaiseTypes.length > 0, "Raise type is not specified"); + require(_fundRaiseTypes.length > 0 && _fundRaiseTypes.length <= 3, "Raise type is not specified"); fundRaiseTypes[uint8(FundRaiseType.ETH)] = false; fundRaiseTypes[uint8(FundRaiseType.POLY)] = false; fundRaiseTypes[uint8(FundRaiseType.SC)] = false; diff --git a/contracts/modules/STO/ISTOStorage.sol b/contracts/modules/STO/STOStorage.sol similarity index 88% rename from contracts/modules/STO/ISTOStorage.sol rename to contracts/modules/STO/STOStorage.sol index b808c98b4..2e2401fb0 100644 --- a/contracts/modules/STO/ISTOStorage.sol +++ b/contracts/modules/STO/STOStorage.sol @@ -1,9 +1,9 @@ pragma solidity ^0.4.24; /** - * @title Storage layout for the ISTO contract + * @title Storage layout for the STO contract */ -contract ISTOStorage { +contract STOStorage { mapping (uint8 => bool) public fundRaiseTypes; mapping (uint8 => uint256) public fundsRaised; @@ -21,4 +21,4 @@ contract ISTOStorage { // Final amount of tokens sold uint256 public totalTokensSold; -} \ No newline at end of file +} diff --git a/contracts/modules/STO/USDTieredSTO.sol b/contracts/modules/STO/USDTieredSTO.sol index f1c959671..c29402355 100644 --- a/contracts/modules/STO/USDTieredSTO.sol +++ b/contracts/modules/STO/USDTieredSTO.sol @@ -1,6 +1,6 @@ pragma solidity ^0.4.24; -import "./ISTO.sol"; +import "./STO.sol"; import "../../interfaces/ISecurityToken.sol"; import "../../interfaces/IOracle.sol"; import "../../RegistryUpdater.sol"; @@ -12,7 +12,7 @@ import "../../storage/USDTieredSTOStorage.sol"; /** * @title STO module for standard capped crowdsale */ -contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard { +contract USDTieredSTO is USDTieredSTOStorage, STO, ReentrancyGuard { using SafeMath for uint256; string public constant POLY_ORACLE = "PolyUsdOracle"; @@ -262,7 +262,7 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard { } usdTokens = _usdTokens; for(i = 0; i < _usdTokens.length; i++) { - require(_usdTokens[i] != address(0), "Invalid USD token"); + require(_usdTokens[i] != address(0) && _usdTokens[i] != address(polyToken), "Invalid USD token"); usdTokenEnabled[_usdTokens[i]] = true; } emit SetAddresses(wallet, reserveWallet, _usdTokens); @@ -276,7 +276,7 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard { * @notice Finalizes the STO and mint remaining tokens to reserve address * @notice Reserve address must be whitelisted to successfully finalize */ - function finalize() public onlyOwner { + function finalize() external onlyOwner { require(!isFinalized, "STO is already finalized"); isFinalized = true; uint256 tempReturned; @@ -301,7 +301,7 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard { * @param _investors Array of investor addresses to modify * @param _accredited Array of bools specifying accreditation status */ - function changeAccredited(address[] _investors, bool[] _accredited) public onlyOwner { + function changeAccredited(address[] _investors, bool[] _accredited) external onlyOwner { require(_investors.length == _accredited.length, "Array length mismatch"); for (uint256 i = 0; i < _investors.length; i++) { if (_accredited[i]) { @@ -319,7 +319,7 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard { * @param _investors Array of investor addresses to modify * @param _nonAccreditedLimit Array of uints specifying non-accredited limits */ - function changeNonAccreditedLimit(address[] _investors, uint256[] _nonAccreditedLimit) public onlyOwner { + function changeNonAccreditedLimit(address[] _investors, uint256[] _nonAccreditedLimit) external onlyOwner { //nonAccreditedLimitUSDOverride require(_investors.length == _nonAccreditedLimit.length, "Array length mismatch"); for (uint256 i = 0; i < _investors.length; i++) { @@ -357,7 +357,7 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard { * @notice Function to set allowBeneficialInvestments (allow beneficiary to be different to funder) * @param _allowBeneficialInvestments Boolean to allow or disallow beneficial investments */ - function changeAllowBeneficialInvestments(bool _allowBeneficialInvestments) public onlyOwner { + function changeAllowBeneficialInvestments(bool _allowBeneficialInvestments) external onlyOwner { require(_allowBeneficialInvestments != allowBeneficialInvestments, "Value unchanged"); allowBeneficialInvestments = _allowBeneficialInvestments; emit SetAllowBeneficialInvestments(allowBeneficialInvestments); @@ -508,7 +508,7 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard { uint256 _investmentValue, FundRaiseType _fundRaiseType ) - public + external view returns(uint256 spentUSD, uint256 spentValue, uint256 tokensMinted) { @@ -732,7 +732,7 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard { * @param _amount Value to convert to USD * @return uint256 Value in USD */ - function convertToUSD(FundRaiseType _fundRaiseType, uint256 _amount) public view returns(uint256) { + function convertToUSD(FundRaiseType _fundRaiseType, uint256 _amount) external view returns(uint256) { uint256 rate = getRate(_fundRaiseType); return DecimalMath.mul(_amount, rate); } @@ -743,7 +743,7 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard { * @param _amount Value to convert from USD * @return uint256 Value in ETH or POLY */ - function convertFromUSD(FundRaiseType _fundRaiseType, uint256 _amount) public view returns(uint256) { + function convertFromUSD(FundRaiseType _fundRaiseType, uint256 _amount) external view returns(uint256) { uint256 rate = getRate(_fundRaiseType); return DecimalMath.div(_amount, rate); } @@ -776,7 +776,7 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard { * param _fundRaiseType The fund raising currency (e.g. ETH, POLY, SC) to calculate sold tokens for * @return uint256 Total number of tokens sold for ETH */ - function getTokensSoldFor(FundRaiseType _fundRaiseType) public view returns (uint256) { + function getTokensSoldFor(FundRaiseType _fundRaiseType) external view returns (uint256) { uint256 tokensSold; for (uint256 i = 0; i < tiers.length; i++) { tokensSold = tokensSold.add(tiers[i].minted[uint8(_fundRaiseType)]); @@ -789,7 +789,7 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard { * param _tier The tier to return minted tokens for * @return uint256[] array of minted tokens in each fund raise type */ - function getTokensMintedByTier(uint256 _tier) public view returns (uint256[]) { + function getTokensMintedByTier(uint256 _tier) external view returns (uint256[]) { require(_tier < tiers.length, "Invalid tier"); uint256[] memory tokensMinted = new uint256[](3); tokensMinted[0] = tiers[_tier].minted[uint8(FundRaiseType.ETH)]; @@ -803,7 +803,7 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard { * param _tier The tier to calculate sold tokens for * @return uint256 Total number of tokens sold in the tier */ - function getTokensSoldByTier(uint256 _tier) public view returns (uint256) { + function getTokensSoldByTier(uint256 _tier) external view returns (uint256) { require(_tier < tiers.length, "Incorrect tier"); uint256 tokensSold; tokensSold = tokensSold.add(tiers[_tier].minted[uint8(FundRaiseType.ETH)]); @@ -816,7 +816,7 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard { * @notice Return the total no. of tiers * @return uint256 Total number of tiers */ - function getNumberOfTiers() public view returns (uint256) { + function getNumberOfTiers() external view returns (uint256) { return tiers.length; } @@ -824,7 +824,7 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard { * @notice Return the usd tokens accepted by the STO * @return address[] usd tokens */ - function getUsdTokens() public view returns (address[]) { + function getUsdTokens() external view returns (address[]) { return usdTokens; } @@ -848,7 +848,7 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard { * @return Amount of tokens sold. * @return Array of bools to show if funding is allowed in ETH, POLY, SC respectively */ - function getSTODetails() public view returns(uint256, uint256, uint256, uint256[], uint256[], uint256, uint256, uint256, bool[]) { + function getSTODetails() external view returns(uint256, uint256, uint256, uint256[], uint256[], uint256, uint256, uint256, bool[]) { uint256[] memory cap = new uint256[](tiers.length); uint256[] memory rate = new uint256[](tiers.length); for(uint256 i = 0; i < tiers.length; i++) { diff --git a/contracts/proxy/USDTieredSTOProxy.sol b/contracts/proxy/USDTieredSTOProxy.sol index a412a8278..050e14a21 100644 --- a/contracts/proxy/USDTieredSTOProxy.sol +++ b/contracts/proxy/USDTieredSTOProxy.sol @@ -4,13 +4,13 @@ import "../storage/USDTieredSTOStorage.sol"; import "./OwnedProxy.sol"; import "../Pausable.sol"; import "openzeppelin-solidity/contracts/ReentrancyGuard.sol"; -import "../modules/STO/ISTOStorage.sol"; +import "../modules/STO/STOStorage.sol"; import "../modules/ModuleStorage.sol"; /** * @title USDTiered STO module Proxy */ -contract USDTieredSTOProxy is USDTieredSTOStorage, ISTOStorage, ModuleStorage, Pausable, ReentrancyGuard, OwnedProxy { +contract USDTieredSTOProxy is USDTieredSTOStorage, STOStorage, ModuleStorage, Pausable, ReentrancyGuard, OwnedProxy { /** * @notice Constructor diff --git a/contracts/storage/USDTieredSTOStorage.sol b/contracts/storage/USDTieredSTOStorage.sol index f801000e0..31e9d803d 100644 --- a/contracts/storage/USDTieredSTOStorage.sol +++ b/contracts/storage/USDTieredSTOStorage.sol @@ -51,9 +51,6 @@ contract USDTieredSTOStorage { // Whether or not the STO has been finalized bool public isFinalized; - // Address where ETH, POLY & Stable Coin funds are delivered - address public wallet; - // Address of issuer reserve wallet for unsold tokens address public reserveWallet; diff --git a/test/p_usd_tiered_sto.js b/test/p_usd_tiered_sto.js index ae1fbbbb0..fca953a18 100644 --- a/test/p_usd_tiered_sto.js +++ b/test/p_usd_tiered_sto.js @@ -1246,7 +1246,8 @@ contract("USDTieredSTO", accounts => { await I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, I_DaiToken.address, { from: NONACCREDITED1 }); // Change Stable coin address - await I_USDTieredSTO_Array[stoId].modifyAddresses(WALLET, RESERVEWALLET, [I_PolyToken.address], { from: ISSUER }); + let I_DaiToken2 = await PolyTokenFaucet.new({from: POLYMATH}); + await I_USDTieredSTO_Array[stoId].modifyAddresses(WALLET, RESERVEWALLET, [I_DaiToken2.address], { from: ISSUER }); // NONACCREDITED DAI await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, I_DaiToken.address, { from: NONACCREDITED1 })); From 69b96d507a22d72a130e7e25d5ec0762e486cf0f Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Fri, 8 Mar 2019 01:14:16 +0530 Subject: [PATCH 40/83] Finalize changed granularity edge case fixed (#588) --- contracts/modules/STO/USDTieredSTO.sol | 3 +++ 1 file changed, 3 insertions(+) diff --git a/contracts/modules/STO/USDTieredSTO.sol b/contracts/modules/STO/USDTieredSTO.sol index c29402355..fca1fe810 100644 --- a/contracts/modules/STO/USDTieredSTO.sol +++ b/contracts/modules/STO/USDTieredSTO.sol @@ -290,6 +290,9 @@ contract USDTieredSTO is USDTieredSTOStorage, STO, ReentrancyGuard { tiers[i].mintedTotal = tiers[i].tokenTotal; } } + uint256 granularity = ISecurityToken(securityToken).granularity(); + tempReturned = tempReturned.div(granularity); + tempReturned = tempReturned.mul(granularity); require(ISecurityToken(securityToken).mint(reserveWallet, tempReturned), "Error in minting"); emit ReserveTokenMint(msg.sender, reserveWallet, tempReturned, currentTier); finalAmountReturned = tempReturned; From b4b8c18d1c31e95f47f2a2e924853953905b7475 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Fri, 8 Mar 2019 10:15:37 +0530 Subject: [PATCH 41/83] Added libz3-dev --- .circleci/config.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index a39d287a0..973e580d2 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -65,6 +65,7 @@ jobs: - restore_cache: key: dependency-cache-{{ checksum "package.json" }} - run: yarn install + - run: sudo apt install libz3-dev - run: sudo npm i truffle -g - run: node --version - run: truffle version @@ -77,7 +78,7 @@ workflows: version: 2 commit: jobs: - - coverage + - docs daily-builds: triggers: - schedule: From 0ef87ee2b9d5a5ae2fc36f45b1ac489a5a795b2f Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Fri, 8 Mar 2019 10:40:00 +0530 Subject: [PATCH 42/83] Updated circleci image --- .circleci/config.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 973e580d2..a90643cef 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -59,14 +59,12 @@ jobs: path: ./coverage/lcov.info docs: docker: - - image: circleci/node:8 + - image: maxsam4/solidity-kit:0.4.24 steps: - checkout - restore_cache: key: dependency-cache-{{ checksum "package.json" }} - run: yarn install - - run: sudo apt install libz3-dev - - run: sudo npm i truffle -g - run: node --version - run: truffle version - run: npm run docs From b3233a912e342be990781a2cb862eda22a90d2eb Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Fri, 8 Mar 2019 10:53:58 +0530 Subject: [PATCH 43/83] Updated solidity-docgen --- .circleci/config.yml | 1 + package.json | 2 +- yarn.lock | 508 +++++++++++++++++++++---------------------- 3 files changed, 252 insertions(+), 259 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index a90643cef..99a9c6924 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -65,6 +65,7 @@ jobs: - restore_cache: key: dependency-cache-{{ checksum "package.json" }} - run: yarn install + - run: wget -O node_modules/solidity-docgen/lib/index.js https://raw.githubusercontent.com/maxsam4/solidity-docgen/build/lib/index.js - run: node --version - run: truffle version - run: npm run docs diff --git a/package.json b/package.json index 57713a060..804b7485d 100644 --- a/package.json +++ b/package.json @@ -93,7 +93,7 @@ "prettier": "^1.14.3", "sol-merger": "^0.1.2", "solidity-coverage": "^0.5.11", - "solidity-docgen": "^0.1.0", + "solidity-docgen": "^0.1.1", "solium": "^1.1.6", "truffle": "4.1.14", "truffle-wallet-provider": "0.0.5" diff --git a/yarn.lock b/yarn.lock index c31bbb848..f9dc37309 100644 --- a/yarn.lock +++ b/yarn.lock @@ -73,15 +73,10 @@ acorn-dynamic-import@^2.0.0: dependencies: acorn "^4.0.3" -acorn-jsx@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" - dependencies: - acorn "^3.0.4" - -acorn@^3.0.4: - version "3.3.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" +acorn-jsx@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.1.tgz#32a064fd925429216a09b141102bfdd185fae40e" + integrity sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg== acorn@^4.0.3: version "4.0.13" @@ -91,10 +86,10 @@ acorn@^5.0.0: version "5.7.3" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" -acorn@^6.0.2: - version "6.0.4" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.0.4.tgz#77377e7353b72ec5104550aa2d2097a2fd40b754" - integrity sha512-VY4i5EKSKkofY2I+6QLTbTTN/UvEQPCo6eiwzzSaSWfpaDhOmStMCMod6wmuPciNq+XS0faCglFu2lHZpdHUtg== +acorn@^6.0.7: + version "6.1.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.1.1.tgz#7d25ae05bb8ad1f9b699108e1094ecd7884adc1f" + integrity sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA== aes-js@3.0.0: version "3.0.0" @@ -104,10 +99,6 @@ aes-js@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.1.1.tgz#89fd1f94ae51b4c72d62466adc1a7323ff52f072" -ajv-keywords@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762" - ajv-keywords@^3.1.0: version "3.2.0" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.2.0.tgz#e86b819c602cf8821ad637413698f1dec021847a" @@ -130,6 +121,16 @@ ajv@^6.1.0: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ajv@^6.9.1: + version "6.10.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.0.tgz#90d0d54439da587cd7e843bfb7045f50bd22bdf1" + integrity sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg== + dependencies: + fast-deep-equal "^2.0.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + align-text@^0.1.1, align-text@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" @@ -149,9 +150,10 @@ amdefine@>=0.0.4: version "1.0.1" resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" -ansi-escapes@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" +ansi-escapes@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" + integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== ansi-regex@^2.0.0, ansi-regex@^2.1.1: version "2.1.1" @@ -161,11 +163,16 @@ ansi-regex@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" +ansi-regex@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.0.0.tgz#70de791edf021404c3fd615aa89118ae0432e5a9" + integrity sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w== + ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" -ansi-styles@^3.2.1: +ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" dependencies: @@ -243,16 +250,6 @@ array-flatten@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" -array-union@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" - dependencies: - array-uniq "^1.0.1" - -array-uniq@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" - array-unique@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" @@ -261,10 +258,6 @@ array-unique@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" -arrify@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" - asn1.js@^4.0.0: version "4.10.1" resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" @@ -293,6 +286,11 @@ assign-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" +astral-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" + integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== + async-each@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" @@ -984,13 +982,10 @@ bignumber.js@^4.0.2: version "4.1.0" resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-4.1.0.tgz#db6f14067c140bd46624815a7916c92d9b6c24b1" -bignumber.js@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-5.0.0.tgz#fbce63f09776b3000a83185badcde525daf34833" - -bignumber.js@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-6.0.0.tgz#bbfa047644609a5af093e9cbd83b0461fa3f6002" +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== "bignumber.js@git+https://github.com/debris/bignumber.js#master": version "2.0.7" @@ -1088,7 +1083,7 @@ borc@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/borc/-/borc-2.0.3.tgz#08845ea73a6d3211120928ee3929f8dc2de9f52e" dependencies: - bignumber.js "^7.2.1" + bignumber.js "^6.0.0" commander "^2.15.0" ieee754 "^1.1.8" json-text-sequence "^0.1" @@ -1307,15 +1302,10 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" -caller-path@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" - dependencies: - callsites "^0.2.0" - -callsites@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" +callsites@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.0.0.tgz#fb7eb569b72ad7a45812f93fd9430a3e410b3dd3" + integrity sha512-tWnkwu9YEq2uzlBDI4RcLn8jrFvF9AOi8PxDNU3hZZjJcjkcRAq3vCI+vZcg1SuxISDYe86k9VZFwAxDiJGoAw== camelcase@^1.0.2: version "1.2.1" @@ -1369,9 +1359,19 @@ chalk@^2.0.0, chalk@^2.1.0, chalk@^2.3.1, chalk@^2.4.1: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chardet@^0.4.0: - version "0.4.2" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" +chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== charenc@~0.0.1: version "0.0.2" @@ -1429,10 +1429,6 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: inherits "^2.0.1" safe-buffer "^5.0.1" -circular-json@^0.3.1: - version "0.3.3" - resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" - class-utils@^0.3.5: version "0.3.6" resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" @@ -1531,13 +1527,7 @@ colors@^1.1.2: version "1.3.2" resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.2.tgz#2df8ff573dfbf255af562f8ce7181d6b971a359b" -combined-stream@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818" - dependencies: - delayed-stream "~1.0.0" - -combined-stream@~1.0.6: +combined-stream@^1.0.6, combined-stream@~1.0.6: version "1.0.7" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828" dependencies: @@ -1577,15 +1567,6 @@ concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" -concat-stream@^1.6.0: - version "1.6.2" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" - dependencies: - buffer-from "^1.0.0" - inherits "^2.0.3" - readable-stream "^2.2.2" - typedarray "^0.0.6" - console-browserify@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" @@ -1713,7 +1694,7 @@ cross-spawn@^6.0.5: semver "^5.5.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" @@ -1926,18 +1907,6 @@ defined@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" -del@^2.0.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" - dependencies: - globby "^5.0.0" - is-path-cwd "^1.0.0" - is-path-in-cwd "^1.0.0" - object-assign "^4.0.1" - pify "^2.0.0" - pinkie-promise "^2.0.0" - rimraf "^2.2.8" - delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -1998,9 +1967,10 @@ doctrine@1.5.0: esutils "^2.0.2" isarray "^1.0.0" -doctrine@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== dependencies: esutils "^2.0.2" @@ -2098,6 +2068,11 @@ elliptic@^6.0.0, elliptic@^6.2.3, elliptic@^6.4.0: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.0" +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + emojis-list@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" @@ -2248,9 +2223,10 @@ escope@^3.6.0: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint-config-standard@^11.0.0: - version "11.0.0" - resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-11.0.0.tgz#87ee0d3c9d95382dc761958cbb23da9eea31e0ba" +eslint-config-standard@^12.0.0: + version "12.0.0" + resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-12.0.0.tgz#638b4c65db0bd5a41319f96bba1f15ddad2107d9" + integrity sha512-COUz8FnXhqFitYj4DTqHzidjIL/t4mumGZto5c7DrBpvWoie+Sn3P4sLEzUGeYhRElWuFEf8K1S1EfvD1vixCQ== eslint-import-resolver-node@^0.3.1: version "0.3.2" @@ -2289,9 +2265,10 @@ eslint-plugin-import@^2.10.0: read-pkg-up "^2.0.0" resolve "^1.6.0" -eslint-plugin-node@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-6.0.1.tgz#bf19642298064379315d7a4b2a75937376fa05e4" +eslint-plugin-node@^8.0.0: + version "8.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-8.0.1.tgz#55ae3560022863d141fa7a11799532340a685964" + integrity sha512-ZjOjbjEi6jd82rIpFSgagv4CHWzG9xsQAVp1ZPlhRnnYxcTgENUVBvhYmkQ7GvT1QFijUSo69RaiOJKhMu6i8w== dependencies: eslint-plugin-es "^1.3.1" eslint-utils "^1.3.1" @@ -2300,17 +2277,20 @@ eslint-plugin-node@^6.0.1: resolve "^1.8.1" semver "^5.5.0" -eslint-plugin-promise@^3.7.0: - version "3.8.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-3.8.0.tgz#65ebf27a845e3c1e9d6f6a5622ddd3801694b621" +eslint-plugin-promise@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.0.1.tgz#2d074b653f35a23d1ba89d8e976a985117d1c6a2" + integrity sha512-Si16O0+Hqz1gDHsys6RtFRrW7cCTB6P7p3OJmKp3Y3dxpQE2qwOA7d3xnV+0mBmrPoi0RBnxlCKvqu70te6wjg== -eslint-plugin-standard@^3.0.1: - version "3.1.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-3.1.0.tgz#2a9e21259ba4c47c02d53b2d0c9135d4b1022d47" +eslint-plugin-standard@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-4.0.0.tgz#f845b45109c99cd90e77796940a344546c8f6b5c" + integrity sha512-OwxJkR6TQiYMmt1EsNRMe5qG3GsbjlcOhbGUBY4LtavF9DsLaTcoR+j2Tdjqi23oUwKNUqX7qcn5fPStafMdlA== -eslint-scope@^3.7.1: - version "3.7.3" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.3.tgz#bb507200d3d17f60247636160b4826284b108535" +eslint-scope@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.2.tgz#5f10cd6cabb1965bf479fa65745673439e21cb0e" + integrity sha512-5q1+B/ogmHl8+paxtOKx38Z8LtWkVGuNt3+GQNErqwLl6ViNp/gdJGMCjZNxZ8j/VYjDNZ2Fo+eQc1TAVPIzbg== dependencies: esrecurse "^4.1.0" estraverse "^4.1.1" @@ -2324,54 +2304,54 @@ eslint-visitor-keys@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" -eslint@^4.19.1: - version "4.19.1" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.19.1.tgz#32d1d653e1d90408854bfb296f076ec7e186a300" +eslint@^5.8.0: + version "5.15.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.15.1.tgz#8266b089fd5391e0009a047050795b1d73664524" + integrity sha512-NTcm6vQ+PTgN3UBsALw5BMhgO6i5EpIjQF/Xb5tIh3sk9QhrFafujUOczGz4J24JBlzWclSB9Vmx8d+9Z6bFCg== dependencies: "@babel/code-frame" "^7.0.0" - ajv "^6.5.3" + ajv "^6.9.1" chalk "^2.1.0" cross-spawn "^6.0.5" debug "^4.0.1" - doctrine "^2.1.0" - eslint-scope "^4.0.0" + doctrine "^3.0.0" + eslint-scope "^4.0.2" eslint-utils "^1.3.1" eslint-visitor-keys "^1.0.0" - espree "^4.0.0" + espree "^5.0.1" esquery "^1.0.1" esutils "^2.0.2" - file-entry-cache "^2.0.0" + file-entry-cache "^5.0.1" functional-red-black-tree "^1.0.1" glob "^7.1.2" globals "^11.7.0" ignore "^4.0.6" + import-fresh "^3.0.0" imurmurhash "^0.1.4" - inquirer "^6.1.0" - is-resolvable "^1.1.0" + inquirer "^6.2.2" js-yaml "^3.12.0" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.3.0" - lodash "^4.17.5" + lodash "^4.17.11" minimatch "^3.0.4" mkdirp "^0.5.1" natural-compare "^1.4.0" optionator "^0.8.2" path-is-inside "^1.0.2" - pluralize "^7.0.0" progress "^2.0.0" regexpp "^2.0.1" - require-uncached "^1.0.3" semver "^5.5.1" strip-ansi "^4.0.0" strip-json-comments "^2.0.1" - table "^5.0.2" + table "^5.2.3" text-table "^0.2.0" -espree@^3.5.4: - version "3.5.4" - resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7" +espree@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-5.0.1.tgz#5d6526fa4fc7f0788a5cf75b15f30323e2f81f7a" + integrity sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A== dependencies: - acorn "^6.0.2" + acorn "^6.0.7" acorn-jsx "^5.0.0" eslint-visitor-keys "^1.0.0" @@ -2618,9 +2598,10 @@ ethereumjs-wallet@^0.6.0: utf8 "^3.0.0" uuid "^3.3.2" -ethers@^3.0.15: - version "3.0.29" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-3.0.29.tgz#ce8139955b4ed44456eb6764b089bb117c86775d" +ethers@^4.0.7: + version "4.0.26" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.26.tgz#a4b17184a0ed3db9c88d1b6d28beaa7d0e0ba3e4" + integrity sha512-3hK4S8eAGhuWZ/feip5z17MswjGgjb4lEPJqWO/O0dNqToYLSHhvu6gGQPs8d9f+XfpEB2EYexfF0qjhWiZjUA== dependencies: "@types/node" "^10.3.2" aes-js "3.0.0" @@ -2787,9 +2768,10 @@ extendr@^2.1.0: dependencies: typechecker "~2.0.1" -external-editor@^2.0.4: - version "2.2.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" +external-editor@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.3.tgz#5866db29a97826dbe4bf3afd24070ead9ea43a27" + integrity sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA== dependencies: chardet "^0.7.0" iconv-lite "^0.4.24" @@ -2881,12 +2863,12 @@ figures@^2.0.0: dependencies: escape-string-regexp "^1.0.5" -file-entry-cache@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" +file-entry-cache@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" + integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== dependencies: - flat-cache "^1.2.1" - object-assign "^4.0.1" + flat-cache "^2.0.1" file-type@^3.8.0: version "3.9.0" @@ -2948,14 +2930,19 @@ find-up@^2.0.0, find-up@^2.1.0: dependencies: locate-path "^2.0.0" -flat-cache@^1.2.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.0.tgz#d3030b32b38154f4e3b7e9c709f490f7ef97c481" +flat-cache@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" + integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== dependencies: - circular-json "^0.3.1" - del "^2.0.2" - graceful-fs "^4.1.2" - write "^0.2.1" + flatted "^2.0.0" + rimraf "2.6.3" + write "1.0.3" + +flatted@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.0.tgz#55122b6536ea496b4b44893ee2608141d10d9916" + integrity sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg== for-each@^0.3.2, for-each@~0.3.3: version "0.3.3" @@ -2982,7 +2969,7 @@ form-data@~2.3.2: resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.2.tgz#4970498be604c20c005d4f5c23aecd21d6b49099" dependencies: asynckit "^0.4.0" - combined-stream "^1.0.6" + combined-stream "1.0.6" mime-types "^2.1.12" forwarded@~0.1.2: @@ -3055,9 +3042,10 @@ fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" -fs@0.0.1-security: - version "0.0.1-security" - resolved "https://registry.yarnpkg.com/fs/-/fs-0.0.1-security.tgz#8a7bd37186b6dddf3813f23858b57ecaaf5e41d4" +fs@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/fs/-/fs-0.0.2.tgz#e1f244ef3933c1b2a64bd4799136060d0f5914f8" + integrity sha1-4fJE7zkzwbKmS9R5kTYGDQ9ZFPg= fsevents@^1.0.0, fsevents@^1.2.2: version "1.2.4" @@ -3168,7 +3156,7 @@ glob@^5.0.15: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.2, glob@~7.1.2: +glob@^7.0.0, glob@^7.0.5, glob@^7.1.2, glob@^7.1.3, glob@~7.1.2: version "7.1.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" dependencies: @@ -3204,17 +3192,6 @@ globals@^9.18.0: version "9.18.0" resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" -globby@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" - dependencies: - array-union "^1.0.1" - arrify "^1.0.0" - glob "^7.0.3" - object-assign "^4.0.1" - pify "^2.0.0" - pinkie-promise "^2.0.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" @@ -3451,9 +3428,15 @@ ignore-walk@^3.0.1: dependencies: minimatch "^3.0.4" -ignore@^3.3.3, ignore@^3.3.6: - version "3.3.10" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" +ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + +ignore@^5.0.2: + version "5.0.5" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.0.5.tgz#c663c548d6ce186fb33616a8ccb5d46e56bdbbf9" + integrity sha512-kOC8IUb8HSDMVcYrDVezCxpJkzSQWTAzf3olpKM6o9rM5zpojx23O0Fl8Wr4+qJ6ZbPEHqf1fdwev/DS7v7pmA== ignorefs@^1.0.0: version "1.2.0" @@ -3470,6 +3453,14 @@ immediate@^3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.2.3.tgz#d140fa8f614659bd6541233097ddaac25cdd991c" +import-fresh@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.0.0.tgz#a3d897f420cab0e671236897f75bc14b4885c390" + integrity sha512-pOnA9tfM3Uwics+SaBLCNyZZZbK+4PTu0OPZtLlMIrv17EdBoC15S9Kn8ckJ9TZTyKb3ywNE5y1yeDxxGA7nTQ== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" @@ -3497,22 +3488,23 @@ ini@~1.3.0: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" -inquirer@^3.0.6: - version "3.3.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9" +inquirer@^6.2.2: + version "6.2.2" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.2.tgz#46941176f65c9eb20804627149b743a218f25406" + integrity sha512-Z2rREiXA6cHRR9KBOarR3WuLlFzlIfAEIiB45ll5SSadMg7WqOh1MKEjjndfuH5ewXdixWCxqnVfGOQzPeiztA== dependencies: - ansi-escapes "^3.0.0" - chalk "^2.0.0" + ansi-escapes "^3.2.0" + chalk "^2.4.2" cli-cursor "^2.1.0" cli-width "^2.0.0" - external-editor "^3.0.0" + external-editor "^3.0.3" figures "^2.0.0" - lodash "^4.17.10" + lodash "^4.17.11" mute-stream "0.0.7" run-async "^2.2.0" - rxjs "^6.1.0" + rxjs "^6.4.0" string-width "^2.1.0" - strip-ansi "^4.0.0" + strip-ansi "^5.0.0" through "^2.3.6" interpret@^1.0.0: @@ -3715,22 +3707,6 @@ is-object@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" -is-path-cwd@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" - -is-path-in-cwd@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz#5ac48b345ef675339bd6c7a48a912110b241cf52" - dependencies: - is-path-inside "^1.0.0" - -is-path-inside@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" - dependencies: - path-is-inside "^1.0.1" - 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" @@ -3759,10 +3735,6 @@ is-regex@^1.0.4: dependencies: has "^1.0.1" -is-resolvable@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" - is-retry-allowed@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" @@ -4130,7 +4102,7 @@ lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" -lodash@4.x, lodash@^4.13.1, lodash@^4.14.2, lodash@^4.17.10, lodash@^4.17.4, lodash@^4.17.5: +lodash@4.x, lodash@^4.13.1, lodash@^4.14.2, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5: version "4.17.11" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" @@ -4345,15 +4317,16 @@ miller-rabin@^4.0.0: bn.js "^4.0.0" brorand "^1.0.1" -mime-db@~1.36.0: - version "1.36.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.36.0.tgz#5020478db3c7fe93aad7bbcc4dcf869c43363397" +mime-db@~1.37.0: + version "1.37.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.37.0.tgz#0b6a0ce6fdbe9576e25f1f2d2fde8830dc0ad0d8" + integrity sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg== mime-types@^2.1.12, mime-types@^2.1.16, mime-types@~2.1.18, mime-types@~2.1.19: version "2.1.20" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.20.tgz#930cb719d571e903738520f8470911548ca2cc19" dependencies: - mime-db "~1.37.0" + mime-db "~1.36.0" mime@1.4.1: version "1.4.1" @@ -4425,11 +4398,7 @@ mkdirp-promise@^5.0.1: dependencies: mkdirp "*" -<<<<<<< HEAD -mkdirp@*, mkdirp@0.5.1, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0: -======= -mkdirp@*, mkdirp@0.5.1, mkdirp@0.5.x, mkdirp@0.x.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: ->>>>>>> e543061f... Added test reporter +mkdirp@*, mkdirp@0.5.1, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" dependencies: @@ -4893,6 +4862,13 @@ pako@~1.0.5: version "1.0.6" resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258" +parent-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.0.tgz#df250bdc5391f4a085fb589dad761f5ad6b865b5" + integrity sha512-8Mf5juOMmiE4FcmzYc4IaiS9L3+9paz2KOiXzkRviCP6aDmN49Hz6EMWz0lGNp9pX80GvvAuLADtyGfW/Em3TA== + dependencies: + callsites "^3.0.0" + parse-asn1@^5.0.0: version "5.1.1" resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.1.tgz#f6bf293818332bd0dab54efb16087724745e6ca8" @@ -4955,7 +4931,7 @@ path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" -path-is-inside@^1.0.1, path-is-inside@^1.0.2: +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" @@ -5031,10 +5007,6 @@ pkg-dir@^1.0.0: dependencies: find-up "^1.0.0" -pluralize@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" - posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" @@ -5209,7 +5181,7 @@ react-dom@^16.2.0: loose-envify "^1.1.0" object-assign "^4.1.1" prop-types "^15.6.2" - scheduler "^0.10.0" + schedule "^0.5.0" react@^16.2.0: version "16.5.2" @@ -5218,7 +5190,7 @@ react@^16.2.0: loose-envify "^1.1.0" object-assign "^4.1.1" prop-types "^15.6.2" - scheduler "^0.10.0" + schedule "^0.5.0" read-pkg-up@^1.0.1: version "1.0.1" @@ -5331,9 +5303,10 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" -regexpp@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-1.1.0.tgz#0e3516dd0b7904f413d2d4193dce4618c3a689ab" +regexpp@^2.0.0, regexpp@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" + integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== regexpu-core@^2.0.0: version "2.0.0" @@ -5435,21 +5408,15 @@ require-main-filename@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" -require-uncached@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" - dependencies: - caller-path "^0.1.0" - resolve-from "^1.0.0" - -resolve-from@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" - resolve-from@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57" +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" @@ -5499,6 +5466,13 @@ rimraf@2, rimraf@^2.2.8, rimraf@^2.6.1: dependencies: glob "^7.0.5" +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== + dependencies: + glob "^7.1.3" + ripemd160@^2.0.0, ripemd160@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" @@ -5522,15 +5496,12 @@ rustbn.js@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/rustbn.js/-/rustbn.js-0.2.0.tgz#8082cb886e707155fd1cb6f23bd591ab8d55d0ca" -rx-lite-aggregates@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" +rxjs@^6.4.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.4.0.tgz#f3bb0fe7bda7fb69deac0c16f17b50b0b8790504" + integrity sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw== dependencies: - rx-lite "*" - -rx-lite@*, rx-lite@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" + tslib "^1.9.0" safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" @@ -5574,9 +5545,10 @@ scandirectory@^2.5.0: safefs "^3.1.2" taskgroup "^4.0.5" -schedule@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/schedule/-/schedule-0.5.0.tgz#c128fffa0b402488b08b55ae74bb9df55cc29cc8" +scheduler@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.10.0.tgz#7988de90fe7edccc774ea175a783e69c40c521e1" + integrity sha512-+TSTVTCBAA3h8Anei3haDc1IRwMeDmtI/y/o3iBe3Mjl2vwYF9DtPDt929HyRmV/e7au7CLu8sc4C4W0VOs29w== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" @@ -5585,9 +5557,10 @@ scrypt-async@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/scrypt-async/-/scrypt-async-1.3.1.tgz#a11fd6fac981b4b823ee01dee0221169500ddae9" -scrypt-js@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-2.0.3.tgz#bb0040be03043da9a012a2cea9fc9f852cfc87d4" +scrypt-js@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-2.0.4.tgz#32f8c5149f0797672e551c07e230f834b6af5f16" + integrity sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw== scrypt.js@0.2.0, scrypt.js@^0.2.0: version "0.2.0" @@ -5773,10 +5746,13 @@ slash@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" -slice-ansi@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" +slice-ansi@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" + integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== dependencies: + ansi-styles "^3.2.0" + astral-regex "^1.0.0" is-fullwidth-code-point "^2.0.0" snapdragon-node@^2.0.1: @@ -5864,9 +5840,10 @@ solidity-coverage@^0.5.11: tree-kill "^1.2.0" web3 "^0.18.4" -solidity-docgen@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/solidity-docgen/-/solidity-docgen-0.1.0.tgz#f3a56ff074e8c7d832af3a3d462c3b5abf0f64cb" +solidity-docgen@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/solidity-docgen/-/solidity-docgen-0.1.1.tgz#b9cd4cc414aab371094b7db8a0a45c535bd6e875" + integrity sha512-BJiE5yqpXjpmmEKPZ/RU98i48xa4/0JRk8AJheKK6+LSckv/MduGeC2sO4MD/btBi03+NicFze3lvlPUjj2jHg== dependencies: commander "^2.14.1" lodash "^4.17.5" @@ -6084,6 +6061,15 @@ string-width@^1.0.1: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" +string-width@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.0.0.tgz#5a1690a57cc78211fffd9bf24bbe24d090604eb1" + integrity sha512-rr8CUxBbvOZDUvc5lNIJ+OC1nPVpz+Siw9VBtUjB9b6jZehZLFt0JMCZzShFHIsI8cbhm0EsNIfWJMFV3cu3Ew== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.0.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" @@ -6114,6 +6100,13 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" +strip-ansi@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.0.0.tgz#f78f68b5d0866c20b2c9b8c61b5298508dc8756f" + integrity sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow== + dependencies: + ansi-regex "^4.0.0" + strip-bom@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" @@ -6196,14 +6189,15 @@ swarm-js@0.1.37: tar.gz "^1.0.5" xhr-request-promise "^0.1.2" -table@4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36" +table@^5.2.3: + version "5.2.3" + resolved "https://registry.yarnpkg.com/table/-/table-5.2.3.tgz#cde0cc6eb06751c009efab27e8c820ca5b67b7f2" + integrity sha512-N2RsDAMvDLvYwFcwbPyF3VmVSSkuF+G1e+8inhBLtHpvwXGw4QRPEZhihQNeEN0i1up6/f6ObCJXNdlRG3YVyQ== dependencies: - ajv "^6.5.3" - lodash "^4.17.10" - slice-ansi "1.0.0" - string-width "^2.1.1" + ajv "^6.9.1" + lodash "^4.17.11" + slice-ansi "^2.1.0" + string-width "^3.0.0" tapable@^0.2.7: version "0.2.8" @@ -6408,9 +6402,10 @@ truffle-error@^0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/truffle-error/-/truffle-error-0.0.3.tgz#4bf55242e14deee1c7194932709182deff2c97ca" -truffle-hdwallet-provider-privkey@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/truffle-hdwallet-provider-privkey/-/truffle-hdwallet-provider-privkey-0.1.0.tgz#9417047a74ad37d923df926154b6486ffb57f6c9" +truffle-hdwallet-provider-privkey@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/truffle-hdwallet-provider-privkey/-/truffle-hdwallet-provider-privkey-0.2.0.tgz#91e9e8a6a5005970a5b442fa89fc198ecd1f71ef" + integrity sha512-p4dCmB/roQaHaRMe7Ihej4/Cdmq7Usi6aZsPv/cc2x7S5bYLSwwpgQBdjz4PjPSgNh8zqLte6ZhWkkW1CEq1iQ== dependencies: ethereumjs-tx "^1.3.4" ethereumjs-wallet "^0.6.0" @@ -6489,10 +6484,6 @@ typedarray-to-buffer@^3.1.2: dependencies: is-typedarray "^1.0.0" -typedarray@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - uglify-js@^2.8.29: version "2.8.29" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" @@ -7107,9 +7098,10 @@ wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" -write@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" +write@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" + integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== dependencies: mkdirp "^0.5.1" From b8eb2f3f28c0b1284ba3562bc2f71571c4c30ec6 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Fri, 8 Mar 2019 10:58:23 +0530 Subject: [PATCH 44/83] Added git identity --- .circleci/config.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 99a9c6924..f3ee15640 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -68,6 +68,8 @@ jobs: - run: wget -O node_modules/solidity-docgen/lib/index.js https://raw.githubusercontent.com/maxsam4/solidity-docgen/build/lib/index.js - run: node --version - run: truffle version + - run: git config --global user.email "contact@mudit.blog" + - run: git config --global user.name "Docs Bot" - run: npm run docs - save_cache: key: dependency-cache-{{ checksum "package.json" }} From 5407f5db455c5cadb4fadd5dbd4e57cd05f9e6cd Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Fri, 8 Mar 2019 11:01:49 +0530 Subject: [PATCH 45/83] Generate docs only on merge to master --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f3ee15640..90e4fb7df 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -79,7 +79,7 @@ workflows: version: 2 commit: jobs: - - docs + - coverage daily-builds: triggers: - schedule: From 3d45fb224f7636c1f71d93b18185bde048b2a7c5 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Thu, 14 Mar 2019 03:13:59 +0530 Subject: [PATCH 46/83] USDTieredSTO Granularity edge case fixed (#595) * sto granularity edge case fixed * Added test case --- contracts/modules/STO/USDTieredSTO.sol | 25 ++-- test/p_usd_tiered_sto.js | 151 +++++++++++++++++++++++++ 2 files changed, 164 insertions(+), 12 deletions(-) diff --git a/contracts/modules/STO/USDTieredSTO.sol b/contracts/modules/STO/USDTieredSTO.sol index fca1fe810..dcc3ada36 100644 --- a/contracts/modules/STO/USDTieredSTO.sol +++ b/contracts/modules/STO/USDTieredSTO.sol @@ -662,21 +662,22 @@ contract USDTieredSTO is USDTieredSTOStorage, STO, ReentrancyGuard { view returns(uint256 spentUSD, uint256 purchasedTokens, bool gotoNextTier) { - uint256 maximumTokens = DecimalMath.div(_investedUSD, _tierPrice); + purchasedTokens = DecimalMath.div(_investedUSD, _tierPrice); uint256 granularity = ISecurityToken(securityToken).granularity(); - maximumTokens = maximumTokens.div(granularity); - maximumTokens = maximumTokens.mul(granularity); - if (maximumTokens > _tierRemaining) { - spentUSD = DecimalMath.mul(_tierRemaining, _tierPrice); - // In case of rounding issues, ensure that spentUSD is never more than investedUSD - if (spentUSD > _investedUSD) { - spentUSD = _investedUSD; - } - purchasedTokens = _tierRemaining; + + if (purchasedTokens > _tierRemaining) { + purchasedTokens = _tierRemaining.div(granularity); gotoNextTier = true; } else { - spentUSD = DecimalMath.mul(maximumTokens, _tierPrice); - purchasedTokens = maximumTokens; + purchasedTokens = purchasedTokens.div(granularity); + } + + purchasedTokens = purchasedTokens.mul(granularity); + spentUSD = DecimalMath.mul(purchasedTokens, _tierPrice); + + // In case of rounding issues, ensure that spentUSD is never more than investedUSD + if (spentUSD > _investedUSD) { + spentUSD = _investedUSD; } } diff --git a/test/p_usd_tiered_sto.js b/test/p_usd_tiered_sto.js index fca953a18..48cad94b8 100644 --- a/test/p_usd_tiered_sto.js +++ b/test/p_usd_tiered_sto.js @@ -678,6 +678,45 @@ contract("USDTieredSTO", accounts => { I_USDTieredSTO_Array.push(USDTieredSTO.at(tx.logs[2].args._module)); }); + it("Should successfully attach the sixth STO module to the security token", async () => { + let stoId = 5; // Non-divisible tokens with bad granularity in tiers + + _startTime.push(latestTime() + duration.days(2)); + _endTime.push(_startTime[stoId] + duration.days(100)); + _ratePerTier.push([BigNumber(1 * 10 ** 18), BigNumber(1 * 10 ** 18)]); // [ 1 USD/Token, 1 USD/Token ] + _ratePerTierDiscountPoly.push([BigNumber(1 * 10 ** 18), BigNumber(1 * 10 ** 18)]); // [ 1 USD/Token, 1 USD/Token ] + _tokensPerTierTotal.push([BigNumber(1001 * 10 ** 17), BigNumber(50 * 10 ** 18)]); // [ 100.1 Token, 50 Token ] + _tokensPerTierDiscountPoly.push([BigNumber(0), BigNumber(0)]); // [ 0 Token, 0 Token ] + _nonAccreditedLimitUSD.push(BigNumber(25 * 10 ** 18)); // [ 25 USD ] + _minimumInvestmentUSD.push(BigNumber(5)); + _fundRaiseTypes.push([0, 1, 2]); + _wallet.push(WALLET); + _reserveWallet.push(RESERVEWALLET); + _usdToken.push([I_DaiToken.address]); + + let config = [ + _startTime[stoId], + _endTime[stoId], + _ratePerTier[stoId], + _ratePerTierDiscountPoly[stoId], + _tokensPerTierTotal[stoId], + _tokensPerTierDiscountPoly[stoId], + _nonAccreditedLimitUSD[stoId], + _minimumInvestmentUSD[stoId], + _fundRaiseTypes[stoId], + _wallet[stoId], + _reserveWallet[stoId], + _usdToken[stoId] + ]; + + let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); + let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER, gasPrice: GAS_PRICE }); + console.log(" Gas addModule: ".grey + tx.receipt.gasUsed.toString().grey); + assert.equal(tx.logs[2].args._types[0], STOKEY, "USDTieredSTO doesn't get deployed"); + assert.equal(web3.utils.hexToString(tx.logs[2].args._name), "USDTieredSTO", "USDTieredSTOFactory module was not added"); + I_USDTieredSTO_Array.push(USDTieredSTO.at(tx.logs[2].args._module)); + }); + it("Should fail because rates and tier array of different length", async () => { let stoId = 0; @@ -3948,6 +3987,118 @@ contract("USDTieredSTO", accounts => { await I_SecurityToken.changeGranularity(1, {from: ISSUER}); }); + it("should successfully buy a granular amount when buying indivisible token accross tiers with invalid tier limit", async () => { + let stoId = 5; + let tierId = 0; + await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1], [true], { from: ISSUER }); + let investment_Tokens = (new BigNumber(110)).mul(10 ** 18); + let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Tokens); + + let refund_Tokens = new BigNumber(0); + let refund_POLY = await convert(stoId, tierId, true, "TOKEN", "POLY", refund_Tokens); + + await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: ACCREDITED1 }); + + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let init_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + let tokensToMint = (await I_USDTieredSTO_Array[stoId].buyTokensView(ACCREDITED1, investment_POLY,POLY))[2]; + + // Buy With POLY + let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { + from: ACCREDITED1, + gasPrice: GAS_PRICE + }); + let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); + console.log(" Gas buyWithPOLY: ".grey + tx2.receipt.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let final_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + assert.equal( + final_TokenSupply.toNumber(), + init_TokenSupply + .add(investment_Tokens) + .sub(refund_Tokens) + .toNumber(), + "Token Supply not changed as expected" + ); + assert.equal( + tokensToMint.toNumber(), + investment_Tokens.sub(refund_Tokens).toNumber(), + "View function returned incorrect data" + ); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal + .add(investment_Tokens) + .sub(refund_Tokens) + .toNumber(), + "Investor Token Balance not changed as expected" + ); + assert.equal( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal.sub(gasCost2).toNumber(), + "Investor ETH Balance not changed as expected" + ); + assert.equal( + final_InvestorPOLYBal.toNumber(), + init_InvestorPOLYBal + .sub(investment_POLY) + .add(refund_POLY) + .toNumber(), + "Investor POLY Balance not changed as expected" + ); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold + .add(investment_Tokens) + .sub(refund_Tokens) + .toNumber(), + "STO Token Sold not changed as expected" + ); + assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); + assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); + assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), "Raised ETH not changed as expected"); + assert.equal( + final_RaisedPOLY.toNumber(), + init_RaisedPOLY + .add(investment_POLY) + .sub(refund_POLY) + .toNumber(), + "Raised POLY not changed as expected" + ); + assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), "Wallet ETH Balance not changed as expected"); + assert.equal( + final_WalletPOLYBal.toNumber(), + init_WalletPOLYBal + .add(investment_POLY) + .sub(refund_POLY) + .toNumber(), + "Wallet POLY Balance not changed as expected" + ); + await I_SecurityToken.changeGranularity(1, {from: ISSUER}); + }); + it("should successfully buy a granular amount and refund balance when buying indivisible token with ETH", async () => { await I_SecurityToken.changeGranularity(10**18, {from: ISSUER}); let stoId = 4; From 0008f283c1a6cd98555825faffb47979b79968d0 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Mon, 18 Mar 2019 05:55:32 +0530 Subject: [PATCH 47/83] gtm matm optimizations (#601) * MATM optimizations * Added code comments * Updated tests * Updated names * Added overflow check --- .../GeneralTransferManager.sol | 133 +++++++++------- .../ManualApprovalTransferManager.sol | 149 +++++++++--------- .../storage/GeneralTransferManagerStorage.sol | 10 +- test/j_manual_approval_transfer_manager.js | 12 +- 4 files changed, 161 insertions(+), 143 deletions(-) diff --git a/contracts/modules/TransferManager/GeneralTransferManager.sol b/contracts/modules/TransferManager/GeneralTransferManager.sol index dc7eabd4b..0d2f96700 100644 --- a/contracts/modules/TransferManager/GeneralTransferManager.sol +++ b/contracts/modules/TransferManager/GeneralTransferManager.sol @@ -24,19 +24,19 @@ contract GeneralTransferManager is GeneralTransferManagerStorage, ITransferManag // Emit when there is change in the flag variable called signingAddress event ChangeSigningAddress(address _signingAddress); // Emit when investor details get modified related to their whitelisting - event ChangeDefaults(uint64 _defaultFromTime, uint64 _defaultToTime); + event ChangeDefaults(uint64 _defaultCanSendAfter, uint64 _defaultCanReceiveAfter); - // _fromTime is the time from which the _investor can send tokens - // _toTime is the time from which the _investor can receive tokens - // if allowAllWhitelistIssuances is TRUE, then _toTime is ignored when receiving tokens from the issuance address - // if allowAllWhitelistTransfers is TRUE, then _toTime and _fromTime is ignored when sending or receiving tokens + // _canSendAfter is the time from which the _investor can send tokens + // _canReceiveAfter is the time from which the _investor can receive tokens + // if allowAllWhitelistIssuances is TRUE, then _canReceiveAfter is ignored when receiving tokens from the issuance address + // if allowAllWhitelistTransfers is TRUE, then _canReceiveAfter and _canSendAfter is ignored when sending or receiving tokens // in any case, any investor sending or receiving tokens, must have a _expiryTime in the future event ModifyWhitelist( address indexed _investor, uint256 _dateAdded, address indexed _addedBy, - uint256 _fromTime, - uint256 _toTime, + uint256 _canSendAfter, + uint256 _canReceiveAfter, uint256 _expiryTime, bool _canBuyFromSTO ); @@ -60,14 +60,17 @@ contract GeneralTransferManager is GeneralTransferManagerStorage, ITransferManag } /** - * @notice Used to change the default times used when fromTime / toTime are zero - * @param _defaultFromTime default for zero fromTime - * @param _defaultToTime default for zero toTime + * @notice Used to change the default times used when canSendAfter / canReceiveAfter are zero + * @param _defaultCanSendAfter default for zero canSendAfter + * @param _defaultCanReceiveAfter default for zero canReceiveAfter */ - function changeDefaults(uint64 _defaultFromTime, uint64 _defaultToTime) public withPerm(FLAGS) { - defaults.fromTime = _defaultFromTime; - defaults.toTime = _defaultToTime; - emit ChangeDefaults(_defaultFromTime, _defaultToTime); + function changeDefaults(uint64 _defaultCanSendAfter, uint64 _defaultCanReceiveAfter) public withPerm(FLAGS) { + /* 0 values are also allowed as they represent that the Issuer + does not want a default value for these variables. + 0 is also the default value of these variables */ + defaults.canSendAfter = _defaultCanSendAfter; + defaults.canReceiveAfter = _defaultCanReceiveAfter; + emit ChangeDefaults(_defaultCanSendAfter, _defaultCanReceiveAfter); } /** @@ -75,6 +78,7 @@ contract GeneralTransferManager is GeneralTransferManagerStorage, ITransferManag * @param _issuanceAddress new address for the issuance */ function changeIssuanceAddress(address _issuanceAddress) public withPerm(FLAGS) { + // address(0x0) is also a valid value and in most cases, the address that issues tokens is 0x0. issuanceAddress = _issuanceAddress; emit ChangeIssuanceAddress(_issuanceAddress); } @@ -84,6 +88,9 @@ contract GeneralTransferManager is GeneralTransferManagerStorage, ITransferManag * @param _signingAddress new address for the signing */ function changeSigningAddress(address _signingAddress) public withPerm(FLAGS) { + /* address(0x0) is also a valid value as an Issuer might want to + give this permission to nobody (except their own address). + 0x0 is also the default value */ signingAddress = _signingAddress; emit ChangeSigningAddress(_signingAddress); } @@ -156,7 +163,7 @@ contract GeneralTransferManager is GeneralTransferManagerStorage, ITransferManag return (_onWhitelist(_to) && _onWhitelist(_from)) ? Result.VALID : Result.NA; } - (uint64 adjustedFromTime, uint64 adjustedToTime) = _adjustTimes(whitelist[_from].fromTime, whitelist[_to].toTime); + (uint64 adjustedCanSendAfter, uint64 adjustedCanReceiveAfter) = _adjustTimes(whitelist[_from].canSendAfter, whitelist[_to].canReceiveAfter); if (_from == issuanceAddress) { // Possible STO transaction, but investor not allowed to purchased from STO if ((whitelist[_to].canBuyFromSTO == 0) && _isSTOAttached()) { @@ -166,14 +173,14 @@ contract GeneralTransferManager is GeneralTransferManagerStorage, ITransferManag if (allowAllWhitelistIssuances) { return _onWhitelist(_to) ? Result.VALID : Result.NA; } else { - return (_onWhitelist(_to) && (adjustedToTime <= uint64(now))) ? Result.VALID : Result.NA; + return (_onWhitelist(_to) && (adjustedCanReceiveAfter <= uint64(now))) ? Result.VALID : Result.NA; } } //Anyone on the whitelist can transfer provided the blocknumber is large enough /*solium-disable-next-line security/no-block-members*/ - return ((_onWhitelist(_from) && (adjustedFromTime <= uint64(now))) && - (_onWhitelist(_to) && (adjustedToTime <= uint64(now)))) ? Result.VALID : Result.NA; /*solium-disable-line security/no-block-members*/ + return ((_onWhitelist(_from) && (adjustedCanSendAfter <= uint64(now))) && + (_onWhitelist(_to) && (adjustedCanReceiveAfter <= uint64(now)))) ? Result.VALID : Result.NA; /*solium-disable-line security/no-block-members*/ } return Result.NA; } @@ -181,36 +188,36 @@ contract GeneralTransferManager is GeneralTransferManagerStorage, ITransferManag /** * @notice Adds or removes addresses from the whitelist. * @param _investor is the address to whitelist - * @param _fromTime is the moment when the sale lockup period ends and the investor can freely sell his tokens - * @param _toTime is the moment when the purchase lockup period ends and the investor can freely purchase tokens from others + * @param _canSendAfter the moment when the sale lockup period ends and the investor can freely sell or transfer away their tokens + * @param _canReceiveAfter the moment when the purchase lockup period ends and the investor can freely purchase or receive from others * @param _expiryTime is the moment till investors KYC will be validated. After that investor need to do re-KYC * @param _canBuyFromSTO is used to know whether the investor is restricted investor or not. */ function modifyWhitelist( address _investor, - uint256 _fromTime, - uint256 _toTime, + uint256 _canSendAfter, + uint256 _canReceiveAfter, uint256 _expiryTime, bool _canBuyFromSTO ) public withPerm(WHITELIST) { - _modifyWhitelist(_investor, _fromTime, _toTime, _expiryTime, _canBuyFromSTO); + _modifyWhitelist(_investor, _canSendAfter, _canReceiveAfter, _expiryTime, _canBuyFromSTO); } /** * @notice Adds or removes addresses from the whitelist. * @param _investor is the address to whitelist - * @param _fromTime is the moment when the sale lockup period ends and the investor can freely sell his tokens - * @param _toTime is the moment when the purchase lockup period ends and the investor can freely purchase tokens from others + * @param _canSendAfter is the moment when the sale lockup period ends and the investor can freely sell his tokens + * @param _canReceiveAfter is the moment when the purchase lockup period ends and the investor can freely purchase tokens from others * @param _expiryTime is the moment till investors KYC will be validated. After that investor need to do re-KYC * @param _canBuyFromSTO is used to know whether the investor is restricted investor or not. */ function _modifyWhitelist( address _investor, - uint256 _fromTime, - uint256 _toTime, + uint256 _canSendAfter, + uint256 _canReceiveAfter, uint256 _expiryTime, bool _canBuyFromSTO ) @@ -224,39 +231,45 @@ contract GeneralTransferManager is GeneralTransferManagerStorage, ITransferManag if (whitelist[_investor].added == uint8(0)) { investors.push(_investor); } - whitelist[_investor] = TimeRestriction(uint64(_fromTime), uint64(_toTime), uint64(_expiryTime), canBuyFromSTO, uint8(1)); - emit ModifyWhitelist(_investor, now, msg.sender, _fromTime, _toTime, _expiryTime, _canBuyFromSTO); + require( + uint64(_canSendAfter) == _canSendAfter && + uint64(_canReceiveAfter) == _canReceiveAfter && + uint64(_expiryTime) == _expiryTime, + "uint64 overflow" + ); + whitelist[_investor] = TimeRestriction(uint64(_canSendAfter), uint64(_canReceiveAfter), uint64(_expiryTime), canBuyFromSTO, uint8(1)); + emit ModifyWhitelist(_investor, now, msg.sender, _canSendAfter, _canReceiveAfter, _expiryTime, _canBuyFromSTO); } /** * @notice Adds or removes addresses from the whitelist. * @param _investors List of the addresses to whitelist - * @param _fromTimes An array of the moment when the sale lockup period ends and the investor can freely sell his tokens - * @param _toTimes An array of the moment when the purchase lockup period ends and the investor can freely purchase tokens from others + * @param _canSendAfters An array of the moment when the sale lockup period ends and the investor can freely sell his tokens + * @param _canReceiveAfters An array of the moment when the purchase lockup period ends and the investor can freely purchase tokens from others * @param _expiryTimes An array of the moment till investors KYC will be validated. After that investor need to do re-KYC * @param _canBuyFromSTO An array of boolean values */ function modifyWhitelistMulti( address[] _investors, - uint256[] _fromTimes, - uint256[] _toTimes, + uint256[] _canSendAfters, + uint256[] _canReceiveAfters, uint256[] _expiryTimes, bool[] _canBuyFromSTO ) public withPerm(WHITELIST) { - require(_investors.length == _fromTimes.length, "Mismatched input lengths"); - require(_fromTimes.length == _toTimes.length, "Mismatched input lengths"); - require(_toTimes.length == _expiryTimes.length, "Mismatched input lengths"); - require(_canBuyFromSTO.length == _toTimes.length, "Mismatched input length"); + require(_investors.length == _canSendAfters.length, "Mismatched input lengths"); + require(_canSendAfters.length == _canReceiveAfters.length, "Mismatched input lengths"); + require(_canReceiveAfters.length == _expiryTimes.length, "Mismatched input lengths"); + require(_canBuyFromSTO.length == _canReceiveAfters.length, "Mismatched input length"); for (uint256 i = 0; i < _investors.length; i++) { - _modifyWhitelist(_investors[i], _fromTimes[i], _toTimes[i], _expiryTimes[i], _canBuyFromSTO[i]); + _modifyWhitelist(_investors[i], _canSendAfters[i], _canReceiveAfters[i], _expiryTimes[i], _canBuyFromSTO[i]); } } /** * @notice Adds or removes addresses from the whitelist - can be called by anyone with a valid signature * @param _investor is the address to whitelist - * @param _fromTime is the moment when the sale lockup period ends and the investor can freely sell his tokens - * @param _toTime is the moment when the purchase lockup period ends and the investor can freely purchase tokens from others + * @param _canSendAfter is the moment when the sale lockup period ends and the investor can freely sell his tokens + * @param _canReceiveAfter is the moment when the purchase lockup period ends and the investor can freely purchase tokens from others * @param _expiryTime is the moment till investors KYC will be validated. After that investor need to do re-KYC * @param _canBuyFromSTO is used to know whether the investor is restricted investor or not. * @param _validFrom is the time that this signature is valid from @@ -268,8 +281,8 @@ contract GeneralTransferManager is GeneralTransferManagerStorage, ITransferManag */ function modifyWhitelistSigned( address _investor, - uint256 _fromTime, - uint256 _toTime, + uint256 _canSendAfter, + uint256 _canReceiveAfter, uint256 _expiryTime, bool _canBuyFromSTO, uint256 _validFrom, @@ -286,10 +299,10 @@ contract GeneralTransferManager is GeneralTransferManagerStorage, ITransferManag require(!nonceMap[_investor][_nonce], "Already used signature"); nonceMap[_investor][_nonce] = true; bytes32 hash = keccak256( - abi.encodePacked(this, _investor, _fromTime, _toTime, _expiryTime, _canBuyFromSTO, _validFrom, _validTo, _nonce) + abi.encodePacked(this, _investor, _canSendAfter, _canReceiveAfter, _expiryTime, _canBuyFromSTO, _validFrom, _validTo, _nonce) ); _checkSig(hash, _v, _r, _s); - _modifyWhitelist(_investor, _fromTime, _toTime, _expiryTime, _canBuyFromSTO); + _modifyWhitelist(_investor, _canSendAfter, _canReceiveAfter, _expiryTime, _canBuyFromSTO); } /** @@ -297,7 +310,7 @@ contract GeneralTransferManager is GeneralTransferManagerStorage, ITransferManag */ function _checkSig(bytes32 _hash, uint8 _v, bytes32 _r, bytes32 _s) internal view { //Check that the signature is valid - //sig should be signing - _investor, _fromTime, _toTime & _expiryTime and be signed by the issuer address + //sig should be signing - _investor, _canSendAfter, _canReceiveAfter & _expiryTime and be signed by the issuer address address signer = ecrecover(keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", _hash)), _v, _r, _s); require(signer == Ownable(securityToken).owner() || signer == signingAddress, "Incorrect signer"); } @@ -322,16 +335,16 @@ contract GeneralTransferManager is GeneralTransferManagerStorage, ITransferManag /** * @notice Internal function to adjust times using default values */ - function _adjustTimes(uint64 _fromTime, uint64 _toTime) internal view returns(uint64, uint64) { - uint64 adjustedFromTime = _fromTime; - uint64 adjustedToTime = _toTime; - if (_fromTime == 0) { - adjustedFromTime = defaults.fromTime; + function _adjustTimes(uint64 _canSendAfter, uint64 _canReceiveAfter) internal view returns(uint64, uint64) { + uint64 adjustedCanSendAfter = _canSendAfter; + uint64 adjustedCanReceiveAfter = _canReceiveAfter; + if (_canSendAfter == 0) { + adjustedCanSendAfter = defaults.canSendAfter; } - if (_toTime == 0) { - adjustedToTime = defaults.toTime; + if (_canReceiveAfter == 0) { + adjustedCanReceiveAfter = defaults.canReceiveAfter; } - return (adjustedFromTime, adjustedToTime); + return (adjustedCanSendAfter, adjustedCanReceiveAfter); } /** @@ -345,9 +358,9 @@ contract GeneralTransferManager is GeneralTransferManagerStorage, ITransferManag * @dev Returns list of all investors data */ function getAllInvestorsData() external view returns(address[], uint256[], uint256[], uint256[], bool[]) { - (uint256[] memory fromTimes, uint256[] memory toTimes, uint256[] memory expiryTimes, bool[] memory canBuyFromSTOs) + (uint256[] memory canSendAfters, uint256[] memory canReceiveAfters, uint256[] memory expiryTimes, bool[] memory canBuyFromSTOs) = _investorsData(investors); - return (investors, fromTimes, toTimes, expiryTimes, canBuyFromSTOs); + return (investors, canSendAfters, canReceiveAfters, expiryTimes, canBuyFromSTOs); } @@ -359,13 +372,13 @@ contract GeneralTransferManager is GeneralTransferManagerStorage, ITransferManag } function _investorsData(address[] _investors) internal view returns(uint256[], uint256[], uint256[], bool[]) { - uint256[] memory fromTimes = new uint256[](_investors.length); - uint256[] memory toTimes = new uint256[](_investors.length); + uint256[] memory canSendAfters = new uint256[](_investors.length); + uint256[] memory canReceiveAfters = new uint256[](_investors.length); uint256[] memory expiryTimes = new uint256[](_investors.length); bool[] memory canBuyFromSTOs = new bool[](_investors.length); for (uint256 i = 0; i < _investors.length; i++) { - fromTimes[i] = whitelist[_investors[i]].fromTime; - toTimes[i] = whitelist[_investors[i]].toTime; + canSendAfters[i] = whitelist[_investors[i]].canSendAfter; + canReceiveAfters[i] = whitelist[_investors[i]].canReceiveAfter; expiryTimes[i] = whitelist[_investors[i]].expiryTime; if (whitelist[_investors[i]].canBuyFromSTO == 0) { canBuyFromSTOs[i] = false; @@ -373,7 +386,7 @@ contract GeneralTransferManager is GeneralTransferManagerStorage, ITransferManag canBuyFromSTOs[i] = true; } } - return (fromTimes, toTimes, expiryTimes, canBuyFromSTOs); + return (canSendAfters, canReceiveAfters, expiryTimes, canBuyFromSTOs); } /** diff --git a/contracts/modules/TransferManager/ManualApprovalTransferManager.sol b/contracts/modules/TransferManager/ManualApprovalTransferManager.sol index f660ac639..5e95f6513 100644 --- a/contracts/modules/TransferManager/ManualApprovalTransferManager.sol +++ b/contracts/modules/TransferManager/ManualApprovalTransferManager.sol @@ -9,12 +9,6 @@ import "openzeppelin-solidity/contracts/math/SafeMath.sol"; contract ManualApprovalTransferManager is ITransferManager { using SafeMath for uint256; - //Address from which issuances come - address public issuanceAddress = address(0); - - //Address which can sign whitelist changes - address public signingAddress = address(0); - bytes32 public constant TRANSFER_APPROVAL = "TRANSFER_APPROVAL"; //Manual approval is an allowance (that has been approved) with an expiry time @@ -27,7 +21,10 @@ contract ManualApprovalTransferManager is ITransferManager { } mapping (address => mapping (address => uint256)) public approvalIndex; - // An array to track all approvals + + // An array to track all approvals. It is an unbounded array but it's not a problem as + // it is never looped through in an onchain call. It is defined as an Array instead of mapping + // just to make it easier for users to fetch list of all approvals through constant functions. ManualApproval[] public approvals; event AddManualApproval( @@ -72,7 +69,7 @@ contract ManualApprovalTransferManager is ITransferManager { return bytes4(0); } - /** + /** * @notice Used to verify the transfer transaction and allow a manually approved transqaction to bypass other restrictions * @param _from Address of the sender * @param _to Address of the receiver @@ -82,13 +79,14 @@ contract ManualApprovalTransferManager is ITransferManager { function verifyTransfer(address _from, address _to, uint256 _amount, bytes /* _data */, bool _isTransfer) public returns(Result) { // function must only be called by the associated security token if _isTransfer == true require(_isTransfer == false || msg.sender == securityToken, "Sender is not the owner"); - - if (!paused && approvalIndex[_from][_to] != 0) { - uint256 index = approvalIndex[_from][_to] - 1; + uint256 index = approvalIndex[_from][_to]; + if (!paused && index != 0) { + index--; //Actual index is stored index - 1. ManualApproval storage approval = approvals[index]; - if ((approval.expiryTime >= now) && (approval.allowance >= _amount)) { + uint256 allowance = approval.allowance; + if ((approval.expiryTime >= now) && (allowance >= _amount)) { if (_isTransfer) { - approval.allowance = approval.allowance.sub(_amount); + approval.allowance = allowance - _amount; } return Result.VALID; } @@ -110,8 +108,8 @@ contract ManualApprovalTransferManager is ITransferManager { uint256 _allowance, uint256 _expiryTime, bytes32 _description - ) - external + ) + external withPerm(TRANSFER_APPROVAL) { _addManualApproval(_from, _to, _allowance, _expiryTime, _description); @@ -121,8 +119,9 @@ contract ManualApprovalTransferManager is ITransferManager { require(_to != address(0), "Invalid to address"); require(_expiryTime > now, "Invalid expiry time"); require(_allowance > 0, "Invalid allowance"); - if (approvalIndex[_from][_to] != 0) { - uint256 index = approvalIndex[_from][_to] - 1; + uint256 index = approvalIndex[_from][_to]; + if (index != 0) { + index--; //Actual index is stored index - 1. require(approvals[index].expiryTime < now || approvals[index].allowance == 0, "Approval already exists"); _revokeManualApproval(_from, _to); } @@ -135,7 +134,7 @@ contract ManualApprovalTransferManager is ITransferManager { * @notice Adds mutiple manual approvals in batch * @param _from is the address array from which transfers are approved * @param _to is the address array to which transfers are approved - * @param _allowances is the array of approved amounts + * @param _allowances is the array of approved amounts * @param _expiryTimes is the array of the times until which eath transfer is allowed * @param _descriptions is the description array for these manual approvals */ @@ -145,8 +144,8 @@ contract ManualApprovalTransferManager is ITransferManager { uint256[] _allowances, uint256[] _expiryTimes, bytes32[] _descriptions - ) - external + ) + external withPerm(TRANSFER_APPROVAL) { _checkInputLengthArray(_from, _to, _allowances, _expiryTimes, _descriptions); @@ -160,69 +159,70 @@ contract ManualApprovalTransferManager is ITransferManager { * @param _from is the address from which transfers are approved * @param _to is the address to which transfers are approved * @param _expiryTime is the time until which the transfer is allowed - * @param _changedAllowance is the changed allowance + * @param _changeInAllowance is the change in allowance * @param _description Description about the manual approval - * @param _change uint values which tells whether the allowances will be increased (1) or decreased (0) + * @param _increase tells whether the allowances will be increased (true) or decreased (false). * or any value when there is no change in allowances */ function modifyManualApproval( address _from, address _to, uint256 _expiryTime, - uint256 _changedAllowance, + uint256 _changeInAllowance, bytes32 _description, - uint8 _change - ) + bool _increase + ) external withPerm(TRANSFER_APPROVAL) { - _modifyManualApproval(_from, _to, _expiryTime, _changedAllowance, _description, _change); + _modifyManualApproval(_from, _to, _expiryTime, _changeInAllowance, _description, _increase); } function _modifyManualApproval( address _from, address _to, uint256 _expiryTime, - uint256 _changedAllowance, + uint256 _changeInAllowance, bytes32 _description, - uint8 _change - ) - internal + bool _increase + ) + internal { require(_to != address(0), "Invalid to address"); /*solium-disable-next-line security/no-block-members*/ require(_expiryTime > now, "Invalid expiry time"); - require(approvalIndex[_from][_to] != 0, "Approval not present"); - uint256 index = approvalIndex[_from][_to] - 1; + uint256 index = approvalIndex[_from][_to]; + require(index != 0, "Approval not present"); + index--; //Index is stored in an incremented form. 0 represnts non existant. ManualApproval storage approval = approvals[index]; - require(approval.allowance != 0 && approval.expiryTime > now, "Not allowed"); - uint256 currentAllowance = approval.allowance; - uint256 newAllowance; - if (_change == 1) { - // Allowance get increased - newAllowance = currentAllowance.add(_changedAllowance); - approval.allowance = newAllowance; - } else if (_change == 0) { - // Allowance get decreased - if (_changedAllowance > currentAllowance) { - newAllowance = 0; - approval.allowance = newAllowance; + uint256 allowance = approval.allowance; + uint256 expiryTime = approval.expiryTime; + require(allowance != 0 && expiryTime > now, "Not allowed"); + + if (_changeInAllowance > 0) { + if (_increase) { + // Allowance get increased + allowance = allowance.add(_changeInAllowance); } else { - newAllowance = currentAllowance.sub(_changedAllowance); - approval.allowance = newAllowance; + // Allowance get decreased + if (_changeInAllowance >= allowance) { + allowance = 0; + } else { + allowance = allowance - _changeInAllowance; + } } - } else { - // No change in the Allowance - newAllowance = currentAllowance; + approval.allowance = allowance; } + // Greedy storage technique - if (approval.expiryTime != _expiryTime) { + if (expiryTime != _expiryTime) { approval.expiryTime = _expiryTime; } if (approval.description != _description) { approval.description = _description; } - emit ModifyManualApproval(_from, _to, _expiryTime, newAllowance, _description, msg.sender); + + emit ModifyManualApproval(_from, _to, _expiryTime, allowance, _description, msg.sender); } /** @@ -230,9 +230,9 @@ contract ManualApprovalTransferManager is ITransferManager { * @param _from is the address array from which transfers are approved * @param _to is the address array to which transfers are approved * @param _expiryTimes is the array of the times until which eath transfer is allowed - * @param _changedAllowances is the array of approved amounts + * @param _changedAllowances is the array of approved amounts * @param _descriptions is the description array for these manual approvals - * @param _changes Array of uint values which tells whether the allowances will be increased (1) or decreased (0) + * @param _increase Array of bool values which tells whether the allowances will be increased (true) or decreased (false) * or any value when there is no change in allowances */ function modifyManualApprovalMulti( @@ -241,15 +241,15 @@ contract ManualApprovalTransferManager is ITransferManager { uint256[] _expiryTimes, uint256[] _changedAllowances, bytes32[] _descriptions, - uint8[] _changes + bool[] _increase ) public withPerm(TRANSFER_APPROVAL) { _checkInputLengthArray(_from, _to, _changedAllowances, _expiryTimes, _descriptions); - require(_changes.length == _changedAllowances.length, "Input length array mismatch"); + require(_increase.length == _changedAllowances.length, "Input length array mismatch"); for (uint256 i = 0; i < _from.length; i++) { - _modifyManualApproval(_from[i], _to[i], _expiryTimes[i], _changedAllowances[i], _descriptions[i], _changes[i]); + _modifyManualApproval(_from[i], _to[i], _expiryTimes[i], _changedAllowances[i], _descriptions[i], _increase[i]); } } @@ -263,13 +263,14 @@ contract ManualApprovalTransferManager is ITransferManager { } function _revokeManualApproval(address _from, address _to) internal { - require(approvalIndex[_from][_to] != 0, "Approval not exist"); - + uint256 index = approvalIndex[_from][_to]; + require(index != 0, "Approval does not exist"); + index--; //Actual index is stored index - 1. + uint256 lastApprovalIndex = approvals.length - 1; // find the record in active approvals array & delete it - uint256 index = approvalIndex[_from][_to] - 1; - if (index != approvals.length -1) { - approvals[index] = approvals[approvals.length -1]; - approvalIndex[approvals[index].from][approvals[index].to] = index + 1; + if (index != lastApprovalIndex) { + approvals[index] = approvals[lastApprovalIndex]; + approvalIndex[approvals[index].from][approvals[index].to] = index + 1; } delete approvalIndex[_from][_to]; approvals.length--; @@ -294,9 +295,9 @@ contract ManualApprovalTransferManager is ITransferManager { uint256[] _expiryTimes, uint256[] _allowances, bytes32[] _descriptions - ) + ) internal - pure + pure { require(_from.length == _to.length && _to.length == _allowances.length && @@ -308,7 +309,7 @@ contract ManualApprovalTransferManager is ITransferManager { /** * @notice Returns the all active approvals corresponds to an address - * @param _user Address of the holder corresponds to whom list of manual approvals + * @param _user Address of the holder corresponds to whom list of manual approvals * need to return * @return address[] addresses from * @return address[] addresses to @@ -318,7 +319,8 @@ contract ManualApprovalTransferManager is ITransferManager { */ function getActiveApprovalsToUser(address _user) external view returns(address[], address[], uint256[], uint256[], bytes32[]) { uint256 counter = 0; - for (uint256 i = 0; i < approvals.length; i++) { + uint256 approvalsLength = approvals.length; + for (uint256 i = 0; i < approvalsLength; i++) { if ((approvals[i].from == _user || approvals[i].to == _user) && approvals[i].expiryTime >= now) counter ++; @@ -331,7 +333,7 @@ contract ManualApprovalTransferManager is ITransferManager { bytes32[] memory description = new bytes32[](counter); counter = 0; - for (i = 0; i < approvals.length; i++) { + for (i = 0; i < approvalsLength; i++) { if ((approvals[i].from == _user || approvals[i].to == _user) && approvals[i].expiryTime >= now) { @@ -341,7 +343,7 @@ contract ManualApprovalTransferManager is ITransferManager { expiryTime[counter]=approvals[i].expiryTime; description[counter]=approvals[i].description; counter ++; - } + } } return (from, to, allowance, expiryTime, description); } @@ -355,8 +357,9 @@ contract ManualApprovalTransferManager is ITransferManager { * @return uint256 Description provided to the approval */ function getApprovalDetails(address _from, address _to) external view returns(uint256, uint256, bytes32) { - if (approvalIndex[_from][_to] != 0) { - uint256 index = approvalIndex[_from][_to] - 1; + uint256 index = approvalIndex[_from][_to]; + if (index != 0) { + index--; if (index < approvals.length) { ManualApproval storage approval = approvals[index]; return( @@ -366,7 +369,6 @@ contract ManualApprovalTransferManager is ITransferManager { ); } } - return (uint256(0), uint256(0), bytes32(0)); } /** @@ -390,8 +392,9 @@ contract ManualApprovalTransferManager is ITransferManager { uint256[] memory allowance = new uint256[](approvals.length); uint256[] memory expiryTime = new uint256[](approvals.length); bytes32[] memory description = new bytes32[](approvals.length); + uint256 approvalsLength = approvals.length; - for (uint256 i = 0; i < approvals.length; i++) { + for (uint256 i = 0; i < approvalsLength; i++) { from[i]=approvals[i].from; to[i]=approvals[i].to; @@ -402,7 +405,7 @@ contract ManualApprovalTransferManager is ITransferManager { } return (from, to, allowance, expiryTime, description); - + } /** diff --git a/contracts/storage/GeneralTransferManagerStorage.sol b/contracts/storage/GeneralTransferManagerStorage.sol index cca7b5dd1..87f886ae7 100644 --- a/contracts/storage/GeneralTransferManagerStorage.sol +++ b/contracts/storage/GeneralTransferManagerStorage.sol @@ -16,8 +16,10 @@ contract GeneralTransferManagerStorage { //from and to timestamps that an investor can send / receive tokens respectively struct TimeRestriction { - uint64 fromTime; - uint64 toTime; + //the moment when the sale lockup period ends and the investor can freely sell or transfer away their tokens + uint64 canSendAfter; + //the moment when the purchase lockup period ends and the investor can freely purchase or receive from others + uint64 canReceiveAfter; uint64 expiryTime; uint8 canBuyFromSTO; uint8 added; @@ -25,8 +27,8 @@ contract GeneralTransferManagerStorage { // Allows all TimeRestrictions to be offset struct Defaults { - uint64 fromTime; - uint64 toTime; + uint64 canSendAfter; + uint64 canReceiveAfter; } // Offset to be applied to all timings (except KYC expiry) diff --git a/test/j_manual_approval_transfer_manager.js b/test/j_manual_approval_transfer_manager.js index 49a2f9645..985d471ca 100644 --- a/test/j_manual_approval_transfer_manager.js +++ b/test/j_manual_approval_transfer_manager.js @@ -459,7 +459,7 @@ contract("ManualApprovalTransferManager", accounts => { latestTime() + duration.days(2), web3.utils.toWei("5"), "New Description", - 0, + false, { from: token_owner } @@ -493,9 +493,9 @@ contract("ManualApprovalTransferManager", accounts => { account_investor1, account_investor4, expiryTimeMA, - web3.utils.toWei("5"), + 0, "New Description", - 45, + true, { from: token_owner } @@ -529,7 +529,7 @@ contract("ManualApprovalTransferManager", accounts => { expiryTimeMA, web3.utils.toWei("4"), "New Description", - 1, + true, { from: token_owner } @@ -557,7 +557,7 @@ contract("ManualApprovalTransferManager", accounts => { expiryTimeMA, web3.utils.toWei("1"), "New Description", - 0, + false, { from: token_owner } @@ -592,7 +592,7 @@ contract("ManualApprovalTransferManager", accounts => { expiryTimeMA, web3.utils.toWei("5"), "New Description", - 0, + false, { from: token_owner } From c3c7fd188f17ec8884913025fd39937066546696 Mon Sep 17 00:00:00 2001 From: Adam Dossa Date: Mon, 18 Mar 2019 10:35:35 -0400 Subject: [PATCH 48/83] Fixes --- .../modules/Checkpoint/DividendCheckpoint.sol | 19 ++++++++++++++-- .../Checkpoint/ERC20DividendCheckpoint.sol | 10 ++++----- .../Checkpoint/EtherDividendCheckpoint.sol | 22 +++++++++---------- contracts/modules/Module.sol | 21 ++++++++++++++++++ contracts/modules/STO/STO.sol | 12 ---------- 5 files changed, 53 insertions(+), 31 deletions(-) diff --git a/contracts/modules/Checkpoint/DividendCheckpoint.sol b/contracts/modules/Checkpoint/DividendCheckpoint.sol index 30cf49c54..d40585e5c 100644 --- a/contracts/modules/Checkpoint/DividendCheckpoint.sol +++ b/contracts/modules/Checkpoint/DividendCheckpoint.sol @@ -10,6 +10,7 @@ pragma solidity ^0.4.24; import "./ICheckpoint.sol"; import "./DividendCheckpointStorage.sol"; import "../Module.sol"; +import "../../Pausable.sol"; import "../../interfaces/ISecurityToken.sol"; import "openzeppelin-solidity/contracts/math/SafeMath.sol"; import "openzeppelin-solidity/contracts/math/Math.sol"; @@ -18,7 +19,7 @@ import "openzeppelin-solidity/contracts/math/Math.sol"; * @title Checkpoint module for issuing ether dividends * @dev abstract contract */ -contract DividendCheckpoint is DividendCheckpointStorage, ICheckpoint, Module { +contract DividendCheckpoint is DividendCheckpointStorage, ICheckpoint, Module, Pausable { using SafeMath for uint256; event SetDefaultExcludedAddresses(address[] _excluded, uint256 _timestamp); @@ -36,6 +37,20 @@ contract DividendCheckpoint is DividendCheckpointStorage, ICheckpoint, Module { _; } + /** + * @notice Pause (overridden function) + */ + function pause() public onlyOwner { + super._pause(); + } + + /** + * @notice Unpause (overridden function) + */ + function unpause() public onlyOwner { + super._unpause(); + } + /** * @notice Function used to intialize the contract variables * @param _wallet Ethereum account address to receive reclaimed dividends and tax @@ -182,7 +197,7 @@ contract DividendCheckpoint is DividendCheckpointStorage, ICheckpoint, Module { * @notice Investors can pull their own dividends * @param _dividendIndex Dividend to pull */ - function pullDividendPayment(uint256 _dividendIndex) public validDividendIndex(_dividendIndex) + function pullDividendPayment(uint256 _dividendIndex) public validDividendIndex(_dividendIndex) whenNotPaused { Dividend storage dividend = dividends[_dividendIndex]; require(!dividend.claimed[msg.sender], "Dividend already claimed"); diff --git a/contracts/modules/Checkpoint/ERC20DividendCheckpoint.sol b/contracts/modules/Checkpoint/ERC20DividendCheckpoint.sol index 1d3c8b1bb..d9dc93579 100644 --- a/contracts/modules/Checkpoint/ERC20DividendCheckpoint.sol +++ b/contracts/modules/Checkpoint/ERC20DividendCheckpoint.sol @@ -241,12 +241,12 @@ contract ERC20DividendCheckpoint is ERC20DividendCheckpointStorage, DividendChec uint256 claimAfterWithheld = claim.sub(withheld); if (claimAfterWithheld > 0) { require(IERC20(dividendTokens[_dividendIndex]).transfer(_payee, claimAfterWithheld), "transfer failed"); - if (withheld > 0) { - _dividend.totalWithheld = _dividend.totalWithheld.add(withheld); - _dividend.withheld[_payee] = withheld; - } - emit ERC20DividendClaimed(_payee, _dividendIndex, dividendTokens[_dividendIndex], claim, withheld); } + if (withheld > 0) { + _dividend.totalWithheld = _dividend.totalWithheld.add(withheld); + _dividend.withheld[_payee] = withheld; + } + emit ERC20DividendClaimed(_payee, _dividendIndex, dividendTokens[_dividendIndex], claim, withheld); } /** diff --git a/contracts/modules/Checkpoint/EtherDividendCheckpoint.sol b/contracts/modules/Checkpoint/EtherDividendCheckpoint.sol index 2952fc955..699da0b57 100644 --- a/contracts/modules/Checkpoint/EtherDividendCheckpoint.sol +++ b/contracts/modules/Checkpoint/EtherDividendCheckpoint.sol @@ -172,19 +172,17 @@ contract EtherDividendCheckpoint is DividendCheckpoint { (uint256 claim, uint256 withheld) = calculateDividend(_dividendIndex, _payee); _dividend.claimed[_payee] = true; uint256 claimAfterWithheld = claim.sub(withheld); - if (claimAfterWithheld > 0) { - /*solium-disable-next-line security/no-send*/ - if (_payee.send(claimAfterWithheld)) { - _dividend.claimedAmount = _dividend.claimedAmount.add(claim); - if (withheld > 0) { - _dividend.totalWithheld = _dividend.totalWithheld.add(withheld); - _dividend.withheld[_payee] = withheld; - } - emit EtherDividendClaimed(_payee, _dividendIndex, claim, withheld); - } else { - _dividend.claimed[_payee] = false; - emit EtherDividendClaimFailed(_payee, _dividendIndex, claim, withheld); + /*solium-disable-next-line security/no-send*/ + if (_payee.send(claimAfterWithheld)) { + _dividend.claimedAmount = _dividend.claimedAmount.add(claim); + if (withheld > 0) { + _dividend.totalWithheld = _dividend.totalWithheld.add(withheld); + _dividend.withheld[_payee] = withheld; } + emit EtherDividendClaimed(_payee, _dividendIndex, claim, withheld); + } else { + _dividend.claimed[_payee] = false; + emit EtherDividendClaimFailed(_payee, _dividendIndex, claim, withheld); } } diff --git a/contracts/modules/Module.sol b/contracts/modules/Module.sol index 1566a3428..4edd39c8d 100644 --- a/contracts/modules/Module.sol +++ b/contracts/modules/Module.sol @@ -56,4 +56,25 @@ contract Module is IModule, ModuleStorage { require(polyToken.transferFrom(securityToken, Ownable(factory).owner(), _amount), "Unable to take fee"); return true; } + + /** + * @notice Reclaims ERC20Basic compatible tokens + * @dev We duplicate here due to the overriden owner & onlyOwner + * @param _tokenContract The address of the token contract + */ + function reclaimERC20(address _tokenContract) external onlyOwner { + require(_tokenContract != address(0), "Invalid address"); + IERC20 token = IERC20(_tokenContract); + uint256 balance = token.balanceOf(address(this)); + require(token.transfer(msg.sender, balance), "Transfer failed"); + } + + /** + * @notice Reclaims ETH + * @dev We duplicate here due to the overriden owner & onlyOwner + */ + function reclaimETH() external onlyOwner { + msg.sender.transfer(address(this).balance); + } + } diff --git a/contracts/modules/STO/STO.sol b/contracts/modules/STO/STO.sol index 5f9a6e9e3..4cb832eaf 100644 --- a/contracts/modules/STO/STO.sol +++ b/contracts/modules/STO/STO.sol @@ -18,18 +18,6 @@ contract STO is ISTO, STOStorage, Module, Pausable { // Event event SetFundRaiseTypes(FundRaiseType[] _fundRaiseTypes); - /** - * @notice Reclaims ERC20Basic compatible tokens - * @dev We duplicate here due to the overriden owner & onlyOwner - * @param _tokenContract The address of the token contract - */ - function reclaimERC20(address _tokenContract) external onlyOwner { - require(_tokenContract != address(0), "Invalid address"); - IERC20 token = IERC20(_tokenContract); - uint256 balance = token.balanceOf(address(this)); - require(token.transfer(msg.sender, balance), "Transfer failed"); - } - /** * @notice Returns funds raised by the STO */ From eba4a935c16df738a310c6b1e1cd2f96bb60c998 Mon Sep 17 00:00:00 2001 From: Adam Dossa Date: Mon, 18 Mar 2019 10:55:20 -0400 Subject: [PATCH 49/83] Allow maturity / expiry dates to be updated --- .../modules/Checkpoint/DividendCheckpoint.sol | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/contracts/modules/Checkpoint/DividendCheckpoint.sol b/contracts/modules/Checkpoint/DividendCheckpoint.sol index d40585e5c..2ded603de 100644 --- a/contracts/modules/Checkpoint/DividendCheckpoint.sol +++ b/contracts/modules/Checkpoint/DividendCheckpoint.sol @@ -26,6 +26,7 @@ contract DividendCheckpoint is DividendCheckpointStorage, ICheckpoint, Module, P event SetWithholding(address[] _investors, uint256[] _withholding, uint256 _timestamp); event SetWithholdingFixed(address[] _investors, uint256 _withholding, uint256 _timestamp); event SetWallet(address indexed _oldWallet, address indexed _newWallet, uint256 _timestamp); + event UpdateDividendDates(uint256 indexed _dividendIndex, uint256 _maturity, uint256 _expiry); modifier validDividendIndex(uint256 _dividendIndex) { require(_dividendIndex < dividends.length, "Invalid dividend"); @@ -267,6 +268,21 @@ contract DividendCheckpoint is DividendCheckpointStorage, ICheckpoint, Module, P */ function withdrawWithholding(uint256 _dividendIndex) external; + /** + * @notice Allows issuer to change maturity / expiry dates for dividends + * @param _dividendIndex Dividend to withdraw from + * @param _maturity updated maturity date + * @param _expiry updated expiry date + */ + function updateDividendDates(uint256 _dividendIndex, uint256 _maturity, uint256 _expiry) onlyOwner { + require(_dividendIndex < dividends.length, "Invalid dividend"); + require(_expiry > _maturity, "Expiry before maturity"); + Dividend storage dividend = dividends[_dividendIndex]; + dividend.expiry = _expiry; + dividend.maturity = _maturity; + emit UpdateDividendDates(_dividendIndex, _maturity, _expiry); + } + /** * @notice Get static dividend data * @return uint256[] timestamp of dividends creation From 548d7fdb168cc0d3e2aac30afb5d5cd832b85f97 Mon Sep 17 00:00:00 2001 From: Adam Dossa Date: Mon, 18 Mar 2019 12:33:02 -0400 Subject: [PATCH 50/83] Add tests & fixes --- contracts/{modules/STO => mocks}/DummySTO.sol | 6 ++- .../STO => mocks}/DummySTOFactory.sol | 4 +- contracts/mocks/MockFactory.sol | 4 +- contracts/mocks/TestSTOFactory.sol | 2 +- .../modules/Checkpoint/DividendCheckpoint.sol | 28 ++++++++++++- contracts/modules/Module.sol | 20 ---------- contracts/modules/STO/STO.sol | 20 ++++++++++ contracts/modules/STO/USDTieredSTO.sol | 18 ++++----- test/e_erc20_dividends.js | 39 +++++++++++++------ test/f_ether_dividends.js | 19 +++++---- test/p_usd_tiered_sto.js | 4 +- 11 files changed, 107 insertions(+), 57 deletions(-) rename contracts/{modules/STO => mocks}/DummySTO.sol (97%) rename contracts/{modules/STO => mocks}/DummySTOFactory.sol (97%) diff --git a/contracts/modules/STO/DummySTO.sol b/contracts/mocks/DummySTO.sol similarity index 97% rename from contracts/modules/STO/DummySTO.sol rename to contracts/mocks/DummySTO.sol index fafc6c1c4..f452a01eb 100644 --- a/contracts/modules/STO/DummySTO.sol +++ b/contracts/mocks/DummySTO.sol @@ -1,7 +1,7 @@ pragma solidity ^0.4.24; -import "./STO.sol"; -import "../../interfaces/ISecurityToken.sol"; +import "../modules/STO/STO.sol"; +import "../interfaces/ISecurityToken.sol"; /** * @title STO module for sample implementation of a different crowdsale module @@ -90,4 +90,6 @@ contract DummySTO is STO { return allPermissions; } + + } diff --git a/contracts/modules/STO/DummySTOFactory.sol b/contracts/mocks/DummySTOFactory.sol similarity index 97% rename from contracts/modules/STO/DummySTOFactory.sol rename to contracts/mocks/DummySTOFactory.sol index 04640ac58..03d5fb3a6 100644 --- a/contracts/modules/STO/DummySTOFactory.sol +++ b/contracts/mocks/DummySTOFactory.sol @@ -1,8 +1,8 @@ pragma solidity ^0.4.24; import "./DummySTO.sol"; -import "../ModuleFactory.sol"; -import "../../libraries/Util.sol"; +import "../modules/ModuleFactory.sol"; +import "../libraries/Util.sol"; /** * @title Factory for deploying DummySTO module diff --git a/contracts/mocks/MockFactory.sol b/contracts/mocks/MockFactory.sol index 627efb71c..8be7754f7 100644 --- a/contracts/mocks/MockFactory.sol +++ b/contracts/mocks/MockFactory.sol @@ -1,6 +1,6 @@ pragma solidity ^0.4.24; -import "../modules/STO/DummySTOFactory.sol"; +import "./DummySTOFactory.sol"; /** * @title Mock Contract Not fit for production environment @@ -32,7 +32,7 @@ contract MockFactory is DummySTOFactory { res[1] = 1; return res; } - + } function changeTypes() external onlyOwner { diff --git a/contracts/mocks/TestSTOFactory.sol b/contracts/mocks/TestSTOFactory.sol index a8bcbbeb6..120f72bbf 100644 --- a/contracts/mocks/TestSTOFactory.sol +++ b/contracts/mocks/TestSTOFactory.sol @@ -1,6 +1,6 @@ pragma solidity ^0.4.24; -import "../modules/STO/DummySTOFactory.sol"; +import "./DummySTOFactory.sol"; contract TestSTOFactory is DummySTOFactory { diff --git a/contracts/modules/Checkpoint/DividendCheckpoint.sol b/contracts/modules/Checkpoint/DividendCheckpoint.sol index 2ded603de..54e6394cf 100644 --- a/contracts/modules/Checkpoint/DividendCheckpoint.sol +++ b/contracts/modules/Checkpoint/DividendCheckpoint.sol @@ -29,13 +29,17 @@ contract DividendCheckpoint is DividendCheckpointStorage, ICheckpoint, Module, P event UpdateDividendDates(uint256 indexed _dividendIndex, uint256 _maturity, uint256 _expiry); modifier validDividendIndex(uint256 _dividendIndex) { + _validDividendIndex(_dividendIndex); + _; + } + + function _validDividendIndex(uint256 _dividendIndex) internal view { require(_dividendIndex < dividends.length, "Invalid dividend"); require(!dividends[_dividendIndex].reclaimed, "Dividend reclaimed"); /*solium-disable-next-line security/no-block-members*/ require(now >= dividends[_dividendIndex].maturity, "Dividend maturity in future"); /*solium-disable-next-line security/no-block-members*/ require(now < dividends[_dividendIndex].expiry, "Dividend expiry in past"); - _; } /** @@ -52,6 +56,26 @@ contract DividendCheckpoint is DividendCheckpointStorage, ICheckpoint, Module, P super._unpause(); } + /** + * @notice Reclaims ERC20Basic compatible tokens + * @dev We duplicate here due to the overriden owner & onlyOwner + * @param _tokenContract The address of the token contract + */ + function reclaimERC20(address _tokenContract) external onlyOwner { + require(_tokenContract != address(0), "Invalid address"); + IERC20 token = IERC20(_tokenContract); + uint256 balance = token.balanceOf(address(this)); + require(token.transfer(msg.sender, balance), "Transfer failed"); + } + + /** + * @notice Reclaims ETH + * @dev We duplicate here due to the overriden owner & onlyOwner + */ + function reclaimETH() external onlyOwner { + msg.sender.transfer(address(this).balance); + } + /** * @notice Function used to intialize the contract variables * @param _wallet Ethereum account address to receive reclaimed dividends and tax @@ -274,7 +298,7 @@ contract DividendCheckpoint is DividendCheckpointStorage, ICheckpoint, Module, P * @param _maturity updated maturity date * @param _expiry updated expiry date */ - function updateDividendDates(uint256 _dividendIndex, uint256 _maturity, uint256 _expiry) onlyOwner { + function updateDividendDates(uint256 _dividendIndex, uint256 _maturity, uint256 _expiry) external onlyOwner { require(_dividendIndex < dividends.length, "Invalid dividend"); require(_expiry > _maturity, "Expiry before maturity"); Dividend storage dividend = dividends[_dividendIndex]; diff --git a/contracts/modules/Module.sol b/contracts/modules/Module.sol index 4edd39c8d..a3698f22f 100644 --- a/contracts/modules/Module.sol +++ b/contracts/modules/Module.sol @@ -57,24 +57,4 @@ contract Module is IModule, ModuleStorage { return true; } - /** - * @notice Reclaims ERC20Basic compatible tokens - * @dev We duplicate here due to the overriden owner & onlyOwner - * @param _tokenContract The address of the token contract - */ - function reclaimERC20(address _tokenContract) external onlyOwner { - require(_tokenContract != address(0), "Invalid address"); - IERC20 token = IERC20(_tokenContract); - uint256 balance = token.balanceOf(address(this)); - require(token.transfer(msg.sender, balance), "Transfer failed"); - } - - /** - * @notice Reclaims ETH - * @dev We duplicate here due to the overriden owner & onlyOwner - */ - function reclaimETH() external onlyOwner { - msg.sender.transfer(address(this).balance); - } - } diff --git a/contracts/modules/STO/STO.sol b/contracts/modules/STO/STO.sol index 4cb832eaf..d05de918e 100644 --- a/contracts/modules/STO/STO.sol +++ b/contracts/modules/STO/STO.sol @@ -53,4 +53,24 @@ contract STO is ISTO, STOStorage, Module, Pausable { emit SetFundRaiseTypes(_fundRaiseTypes); } + /** + * @notice Reclaims ERC20Basic compatible tokens + * @dev We duplicate here due to the overriden owner & onlyOwner + * @param _tokenContract The address of the token contract + */ + function reclaimERC20(address _tokenContract) external onlyOwner { + require(_tokenContract != address(0), "Invalid address"); + IERC20 token = IERC20(_tokenContract); + uint256 balance = token.balanceOf(address(this)); + require(token.transfer(msg.sender, balance), "Transfer failed"); + } + + /** + * @notice Reclaims ETH + * @dev We duplicate here due to the overriden owner & onlyOwner + */ + function reclaimETH() external onlyOwner { + msg.sender.transfer(address(this).balance); + } + } diff --git a/contracts/modules/STO/USDTieredSTO.sol b/contracts/modules/STO/USDTieredSTO.sol index dcc3ada36..e40e4c6b0 100644 --- a/contracts/modules/STO/USDTieredSTO.sol +++ b/contracts/modules/STO/USDTieredSTO.sol @@ -277,7 +277,7 @@ contract USDTieredSTO is USDTieredSTOStorage, STO, ReentrancyGuard { * @notice Reserve address must be whitelisted to successfully finalize */ function finalize() external onlyOwner { - require(!isFinalized, "STO is already finalized"); + require(!isFinalized, "STO is finalized"); isFinalized = true; uint256 tempReturned; uint256 tempSold; @@ -305,7 +305,7 @@ contract USDTieredSTO is USDTieredSTOStorage, STO, ReentrancyGuard { * @param _accredited Array of bools specifying accreditation status */ function changeAccredited(address[] _investors, bool[] _accredited) external onlyOwner { - require(_investors.length == _accredited.length, "Array length mismatch"); + require(_investors.length == _accredited.length, "Array mismatch"); for (uint256 i = 0; i < _investors.length; i++) { if (_accredited[i]) { investors[_investors[i]].accredited = uint8(1); @@ -324,7 +324,7 @@ contract USDTieredSTO is USDTieredSTOStorage, STO, ReentrancyGuard { */ function changeNonAccreditedLimit(address[] _investors, uint256[] _nonAccreditedLimit) external onlyOwner { //nonAccreditedLimitUSDOverride - require(_investors.length == _nonAccreditedLimit.length, "Array length mismatch"); + require(_investors.length == _nonAccreditedLimit.length, "Array mismatch"); for (uint256 i = 0; i < _investors.length; i++) { investors[_investors[i]].nonAccreditedLimitUSDOverride = _nonAccreditedLimit[i]; _addToInvestorsList(_investors[i]); @@ -361,7 +361,7 @@ contract USDTieredSTO is USDTieredSTOStorage, STO, ReentrancyGuard { * @param _allowBeneficialInvestments Boolean to allow or disallow beneficial investments */ function changeAllowBeneficialInvestments(bool _allowBeneficialInvestments) external onlyOwner { - require(_allowBeneficialInvestments != allowBeneficialInvestments, "Value unchanged"); + require(_allowBeneficialInvestments != allowBeneficialInvestments); allowBeneficialInvestments = _allowBeneficialInvestments; emit SetAllowBeneficialInvestments(allowBeneficialInvestments); } @@ -399,7 +399,7 @@ contract USDTieredSTO is USDTieredSTOStorage, STO, ReentrancyGuard { uint256 rate = getRate(FundRaiseType.ETH); uint256 initialMinted = getTokensMinted(); (uint256 spentUSD, uint256 spentValue) = _buyTokens(_beneficiary, msg.value, rate, FundRaiseType.ETH); - require(getTokensMinted().sub(initialMinted) >= _minTokens, "Insufficient tokens minted"); + require(getTokensMinted().sub(initialMinted) >= _minTokens, "Insufficient minted"); // Modify storage investorInvested[_beneficiary][uint8(FundRaiseType.ETH)] = investorInvested[_beneficiary][uint8(FundRaiseType.ETH)].add(spentValue); fundsRaised[uint8(FundRaiseType.ETH)] = fundsRaised[uint8(FundRaiseType.ETH)].add(spentValue); @@ -434,11 +434,11 @@ contract USDTieredSTO is USDTieredSTOStorage, STO, ReentrancyGuard { } function _buyWithTokens(address _beneficiary, uint256 _tokenAmount, FundRaiseType _fundRaiseType, uint256 _minTokens, IERC20 _token) internal { - require(_fundRaiseType == FundRaiseType.POLY || _fundRaiseType == FundRaiseType.SC, "Invalid raise type"); + require(_fundRaiseType == FundRaiseType.POLY || _fundRaiseType == FundRaiseType.SC, "Invalid raise"); uint256 initialMinted = getTokensMinted(); uint256 rate = getRate(_fundRaiseType); (uint256 spentUSD, uint256 spentValue) = _buyTokens(_beneficiary, _tokenAmount, rate, _fundRaiseType); - require(getTokensMinted().sub(initialMinted) >= _minTokens, "Insufficient tokens minted"); + require(getTokensMinted().sub(initialMinted) >= _minTokens, "Insufficient minted"); // Modify storage investorInvested[_beneficiary][uint8(_fundRaiseType)] = investorInvested[_beneficiary][uint8(_fundRaiseType)].add(spentValue); fundsRaised[uint8(_fundRaiseType)] = fundsRaised[uint8(_fundRaiseType)].add(spentValue); @@ -552,12 +552,12 @@ contract USDTieredSTO is USDTieredSTOStorage, STO, ReentrancyGuard { require(_investmentValue > 0, "No funds were sent"); // Check for minimum investment - require(investedUSD.add(investorInvestedUSD[_beneficiary]) >= minimumInvestmentUSD, "Total investment < minimumInvestmentUSD"); + require(investedUSD.add(investorInvestedUSD[_beneficiary]) >= minimumInvestmentUSD, "investment < minimumInvestmentUSD"); netInvestedUSD = investedUSD; // Check for non-accredited cap if (investors[_beneficiary].accredited == uint8(0)) { uint256 investorLimitUSD = (investors[_beneficiary].nonAccreditedLimitUSDOverride == 0) ? nonAccreditedLimitUSD : investors[_beneficiary].nonAccreditedLimitUSDOverride; - require(investorInvestedUSD[_beneficiary] < investorLimitUSD, "Over Non-accredited investor limit"); + require(investorInvestedUSD[_beneficiary] < investorLimitUSD, "Over investor limit"); if (investedUSD.add(investorInvestedUSD[_beneficiary]) > investorLimitUSD) netInvestedUSD = investorLimitUSD.sub(investorInvestedUSD[_beneficiary]); } diff --git a/test/e_erc20_dividends.js b/test/e_erc20_dividends.js index 1d3820991..af5620832 100644 --- a/test/e_erc20_dividends.js +++ b/test/e_erc20_dividends.js @@ -663,10 +663,10 @@ contract("ERC20DividendCheckpoint", accounts => { ); }); - it("Set withholding tax of 20% on account_temp and 10% on investor2", async () => { + it("Set withholding tax of 20% on account_temp and 100% on investor2", async () => { await I_ERC20DividendCheckpoint.setWithholding( [account_temp, account_investor2], - [BigNumber(20 * 10 ** 16), BigNumber(10 * 10 ** 16)], + [BigNumber(20 * 10 ** 16), BigNumber(100 * 10 ** 16)], { from: token_owner } ); }); @@ -800,7 +800,7 @@ contract("ERC20DividendCheckpoint", accounts => { assert.equal(dividendAmount3[0].toNumber(), web3.utils.toWei("7", "ether")); assert.equal(dividendAmount_temp[0].toNumber(), web3.utils.toWei("1", "ether")); assert.equal(dividendAmount1[1].toNumber(), web3.utils.toWei("0", "ether")); - assert.equal(dividendAmount2[1].toNumber(), web3.utils.toWei("0.2", "ether")); + assert.equal(dividendAmount2[1].toNumber(), web3.utils.toWei("2", "ether")); assert.equal(dividendAmount3[1].toNumber(), web3.utils.toWei("0", "ether")); assert.equal(dividendAmount_temp[1].toNumber(), web3.utils.toWei("0.2", "ether")); }); @@ -810,15 +810,23 @@ contract("ERC20DividendCheckpoint", accounts => { let investor2Balance = new BigNumber(await I_PolyToken.balanceOf(account_investor2)); let investor3Balance = new BigNumber(await I_PolyToken.balanceOf(account_investor3)); let tempBalance = new BigNumber(await web3.eth.getBalance(account_temp)); - await I_ERC20DividendCheckpoint.pullDividendPayment(3, { from: account_investor2, gasPrice: 0 }); + let _blockNo = latestBlock(); + let tx = await I_ERC20DividendCheckpoint.pullDividendPayment(3, { from: account_investor2, gasPrice: 0 }); let investor1BalanceAfter1 = new BigNumber(await I_PolyToken.balanceOf(account_investor1)); let investor2BalanceAfter1 = new BigNumber(await I_PolyToken.balanceOf(account_investor2)); let investor3BalanceAfter1 = new BigNumber(await I_PolyToken.balanceOf(account_investor3)); let tempBalanceAfter1 = new BigNumber(await web3.eth.getBalance(account_temp)); assert.equal(investor1BalanceAfter1.sub(investor1Balance).toNumber(), 0); - assert.equal(investor2BalanceAfter1.sub(investor2Balance).toNumber(), web3.utils.toWei("1.8", "ether")); + // Full amount is in withheld tax + assert.equal(investor2BalanceAfter1.sub(investor2Balance).toNumber(), 0); assert.equal(investor3BalanceAfter1.sub(investor3Balance).toNumber(), 0); assert.equal(tempBalanceAfter1.sub(tempBalance).toNumber(), 0); + //Check tx contains event... + const log = await promisifyLogWatch(I_ERC20DividendCheckpoint.ERC20DividendClaimed({ from: _blockNo }), 1); + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._payee, account_investor2); + assert.equal(log.args._withheld.toNumber(), web3.utils.toWei("2", "ether")); + assert.equal(log.args._amount.toNumber(), web3.utils.toWei("2", "ether")); }); it("Should issuer pushes temp investor - investor1 excluded", async () => { @@ -895,12 +903,12 @@ contract("ERC20DividendCheckpoint", accounts => { assert.equal(info[0][3], account_investor3, "account match"); assert.equal(info[3][0].toNumber(), 0, "withheld match"); - assert.equal(info[3][1].toNumber(), web3.utils.toWei("0.2", "ether"), "withheld match"); + assert.equal(info[3][1].toNumber(), web3.utils.toWei("2", "ether"), "withheld match"); assert.equal(info[3][2].toNumber(), web3.utils.toWei("0.2", "ether"), "withheld match"); assert.equal(info[3][3].toNumber(), 0, "withheld match"); assert.equal(info[4][0].toNumber(), 0, "excluded"); - assert.equal(info[4][1].toNumber(), web3.utils.toWei("1.8", "ether"), "claim match"); + assert.equal(info[4][1].toNumber(), web3.utils.toWei("0", "ether"), "claim match"); assert.equal(info[4][2].toNumber(), web3.utils.toWei("0.8", "ether"), "claim match"); assert.equal(info[4][3].toNumber(), web3.utils.toWei("7", "ether"), "claim match"); @@ -909,11 +917,20 @@ contract("ERC20DividendCheckpoint", accounts => { assert.equal(info[5][2].toNumber(), (await I_SecurityToken.balanceOfAt(account_temp, 4)).toNumber(), "balance match"); assert.equal(info[5][3].toNumber(), (await I_SecurityToken.balanceOfAt(account_investor3, 4)).toNumber(), "balance match"); - + let dividend = await I_ERC20DividendCheckpoint.dividends.call(3); + console.log("totalWithheld: " + dividend[8].toNumber()); + console.log("totalWithheldWithdrawn: " + dividend[9].toNumber()); + assert.equal(dividend[8].toNumber(), web3.utils.toWei("2.2", "ether")); + assert.equal(dividend[9].toNumber(), 0); let issuerBalance = new BigNumber(await I_PolyToken.balanceOf(wallet)); await I_ERC20DividendCheckpoint.withdrawWithholding(3, { from: token_owner, gasPrice: 0 }); let issuerBalanceAfter = new BigNumber(await I_PolyToken.balanceOf(wallet)); - assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei("0.4", "ether")); + assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei("2.2", "ether")); + dividend = await I_ERC20DividendCheckpoint.dividends.call(3); + console.log("totalWithheld: " + dividend[8].toNumber()); + console.log("totalWithheldWithdrawn: " + dividend[9].toNumber()); + assert.equal(dividend[8].toNumber(), web3.utils.toWei("2.2", "ether")); + assert.equal(dividend[9].toNumber(), web3.utils.toWei("2.2", "ether")); }); it("Issuer changes wallet address", async () => { @@ -969,7 +986,7 @@ contract("ERC20DividendCheckpoint", accounts => { assert.equal(tx.length, 2); }); - it("should registr a delegate", async () => { + it("should register a delegate", async () => { [I_GeneralPermissionManagerFactory] = await deployGPMAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, 0); let tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "0x", 0, 0, { from: token_owner }); assert.equal(tx.logs[2].args._types[0].toNumber(), delegateManagerKey, "General Permission Manager doesn't get deployed"); @@ -1159,7 +1176,7 @@ contract("ERC20DividendCheckpoint", accounts => { assert.equal(info[1][2].toNumber(), (await I_SecurityToken.balanceOfAt.call(account_temp, checkpointID)).toNumber(), "balance match"); assert.equal(info[1][3].toNumber(), (await I_SecurityToken.balanceOfAt.call(account_investor3, checkpointID)).toNumber(), "balance match"); assert.equal(info[2][0].toNumber(), 0, "withholding match"); - assert.equal(info[2][1].toNumber(), BigNumber(10 * 10 ** 16).toNumber(), "withholding match"); + assert.equal(info[2][1].toNumber(), BigNumber(100 * 10 ** 16).toNumber(), "withholding match"); assert.equal(info[2][2].toNumber(), BigNumber(20 * 10 ** 16).toNumber(), "withholding match"); assert.equal(info[2][3].toNumber(), 0, "withholding match"); assert.equal(tx.logs[0].args._checkpointId.toNumber(), checkpointID); diff --git a/test/f_ether_dividends.js b/test/f_ether_dividends.js index 6849e9cbd..e079649ae 100644 --- a/test/f_ether_dividends.js +++ b/test/f_ether_dividends.js @@ -363,6 +363,10 @@ contract("EtherDividendCheckpoint", accounts => { assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei("0", "ether")); }); + it("Set withholding tax of 100% on investor 2", async () => { + await I_EtherDividendCheckpoint.setWithholdingFixed([account_investor2], BigNumber(100 * 10 ** 16), { from: token_owner }); + }); + it("Buy some tokens for account_temp (1 ETH)", async () => { // Add the Investor in to the whitelist @@ -486,12 +490,13 @@ contract("EtherDividendCheckpoint", accounts => { let investor1BalanceAfter1 = new BigNumber(await web3.eth.getBalance(account_investor1)); let investor2BalanceAfter1 = new BigNumber(await web3.eth.getBalance(account_investor2)); let investor3BalanceAfter1 = new BigNumber(await web3.eth.getBalance(account_investor3)); - await I_EtherDividendCheckpoint.pushDividendPayment(2, 0, 10, { from: token_owner }); + let _blockNo = latestBlock(); + let tx = await I_EtherDividendCheckpoint.pushDividendPayment(2, 0, 10, { from: token_owner }); let investor1BalanceAfter2 = new BigNumber(await web3.eth.getBalance(account_investor1)); let investor2BalanceAfter2 = new BigNumber(await web3.eth.getBalance(account_investor2)); let investor3BalanceAfter2 = new BigNumber(await web3.eth.getBalance(account_investor3)); assert.equal(investor1BalanceAfter2.sub(investor1BalanceAfter1).toNumber(), 0); - assert.equal(investor2BalanceAfter2.sub(investor2BalanceAfter1).toNumber(), web3.utils.toWei("2.4", "ether")); + assert.equal(investor2BalanceAfter2.sub(investor2BalanceAfter1).toNumber(), 0); assert.equal(investor3BalanceAfter2.sub(investor3BalanceAfter1).toNumber(), 0); //Check fully claimed assert.equal((await I_EtherDividendCheckpoint.dividends(2))[5].toNumber(), web3.utils.toWei("11", "ether")); @@ -501,7 +506,7 @@ contract("EtherDividendCheckpoint", accounts => { let issuerBalance = new BigNumber(await web3.eth.getBalance(wallet)); await I_EtherDividendCheckpoint.withdrawWithholding(2, { from: token_owner, gasPrice: 0 }); let issuerBalanceAfter = new BigNumber(await web3.eth.getBalance(wallet)); - assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei("0.6", "ether")); + assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei("3", "ether")); }); it("Investor 2 transfers 1 ETH of his token balance to investor 1", async () => { @@ -531,7 +536,7 @@ contract("EtherDividendCheckpoint", accounts => { ); }); - it("Create another new dividend with bad expirty - fails", async () => { + it("Create another new dividend with bad expiry - fails", async () => { let maturity = latestTime() - duration.days(5); let expiry = latestTime() - duration.days(2); await catchRevert( @@ -648,7 +653,7 @@ contract("EtherDividendCheckpoint", accounts => { assert.equal(dividendAmount1[0].toNumber(), web3.utils.toWei("0", "ether")); assert.equal(dividendAmount1[1].toNumber(), web3.utils.toWei("0", "ether")); assert.equal(dividendAmount2[0].toNumber(), web3.utils.toWei("2", "ether")); - assert.equal(dividendAmount2[1].toNumber(), web3.utils.toWei("0.4", "ether")); + assert.equal(dividendAmount2[1].toNumber(), web3.utils.toWei("2", "ether")); assert.equal(dividendAmount3[0].toNumber(), web3.utils.toWei("7", "ether")); assert.equal(dividendAmount3[1].toNumber(), web3.utils.toWei("0", "ether")); assert.equal(dividendAmount_temp[0].toNumber(), web3.utils.toWei("1", "ether")); @@ -666,7 +671,7 @@ contract("EtherDividendCheckpoint", accounts => { let investor3BalanceAfter1 = new BigNumber(await web3.eth.getBalance(account_investor3)); let tempBalanceAfter1 = new BigNumber(await web3.eth.getBalance(account_temp)); assert.equal(investor1BalanceAfter1.sub(investor1Balance).toNumber(), 0); - assert.equal(investor2BalanceAfter1.sub(investor2Balance).toNumber(), web3.utils.toWei("1.6", "ether")); + assert.equal(investor2BalanceAfter1.sub(investor2Balance).toNumber(), 0); assert.equal(investor3BalanceAfter1.sub(investor3Balance).toNumber(), 0); assert.equal(tempBalanceAfter1.sub(tempBalance).toNumber(), 0); }); @@ -769,7 +774,7 @@ contract("EtherDividendCheckpoint", accounts => { let tokenBalanceAfter = new BigNumber(await web3.eth.getBalance(I_PolyToken.address)); assert.equal(investor1BalanceAfter.sub(investor1BalanceBefore).toNumber(), web3.utils.toWei("1", "ether")); - assert.equal(investor2BalanceAfter.sub(investor2BalanceBefore).toNumber(), web3.utils.toWei("1.6", "ether")); + assert.equal(investor2BalanceAfter.sub(investor2BalanceBefore).toNumber(), 0); assert.equal(investor3BalanceAfter.sub(investor3BalanceBefore).toNumber(), web3.utils.toWei("7", "ether")); assert.equal(tempBalanceAfter.sub(tempBalanceBefore).toNumber(), web3.utils.toWei("1", "ether")); assert.equal(tokenBalanceAfter.sub(tokenBalanceBefore).toNumber(), web3.utils.toWei("0", "ether")); diff --git a/test/p_usd_tiered_sto.js b/test/p_usd_tiered_sto.js index 48cad94b8..5d7de01a5 100644 --- a/test/p_usd_tiered_sto.js +++ b/test/p_usd_tiered_sto.js @@ -2197,7 +2197,7 @@ contract("USDTieredSTO", accounts => { let investorStatus = await I_USDTieredSTO_Array[stoId].investors.call(NONACCREDITED1); console.log("Current limit: " + investorStatus[2].toNumber()); let totalStatus = await I_USDTieredSTO_Array[stoId].getAccreditedData.call(); - + assert.equal(totalStatus[0][0], NONACCREDITED1, "Account match"); assert.equal(totalStatus[0][1], ACCREDITED1, "Account match"); assert.equal(totalStatus[1][0], false, "Account match"); @@ -4665,6 +4665,8 @@ contract("USDTieredSTO", accounts => { await I_USDOracle.changePrice(USDETH, { from: POLYMATH }); await I_POLYOracle.changePrice(USDPOLY, { from: POLYMATH }); }); + + it("should allow issuer to retrieve funds", async () => { }); describe("Test getter functions", async () => { From 4463496b80cd617a8ce368f8da96b93fa4ca434a Mon Sep 17 00:00:00 2001 From: Adam Dossa Date: Mon, 18 Mar 2019 12:37:27 -0400 Subject: [PATCH 51/83] Typo --- test/p_usd_tiered_sto.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/p_usd_tiered_sto.js b/test/p_usd_tiered_sto.js index 5d7de01a5..ee5838d0a 100644 --- a/test/p_usd_tiered_sto.js +++ b/test/p_usd_tiered_sto.js @@ -4666,7 +4666,6 @@ contract("USDTieredSTO", accounts => { await I_POLYOracle.changePrice(USDPOLY, { from: POLYMATH }); }); - it("should allow issuer to retrieve funds", async () => { }); describe("Test getter functions", async () => { From 8577bd8d94ac30e2b1b4b5f43da51a1c9d50850d Mon Sep 17 00:00:00 2001 From: Adam Dossa Date: Mon, 18 Mar 2019 16:14:13 -0400 Subject: [PATCH 52/83] More tests --- contracts/mocks/DummySTO.sol | 4 ++- test/b_capped_sto.js | 58 ++++++++++++++++++++++++++++++++++-- 2 files changed, 58 insertions(+), 4 deletions(-) diff --git a/contracts/mocks/DummySTO.sol b/contracts/mocks/DummySTO.sol index f452a01eb..a444df49c 100644 --- a/contracts/mocks/DummySTO.sol +++ b/contracts/mocks/DummySTO.sol @@ -90,6 +90,8 @@ contract DummySTO is STO { return allPermissions; } - + function () payable { + //Payable fallback function to allow us to test leaking ETH + } } diff --git a/test/b_capped_sto.js b/test/b_capped_sto.js index 13dff7d85..6cbbbe51a 100644 --- a/test/b_capped_sto.js +++ b/test/b_capped_sto.js @@ -2,11 +2,12 @@ import latestTime from "./helpers/latestTime"; import { duration, ensureException, promisifyLogWatch, latestBlock } from "./helpers/utils"; import { takeSnapshot, increaseTime, revertToSnapshot } from "./helpers/time"; import { encodeModuleCall } from "./helpers/encodeCall"; -import { setUpPolymathNetwork, deployGPMAndVerifyed } from "./helpers/createInstances"; +import { setUpPolymathNetwork, deployGPMAndVerifyed, deployDummySTOAndVerifyed } from "./helpers/createInstances"; import { catchRevert } from "./helpers/exceptions"; const CappedSTOFactory = artifacts.require("./CappedSTOFactory.sol"); const CappedSTO = artifacts.require("./CappedSTO.sol"); +const DummySTO = artifacts.require("./DummySTO.sol"); const SecurityToken = artifacts.require("./SecurityToken.sol"); const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); const GeneralPermissionManager = artifacts.require("./GeneralPermissionManager"); @@ -54,6 +55,7 @@ contract("CappedSTO", accounts => { let I_SecurityToken_POLY; let I_CappedSTO_Array_ETH = []; let I_CappedSTO_Array_POLY = []; + let I_DummySTO; let I_PolyToken; let I_PolymathRegistry; let I_STRProxied; @@ -441,7 +443,7 @@ contract("CappedSTO", accounts => { }); it("Should restrict to buy tokens after hiting the cap in second tx first tx pass", async () => { - + // Fallback transaction await web3.eth.sendTransaction({ @@ -850,6 +852,56 @@ contract("CappedSTO", accounts => { }); }); + describe("Check that we can reclaim ETH and ERC20 tokens from an STO", async () => { + //xxx + it("should attach a dummy STO", async () => { + let I_DummySTOFactory; + [I_DummySTOFactory] = await deployDummySTOAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, 0); + const DummySTOParameters = ["uint256", "uint256", "uint256", "string"]; + let startTime = latestTime() + duration.days(1); + let endTime = startTime + duration.days(30); + const cap = web3.utils.toWei("10000"); + const dummyBytesSig = encodeModuleCall(DummySTOParameters, [startTime, endTime, cap, "Hello"]); + const tx = await I_SecurityToken_ETH.addModule(I_DummySTOFactory.address, dummyBytesSig, maxCost, 0, { from: token_owner }); + assert.equal(tx.logs[2].args._types[0], stoKey, `Wrong module type added`); + assert.equal( + web3.utils.hexToString(tx.logs[2].args._name), + "DummySTO", + `Wrong STO module added` + ); + I_DummySTO = DummySTO.at(tx.logs[2].args._module); + }); + it("should send some funds and ERC20 to the DummySTO", async () => { + let tx = await web3.eth.sendTransaction({ + from: account_investor1, + to: I_DummySTO.address, + gas: 2100000, + value: web3.utils.toWei("1", "ether") + }); + let dummyETH = BigNumber(await web3.eth.getBalance(I_DummySTO.address)); + assert.equal(dummyETH.toNumber(), web3.utils.toWei("1", "ether")); + await I_PolyToken.getTokens(web3.utils.toWei("2", "ether"), I_DummySTO.address); + let dummyPOLY = BigNumber(await I_PolyToken.balanceOf(I_DummySTO.address)); + assert.equal(dummyPOLY.toNumber(), web3.utils.toWei("2", "ether")); + }); + + it("should reclaim ETH and ERC20 from STO", async () => { + let initialIssuerETH = BigNumber(await web3.eth.getBalance(token_owner)); + let initialIssuerPOLY = BigNumber(await I_PolyToken.balanceOf(token_owner)); + let tx = await I_DummySTO.reclaimERC20(I_PolyToken.address, {from: token_owner, gasPrice: 0}); + let tx2 = await I_DummySTO.reclaimETH({from: token_owner, gasPrice: 0}); + let finalIssuerETH = BigNumber(await web3.eth.getBalance(token_owner)); + let finalIssuerPOLY = BigNumber(await I_PolyToken.balanceOf(token_owner)); + assert.equal(finalIssuerETH.sub(initialIssuerETH).toNumber(), web3.utils.toWei("1", "ether")); + assert.equal(finalIssuerPOLY.sub(initialIssuerPOLY).toNumber(), web3.utils.toWei("2", "ether")); + let dummyETH = BigNumber(await web3.eth.getBalance(I_DummySTO.address)); + assert.equal(dummyETH.toNumber(), 0); + let dummyPOLY = BigNumber(await I_PolyToken.balanceOf(I_DummySTO.address)); + assert.equal(dummyPOLY.toNumber(), 0); + }); + }); + + describe("Test cases for the CappedSTOFactory", async () => { it("should get the exact details of the factory", async () => { assert.equal((await I_CappedSTOFactory.getSetupCost.call()).toNumber(), cappedSTOSetupCost); @@ -996,7 +1048,7 @@ contract("CappedSTO", accounts => { it("Should successfully invest in second STO", async () => { const polyToInvest = 1000; const stToReceive = (polyToInvest * P_rate)/Math.pow(10, 18); - + await I_PolyToken.getTokens(polyToInvest * Math.pow(10, 18), account_investor3); let tx = await I_GeneralTransferManager.modifyWhitelist(account_investor3, P_fromTime, P_toTime, P_expiryTime, true, { From 219f24e626bf237535524ecda58aab221c8af9b6 Mon Sep 17 00:00:00 2001 From: Adam Dossa Date: Mon, 18 Mar 2019 17:15:53 -0400 Subject: [PATCH 53/83] Add more test cases --- .../modules/Checkpoint/DividendCheckpoint.sol | 4 +++ test/b_capped_sto.js | 2 ++ test/e_erc20_dividends.js | 34 +++++++++++++++++++ test/f_ether_dividends.js | 23 +++++++++++++ 4 files changed, 63 insertions(+) diff --git a/contracts/modules/Checkpoint/DividendCheckpoint.sol b/contracts/modules/Checkpoint/DividendCheckpoint.sol index 54e6394cf..626638924 100644 --- a/contracts/modules/Checkpoint/DividendCheckpoint.sol +++ b/contracts/modules/Checkpoint/DividendCheckpoint.sol @@ -294,6 +294,10 @@ contract DividendCheckpoint is DividendCheckpointStorage, ICheckpoint, Module, P /** * @notice Allows issuer to change maturity / expiry dates for dividends + * @dev NB - setting the maturity of a currently matured dividend to a future date + * @dev will effectively refreeze claims on that dividend until the new maturity date passes + * @ dev NB - setting the expiry date to a past date will mean no more payments can be pulled + * @dev or pushed out of a dividend * @param _dividendIndex Dividend to withdraw from * @param _maturity updated maturity date * @param _expiry updated expiry date diff --git a/test/b_capped_sto.js b/test/b_capped_sto.js index 6cbbbe51a..ea4317638 100644 --- a/test/b_capped_sto.js +++ b/test/b_capped_sto.js @@ -888,6 +888,8 @@ contract("CappedSTO", accounts => { it("should reclaim ETH and ERC20 from STO", async () => { let initialIssuerETH = BigNumber(await web3.eth.getBalance(token_owner)); let initialIssuerPOLY = BigNumber(await I_PolyToken.balanceOf(token_owner)); + await catchRevert(I_DummySTO.reclaimERC20(I_PolyToken.address, {from: account_polymath, gasPrice: 0})); + await catchRevert(I_DummySTO.reclaimETH( {from: account_polymath, gasPrice: 0})); let tx = await I_DummySTO.reclaimERC20(I_PolyToken.address, {from: token_owner, gasPrice: 0}); let tx2 = await I_DummySTO.reclaimETH({from: token_owner, gasPrice: 0}); let finalIssuerETH = BigNumber(await web3.eth.getBalance(token_owner)); diff --git a/test/e_erc20_dividends.js b/test/e_erc20_dividends.js index af5620832..324c2c3a2 100644 --- a/test/e_erc20_dividends.js +++ b/test/e_erc20_dividends.js @@ -805,6 +805,15 @@ contract("ERC20DividendCheckpoint", accounts => { assert.equal(dividendAmount_temp[1].toNumber(), web3.utils.toWei("0.2", "ether")); }); + it("Pause and unpause the dividend contract", async () => { + await catchRevert(I_ERC20DividendCheckpoint.pause({from: account_polymath})); + let tx = await I_ERC20DividendCheckpoint.pause({from: token_owner}); + await catchRevert(I_ERC20DividendCheckpoint.pullDividendPayment(3, { from: account_investor2, gasPrice: 0 })); + await catchRevert(I_ERC20DividendCheckpoint.unpause({from: account_polymath})); + tx = await I_ERC20DividendCheckpoint.unpause({from: token_owner}); + }); + + it("Investor 2 claims dividend", async () => { let investor1Balance = new BigNumber(await I_PolyToken.balanceOf(account_investor1)); let investor2Balance = new BigNumber(await I_PolyToken.balanceOf(account_investor2)); @@ -834,7 +843,10 @@ contract("ERC20DividendCheckpoint", accounts => { let investor2BalanceAfter1 = new BigNumber(await I_PolyToken.balanceOf(account_investor2)); let investor3BalanceAfter1 = new BigNumber(await I_PolyToken.balanceOf(account_investor3)); let tempBalanceAfter1 = new BigNumber(await I_PolyToken.balanceOf(account_temp)); + // Issuer can still push payments when contract is paused + let tx = await I_ERC20DividendCheckpoint.pause({from: token_owner}); await I_ERC20DividendCheckpoint.pushDividendPaymentToAddresses(3, [account_temp, account_investor1], { from: token_owner }); + tx = await I_ERC20DividendCheckpoint.unpause({from: token_owner}); let investor1BalanceAfter2 = new BigNumber(await I_PolyToken.balanceOf(account_investor1)); let investor2BalanceAfter2 = new BigNumber(await I_PolyToken.balanceOf(account_investor2)); let investor3BalanceAfter2 = new BigNumber(await I_PolyToken.balanceOf(account_investor3)); @@ -1227,6 +1239,28 @@ contract("ERC20DividendCheckpoint", accounts => { assert.equal(tx.logs[0].args._checkpointId.toNumber(), 10); }); + it("Update maturity and expiry dates on dividend", async () => { + await catchRevert(I_ERC20DividendCheckpoint.updateDividendDates(7, 0, 1, {from: account_polymath})); + let tx = await I_ERC20DividendCheckpoint.updateDividendDates(7, 0, 1, {from: token_owner}); + let info = await I_ERC20DividendCheckpoint.getDividendData.call(7); + assert.equal(info[1].toNumber(), 0); + assert.equal(info[2].toNumber(), 1); + // Can now reclaim the dividend + await I_ERC20DividendCheckpoint.reclaimDividend(7, {from: token_owner}); + }); + + it("Reclaim ERC20 tokens from the dividend contract", async () => { + let currentDividendBalance = BigNumber(await I_PolyToken.balanceOf.call(I_ERC20DividendCheckpoint.address)); + let currentIssuerBalance = BigNumber(await I_PolyToken.balanceOf.call(token_owner)); + await catchRevert(I_ERC20DividendCheckpoint.reclaimERC20(I_PolyToken.address, {from: account_polymath})); + let tx = await I_ERC20DividendCheckpoint.reclaimERC20(I_PolyToken.address, {from: token_owner}); + assert.equal(await I_PolyToken.balanceOf.call(I_ERC20DividendCheckpoint.address), 0); + let newIssuerBalance = BigNumber(await I_PolyToken.balanceOf.call(token_owner)); + console.log("Reclaimed: " + currentDividendBalance.toNumber()); + assert.equal(newIssuerBalance.sub(currentIssuerBalance).toNumber(), currentDividendBalance.toNumber()); + }); + + it("should allow manager with permission to create checkpoint", async () => { let initCheckpointID = await I_SecurityToken.createCheckpoint.call({ from: token_owner }); await I_ERC20DividendCheckpoint.createCheckpoint({ from: account_manager }); diff --git a/test/f_ether_dividends.js b/test/f_ether_dividends.js index e079649ae..f6e6f2f4a 100644 --- a/test/f_ether_dividends.js +++ b/test/f_ether_dividends.js @@ -948,8 +948,31 @@ contract("EtherDividendCheckpoint", accounts => { { from: account_manager, value: web3.utils.toWei("12", "ether") } ); assert.equal(tx.logs[0].args._checkpointId.toNumber(), 12); + console.log(tx.logs[0].args._dividendIndex.toNumber()); }); + it("Update maturity and expiry dates on dividend", async () => { + await catchRevert(I_EtherDividendCheckpoint.updateDividendDates(8, 0, 1, {from: account_polymath})); + let tx = await I_EtherDividendCheckpoint.updateDividendDates(8, 0, 1, {from: token_owner}); + let info = await I_EtherDividendCheckpoint.getDividendData.call(8); + assert.equal(info[1].toNumber(), 0); + assert.equal(info[2].toNumber(), 1); + // Can now reclaim the dividend + await I_EtherDividendCheckpoint.reclaimDividend(8, {from: token_owner}); + }); + + it("Reclaim ETH from the dividend contract", async () => { + let currentDividendBalance = BigNumber(await web3.eth.getBalance(I_EtherDividendCheckpoint.address)); + let currentIssuerBalance = BigNumber(await web3.eth.getBalance(token_owner)); + await catchRevert(I_EtherDividendCheckpoint.reclaimETH({from: account_polymath, gasPrice: 0})); + let tx = await I_EtherDividendCheckpoint.reclaimETH({from: token_owner, gasPrice: 0}); + assert.equal(await web3.eth.getBalance(I_EtherDividendCheckpoint.address), 0); + let newIssuerBalance = BigNumber(await web3.eth.getBalance(token_owner)); + console.log("Reclaimed: " + currentDividendBalance.toNumber()); + assert.equal(newIssuerBalance.sub(currentIssuerBalance).toNumber(), currentDividendBalance.toNumber()); + }); + + it("should allow manager with permission to create checkpoint", async () => { let initCheckpointID = await I_SecurityToken.createCheckpoint.call({ from: token_owner }); await I_EtherDividendCheckpoint.createCheckpoint({ from: account_manager }); From 8766fb1ee6d92d4816221b5cc1cb6e0baadd311f Mon Sep 17 00:00:00 2001 From: Adam Dossa Date: Wed, 20 Mar 2019 07:57:58 -0400 Subject: [PATCH 54/83] Update versions --- contracts/modules/Checkpoint/ERC20DividendCheckpointFactory.sol | 2 +- contracts/modules/Checkpoint/EtherDividendCheckpointFactory.sol | 2 +- contracts/modules/STO/CappedSTOFactory.sol | 2 +- contracts/modules/STO/USDTieredSTOFactory.sol | 2 +- test/b_capped_sto.js | 2 +- test/e_erc20_dividends.js | 2 +- test/f_ether_dividends.js | 2 +- test/p_usd_tiered_sto.js | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/contracts/modules/Checkpoint/ERC20DividendCheckpointFactory.sol b/contracts/modules/Checkpoint/ERC20DividendCheckpointFactory.sol index 3935154cf..e18e54e96 100644 --- a/contracts/modules/Checkpoint/ERC20DividendCheckpointFactory.sol +++ b/contracts/modules/Checkpoint/ERC20DividendCheckpointFactory.sol @@ -24,7 +24,7 @@ contract ERC20DividendCheckpointFactory is ModuleFactory { ModuleFactory(_polyAddress, _setupCost, _usageCost, _subscriptionCost) { require(_logicContract != address(0), "Invalid logic contract"); - version = "2.1.0"; + version = "2.1.1"; name = "ERC20DividendCheckpoint"; title = "ERC20 Dividend Checkpoint"; description = "Create ERC20 dividends for token holders at a specific checkpoint"; diff --git a/contracts/modules/Checkpoint/EtherDividendCheckpointFactory.sol b/contracts/modules/Checkpoint/EtherDividendCheckpointFactory.sol index 923af1c64..0d74febf2 100644 --- a/contracts/modules/Checkpoint/EtherDividendCheckpointFactory.sol +++ b/contracts/modules/Checkpoint/EtherDividendCheckpointFactory.sol @@ -24,7 +24,7 @@ contract EtherDividendCheckpointFactory is ModuleFactory { ModuleFactory(_polyAddress, _setupCost, _usageCost, _subscriptionCost) { require(_logicContract != address(0), "Invalid logic contract"); - version = "2.1.0"; + version = "2.1.1"; name = "EtherDividendCheckpoint"; title = "Ether Dividend Checkpoint"; description = "Create ETH dividends for token holders at a specific checkpoint"; diff --git a/contracts/modules/STO/CappedSTOFactory.sol b/contracts/modules/STO/CappedSTOFactory.sol index 273389737..f649a0f5e 100644 --- a/contracts/modules/STO/CappedSTOFactory.sol +++ b/contracts/modules/STO/CappedSTOFactory.sol @@ -16,7 +16,7 @@ contract CappedSTOFactory is ModuleFactory { constructor (address _polyAddress, uint256 _setupCost, uint256 _usageCost, uint256 _subscriptionCost) public ModuleFactory(_polyAddress, _setupCost, _usageCost, _subscriptionCost) { - version = "2.1.0"; + version = "2.1.1"; name = "CappedSTO"; title = "Capped STO"; description = "This smart contract creates a maximum number of tokens (i.e. hard cap) which the total aggregate of tokens acquired by all investors cannot exceed. Security tokens are sent to the investor upon reception of the funds (ETH or POLY), and any security tokens left upon termination of the offering will not be minted."; diff --git a/contracts/modules/STO/USDTieredSTOFactory.sol b/contracts/modules/STO/USDTieredSTOFactory.sol index 1e44c7a7e..ba09d77c1 100644 --- a/contracts/modules/STO/USDTieredSTOFactory.sol +++ b/contracts/modules/STO/USDTieredSTOFactory.sol @@ -21,7 +21,7 @@ contract USDTieredSTOFactory is ModuleFactory { { require(_logicContract != address(0), "0x address is not allowed"); logicContract = _logicContract; - version = "2.1.0"; + version = "2.1.1"; name = "USDTieredSTO"; title = "USD Tiered STO"; /*solium-disable-next-line max-len*/ diff --git a/test/b_capped_sto.js b/test/b_capped_sto.js index ea4317638..0779ed142 100644 --- a/test/b_capped_sto.js +++ b/test/b_capped_sto.js @@ -922,7 +922,7 @@ contract("CappedSTO", accounts => { ); let tags = await I_CappedSTOFactory.getTags.call(); assert.equal(web3.utils.hexToString(tags[0]), "Capped"); - assert.equal(await I_CappedSTOFactory.version.call(), "2.1.0"); + assert.equal(await I_CappedSTOFactory.version.call(), "2.1.1"); }); it("Should fail to change the title -- bad owner", async () => { diff --git a/test/e_erc20_dividends.js b/test/e_erc20_dividends.js index 324c2c3a2..692916f67 100644 --- a/test/e_erc20_dividends.js +++ b/test/e_erc20_dividends.js @@ -1272,7 +1272,7 @@ contract("ERC20DividendCheckpoint", accounts => { it("should get the exact details of the factory", async () => { assert.equal((await I_ERC20DividendCheckpointFactory.getSetupCost.call()).toNumber(), 0); assert.equal((await I_ERC20DividendCheckpointFactory.getTypes.call())[0], 4); - assert.equal(await I_ERC20DividendCheckpointFactory.version.call(), "2.1.0"); + assert.equal(await I_ERC20DividendCheckpointFactory.version.call(), "2.1.1"); assert.equal( web3.utils.toAscii(await I_ERC20DividendCheckpointFactory.getName.call()).replace(/\u0000/g, ""), "ERC20DividendCheckpoint", diff --git a/test/f_ether_dividends.js b/test/f_ether_dividends.js index f6e6f2f4a..1f7646ce6 100644 --- a/test/f_ether_dividends.js +++ b/test/f_ether_dividends.js @@ -984,7 +984,7 @@ contract("EtherDividendCheckpoint", accounts => { it("should get the exact details of the factory", async () => { assert.equal((await I_EtherDividendCheckpointFactory.getSetupCost.call()).toNumber(), 0); assert.equal((await I_EtherDividendCheckpointFactory.getTypes.call())[0], 4); - assert.equal(await I_EtherDividendCheckpointFactory.version.call(), "2.1.0"); + assert.equal(await I_EtherDividendCheckpointFactory.version.call(), "2.1.1"); assert.equal( web3.utils.toAscii(await I_EtherDividendCheckpointFactory.getName.call()).replace(/\u0000/g, ""), "EtherDividendCheckpoint", diff --git a/test/p_usd_tiered_sto.js b/test/p_usd_tiered_sto.js index ee5838d0a..117916054 100644 --- a/test/p_usd_tiered_sto.js +++ b/test/p_usd_tiered_sto.js @@ -4792,7 +4792,7 @@ contract("USDTieredSTO", accounts => { "Wrong Module added"); assert.equal(await I_USDTieredSTOFactory.title.call(), "USD Tiered STO", "Wrong Module added"); assert.equal(await I_USDTieredSTOFactory.getInstructions.call(), "Initialises a USD tiered STO.", "Wrong Module added"); - assert.equal(await I_USDTieredSTOFactory.version.call(), "2.1.0"); + assert.equal(await I_USDTieredSTOFactory.version.call(), "2.1.1"); let tags = await I_USDTieredSTOFactory.getTags.call(); assert.equal(web3.utils.hexToString(tags[0]), "USD"); assert.equal(web3.utils.hexToString(tags[1]), "Tiered"); From 06bec001bd275f546b1efb52478c5ca249fb2141 Mon Sep 17 00:00:00 2001 From: Adam Dossa Date: Wed, 20 Mar 2019 07:59:40 -0400 Subject: [PATCH 55/83] Only bump dividends --- contracts/modules/STO/CappedSTOFactory.sol | 2 +- contracts/modules/STO/USDTieredSTOFactory.sol | 2 +- test/b_capped_sto.js | 2 +- test/p_usd_tiered_sto.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/contracts/modules/STO/CappedSTOFactory.sol b/contracts/modules/STO/CappedSTOFactory.sol index f649a0f5e..273389737 100644 --- a/contracts/modules/STO/CappedSTOFactory.sol +++ b/contracts/modules/STO/CappedSTOFactory.sol @@ -16,7 +16,7 @@ contract CappedSTOFactory is ModuleFactory { constructor (address _polyAddress, uint256 _setupCost, uint256 _usageCost, uint256 _subscriptionCost) public ModuleFactory(_polyAddress, _setupCost, _usageCost, _subscriptionCost) { - version = "2.1.1"; + version = "2.1.0"; name = "CappedSTO"; title = "Capped STO"; description = "This smart contract creates a maximum number of tokens (i.e. hard cap) which the total aggregate of tokens acquired by all investors cannot exceed. Security tokens are sent to the investor upon reception of the funds (ETH or POLY), and any security tokens left upon termination of the offering will not be minted."; diff --git a/contracts/modules/STO/USDTieredSTOFactory.sol b/contracts/modules/STO/USDTieredSTOFactory.sol index ba09d77c1..1e44c7a7e 100644 --- a/contracts/modules/STO/USDTieredSTOFactory.sol +++ b/contracts/modules/STO/USDTieredSTOFactory.sol @@ -21,7 +21,7 @@ contract USDTieredSTOFactory is ModuleFactory { { require(_logicContract != address(0), "0x address is not allowed"); logicContract = _logicContract; - version = "2.1.1"; + version = "2.1.0"; name = "USDTieredSTO"; title = "USD Tiered STO"; /*solium-disable-next-line max-len*/ diff --git a/test/b_capped_sto.js b/test/b_capped_sto.js index 0779ed142..ea4317638 100644 --- a/test/b_capped_sto.js +++ b/test/b_capped_sto.js @@ -922,7 +922,7 @@ contract("CappedSTO", accounts => { ); let tags = await I_CappedSTOFactory.getTags.call(); assert.equal(web3.utils.hexToString(tags[0]), "Capped"); - assert.equal(await I_CappedSTOFactory.version.call(), "2.1.1"); + assert.equal(await I_CappedSTOFactory.version.call(), "2.1.0"); }); it("Should fail to change the title -- bad owner", async () => { diff --git a/test/p_usd_tiered_sto.js b/test/p_usd_tiered_sto.js index 117916054..ee5838d0a 100644 --- a/test/p_usd_tiered_sto.js +++ b/test/p_usd_tiered_sto.js @@ -4792,7 +4792,7 @@ contract("USDTieredSTO", accounts => { "Wrong Module added"); assert.equal(await I_USDTieredSTOFactory.title.call(), "USD Tiered STO", "Wrong Module added"); assert.equal(await I_USDTieredSTOFactory.getInstructions.call(), "Initialises a USD tiered STO.", "Wrong Module added"); - assert.equal(await I_USDTieredSTOFactory.version.call(), "2.1.1"); + assert.equal(await I_USDTieredSTOFactory.version.call(), "2.1.0"); let tags = await I_USDTieredSTOFactory.getTags.call(); assert.equal(web3.utils.hexToString(tags[0]), "USD"); assert.equal(web3.utils.hexToString(tags[1]), "Tiered"); From 9872bf9e8ab959503a65af9695f4c64daf047e40 Mon Sep 17 00:00:00 2001 From: Victor Date: Wed, 20 Mar 2019 09:32:29 -0300 Subject: [PATCH 56/83] Fix decimals in dividends modules --- CLI/commands/dividends_manager.js | 84 ++++++++++++++++++------------- 1 file changed, 49 insertions(+), 35 deletions(-) diff --git a/CLI/commands/dividends_manager.js b/CLI/commands/dividends_manager.js index f4aca926e..4aa438b38 100644 --- a/CLI/commands/dividends_manager.js +++ b/CLI/commands/dividends_manager.js @@ -238,9 +238,12 @@ async function manageExistingDividend(dividendIndex) { let dividend = await currentDividendsModule.methods.dividends(dividendIndex).call(); let dividendTokenAddress = gbl.constants.ADDRESS_ZERO; let dividendTokenSymbol = 'ETH'; + let dividendTokenDecimals = 18; if (dividendsType === 'ERC20') { dividendTokenAddress = await currentDividendsModule.methods.dividendTokens(dividendIndex).call(); dividendTokenSymbol = await getERC20TokenSymbol(dividendTokenAddress); + let erc20token = new web3.eth.Contract(abis.erc20(), dividendTokenAddress); + dividendTokenDecimals = await erc20token.methods.decimals().call(); } let progress = await currentDividendsModule.methods.getDividendProgress(dividendIndex).call(); let investorArray = progress[0]; @@ -266,12 +269,12 @@ async function manageExistingDividend(dividendIndex) { console.log(`- Maturity: ${moment.unix(dividend.maturity).format('MMMM Do YYYY, HH:mm:ss')}`); console.log(`- Expiry: ${moment.unix(dividend.expiry).format('MMMM Do YYYY, HH:mm:ss')}`); console.log(`- At checkpoint: ${dividend.checkpointId}`); - console.log(`- Amount: ${web3.utils.fromWei(dividend.amount)} ${dividendTokenSymbol}`); - console.log(`- Claimed amount: ${web3.utils.fromWei(dividend.claimedAmount)} ${dividendTokenSymbol}`); + console.log(`- Amount: ${dividend.amount / Math.pow(10, dividendTokenDecimals)} ${dividendTokenSymbol}`); + console.log(`- Claimed amount: ${dividend.claimedAmount / Math.pow(10, dividendTokenDecimals)} ${dividendTokenSymbol}`); console.log(`- Taxes:`); - console.log(` To withhold: ${web3.utils.fromWei(taxesToWithHeld)} ${dividendTokenSymbol}`); - console.log(` Withheld to-date: ${web3.utils.fromWei(dividend.totalWithheld)} ${dividendTokenSymbol}`); - console.log(` Withdrawn to-date: ${web3.utils.fromWei(dividend.totalWithheldWithdrawn)} ${dividendTokenSymbol}`); + console.log(` To withhold: ${taxesToWithHeld / Math.pow(10, dividendTokenDecimals)} ${dividendTokenSymbol}`); + console.log(` Withheld to-date: ${dividend.totalWithheld / Math.pow(10, dividendTokenDecimals)} ${dividendTokenSymbol}`); + console.log(` Withdrawn to-date: ${dividend.totalWithheldWithdrawn / Math.pow(10, dividendTokenDecimals)} ${dividendTokenSymbol}`); console.log(`- Total investors: ${investorArray.length}`); console.log(` Have already claimed: ${claimedInvestors} (${investorArray.length - excludedInvestors !== 0 ? claimedInvestors / (investorArray.length - excludedInvestors) * 100 : 0}%)`); console.log(` Excluded: ${excludedInvestors} `); @@ -300,6 +303,7 @@ async function manageExistingDividend(dividendIndex) { showReport( web3.utils.hexToUtf8(dividend.name), dividendTokenSymbol, + dividendTokenDecimals, dividend.amount, // Total amount of dividends sent dividend.totalWithheld, // Total amount of taxes withheld dividend.claimedAmount, // Total amount of dividends distributed @@ -314,13 +318,13 @@ async function manageExistingDividend(dividendIndex) { await pushDividends(dividendIndex, dividend.checkpointId); break; case 'Explore account': - await exploreAccount(dividendIndex, dividendTokenAddress, dividendTokenSymbol); + await exploreAccount(dividendIndex, dividendTokenAddress, dividendTokenSymbol, dividendTokenDecimals); break; case 'Withdraw withholding': - await withdrawWithholding(dividendIndex, dividendTokenSymbol); + await withdrawWithholding(dividendIndex, dividendTokenSymbol, dividendTokenDecimals); break; case 'Reclaim expired dividends': - await reclaimedDividend(dividendIndex, dividendTokenSymbol); + await reclaimedDividend(dividendIndex, dividendTokenSymbol, dividendTokenDecimals); return; case 'RETURN': return; @@ -376,6 +380,7 @@ async function createDividends() { let dividendName = readlineSync.question(`Enter a name or title to indetify this dividend: `); let dividendToken = gbl.constants.ADDRESS_ZERO; let dividendSymbol = 'ETH'; + let dividendTokenDecimals = 18; let token; if (dividendsType === 'ERC20') { do { @@ -390,6 +395,7 @@ async function createDividends() { if (erc20Symbol != null) { token = new web3.eth.Contract(abis.erc20(), dividendToken); dividendSymbol = erc20Symbol; + dividendTokenDecimals = await token.methods.decimals().call(); } else { console.log(chalk.red(`${dividendToken} is not a valid ERC20 token address!!`)); } @@ -397,10 +403,13 @@ async function createDividends() { } let dividendAmount = readlineSync.question(`How much ${dividendSymbol} would you like to distribute to token holders? `); - let dividendAmountBN = new web3.utils.BN(dividendAmount); - let issuerBalance = new web3.utils.BN(web3.utils.fromWei(await getBalance(Issuer.address, dividendToken))); - if (issuerBalance.lt(dividendAmountBN)) { - console.log(chalk.red(`You have ${issuerBalance} ${dividendSymbol}.You need ${dividendAmountBN.sub(issuerBalance)} ${dividendSymbol} more!`)); + console.log("Decimals:", dividendTokenDecimals); + let dividendAmountBN = parseFloat(dividendAmount) * Math.pow(10, dividendTokenDecimals); + console.log('Amount to use:', dividendAmountBN); + let issuerBalance = await getBalance(Issuer.address, dividendToken); + console.log('Issuer balance:', issuerBalance); + if (issuerBalance < dividendAmountBN) { + console.log(chalk.red(`You have ${issuerBalance / Math.pow(10, dividendTokenDecimals)} ${dividendSymbol}. You need ${(dividendAmountBN - issuerBalance) / Math.pow(10, dividendTokenDecimals)} ${dividendSymbol} more!`)); } else { let checkpointId = await selectCheckpoint(true); // If there are no checkpoints, it must create a new one let now = Math.floor(Date.now() / 1000); @@ -412,21 +421,21 @@ async function createDividends() { let createDividendAction; if (dividendsType == 'ERC20') { - let approveAction = token.methods.approve(currentDividendsModule._address, web3.utils.toWei(dividendAmountBN)); + let approveAction = token.methods.approve(currentDividendsModule._address, dividendAmountBN); await common.sendTransaction(approveAction); if (checkpointId > 0) { if (useDefaultExcluded) { - createDividendAction = currentDividendsModule.methods.createDividendWithCheckpoint(maturityTime, expiryTime, token.options.address, web3.utils.toWei(dividendAmountBN), checkpointId, web3.utils.toHex(dividendName)); + createDividendAction = currentDividendsModule.methods.createDividendWithCheckpoint(maturityTime, expiryTime, token.options.address, dividendAmountBN, checkpointId, web3.utils.toHex(dividendName)); } else { let excluded = getExcludedFromDataFile(); - createDividendAction = currentDividendsModule.methods.createDividendWithCheckpointAndExclusions(maturityTime, expiryTime, token.options.address, web3.utils.toWei(dividendAmountBN), checkpointId, excluded[0], web3.utils.toHex(dividendName)); + createDividendAction = currentDividendsModule.methods.createDividendWithCheckpointAndExclusions(maturityTime, expiryTime, token.options.address, dividendAmountBN, checkpointId, excluded[0], web3.utils.toHex(dividendName)); } } else { if (useDefaultExcluded) { - createDividendAction = currentDividendsModule.methods.createDividend(maturityTime, expiryTime, token.options.address, web3.utils.toWei(dividendAmountBN), web3.utils.toHex(dividendName)); + createDividendAction = currentDividendsModule.methods.createDividend(maturityTime, expiryTime, token.options.address, dividendAmountBN, web3.utils.toHex(dividendName)); } else { let excluded = getExcludedFromDataFile(); - createDividendAction = currentDividendsModule.methods.createDividendWithExclusions(maturityTime, expiryTime, token.options.address, web3.utils.toWei(dividendAmountBN), excluded[0], web3.utils.toHex(dividendName)); + createDividendAction = currentDividendsModule.methods.createDividendWithExclusions(maturityTime, expiryTime, token.options.address, dividendAmountBN, excluded[0], web3.utils.toHex(dividendName)); } } let receipt = await common.sendTransaction(createDividendAction); @@ -470,7 +479,7 @@ function showInvestors(investorsArray, claimedArray, excludedArray) { console.log(table(dataTable)); } -function showReport(_name, _tokenSymbol, _amount, _witthheld, _claimed, _investorArray, _claimedArray, _excludedArray, _withheldArray, _amountArray) { +function showReport(_name, _tokenSymbol, _tokenDecimals, _amount, _witthheld, _claimed, _investorArray, _claimedArray, _excludedArray, _withheldArray, _amountArray) { let title = `${_name.toUpperCase()} DIVIDEND REPORT`; let dataTable = [[ @@ -485,10 +494,10 @@ function showReport(_name, _tokenSymbol, _amount, _witthheld, _claimed, _investo let investor = _investorArray[i]; let excluded = _excludedArray[i]; let withdrawn = _claimedArray[i] ? 'YES' : 'NO'; - let amount = !excluded ? web3.utils.fromWei(web3.utils.toBN(_amountArray[i]).add(web3.utils.toBN(_withheldArray[i]))) : 0; - let withheld = !excluded ? web3.utils.fromWei(_withheldArray[i]) : 'NA'; + let amount = !excluded ? web3.utils.toBN(_amountArray[i]).add(web3.utils.toBN(_withheldArray[i])).divn(Math.pow(10, _tokenDecimals)) : 0; + let withheld = !excluded ? parseFloat(_withheldArray[i]) / Math.pow(10, _tokenDecimals) : 'NA'; let withheldPercentage = (!excluded) ? (withheld !== '0' ? parseFloat(withheld) / parseFloat(amount) * 100 : 0) : 'NA'; - let received = !excluded ? web3.utils.fromWei(_amountArray[i]) : 0; + let received = !excluded ? parseFloat(_amountArray[i]) / Math.pow(10, _tokenDecimals) : 0; dataTable.push([ investor, amount, @@ -501,9 +510,9 @@ function showReport(_name, _tokenSymbol, _amount, _witthheld, _claimed, _investo console.log(chalk.yellow(`-----------------------------------------------------------------------------------------------------------------------------------------------------------`)); console.log(title.padStart((50 - title.length) / 2, '*').padEnd((50 - title.length) / 2, '*')); console.log(); - console.log(`- Total amount of dividends sent: ${web3.utils.fromWei(_amount)} ${_tokenSymbol} `); - console.log(`- Total amount of taxes withheld: ${web3.utils.fromWei(_witthheld)} ${_tokenSymbol} `); - console.log(`- Total amount of dividends distributed: ${web3.utils.fromWei(_claimed)} ${_tokenSymbol} `); + console.log(`- Total amount of dividends sent: ${parseFloat(_amount) / Math.pow(10, _tokenDecimals)} ${_tokenSymbol} `); + console.log(`- Total amount of taxes withheld: ${parseFloat(_witthheld) / Math.pow(10, _tokenDecimals)} ${_tokenSymbol} `); + console.log(`- Total amount of dividends distributed: ${parseFloat(_claimed) / Math.pow(10, _tokenDecimals)} ${_tokenSymbol} `); console.log(`- Total amount of investors: ${_investorArray.length} `); console.log(); console.log(table(dataTable)); @@ -536,7 +545,7 @@ async function pushDividends(dividendIndex, checkpointId) { } } -async function exploreAccount(dividendIndex, dividendTokenAddress, dividendTokenSymbol) { +async function exploreAccount(dividendIndex, dividendTokenAddress, dividendTokenSymbol, dividendTokenDecimals) { let account = readlineSync.question('Enter address to explore: ', { limit: function (input) { return web3.utils.isAddress(input); @@ -553,33 +562,33 @@ async function exploreAccount(dividendIndex, dividendTokenAddress, dividendToken console.log(); console.log(`Security token balance: ${web3.utils.fromWei(securityTokenBalance)} ${tokenSymbol} `); - console.log(`Dividend token balance: ${web3.utils.fromWei(dividendTokenBalance)} ${dividendTokenSymbol} `); + console.log(`Dividend token balance: ${dividendTokenBalance / Math.pow(10, dividendTokenDecimals)} ${dividendTokenSymbol} `); console.log(`Is excluded: ${isExcluded ? 'YES' : 'NO'} `); if (!isExcluded) { console.log(`Has claimed: ${hasClaimed ? 'YES' : 'NO'} `); if (!hasClaimed) { - console.log(`Dividends available: ${web3.utils.fromWei(dividendBalance)} ${dividendTokenSymbol} `); - console.log(`Tax withheld: ${web3.utils.fromWei(dividendTax)} ${dividendTokenSymbol} `); + console.log(`Dividends available: ${dividendBalance / Math.pow(10, dividendTokenDecimals)} ${dividendTokenSymbol} `); + console.log(`Tax withheld: ${dividendTax / Math.pow(10, dividendTokenDecimals)} ${dividendTokenSymbol} `); } } console.log(); } -async function withdrawWithholding(dividendIndex, dividendTokenSymbol) { +async function withdrawWithholding(dividendIndex, dividendTokenSymbol, dividendTokenDecimals) { let action = currentDividendsModule.methods.withdrawWithholding(dividendIndex); let receipt = await common.sendTransaction(action); let eventName = dividendsType === 'ERC20' ? 'ERC20DividendWithholdingWithdrawn' : 'EtherDividendWithholdingWithdrawn'; let event = common.getEventFromLogs(currentDividendsModule._jsonInterface, receipt.logs, eventName); - console.log(chalk.green(`Successfully withdrew ${web3.utils.fromWei(event._withheldAmount)} ${dividendTokenSymbol} from dividend ${event._dividendIndex} tax withholding.`)); + console.log(chalk.green(`Successfully withdrew ${event._withheldAmount / Math.pow(10, dividendTokenDecimals)} ${dividendTokenSymbol} from dividend ${event._dividendIndex} tax withholding.`)); } -async function reclaimedDividend(dividendIndex, dividendTokenSymbol) { +async function reclaimedDividend(dividendIndex, dividendTokenSymbol, dividendTokenDecimals) { let action = currentDividendsModule.methods.reclaimDividend(dividendIndex); let receipt = await common.sendTransaction(action); let eventName = dividendsType === 'ERC20' ? 'ERC20DividendReclaimed' : 'EtherDividendReclaimed'; let event = common.getEventFromLogs(currentDividendsModule._jsonInterface, receipt.logs, eventName); console.log(` -Reclaimed amount ${ web3.utils.fromWei(event._claimedAmount)} ${dividendTokenSymbol} +Reclaimed amount ${event._claimedAmount / Math.pow(10, dividendTokenDecimals)} ${dividendTokenSymbol} to account ${ event._claimer} ` ); } @@ -699,7 +708,7 @@ async function selectDividend(dividends) { let result = null; let options = dividends.map(function (d) { return `${d.name} - Amount: ${web3.utils.fromWei(d.amount)} ${d.tokenSymbol} + Amount: ${parseFloat(d.amount) / Math.pow(10, d.tokenDecimals)} ${d.tokenSymbol} Status: ${isExpiredDividend(d) ? 'Expired' : hasRemaining(d) ? 'In progress' : 'Completed'} Token: ${d.tokenSymbol} Created: ${moment.unix(d.created).format('MMMM Do YYYY, HH:mm:ss')} @@ -715,7 +724,7 @@ async function selectDividend(dividends) { } async function getDividends() { - function DividendData(_index, _created, _maturity, _expiry, _amount, _claimedAmount, _name, _tokenSymbol) { + function DividendData(_index, _created, _maturity, _expiry, _amount, _claimedAmount, _name, _tokenSymbol, _tokenDecimals) { this.index = _index; this.created = _created; this.maturity = _maturity; @@ -724,6 +733,7 @@ async function getDividends() { this.claimedAmount = _claimedAmount; this.name = _name; this.tokenSymbol = _tokenSymbol; + this.tokenDecimals = _tokenDecimals; } let dividends = []; @@ -736,9 +746,12 @@ async function getDividends() { let nameArray = dividendsData.names; for (let i = 0; i < nameArray.length; i++) { let tokenSymbol = 'ETH'; + let dividendTokenDecimals = 18; if (dividendsType === 'ERC20') { let tokenAddress = await currentDividendsModule.methods.dividendTokens(i).call(); tokenSymbol = await getERC20TokenSymbol(tokenAddress); + let erc20token = new web3.eth.Contract(abis.erc20(), tokenAddress); + dividendTokenDecimals = await erc20token.methods.decimals().call(); } dividends.push( new DividendData( @@ -749,7 +762,8 @@ async function getDividends() { amountArray[i], claimedAmountArray[i], web3.utils.hexToUtf8(nameArray[i]), - tokenSymbol + tokenSymbol, + dividendTokenDecimals ) ); } From 7095b380f832d41806c26ab4cf4b19d413c689c8 Mon Sep 17 00:00:00 2001 From: Victor Date: Wed, 20 Mar 2019 09:32:42 -0300 Subject: [PATCH 57/83] STOs are listed with its version --- CLI/commands/sto_manager.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/CLI/commands/sto_manager.js b/CLI/commands/sto_manager.js index 4a96b1088..8ab5b62fd 100644 --- a/CLI/commands/sto_manager.js +++ b/CLI/commands/sto_manager.js @@ -122,13 +122,17 @@ async function addSTOModule(stoConfig) { let optionSelected; if (typeof stoConfig === 'undefined') { let availableModules = await moduleRegistry.methods.getModulesByTypeAndToken(gbl.constants.MODULES_TYPES.STO, securityToken.options.address).call(); - let options = await Promise.all(availableModules.map(async function (m) { + let moduleList = await Promise.all(availableModules.map(async function (m) { let moduleFactoryABI = abis.moduleFactory(); let moduleFactory = new web3.eth.Contract(moduleFactoryABI, m); - return web3.utils.hexToUtf8(await moduleFactory.methods.name().call()); + let moduleName = web3.utils.hexToUtf8(await moduleFactory.methods.name().call()); + let moduleVersion = await moduleFactory.methods.version().call(); + return { name: moduleName, version: moduleVersion, factoryAddress: m }; })); + let options = moduleList.map(m => `${m.name} - ${m.version} (${m.factoryAddress})`); + let index = readlineSync.keyInSelect(options, 'What type of STO do you want?', { cancel: 'RETURN' }); - optionSelected = index != -1 ? options[index] : 'RETURN'; + optionSelected = index != -1 ? moduleList[index].name : 'RETURN'; } else { optionSelected = stoConfig.type; } @@ -972,6 +976,8 @@ async function getBalance(from, type) { return await web3.eth.getBalance(from); case gbl.constants.FUND_RAISE_TYPES.POLY: return await polyToken.methods.balanceOf(from).call(); + default: + return '0'; } } From daf208b31385c8a98dd42cd33d62d959b60f1397 Mon Sep 17 00:00:00 2001 From: Victor Date: Wed, 20 Mar 2019 10:54:35 -0300 Subject: [PATCH 58/83] Reclaim ETH and ERC20 tokens from STO and Dividends modules --- CLI/commands/dividends_manager.js | 45 ++++++++++++++++++++++++++----- CLI/commands/sto_manager.js | 32 ++++++++++++++++++++++ 2 files changed, 70 insertions(+), 7 deletions(-) diff --git a/CLI/commands/dividends_manager.js b/CLI/commands/dividends_manager.js index 4aa438b38..97e6985c7 100644 --- a/CLI/commands/dividends_manager.js +++ b/CLI/commands/dividends_manager.js @@ -146,7 +146,7 @@ async function dividendsManager() { if (currentDividends.length > 0) { options.push('Manage existing dividends'); } - options.push('Create new dividends'); + options.push('Create new dividends', 'Reclaim ETH or ERC20 tokens from contract'); let index = readlineSync.keyInSelect(options, 'What do you want to do?', { cancel: 'RETURN' }); let selected = index != -1 ? options[index] : 'RETURN'; @@ -178,6 +178,9 @@ async function dividendsManager() { case 'Create new dividends': await createDividends(); break; + case 'Reclaim ETH or ERC20 tokens from contract': + await reclaimFromContract(); + break; case 'RETURN': return; } @@ -326,6 +329,9 @@ async function manageExistingDividend(dividendIndex) { case 'Reclaim expired dividends': await reclaimedDividend(dividendIndex, dividendTokenSymbol, dividendTokenDecimals); return; + case 'Reclaim ETH or ERC20 tokens from contract': + await reclaim + break; case 'RETURN': return; } @@ -403,14 +409,12 @@ async function createDividends() { } let dividendAmount = readlineSync.question(`How much ${dividendSymbol} would you like to distribute to token holders? `); - console.log("Decimals:", dividendTokenDecimals); - let dividendAmountBN = parseFloat(dividendAmount) * Math.pow(10, dividendTokenDecimals); - console.log('Amount to use:', dividendAmountBN); + let dividendAmountToSend = parseFloat(dividendAmount) * Math.pow(10, dividendTokenDecimals); let issuerBalance = await getBalance(Issuer.address, dividendToken); - console.log('Issuer balance:', issuerBalance); - if (issuerBalance < dividendAmountBN) { + if (issuerBalance < dividendAmountToSend) { console.log(chalk.red(`You have ${issuerBalance / Math.pow(10, dividendTokenDecimals)} ${dividendSymbol}. You need ${(dividendAmountBN - issuerBalance) / Math.pow(10, dividendTokenDecimals)} ${dividendSymbol} more!`)); } else { + let dividendAmountBN = new web3.utils.BN(dividendAmountToSend.toString()); let checkpointId = await selectCheckpoint(true); // If there are no checkpoints, it must create a new one let now = Math.floor(Date.now() / 1000); let maturityTime = readlineSync.questionInt('Enter the dividend maturity time from which dividend can be paid (Unix Epoch time)\n(Now = ' + now + ' ): ', { defaultInput: now }); @@ -457,7 +461,7 @@ async function createDividends() { createDividendAction = currentDividendsModule.methods.createDividendWithExclusions(maturityTime, expiryTime, excluded, web3.utils.toHex(dividendName)); } } - let receipt = await common.sendTransaction(createDividendAction, { value: web3.utils.toWei(dividendAmountBN) }); + let receipt = await common.sendTransaction(createDividendAction, { value: dividendAmountBN }); let event = common.getEventFromLogs(currentDividendsModule._jsonInterface, receipt.logs, 'EtherDividendDeposited'); console.log(` Dividend ${ event._dividendIndex} deposited` @@ -466,6 +470,33 @@ Dividend ${ event._dividendIndex} deposited` } } +async function reclaimFromContract() { + let options = ['ETH', 'ERC20']; + let index = readlineSync.keyInSelect(options, 'What do you want to reclaim?', { cancel: 'RETURN' }); + let selected = index != -1 ? options[index] : 'RETURN'; + switch (selected) { + case 'ETH': + let ethBalance = await web3.eth.getBalance(currentDividendsModule.options.address); + console.log(chalk.yellow(`Current ETH balance: ${web3.utils.fromWei(ethBalance)} ETH`)); + let reclaimETHAction = currentDividendsModule.methods.reclaimETH(); + await common.sendTransaction(reclaimETHAction); + console.log(chalk.green('ETH has been reclaimed succesfully!')); + break; + case 'ERC20': + let erc20Address = readlineSync.question('Enter the ERC20 token address to reclaim (POLY = ' + polyToken.options.address + '): ', { + limit: function (input) { + return web3.utils.isAddress(input); + }, + limitMessage: "Must be a valid address", + defaultInput: polyToken.options.address + }); + let reclaimERC20Action = currentDividendsModule.methods.reclaimERC20(erc20Address); + await common.sendTransaction(reclaimERC20Action, { factor: 2 }); + console.log(chalk.green('ERC20 has been reclaimed succesfully!')); + break + } +} + function showInvestors(investorsArray, claimedArray, excludedArray) { let dataTable = [['Investor', 'Has claimed', 'Is excluded']]; for (let i = 0; i < investorsArray.length; i++) { diff --git a/CLI/commands/sto_manager.js b/CLI/commands/sto_manager.js index 8ab5b62fd..2f09540f6 100644 --- a/CLI/commands/sto_manager.js +++ b/CLI/commands/sto_manager.js @@ -786,6 +786,8 @@ async function usdTieredSTO_configure(currentSTO) { 'Modify limits configuration', 'Modify funding configuration'); } + options.push('Reclaim ETH or ERC20 token from contract'); + let index = readlineSync.keyInSelect(options, 'What do you want to do?', { cancel: 'RETURN' }); let selected = index != -1 ? options[index] : 'Exit'; switch (selected) { @@ -844,6 +846,9 @@ async function usdTieredSTO_configure(currentSTO) { await modfifyFunding(currentSTO); await usdTieredSTO_status(currentSTO); break; + case 'Reclaim ETH or ERC20 token from contract': + await reclaimFromContract(currentSTO); + break; } } } @@ -967,6 +972,33 @@ async function modfifyTiers(currentSTO) { await common.sendTransaction(modifyTiersAction); } +async function reclaimFromContract(currentSTO) { + let options = ['ETH', 'ERC20']; + let index = readlineSync.keyInSelect(options, 'What do you want to reclaim?', { cancel: 'RETURN' }); + let selected = index != -1 ? options[index] : 'RETURN'; + switch (selected) { + case 'ETH': + let ethBalance = await this.getBalance(currentSTO.options.address, gbl.constants.FUND_RAISE_TYPES.ETH); + console.log(chalk.yellow(`Current ETH balance: ${web3.utils.fromWei(ethBalance)} ETH`)); + let reclaimETHAction = currentSTO.methods.reclaimETH(); + await common.sendTransaction(reclaimETHAction); + console.log(chalk.green('ETH has been reclaimed succesfully!')); + break; + case 'ERC20': + let erc20Address = readlineSync.question('Enter the ERC20 token address to reclaim (POLY = ' + polyToken.options.address + '): ', { + limit: function (input) { + return web3.utils.isAddress(input); + }, + limitMessage: "Must be a valid address", + defaultInput: polyToken.options.address + }); + let reclaimERC20Action = currentSTO.methods.reclaimERC20(erc20Address); + await common.sendTransaction(reclaimERC20Action); + console.log(chalk.green('ERC20 has been reclaimed succesfully!')); + break + } +} + ////////////////////// // HELPER FUNCTIONS // ////////////////////// From a6f289b9f11eb58adf508093f265bf5d921375f5 Mon Sep 17 00:00:00 2001 From: Victor Date: Wed, 20 Mar 2019 10:59:55 -0300 Subject: [PATCH 59/83] Pause/Unpase dividend modules --- CLI/commands/token_manager.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/CLI/commands/token_manager.js b/CLI/commands/token_manager.js index 8ceb3bb4f..76f5f50fe 100644 --- a/CLI/commands/token_manager.js +++ b/CLI/commands/token_manager.js @@ -506,8 +506,10 @@ async function pauseModule(modules) { moduleABI = abis.ISTO(); } else if (modules[index].type == gbl.constants.MODULES_TYPES.TRANSFER) { moduleABI = abis.ITransferManager(); + } else if (modules[index].type == gbl.constants.MODULES_TYPES.DIVIDENDS) { + moduleABI = abis.erc20DividendCheckpoint(); } else { - console.log(chalk.red(`Only STO and TM modules can be paused/unpaused`)); + console.log(chalk.red(`Only STO, TM and DIVIDEND modules can be paused/unpaused`)); process.exit(0); } let pausableModule = new web3.eth.Contract(moduleABI, modules[index].address); @@ -527,8 +529,10 @@ async function unpauseModule(modules) { moduleABI = abis.ISTO(); } else if (modules[index].type == gbl.constants.MODULES_TYPES.TRANSFER) { moduleABI = abis.ITransferManager(); + } else if (modules[index].type == gbl.constants.MODULES_TYPES.DIVIDENDS) { + moduleABI = abis.erc20DividendCheckpoint(); } else { - console.log(chalk.red(`Only STO and TM modules can be paused/unpaused`)); + console.log(chalk.red(`Only STO, TM and DIVIDEND modules can be paused/unpaused`)); process.exit(0); } let pausableModule = new web3.eth.Contract(moduleABI, modules[index].address); @@ -616,7 +620,7 @@ async function getAllModules() { let details = await securityToken.methods.getModule(allModules[i]).call(); let nameTemp = web3.utils.hexToUtf8(details[0]); let pausedTemp = null; - if (type == gbl.constants.MODULES_TYPES.STO || type == gbl.constants.MODULES_TYPES.TRANSFER) { + if (type == gbl.constants.MODULES_TYPES.STO || type == gbl.constants.MODULES_TYPES.TRANSFER || type == gbl.constants.MODULES_TYPES.DIVIDENDS) { let abiTemp = JSON.parse(require('fs').readFileSync(`${__dirname}/../../build/contracts/${nameTemp}.json`).toString()).abi; let contractTemp = new web3.eth.Contract(abiTemp, details[1]); pausedTemp = await contractTemp.methods.paused().call(); From b0b71d35043d6cffa8723da74c9ddbb34ece233e Mon Sep 17 00:00:00 2001 From: Victor Date: Wed, 20 Mar 2019 11:00:29 -0300 Subject: [PATCH 60/83] Minor fix --- CLI/commands/dividends_manager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CLI/commands/dividends_manager.js b/CLI/commands/dividends_manager.js index 97e6985c7..8ceaa627e 100644 --- a/CLI/commands/dividends_manager.js +++ b/CLI/commands/dividends_manager.js @@ -491,7 +491,7 @@ async function reclaimFromContract() { defaultInput: polyToken.options.address }); let reclaimERC20Action = currentDividendsModule.methods.reclaimERC20(erc20Address); - await common.sendTransaction(reclaimERC20Action, { factor: 2 }); + await common.sendTransaction(reclaimERC20Action); console.log(chalk.green('ERC20 has been reclaimed succesfully!')); break } From fc88f2d7ba232dde52c1c93ddd8170002f021d2f Mon Sep 17 00:00:00 2001 From: Victor Date: Wed, 20 Mar 2019 17:00:58 -0300 Subject: [PATCH 61/83] BigNumber library for dividends --- CLI/commands/dividends_manager.js | 10 +++--- CLI/package.json | 3 +- CLI/yarn.lock | 53 ++++++++++++++++++++++++++++--- 3 files changed, 56 insertions(+), 10 deletions(-) diff --git a/CLI/commands/dividends_manager.js b/CLI/commands/dividends_manager.js index 8ceaa627e..20880f7c0 100644 --- a/CLI/commands/dividends_manager.js +++ b/CLI/commands/dividends_manager.js @@ -6,6 +6,7 @@ const gbl = require('./common/global'); const contracts = require('./helpers/contract_addresses'); const abis = require('./helpers/contract_abis'); const csvParse = require('./helpers/csv'); +const BigNumber = require('bignumber.js'); const { table } = require('table') const EXCLUSIONS_DATA_CSV = `${__dirname}/../data/Checkpoint/exclusions_data.csv`; @@ -409,12 +410,11 @@ async function createDividends() { } let dividendAmount = readlineSync.question(`How much ${dividendSymbol} would you like to distribute to token holders? `); - let dividendAmountToSend = parseFloat(dividendAmount) * Math.pow(10, dividendTokenDecimals); - let issuerBalance = await getBalance(Issuer.address, dividendToken); - if (issuerBalance < dividendAmountToSend) { + let dividendAmountBN = new BigNumber(dividendAmount).times(Math.pow(10, dividendTokenDecimals)); + let issuerBalance = new BigNumber(await getBalance(Issuer.address, dividendToken)); + if (issuerBalance.lt(dividendAmountBN)) { console.log(chalk.red(`You have ${issuerBalance / Math.pow(10, dividendTokenDecimals)} ${dividendSymbol}. You need ${(dividendAmountBN - issuerBalance) / Math.pow(10, dividendTokenDecimals)} ${dividendSymbol} more!`)); } else { - let dividendAmountBN = new web3.utils.BN(dividendAmountToSend.toString()); let checkpointId = await selectCheckpoint(true); // If there are no checkpoints, it must create a new one let now = Math.floor(Date.now() / 1000); let maturityTime = readlineSync.questionInt('Enter the dividend maturity time from which dividend can be paid (Unix Epoch time)\n(Now = ' + now + ' ): ', { defaultInput: now }); @@ -525,7 +525,7 @@ function showReport(_name, _tokenSymbol, _tokenDecimals, _amount, _witthheld, _c let investor = _investorArray[i]; let excluded = _excludedArray[i]; let withdrawn = _claimedArray[i] ? 'YES' : 'NO'; - let amount = !excluded ? web3.utils.toBN(_amountArray[i]).add(web3.utils.toBN(_withheldArray[i])).divn(Math.pow(10, _tokenDecimals)) : 0; + let amount = !excluded ? new BigNumber(_amountArray[i]).plus(_withheldArray[i]).div((Math.pow(10, _tokenDecimals))) : 0; let withheld = !excluded ? parseFloat(_withheldArray[i]) / Math.pow(10, _tokenDecimals) : 'NA'; let withheldPercentage = (!excluded) ? (withheld !== '0' ? parseFloat(withheld) / parseFloat(amount) * 100 : 0) : 'NA'; let received = !excluded ? parseFloat(_amountArray[i]) / Math.pow(10, _tokenDecimals) : 0; diff --git a/CLI/package.json b/CLI/package.json index cc2773b74..354ecc878 100644 --- a/CLI/package.json +++ b/CLI/package.json @@ -4,11 +4,12 @@ "description": "CLI for Polymath-core", "main": "polymath-cli.js", "scripts": { - "stable_coin": "scripts/stable_coin.sh" + "stable_coin": "scripts/stable_coin.sh" }, "author": "Polymath Inc", "license": "MIT", "dependencies": { + "bignumber.js": "^8.1.1", "chalk": "^2.4.1", "commander": "^2.16.0", "csv-parse": "^4.0.1", diff --git a/CLI/yarn.lock b/CLI/yarn.lock index 82d60b57f..2cb4b3482 100644 --- a/CLI/yarn.lock +++ b/CLI/yarn.lock @@ -15,6 +15,11 @@ accepts@~1.3.5: mime-types "~2.1.18" negotiator "0.6.1" +aes-js@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" + integrity sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0= + ajv@^5.3.0: version "5.5.2" resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" @@ -125,6 +130,11 @@ bcrypt-pbkdf@^1.0.0: dependencies: tweetnacl "^0.14.3" +bignumber.js@^8.1.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-8.1.1.tgz#4b072ae5aea9c20f6730e4e5d529df1271c4d885" + integrity sha512-QD46ppGintwPGuL1KqmwhR0O+N2cZUg8JG/VzwI2e28sM9TqHjQB10lI4QAaMHVbLzwVLLAwEglpKPViWX+5NQ== + bl@^1.0.0: version "1.2.2" resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.2.tgz#a160911717103c07410cef63ef51b397c025af9c" @@ -386,6 +396,11 @@ cookie@0.3.1: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= +cookiejar@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.2.tgz#dd8a235530752f988f9a0844f3fc589e3111125c" + integrity sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA== + core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -586,6 +601,16 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= +elliptic@6.3.3: + version "6.3.3" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.3.3.tgz#5482d9646d54bcb89fd7d994fc9e2e9568876e3f" + integrity sha1-VILZZG1UvLif19mU/J4ulWiHbj8= + dependencies: + bn.js "^4.4.0" + brorand "^1.0.1" + hash.js "^1.0.0" + inherits "^2.0.1" + elliptic@^6.0.0, elliptic@^6.4.0: version "6.4.1" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.1.tgz#c2d0b7776911b86722c632c3c06c60f2f819939a" @@ -963,6 +988,14 @@ hash-base@^3.0.0: inherits "^2.0.1" safe-buffer "^5.0.1" +hash.js@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.3.tgz#340dedbe6290187151c1ea1d777a3448935df846" + integrity sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.0" + hash.js@^1.0.0, hash.js@^1.0.3: version "1.1.5" resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.5.tgz#e38ab4b85dfb1e0c40fe9265c0e9b54854c23812" @@ -1717,6 +1750,11 @@ servify@^0.1.12: request "^2.79.0" xhr "^2.3.3" +setimmediate@1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.4.tgz#20e81de622d4a02588ce0c8da8973cbcf1d3138f" + integrity sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48= + setimmediate@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" @@ -2318,10 +2356,12 @@ xhr-request@^1.0.1: url-set-query "^1.0.0" xhr "^2.0.4" -xhr2@0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/xhr2/-/xhr2-0.1.4.tgz#7f87658847716db5026323812f818cadab387a5f" - integrity sha1-f4dliEdxbbUCYyOBL4GMras4el8= +xhr2-cookies@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz#7d77449d0999197f155cb73b23df72505ed89d48" + integrity sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg= + dependencies: + cookiejar "^2.1.1" xhr@^2.0.4, xhr@^2.3.3: version "2.5.0" @@ -2333,6 +2373,11 @@ xhr@^2.0.4, xhr@^2.3.3: parse-headers "^2.0.0" xtend "^4.0.0" +xmlhttprequest@1.8.0: + version "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: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" From ea1cbc8725330aa8f735f778a5987d1b57488b0a Mon Sep 17 00:00:00 2001 From: Victor Date: Wed, 20 Mar 2019 17:34:40 -0300 Subject: [PATCH 62/83] STO selection fix --- CLI/commands/sto_manager.js | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/CLI/commands/sto_manager.js b/CLI/commands/sto_manager.js index 2f09540f6..4b7165373 100644 --- a/CLI/commands/sto_manager.js +++ b/CLI/commands/sto_manager.js @@ -119,10 +119,11 @@ async function modifySTO(selectedSTO, currentSTO) { async function addSTOModule(stoConfig) { console.log(chalk.blue('Launch STO - Configuration')); + let factorySelected; let optionSelected; if (typeof stoConfig === 'undefined') { let availableModules = await moduleRegistry.methods.getModulesByTypeAndToken(gbl.constants.MODULES_TYPES.STO, securityToken.options.address).call(); - let moduleList = await Promise.all(availableModules.map(async function (m) { + moduleList = await Promise.all(availableModules.map(async function (m) { let moduleFactoryABI = abis.moduleFactory(); let moduleFactory = new web3.eth.Contract(moduleFactoryABI, m); let moduleName = web3.utils.hexToUtf8(await moduleFactory.methods.name().call()); @@ -133,17 +134,19 @@ async function addSTOModule(stoConfig) { let index = readlineSync.keyInSelect(options, 'What type of STO do you want?', { cancel: 'RETURN' }); optionSelected = index != -1 ? moduleList[index].name : 'RETURN'; + factorySelected = moduleList[index].factoryAddress; } else { optionSelected = stoConfig.type; + factorySelected = await await contracts.getModuleFactoryAddressByName(securityToken.options.address, gbl.constants.MODULES_TYPES.STO, optionSelected); } console.log('Selected:', optionSelected, '\n'); switch (optionSelected) { case 'CappedSTO': - let cappedSTO = await cappedSTO_launch(stoConfig); + let cappedSTO = await cappedSTO_launch(stoConfig, factorySelected); await cappedSTO_status(cappedSTO); break; case 'USDTieredSTO': - let usdTieredSTO = await usdTieredSTO_launch(stoConfig); + let usdTieredSTO = await usdTieredSTO_launch(stoConfig, factorySelected); await usdTieredSTO_status(usdTieredSTO); break; } @@ -152,12 +155,11 @@ async function addSTOModule(stoConfig) { //////////////// // Capped STO // //////////////// -async function cappedSTO_launch(stoConfig) { +async function cappedSTO_launch(stoConfig, factoryAddress) { console.log(chalk.blue('Launch STO - Capped STO in No. of Tokens')); let cappedSTOFactoryABI = abis.cappedSTOFactory(); - let cappedSTOFactoryAddress = await contracts.getModuleFactoryAddressByName(securityToken.options.address, gbl.constants.MODULES_TYPES.STO, "CappedSTO"); - let cappedSTOFactory = new web3.eth.Contract(cappedSTOFactoryABI, cappedSTOFactoryAddress); + let cappedSTOFactory = new web3.eth.Contract(cappedSTOFactoryABI, factoryAddress); cappedSTOFactory.setProvider(web3.currentProvider); let stoFee = new web3.utils.BN(await cappedSTOFactory.methods.getSetupCost().call()); @@ -221,7 +223,7 @@ async function cappedSTO_launch(stoConfig) { cappedSTOconfig.wallet] ); - let addModuleAction = securityToken.methods.addModule(cappedSTOFactoryAddress, bytesSTO, stoFee, 0); + let addModuleAction = securityToken.methods.addModule(cappedSTOFactory.options.address, bytesSTO, stoFee, 0); let receipt = await common.sendTransaction(addModuleAction); let event = common.getEventFromLogs(securityToken._jsonInterface, receipt.logs, 'ModuleAdded'); console.log(`STO deployed at address: ${event._module}`); @@ -512,12 +514,11 @@ function timesConfigUSDTieredSTO(stoConfig) { return times; } -async function usdTieredSTO_launch(stoConfig) { +async function usdTieredSTO_launch(stoConfig, factoryAddress) { console.log(chalk.blue('Launch STO - USD pegged tiered STO')); let usdTieredSTOFactoryABI = abis.usdTieredSTOFactory(); - let usdTieredSTOFactoryAddress = await contracts.getModuleFactoryAddressByName(securityToken.options.address, gbl.constants.MODULES_TYPES.STO, 'USDTieredSTO'); - let usdTieredSTOFactory = new web3.eth.Contract(usdTieredSTOFactoryABI, usdTieredSTOFactoryAddress); + let usdTieredSTOFactory = new web3.eth.Contract(usdTieredSTOFactoryABI, factoryAddress); usdTieredSTOFactory.setProvider(web3.currentProvider); let stoFee = new web3.utils.BN(await usdTieredSTOFactory.methods.getSetupCost().call()); @@ -562,7 +563,7 @@ async function usdTieredSTO_launch(stoConfig) { addresses.usdToken] ); - let addModuleAction = securityToken.methods.addModule(usdTieredSTOFactoryAddress, bytesSTO, stoFee, 0); + let addModuleAction = securityToken.methods.addModule(usdTieredSTOFactory.options.address, bytesSTO, stoFee, 0); let receipt = await common.sendTransaction(addModuleAction); let event = common.getEventFromLogs(securityToken._jsonInterface, receipt.logs, 'ModuleAdded'); console.log(`STO deployed at address: ${event._module}`); From 2c20b2fbfd92d184bc3076c117d73b4024dcf1c5 Mon Sep 17 00:00:00 2001 From: Victor Date: Wed, 20 Mar 2019 21:45:06 -0300 Subject: [PATCH 63/83] Fix for pause/unpause STOs --- CLI/commands/helpers/contract_abis.js | 8 ++++---- CLI/commands/token_manager.js | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CLI/commands/helpers/contract_abis.js b/CLI/commands/helpers/contract_abis.js index f5d8064a6..2cf7b113d 100644 --- a/CLI/commands/helpers/contract_abis.js +++ b/CLI/commands/helpers/contract_abis.js @@ -21,7 +21,7 @@ let erc20DividendCheckpointABI; let etherDividendCheckpointABI; let moduleInterfaceABI; let ownableABI; -let iSTOABI; +let stoABI; let iTransferManagerABI; let moduleFactoryABI; let erc20ABI; @@ -50,7 +50,7 @@ try { etherDividendCheckpointABI = JSON.parse(require('fs').readFileSync(`${__dirname}/../../../build/contracts/EtherDividendCheckpoint.json`).toString()).abi; moduleInterfaceABI = JSON.parse(require('fs').readFileSync(`${__dirname}/../../../build/contracts/IModule.json`).toString()).abi; ownableABI = JSON.parse(require('fs').readFileSync(`${__dirname}/../../../build/contracts/Ownable.json`).toString()).abi; - iSTOABI = JSON.parse(require('fs').readFileSync(`${__dirname}/../../../build/contracts/ISTO.json`).toString()).abi + stoABI = JSON.parse(require('fs').readFileSync(`${__dirname}/../../../build/contracts/STO.json`).toString()).abi iTransferManagerABI = JSON.parse(require('fs').readFileSync(`${__dirname}/../../../build/contracts/ITransferManager.json`).toString()).abi moduleFactoryABI = JSON.parse(require('fs').readFileSync(`${__dirname}/../../../build/contracts/ModuleFactory.json`).toString()).abi; erc20ABI = JSON.parse(require('fs').readFileSync(`${__dirname}/../../../build/contracts/DetailedERC20.json`).toString()).abi; @@ -129,8 +129,8 @@ module.exports = { ownable: function () { return ownableABI; }, - ISTO: function () { - return iSTOABI; + sto: function () { + return stoABI; }, ITransferManager: function () { return iTransferManagerABI; diff --git a/CLI/commands/token_manager.js b/CLI/commands/token_manager.js index 76f5f50fe..ccbcf80d8 100644 --- a/CLI/commands/token_manager.js +++ b/CLI/commands/token_manager.js @@ -503,7 +503,7 @@ async function pauseModule(modules) { console.log("\nSelected:", options[index]); let moduleABI; if (modules[index].type == gbl.constants.MODULES_TYPES.STO) { - moduleABI = abis.ISTO(); + moduleABI = abis.sto(); } else if (modules[index].type == gbl.constants.MODULES_TYPES.TRANSFER) { moduleABI = abis.ITransferManager(); } else if (modules[index].type == gbl.constants.MODULES_TYPES.DIVIDENDS) { @@ -526,7 +526,7 @@ async function unpauseModule(modules) { console.log("\nSelected: ", options[index]); let moduleABI; if (modules[index].type == gbl.constants.MODULES_TYPES.STO) { - moduleABI = abis.ISTO(); + moduleABI = abis.sto(); } else if (modules[index].type == gbl.constants.MODULES_TYPES.TRANSFER) { moduleABI = abis.ITransferManager(); } else if (modules[index].type == gbl.constants.MODULES_TYPES.DIVIDENDS) { From a19b2a75bd87bf74c29a4dfe7f3a7b18a1326ae7 Mon Sep 17 00:00:00 2001 From: Victor Date: Wed, 20 Mar 2019 22:26:04 -0300 Subject: [PATCH 64/83] Show sto version when selecting --- CLI/commands/sto_manager.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/CLI/commands/sto_manager.js b/CLI/commands/sto_manager.js index 4b7165373..756787e2d 100644 --- a/CLI/commands/sto_manager.js +++ b/CLI/commands/sto_manager.js @@ -72,7 +72,7 @@ function selectExistingSTO(stoModules, showPaused) { if (!showPaused) { filteredModules = stoModules.filter(m => !m.paused); } - let options = filteredModules.map(m => `${m.name} at ${m.address}`); + let options = filteredModules.map(m => `${m.name} (${m.version}) at ${m.address}`); let index = readlineSync.keyInSelect(options, 'Select a module: ', { cancel: false }); console.log('Selected:', options[index], '\n'); let selectedName = filteredModules[index].name; @@ -1015,13 +1015,14 @@ async function getBalance(from, type) { } async function getAllModulesByType(type) { - function ModuleInfo(_moduleType, _name, _address, _factoryAddress, _archived, _paused) { + function ModuleInfo(_moduleType, _name, _address, _factoryAddress, _archived, _paused, _version) { this.name = _name; this.type = _moduleType; this.address = _address; this.factoryAddress = _factoryAddress; this.archived = _archived; this.paused = _paused; + this.version = _version; } let modules = []; @@ -1037,7 +1038,10 @@ async function getAllModulesByType(type) { let contractTemp = new web3.eth.Contract(abiTemp, details[1]); pausedTemp = await contractTemp.methods.paused().call(); } - modules.push(new ModuleInfo(type, nameTemp, details[1], details[2], details[3], pausedTemp)); + let factoryAbi = abis.moduleFactory(); + let factory = new web3.eth.Contract(factoryAbi, details[2]); + let versionTemp = await factory.methods.version().call(); + modules.push(new ModuleInfo(type, nameTemp, details[1], details[2], details[3], pausedTemp, versionTemp)); } return modules; From c60492507505b3b7cc3c22c83dd5b92a44165a1d Mon Sep 17 00:00:00 2001 From: Pablo Ruiz Date: Wed, 20 Mar 2019 23:47:14 -0300 Subject: [PATCH 65/83] Updated Kovan addresses --- README.md | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 51610e9d4..d310ec4e5 100644 --- a/README.md +++ b/README.md @@ -154,27 +154,21 @@ New Kovan PolyTokenFaucet: 0xb347b9f5b56b431b2cf4e1d90a5995f7519ca792 | Contract | Address | | ---------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | -| SecurityTokenRegistry (Proxy): | [0xbefb81114d532bddddc724af20c3516fa75f0afb](https://kovan.etherscan.io/address/0xbefb81114d532bddddc724af20c3516fa75f0afb) | -| ModuleRegistry (Proxy): | [0x0fac8d8cce224eead73c1187df96570aa80a568b](https://kovan.etherscan.io/address/0x0fac8d8cce224eead73c1187df96570aa80a568b) | -| Polymath Registry: | [0x9903e7b5acfe5fa9713771a8d861eb1df8cd7046](https://kovan.etherscan.io/address/0x9903e7b5acfe5fa9713771a8d861eb1df8cd7046) | -| Feature Registry: | [0xa8f85006fdacb3d59ffae564c05433f0c949e911](https://kovan.etherscan.io/address/0xa8f85006fdacb3d59ffae564c05433f0c949e911) | +| SecurityTokenRegistry (Proxy): | [0x91110c2f67e2881a8540417be9eadf5bc9f2f248](https://kovan.etherscan.io/address/0x91110c2f67e2881a8540417be9eadf5bc9f2f248) | +| ModuleRegistry (Proxy): | [0xde6d19d7a68d453244227b6ccc5d8e6c2314627a](https://kovan.etherscan.io/address/0xde6d19d7a68d453244227b6ccc5d8e6c2314627a) | +| Polymath Registry: | [0x5b215a7d39ee305ad28da29bf2f0425c6c2a00b3](https://kovan.etherscan.io/address/0x5b215a7d39ee305ad28da29bf2f0425c6c2a00b3) | +| Feature Registry: | [0x8967a7cfc4b455398be2356cd05cd43b7a39697e](https://kovan.etherscan.io/address/0x8967a7cfc4b455398be2356cd05cd43b7a39697e) | | ETHOracle: | [0xCE5551FC9d43E9D2CC255139169FC889352405C8](https://kovan.etherscan.io/address/0xCE5551FC9d43E9D2CC255139169FC889352405C8) | | POLYOracle: | [0x461d98EF2A0c7Ac1416EF065840fF5d4C946206C](https://kovan.etherscan.io/address/0x461d98EF2A0c7Ac1416EF065840fF5d4C946206C) | -| General Transfer Manager Factory: | [0xfe7e2bb6c200d5222c82d0f8fecca5f8fe4ab8ce](https://kovan.etherscan.io/address/0xfe7e2bb6c200d5222c82d0f8fecca5f8fe4ab8ce) | -| General Permission Manager Factory: | [0xde5eaa8d73f43fc5e7badb203f03ecae2b29bd92](https://kovan.etherscan.io/address/0xde5eaa8d73f43fc5e7badb203f03ecae2b29bd92) | -| CappedSTOFactory: | [0xe14d7dd044cc6cfe37548b6791416c59f19bfc0d](https://kovan.etherscan.io/address/0xe14d7dd044cc6cfe37548b6791416c59f19bfc0d) | -| USDTieredSTO Factory: | [0xf9f0bb9f868d411dd9a9511a79d172449e3c15f5](https://kovan.etherscan.io/address/0xf9f0bb9f868d411dd9a9511a79d172449e3c15f5) | -| EthDividendsCheckpointFactory: | [0x2861425ba5abbf50089c473b28f6c40a8ea5262a](https://kovan.etherscan.io/address/0x2861425ba5abbf50089c473b28f6c40a8ea5262a) | -| ERC20 Dividends Checkpoint Factory: | [0xbf9495550417feaacc43f86d2244581b6d688431](https://kovan.etherscan.io/address/0xbf9495550417feaacc43f86d2244581b6d688431) | -| Count Transfer Manager Factory: | [0x3c3c1f40ae2bdca82b90541b2cfbd41caa941c0e](https://kovan.etherscan.io/address/0x3c3c1f40ae2bdca82b90541b2cfbd41caa941c0e) | -| Percentage Transfer Manager Factory: | [0x8cd00c3914b2967a8b79815037f51c76874236b8](https://kovan.etherscan.io/address/0x8cd00c3914b2967a8b79815037f51c76874236b8) | +| General Transfer Manager Factory: | [0x650e9507e983077d6f822472a7dcc37626d55c7f](https://kovan.etherscan.io/address/0x650e9507e983077d6f822472a7dcc37626d55c7f) | +| General Permission Manager Factory: | [0xbf0bd6305b523ce055baa6dfaa9676d6b9e6090b](https://kovan.etherscan.io/address/0xbf0bd6305b523ce055baa6dfaa9676d6b9e6090b) | +| CappedSTOFactory: | [0x01510b2c03296473f883c12d0723f0a46aa67f13](https://kovan.etherscan.io/address/0x01510b2c03296473f883c12d0723f0a46aa67f13) | +| USDTieredSTO Factory: | [0x8b9743e6129f7b7cca04e3611b5c8cd9b1d11e90](https://kovan.etherscan.io/address/0x8b9743e6129f7b7cca04e3611b5c8cd9b1d11e90) | +| ERC20 Dividends Checkpoint Factory: | [0x4369751df5bcb2f12f1790f525ef212a622b9c60](https://kovan.etherscan.io/address/0x4369751df5bcb2f12f1790f525ef212a622b9c60) | +| Count Transfer Manager Factory: | [0xc7cf0c1ddc85c18672951f9bfeb7163ecc8f0e2f](https://kovan.etherscan.io/address/0xc7cf0c1ddc85c18672951f9bfeb7163ecc8f0e2f) | +| Percentage Transfer Manager Factory: | [0xfea5fcb254bcb4ada0f86903ff822d6372325cb1](https://kovan.etherscan.io/address/0xfea5fcb254bcb4ada0f86903ff822d6372325cb1) | | Manual Approval Transfer Manager Factory: | [0x9faa79e2ccf0eb49aa6ebde1795ad2e951ce78f8](https://kovan.etherscan.io/address/0x9faa79e2ccf0eb49aa6ebde1795ad2e951ce78f8) | - -New ManualApprovalTransferManager 0x9faa79e2ccf0eb49aa6ebde1795ad2e951ce78f8 -(Fixed 0x0 from bug) - - ## Package version requirements for your machine: - node v8.x.x or v9.x.x From a5b6c32ce8b281c6b57749ec1e00a5519d8b6910 Mon Sep 17 00:00:00 2001 From: Victor Date: Thu, 21 Mar 2019 17:26:46 -0300 Subject: [PATCH 66/83] Version info for all modules --- CLI/commands/token_manager.js | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/CLI/commands/token_manager.js b/CLI/commands/token_manager.js index ccbcf80d8..a908a4277 100644 --- a/CLI/commands/token_manager.js +++ b/CLI/commands/token_manager.js @@ -107,27 +107,27 @@ async function displayModules() { if (numPM) { console.log(`Permission Manager Modules:`); - pmModules.map(m => console.log(`- ${m.name} is ${(m.archived) ? chalk.yellow('archived') : 'unarchived'} at ${m.address}`)); + pmModules.map(m => console.log(`- ${m.name} (${m.version}) is ${(m.archived) ? chalk.yellow('archived') : 'unarchived'} at ${m.address}`)); } if (numTM) { console.log(`Transfer Manager Modules:`); - tmModules.map(m => console.log(`- ${m.name} is ${(m.archived) ? chalk.yellow('archived') : 'unarchived'} at ${m.address}`)); + tmModules.map(m => console.log(`- ${m.name} (${m.version}) is ${(m.archived) ? chalk.yellow('archived') : 'unarchived'} at ${m.address}`)); } if (numSTO) { console.log(`STO Modules:`); - stoModules.map(m => console.log(`- ${m.name} is ${(m.archived) ? chalk.yellow('archived') : 'unarchived'} at ${m.address}`)); + stoModules.map(m => console.log(`- ${m.name} (${m.version}) is ${(m.archived) ? chalk.yellow('archived') : 'unarchived'} at ${m.address}`)); } if (numCP) { console.log(`Checkpoint Modules:`); - cpModules.map(m => console.log(`- ${m.name} is ${(m.archived) ? chalk.yellow('archived') : 'unarchived'} at ${m.address}`)); + cpModules.map(m => console.log(`- ${m.name} (${m.version}) is ${(m.archived) ? chalk.yellow('archived') : 'unarchived'} at ${m.address}`)); } if (numBURN) { console.log(` Burn Modules:`); - burnModules.map(m => console.log(`- ${m.name} is ${(m.archived) ? chalk.yellow('archived') : 'unarchived'} at ${m.address}`)); + burnModules.map(m => console.log(`- ${m.name} (${m.version}) is ${(m.archived) ? chalk.yellow('archived') : 'unarchived'} at ${m.address}`)); } } @@ -497,7 +497,7 @@ async function addModule() { } async function pauseModule(modules) { - let options = modules.map(m => `${m.name} (${m.address})`); + let options = modules.map(m => `${m.name} (${m.version}) at ${m.address}`); let index = readlineSync.keyInSelect(options, 'Which module would you like to pause?'); if (index != -1) { console.log("\nSelected:", options[index]); @@ -520,7 +520,7 @@ async function pauseModule(modules) { } async function unpauseModule(modules) { - let options = modules.map(m => `${m.name} (${m.address})`); + let options = modules.map(m => `${m.name} (${m.version}) at ${m.address}`); let index = readlineSync.keyInSelect(options, 'Which module would you like to pause?'); if (index != -1) { console.log("\nSelected: ", options[index]); @@ -543,7 +543,7 @@ async function unpauseModule(modules) { } async function archiveModule(modules) { - let options = modules.map(m => `${m.name} (${m.address})`); + let options = modules.map(m => `${m.name} (${m.version}) at ${m.address}`); let index = readlineSync.keyInSelect(options, 'Which module would you like to archive?'); if (index != -1) { console.log("\nSelected: ", options[index]); @@ -554,7 +554,7 @@ async function archiveModule(modules) { } async function unarchiveModule(modules) { - let options = modules.map(m => `${m.name} (${m.address})`); + let options = modules.map(m => `${m.name} (${m.version}) at ${m.address}`); let index = readlineSync.keyInSelect(options, 'Which module would you like to unarchive?'); if (index != -1) { console.log("\nSelected: ", options[index]); @@ -565,7 +565,7 @@ async function unarchiveModule(modules) { } async function removeModule(modules) { - let options = modules.map(m => `${m.name} (${m.address})`); + let options = modules.map(m => `${m.name} (${m.version}) at ${m.address}`); let index = readlineSync.keyInSelect(options, 'Which module would you like to remove?'); if (index != -1) { console.log("\nSelected: ", options[index]); @@ -576,7 +576,7 @@ async function removeModule(modules) { } async function changeBudget(modules) { - let options = modules.map(m => `${m.name} (${m.address})`); + let options = modules.map(m => `${m.name} (${m.version}) at ${m.address}`); let index = readlineSync.keyInSelect(options, 'Which module would you like to change budget for?'); if (index != -1) { console.log("\nSelected: ", options[index]); @@ -599,13 +599,14 @@ async function showUserInfo(_user) { } async function getAllModules() { - function ModuleInfo(_moduleType, _name, _address, _factoryAddress, _archived, _paused) { + function ModuleInfo(_moduleType, _name, _address, _factoryAddress, _archived, _paused, _version) { this.name = _name; this.type = _moduleType; this.address = _address; this.factoryAddress = _factoryAddress; this.archived = _archived; this.paused = _paused; + this.version = _version; } let modules = []; @@ -620,12 +621,16 @@ async function getAllModules() { let details = await securityToken.methods.getModule(allModules[i]).call(); let nameTemp = web3.utils.hexToUtf8(details[0]); let pausedTemp = null; - if (type == gbl.constants.MODULES_TYPES.STO || type == gbl.constants.MODULES_TYPES.TRANSFER || type == gbl.constants.MODULES_TYPES.DIVIDENDS) { + let factoryAbi = abis.moduleFactory(); + let factory = new web3.eth.Contract(factoryAbi, details[2]); + let versionTemp = await factory.methods.version().call(); + if (type == gbl.constants.MODULES_TYPES.STO || type == gbl.constants.MODULES_TYPES.TRANSFER || (type == gbl.constants.MODULES_TYPES.DIVIDENDS && versionTemp === '2.1.1')) { let abiTemp = JSON.parse(require('fs').readFileSync(`${__dirname}/../../build/contracts/${nameTemp}.json`).toString()).abi; let contractTemp = new web3.eth.Contract(abiTemp, details[1]); pausedTemp = await contractTemp.methods.paused().call(); } - modules.push(new ModuleInfo(type, nameTemp, details[1], details[2], details[3], pausedTemp)); + + modules.push(new ModuleInfo(type, nameTemp, details[1], details[2], details[3], pausedTemp, versionTemp)); } catch (error) { console.log(error); console.log(chalk.red(` From c4afe289cc1b8f1f501562f64db03a6236ffda08 Mon Sep 17 00:00:00 2001 From: satyam Date: Tue, 26 Mar 2019 16:08:47 +0530 Subject: [PATCH 67/83] audit fixes 1..9 --- contracts/libraries/VolumeRestrictionLib.sol | 35 +- .../TransferManager/VolumeRestrictionTM.sol | 356 +++--- .../storage/VolumeRestrictionTMStorage.sol | 4 +- package.json | 2 +- test/y_volume_restriction_tm.js | 30 +- yarn.lock | 1031 +---------------- 6 files changed, 200 insertions(+), 1258 deletions(-) diff --git a/contracts/libraries/VolumeRestrictionLib.sol b/contracts/libraries/VolumeRestrictionLib.sol index 9f71d3fed..7129eecca 100644 --- a/contracts/libraries/VolumeRestrictionLib.sol +++ b/contracts/libraries/VolumeRestrictionLib.sol @@ -15,7 +15,7 @@ library VolumeRestrictionLib { uint256[] _startTimes, uint256[] _rollingPeriodInDays, uint256[] _endTimes, - uint256[] _restrictionTypes + VolumeRestrictionTMStorage.RestrictionType[] _restrictionTypes ) internal pure @@ -30,14 +30,20 @@ library VolumeRestrictionLib { ); } - function deleteHolderFromList(VolumeRestrictionTMStorage.RestrictedData storage data, address _holder, uint8 _typeOfPeriod) public { + function deleteHolderFromList( + VolumeRestrictionTMStorage.RestrictedData storage data, + address _holder, + VolumeRestrictionTMStorage.TypeOfPeriod _typeOfPeriod + ) + public + { // Deleting the holder if holder's type of Period is `Both` type otherwise // it will assign the given type `_typeOfPeriod` to the _holder typeOfPeriod // `_typeOfPeriod` it always be contrary to the removing restriction // if removing restriction is individual then typeOfPeriod is TypeOfPeriod.OneDay // in uint8 its value is 1. if removing restriction is daily individual then typeOfPeriod // is TypeOfPeriod.MultipleDays in uint8 its value is 0. - if (data.restrictedHolders[_holder].typeOfPeriod != uint8(VolumeRestrictionTMStorage.TypeOfPeriod.Both)) { + if (data.restrictedHolders[_holder].typeOfPeriod != VolumeRestrictionTMStorage.TypeOfPeriod.Both) { uint128 index = data.restrictedHolders[_holder].index; uint256 _len = data.restrictedAddresses.length; if (index != _len) { @@ -51,19 +57,34 @@ library VolumeRestrictionLib { } } - function addRestrictionData(VolumeRestrictionTMStorage.RestrictedData storage data, address _holder, uint8 _callFrom, uint256 _endTime) public { + function addRestrictionData( + VolumeRestrictionTMStorage.RestrictedData storage data, + address _holder, + VolumeRestrictionTMStorage.TypeOfPeriod _callFrom, + uint256 _endTime + ) + public + { uint128 index = data.restrictedHolders[_holder].index; if (data.restrictedHolders[_holder].seen == 0) { data.restrictedAddresses.push(_holder); index = uint128(data.restrictedAddresses.length); } - uint8 _type = _getTypeOfPeriod(data.restrictedHolders[_holder].typeOfPeriod, _callFrom, _endTime); + VolumeRestrictionTMStorage.TypeOfPeriod _type = _getTypeOfPeriod(data.restrictedHolders[_holder].typeOfPeriod, _callFrom, _endTime); data.restrictedHolders[_holder] = VolumeRestrictionTMStorage.RestrictedHolder(uint8(1), _type, index); } - function _getTypeOfPeriod(uint8 _currentTypeOfPeriod, uint8 _callFrom, uint256 _endTime) internal pure returns(uint8) { + function _getTypeOfPeriod( + VolumeRestrictionTMStorage.TypeOfPeriod _currentTypeOfPeriod, + VolumeRestrictionTMStorage.TypeOfPeriod _callFrom, + uint256 _endTime + ) + internal + pure + returns(VolumeRestrictionTMStorage.TypeOfPeriod) + { if (_currentTypeOfPeriod != _callFrom && _endTime != uint256(0)) - return uint8(VolumeRestrictionTMStorage.TypeOfPeriod.Both); + return VolumeRestrictionTMStorage.TypeOfPeriod.Both; else return _callFrom; } diff --git a/contracts/modules/TransferManager/VolumeRestrictionTM.sol b/contracts/modules/TransferManager/VolumeRestrictionTM.sol index 6547d1b61..fdb691223 100644 --- a/contracts/modules/TransferManager/VolumeRestrictionTM.sol +++ b/contracts/modules/TransferManager/VolumeRestrictionTM.sol @@ -21,7 +21,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { uint256 _startTime, uint256 _rollingPeriodInDays, uint256 _endTime, - uint256 _typeOfRestriction + RestrictionType _typeOfRestriction ); // Emit when the new daily (Individual) restriction is added event AddIndividualDailyRestriction( @@ -30,7 +30,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { uint256 _startTime, uint256 _rollingPeriodInDays, uint256 _endTime, - uint256 _typeOfRestriction + RestrictionType _typeOfRestriction ); // Emit when the individual restriction is modified for a given address event ModifyIndividualRestriction( @@ -39,7 +39,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { uint256 _startTime, uint256 _rollingPeriodInDays, uint256 _endTime, - uint256 _typeOfRestriction + RestrictionType _typeOfRestriction ); // Emit when individual daily restriction get modified event ModifyIndividualDailyRestriction( @@ -48,7 +48,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { uint256 _startTime, uint256 _rollingPeriodInDays, uint256 _endTime, - uint256 _typeOfRestriction + RestrictionType _typeOfRestriction ); // Emit when the new global restriction is added event AddDefaultRestriction( @@ -56,7 +56,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { uint256 _startTime, uint256 _rollingPeriodInDays, uint256 _endTime, - uint256 _typeOfRestriction + RestrictionType _typeOfRestriction ); // Emit when the new daily (Default) restriction is added event AddDefaultDailyRestriction( @@ -64,7 +64,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { uint256 _startTime, uint256 _rollingPeriodInDays, uint256 _endTime, - uint256 _typeOfRestriction + RestrictionType _typeOfRestriction ); // Emit when default restriction get modified event ModifyDefaultRestriction( @@ -72,7 +72,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { uint256 _startTime, uint256 _rollingPeriodInDays, uint256 _endTime, - uint256 _typeOfRestriction + RestrictionType _typeOfRestriction ); // Emit when daily default restriction get modified event ModifyDefaultDailyRestriction( @@ -80,7 +80,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { uint256 _startTime, uint256 _rollingPeriodInDays, uint256 _endTime, - uint256 _typeOfRestriction + RestrictionType _typeOfRestriction ); // Emit when the individual restriction gets removed event IndividualRestrictionRemoved(address indexed _holder); @@ -118,13 +118,14 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { // Checking the individual restriction if the `_from` comes in the individual category if ((individualRestriction[_from].endTime >= now && individualRestriction[_from].startTime <= now) || (individualDailyRestriction[_from].endTime >= now && individualDailyRestriction[_from].startTime <= now)) { - - return _individualRestrictionCheck(_from, _amount, _isTransfer); + + return _restrictionCheck(_isTransfer, _from, _amount, userToBucket[_from], individualRestriction[_from], false); + // If the `_from` doesn't fall under the individual category. It will processed with in the global category automatically } else if ((defaultRestriction.endTime >= now && defaultRestriction.startTime <= now) || (defaultDailyRestriction.endTime >= now && defaultDailyRestriction.startTime <= now)) { - - return _defaultRestrictionCheck(_from, _amount, _isTransfer); + + return _restrictionCheck(_isTransfer, _from, _amount, defaultUserToBucket[_from], defaultRestriction, true); } } return Result.NA; @@ -135,7 +136,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { * @param _wallet Ethereum wallet/contract address that need to be exempted * @param _change Boolean value used to add (i.e true) or remove (i.e false) from the list */ - function changeExemptWalletList(address _wallet, bool _change) public withPerm(ADMIN) { + function changeExemptWalletList(address _wallet, bool _change) external withPerm(ADMIN) { require(_wallet != address(0)); require((exemptIndex[_wallet] == 0) == _change); if (_change) { @@ -165,7 +166,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { uint256 _startTime, uint256 _rollingPeriodInDays, uint256 _endTime, - uint256 _restrictionType + RestrictionType _restrictionType ) external withPerm(ADMIN) @@ -187,20 +188,12 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { uint256 _startTime, uint256 _rollingPeriodInDays, uint256 _endTime, - uint256 _restrictionType + RestrictionType _restrictionType ) internal { - - if (_startTime == 0) { - _startTime = now; - } - require( - individualRestriction[_holder].endTime < now, - "Not Allowed" - ); require(_holder != address(0) && exemptIndex[_holder] == 0, "Invalid address"); - _checkInputParams(_allowedTokens, _startTime, _rollingPeriodInDays, _endTime, _restrictionType, now); + _checkInputParams(_allowedTokens, _startTime, _rollingPeriodInDays, _endTime, _restrictionType, now, false); if (individualRestriction[_holder].endTime != 0) { _removeIndividualRestriction(_holder); @@ -210,9 +203,9 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { _startTime, _rollingPeriodInDays, _endTime, - RestrictionType(_restrictionType) + _restrictionType ); - VolumeRestrictionLib.addRestrictionData(holderData, _holder, uint8(TypeOfPeriod.MultipleDays), individualRestriction[_holder].endTime); + VolumeRestrictionLib.addRestrictionData(holderData, _holder, TypeOfPeriod.MultipleDays, individualRestriction[_holder].endTime); emit AddIndividualRestriction( _holder, _allowedTokens, @@ -224,7 +217,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { } /** - * @notice Use to add the new individual daily restriction for all token holder + * @notice Use to add the new individual daily restriction for a given token holder * @param _holder Address of the token holder, whom restriction will be implied * @param _allowedTokens Amount of tokens allowed to be traded for all token holder. * @param _startTime Unix timestamp at which restriction get into effect @@ -236,7 +229,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { uint256 _allowedTokens, uint256 _startTime, uint256 _endTime, - uint256 _restrictionType + RestrictionType _restrictionType ) external withPerm(ADMIN) @@ -256,18 +249,11 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { uint256 _allowedTokens, uint256 _startTime, uint256 _endTime, - uint256 _restrictionType + RestrictionType _restrictionType ) internal { - if (_startTime == 0) { - _startTime = now; - } - require( - individualDailyRestriction[_holder].endTime < now, - "Not Allowed" - ); - _checkInputParams(_allowedTokens, _startTime, 1, _endTime, _restrictionType, now); + _checkInputParams(_allowedTokens, _startTime, 1, _endTime, _restrictionType, now, false); if (individualDailyRestriction[_holder].endTime != 0) { _removeIndividualDailyRestriction(_holder); } @@ -276,9 +262,9 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { _startTime, 1, _endTime, - RestrictionType(_restrictionType) + _restrictionType ); - VolumeRestrictionLib.addRestrictionData(holderData, _holder, uint8(TypeOfPeriod.OneDay), individualRestriction[_holder].endTime); + VolumeRestrictionLib.addRestrictionData(holderData, _holder, TypeOfPeriod.OneDay, individualRestriction[_holder].endTime); emit AddIndividualDailyRestriction( _holder, _allowedTokens, @@ -302,9 +288,9 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { uint256[] _allowedTokens, uint256[] _startTimes, uint256[] _endTimes, - uint256[] _restrictionTypes + RestrictionType[] _restrictionTypes ) - public + external withPerm(ADMIN) { //NB - we duplicate _startTimes below to allow function reuse @@ -335,7 +321,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { uint256[] _startTimes, uint256[] _rollingPeriodInDays, uint256[] _endTimes, - uint256[] _restrictionTypes + RestrictionType[] _restrictionTypes ) public withPerm(ADMIN) @@ -366,30 +352,22 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { uint256 _startTime, uint256 _rollingPeriodInDays, uint256 _endTime, - uint256 _restrictionType + RestrictionType _restrictionType ) external withPerm(ADMIN) { - uint256 startTime = _startTime; - if (_startTime == 0) { - startTime = now; - } - require( - defaultRestriction.endTime < now, - "Not Allowed" - ); - _checkInputParams(_allowedTokens, startTime, _rollingPeriodInDays, _endTime, _restrictionType, now); + _checkInputParams(_allowedTokens, _startTime, _rollingPeriodInDays, _endTime, _restrictionType, now, false); defaultRestriction = VolumeRestriction( _allowedTokens, - startTime, + _startTime, _rollingPeriodInDays, _endTime, - RestrictionType(_restrictionType) + _restrictionType ); emit AddDefaultRestriction( _allowedTokens, - startTime, + _startTime, _rollingPeriodInDays, _endTime, _restrictionType @@ -407,30 +385,22 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { uint256 _allowedTokens, uint256 _startTime, uint256 _endTime, - uint256 _restrictionType + RestrictionType _restrictionType ) external withPerm(ADMIN) { - uint256 startTime = _startTime; - if (_startTime == 0) { - startTime = now; - } - require( - defaultDailyRestriction.endTime < now, - "Not Allowed" - ); - _checkInputParams(_allowedTokens, startTime, 1, _endTime, _restrictionType, now); + _checkInputParams(_allowedTokens, _startTime, 1, _endTime, _restrictionType, now, false); defaultDailyRestriction = VolumeRestriction( _allowedTokens, - startTime, + _startTime, 1, _endTime, - RestrictionType(_restrictionType) + _restrictionType ); emit AddDefaultDailyRestriction( _allowedTokens, - startTime, + _startTime, 1, _endTime, _restrictionType @@ -450,7 +420,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { require(_holder != address(0)); require(individualRestriction[_holder].endTime != 0); individualRestriction[_holder] = VolumeRestriction(0, 0, 0, 0, RestrictionType(0)); - VolumeRestrictionLib.deleteHolderFromList(holderData, _holder, uint8(TypeOfPeriod.OneDay)); + VolumeRestrictionLib.deleteHolderFromList(holderData, _holder, TypeOfPeriod.OneDay); userToBucket[_holder].lastTradedDayTime = 0; userToBucket[_holder].sumOfLastPeriod = 0; userToBucket[_holder].daysCovered = 0; @@ -480,7 +450,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { require(_holder != address(0)); require(individualDailyRestriction[_holder].endTime != 0); individualDailyRestriction[_holder] = VolumeRestriction(0, 0, 0, 0, RestrictionType(0)); - VolumeRestrictionLib.deleteHolderFromList(holderData, _holder, uint8(TypeOfPeriod.MultipleDays)); + VolumeRestrictionLib.deleteHolderFromList(holderData, _holder, TypeOfPeriod.MultipleDays); userToBucket[_holder].dailyLastTradedDayTime = 0; emit IndividualDailyRestrictionRemoved(_holder); } @@ -498,7 +468,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { /** * @notice Use to remove the default restriction */ - function removeDefaultRestriction() public withPerm(ADMIN) { + function removeDefaultRestriction() external withPerm(ADMIN) { require(defaultRestriction.endTime != 0); defaultRestriction = VolumeRestriction(0, 0, 0, 0, RestrictionType(0)); emit DefaultRestrictionRemoved(); @@ -528,7 +498,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { uint256 _startTime, uint256 _rollingPeriodInDays, uint256 _endTime, - uint256 _restrictionType + RestrictionType _restrictionType ) external withPerm(ADMIN) @@ -550,22 +520,18 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { uint256 _startTime, uint256 _rollingPeriodInDays, uint256 _endTime, - uint256 _restrictionType + RestrictionType _restrictionType ) internal { - /* uint256 startTime = _startTime; */ - if (_startTime == 0) { - _startTime = now; - } - require(individualRestriction[_holder].startTime > now, "Not Allowed"); - _checkInputParams(_allowedTokens, _startTime, _rollingPeriodInDays, _endTime, _restrictionType, now); + _isAllowedToModify(individualRestriction[_holder].startTime); + _checkInputParams(_allowedTokens, _startTime, _rollingPeriodInDays, _endTime, _restrictionType, now, false); individualRestriction[_holder] = VolumeRestriction( _allowedTokens, _startTime, _rollingPeriodInDays, _endTime, - RestrictionType(_restrictionType) + _restrictionType ); emit ModifyIndividualRestriction( _holder, @@ -592,7 +558,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { uint256 _allowedTokens, uint256 _startTime, uint256 _endTime, - uint256 _restrictionType + RestrictionType _restrictionType ) external withPerm(ADMIN) @@ -612,22 +578,20 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { uint256 _allowedTokens, uint256 _startTime, uint256 _endTime, - uint256 _restrictionType + RestrictionType _restrictionType ) internal { - if (_startTime == 0) { - _startTime = now; - } _checkInputParams(_allowedTokens, _startTime, 1, _endTime, _restrictionType, - (individualDailyRestriction[_holder].startTime <= now ? individualDailyRestriction[_holder].startTime : now) + (individualDailyRestriction[_holder].startTime <= now ? individualDailyRestriction[_holder].startTime : now), + true ); individualDailyRestriction[_holder] = VolumeRestriction( _allowedTokens, _startTime, 1, _endTime, - RestrictionType(_restrictionType) + _restrictionType ); emit ModifyIndividualDailyRestriction( _holder, @@ -652,9 +616,9 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { uint256[] _allowedTokens, uint256[] _startTimes, uint256[] _endTimes, - uint256[] _restrictionTypes + RestrictionType[] _restrictionTypes ) - public + external withPerm(ADMIN) { //NB - we duplicate _startTimes below to allow function reuse @@ -685,7 +649,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { uint256[] _startTimes, uint256[] _rollingPeriodInDays, uint256[] _endTimes, - uint256[] _restrictionTypes + RestrictionType[] _restrictionTypes ) public withPerm(ADMIN) @@ -716,27 +680,23 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { uint256 _startTime, uint256 _rollingPeriodInDays, uint256 _endTime, - uint256 _restrictionType + RestrictionType _restrictionType ) external withPerm(ADMIN) { - require(defaultRestriction.startTime > now, "Not Allowed"); - uint256 startTime = _startTime; - if (_startTime == 0) { - startTime = now; - } - _checkInputParams(_allowedTokens, startTime, _rollingPeriodInDays, _endTime, _restrictionType, now); + _isAllowedToModify(defaultRestriction.startTime); + _checkInputParams(_allowedTokens, _startTime, _rollingPeriodInDays, _endTime, _restrictionType, now, false); defaultRestriction = VolumeRestriction( _allowedTokens, - startTime, + _startTime, _rollingPeriodInDays, _endTime, - RestrictionType(_restrictionType) + _restrictionType ); emit ModifyDefaultRestriction( _allowedTokens, - startTime, + _startTime, _rollingPeriodInDays, _endTime, _restrictionType @@ -756,30 +716,27 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { uint256 _allowedTokens, uint256 _startTime, uint256 _endTime, - uint256 _restrictionType + RestrictionType _restrictionType ) external withPerm(ADMIN) { - uint256 startTime = _startTime; - if (_startTime == 0) { - startTime = now; - } // If old startTime is already passed then new startTime should be greater than or equal to the // old startTime otherwise any past startTime can be allowed in compare to earlier startTime. - _checkInputParams(_allowedTokens, startTime, 1, _endTime, _restrictionType, - (defaultDailyRestriction.startTime <= now ? defaultDailyRestriction.startTime : now) + _checkInputParams(_allowedTokens, _startTime, 1, _endTime, _restrictionType, + (defaultDailyRestriction.startTime <= now ? defaultDailyRestriction.startTime : now), + true ); defaultDailyRestriction = VolumeRestriction( _allowedTokens, - startTime, + _startTime, 1, _endTime, - RestrictionType(_restrictionType) + _restrictionType ); emit ModifyDefaultDailyRestriction( _allowedTokens, - startTime, + _startTime, 1, _endTime, _restrictionType @@ -790,22 +747,36 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { * @notice Internal function used to validate the transaction for a given address * If it validates then it also update the storage corressponds to the default restriction */ - function _defaultRestrictionCheck(address _from, uint256 _amount, bool _isTransfer) internal returns (Result) { + function _restrictionCheck( + bool _isTransfer, + address _from, + uint256 _amount, + BucketDetails storage _bucketDetails, + VolumeRestriction memory _restriction, + bool _isDefault + ) + internal + returns (Result) + { // using the variable to avoid stack too deep error - BucketDetails storage bucketDetails = defaultUserToBucket[_from]; - uint256 daysCovered = defaultRestriction.rollingPeriodInDays; + VolumeRestriction memory dailyRestriction = individualDailyRestriction[_from]; + if (_isDefault) + dailyRestriction = defaultDailyRestriction; + + uint256 daysCovered = _restriction.rollingPeriodInDays; uint256 fromTimestamp = 0; uint256 sumOfLastPeriod = 0; uint256 dailyTime = 0; + // This variable works for both allowedDefault or allowedIndividual bool allowedDefault = true; bool allowedDaily; - if (defaultRestriction.endTime >= now && defaultRestriction.startTime <= now) { - if (bucketDetails.lastTradedDayTime < defaultRestriction.startTime) { + if (_restriction.endTime >= now && _restriction.startTime <= now) { + if (_bucketDetails.lastTradedDayTime < _restriction.startTime) { // It will execute when the txn is performed first time after the addition of individual restriction - fromTimestamp = defaultRestriction.startTime; + fromTimestamp = _restriction.startTime; } else { // Picking up the last timestamp - fromTimestamp = bucketDetails.lastTradedDayTime; + fromTimestamp = _bucketDetails.lastTradedDayTime; } // Check with the bucket and parse all the new timestamps to calculate the sumOfLastPeriod @@ -815,14 +786,16 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { BokkyPooBahsDateTimeLibrary.diffDays(fromTimestamp, now), _from, daysCovered, - bucketDetails + _bucketDetails, + _isDefault ); // validation of the transaction amount - if (!_checkValidAmountToTransact(sumOfLastPeriod, _amount, defaultRestriction)) { + if (!_checkValidAmountToTransact(sumOfLastPeriod, _amount, _restriction)) { allowedDefault = false; } } - (allowedDaily, dailyTime) = _dailyTxCheck(_from, _amount, bucketDetails.dailyLastTradedDayTime, defaultDailyRestriction); + + (allowedDaily, dailyTime) = _dailyTxCheck(_from, _amount, _bucketDetails.dailyLastTradedDayTime, dailyRestriction, _isDefault); if (_isTransfer) { _updateStorage( @@ -832,74 +805,18 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { sumOfLastPeriod, daysCovered, dailyTime, - defaultDailyRestriction.endTime, - true + _isDefault ); } return ((allowedDaily && allowedDefault) == true ? Result.NA : Result.INVALID); } - /** - * @notice Internal function used to validate the transaction for a given address - * If it validates then it also update the storage corressponds to the individual restriction - */ - function _individualRestrictionCheck(address _from, uint256 _amount, bool _isTransfer) internal returns (Result) { - // using the variable to avoid stack too deep error - BucketDetails memory bucketDetails = userToBucket[_from]; - VolumeRestriction memory dailyRestriction = individualDailyRestriction[_from]; - VolumeRestriction memory restriction = individualRestriction[_from]; - uint256 daysCovered = individualRestriction[_from].rollingPeriodInDays; - uint256 fromTimestamp = 0; - uint256 sumOfLastPeriod = 0; - uint256 dailyTime = 0; - bool allowedIndividual = true; - bool allowedDaily; - if (restriction.endTime >= now && restriction.startTime <= now) { - if (bucketDetails.lastTradedDayTime < restriction.startTime) { - // It will execute when the txn is performed first time after the addition of individual restriction - fromTimestamp = restriction.startTime; - } else { - // Picking up the last timestamp - fromTimestamp = bucketDetails.lastTradedDayTime; - } - - // Check with the bucket and parse all the new timestamps to calculate the sumOfLastPeriod - // re-using the local variables to avoid the stack too deep error. - (sumOfLastPeriod, fromTimestamp, daysCovered) = _bucketCheck( - fromTimestamp, - BokkyPooBahsDateTimeLibrary.diffDays(fromTimestamp, now), - _from, - daysCovered, - bucketDetails - ); - // validation of the transaction amount - if (!_checkValidAmountToTransact(sumOfLastPeriod, _amount, restriction)) { - allowedIndividual = false; - } - } - (allowedDaily, dailyTime) = _dailyTxCheck(_from, _amount, bucketDetails.dailyLastTradedDayTime, dailyRestriction); - - if (_isTransfer) { - _updateStorage( - _from, - _amount, - fromTimestamp, - sumOfLastPeriod, - daysCovered, - dailyTime, - dailyRestriction.endTime, - false - ); - } - - return ((allowedDaily && allowedIndividual) ? Result.NA : Result.INVALID); - } - function _dailyTxCheck( address from, uint256 amount, uint256 dailyLastTradedDayTime, - VolumeRestriction restriction + VolumeRestriction restriction, + bool isDefault ) internal view @@ -915,7 +832,10 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { else if (now.sub(dailyLastTradedDayTime) >= 1 days) dailyLastTradedDayTime = dailyLastTradedDayTime.add(BokkyPooBahsDateTimeLibrary.diffDays(dailyLastTradedDayTime, now).mul(1 days)); // Assgining total sum traded on dailyLastTradedDayTime timestamp - txSumOfDay = bucket[from][dailyLastTradedDayTime]; + if (isDefault) + txSumOfDay = defaultBucket[from][dailyLastTradedDayTime]; + else + txSumOfDay = bucket[from][dailyLastTradedDayTime]; return (_checkValidAmountToTransact(txSumOfDay, amount, restriction), dailyLastTradedDayTime); } return (true, dailyLastTradedDayTime); @@ -927,7 +847,8 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { uint256 _diffDays, address _from, uint256 _rollingPeriodInDays, - BucketDetails memory _bucketDetails + BucketDetails memory _bucketDetails, + bool isDefault ) internal view @@ -953,7 +874,10 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { // Loop starts from the first day covered in sumOfLastPeriod upto the day that is covered by rolling period. uint256 temp = _bucketDetails.daysCovered.sub(counter.sub(_rollingPeriodInDays)); temp = _bucketDetails.lastTradedDayTime.sub(temp.mul(1 days)); - sumOfLastPeriod = sumOfLastPeriod.sub(bucket[_from][temp]); + if (isDefault) + sumOfLastPeriod = sumOfLastPeriod.sub(defaultBucket[_from][temp]); + else + sumOfLastPeriod = sumOfLastPeriod.sub(bucket[_from][temp]); } // Adding the last amount that is transacted on the `_fromTime` not actually doing it but left written to understand // the alogrithm @@ -993,7 +917,6 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { uint256 _sumOfLastPeriod, uint256 _daysCovered, uint256 _dailyLastTradedDayTime, - uint256 _endTime, bool isDefault ) internal @@ -1001,11 +924,12 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { if (isDefault){ BucketDetails storage defaultUserToBucketDetails = defaultUserToBucket[_from]; - _updateStorageActual(_from, _amount, _lastTradedDayTime, _sumOfLastPeriod, _daysCovered, _dailyLastTradedDayTime, _endTime, defaultUserToBucketDetails); + _updateStorageActual(_from, _amount, _lastTradedDayTime, _sumOfLastPeriod, _daysCovered, _dailyLastTradedDayTime, defaultDailyRestriction.endTime, true, defaultUserToBucketDetails); } else { BucketDetails storage userToBucketDetails = userToBucket[_from]; - _updateStorageActual(_from, _amount, _lastTradedDayTime, _sumOfLastPeriod, _daysCovered, _dailyLastTradedDayTime, _endTime, userToBucketDetails); + uint256 _endTime = individualDailyRestriction[_from].endTime; + _updateStorageActual(_from, _amount, _lastTradedDayTime, _sumOfLastPeriod, _daysCovered, _dailyLastTradedDayTime, _endTime, false, userToBucketDetails); } } @@ -1017,6 +941,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { uint256 _daysCovered, uint256 _dailyLastTradedDayTime, uint256 _endTime, + bool isDefault, BucketDetails storage details ) internal @@ -1037,11 +962,18 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { if (_lastTradedDayTime !=0) { details.sumOfLastPeriod = _sumOfLastPeriod.add(_amount); // Increasing the total amount of the day by `_amount` - bucket[_from][_lastTradedDayTime] = bucket[_from][_lastTradedDayTime].add(_amount); + if (isDefault) + defaultBucket[_from][_lastTradedDayTime] = defaultBucket[_from][_lastTradedDayTime].add(_amount); + else + bucket[_from][_lastTradedDayTime] = bucket[_from][_lastTradedDayTime].add(_amount); } if ((_dailyLastTradedDayTime != _lastTradedDayTime) && _dailyLastTradedDayTime != 0 && now <= _endTime) { // Increasing the total amount of the day by `_amount` - bucket[_from][_dailyLastTradedDayTime] = bucket[_from][_dailyLastTradedDayTime].add(_amount); + if (isDefault) + defaultBucket[_from][_dailyLastTradedDayTime] = defaultBucket[_from][_dailyLastTradedDayTime].add(_amount); + else + bucket[_from][_dailyLastTradedDayTime] = bucket[_from][_dailyLastTradedDayTime].add(_amount); + } } } @@ -1051,20 +983,26 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { uint256 _startTime, uint256 _rollingPeriodDays, uint256 _endTime, - uint256 _restrictionType, - uint256 _earliestStartTime + RestrictionType _restrictionType, + uint256 _earliestStartTime, + bool isModifyDaily ) internal pure { - require(_restrictionType == 0 || _restrictionType == 1, "Invalid type"); - require(_startTime >= _earliestStartTime, "Invalid startTime"); - if (_restrictionType == uint256(RestrictionType.Fixed)) { - require(_allowedTokens > 0, "Invalid value"); + require(_restrictionType == RestrictionType.Fixed || _restrictionType == RestrictionType.Percentage, + "Invalid restriction type" + ); + if (isModifyDaily) + require(_startTime >= _earliestStartTime, "Invalid startTime"); + else + require(_startTime > _earliestStartTime, "Invalid startTime"); + if (_restrictionType == RestrictionType.Fixed) { + require(_allowedTokens > 0, "Invalid tokens value"); } else { require( _allowedTokens > 0 && _allowedTokens <= 100 * 10 ** 16, - "Invalid value" + "Invalid tokens value" ); } // Maximum limit for the rollingPeriod is 365 days @@ -1075,6 +1013,10 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { ); } + function _isAllowedToModify(uint256 _startTime) internal view { + require(_startTime > now, "Not Allowed to modify after startTime passed"); + } + /** * @notice Use to get the bucket details for a given address * @param _user Address of the token holder for whom the bucket details has queried @@ -1083,7 +1025,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { * @return uint256 days covered * @return uint256 24h lastTradedDayTime */ - function getIndividualBucketDetailsToUser(address _user) public view returns(uint256, uint256, uint256, uint256) { + function getIndividualBucketDetailsToUser(address _user) external view returns(uint256, uint256, uint256, uint256) { return( userToBucket[_user].lastTradedDayTime, userToBucket[_user].sumOfLastPeriod, @@ -1100,7 +1042,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { * @return uint256 days covered * @return uint256 24h lastTradedDayTime */ - function getDefaultBucketDetailsToUser(address _user) public view returns(uint256, uint256, uint256, uint256) { + function getDefaultBucketDetailsToUser(address _user) external view returns(uint256, uint256, uint256, uint256) { return( defaultUserToBucket[_user].lastTradedDayTime, defaultUserToBucket[_user].sumOfLastPeriod, @@ -1115,7 +1057,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { * @param _at Timestamp */ function getTotalTradedByUser(address _user, uint256 _at) external view returns(uint256) { - return bucket[_user][_at]; + return (bucket[_user][_at].add(defaultBucket[_user][_at])); } /** @@ -1139,7 +1081,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { * @return uint256 List of the start time of the restriction corresponds to restricted address * @return uint256 List of the rolling period in days for a restriction corresponds to restricted address. * @return uint256 List of the end time of the restriction corresponds to restricted address. - * @return uint8 List of the type of restriction to validate the value of the `allowedTokens` + * @return RestrictionType List of the type of restriction to validate the value of the `allowedTokens` * of the restriction corresponds to restricted address */ function getRestrictedData() external view returns( @@ -1148,29 +1090,31 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { uint256[] memory startTime, uint256[] memory rollingPeriodInDays, uint256[] memory endTime, - uint8[] memory typeOfRestriction + RestrictionType[] memory typeOfRestriction ) { uint256 counter = 0; uint256 i = 0; for (i = 0; i < holderData.restrictedAddresses.length; i++) { - counter = counter + (holderData.restrictedHolders[holderData.restrictedAddresses[i]].typeOfPeriod == uint8(2) ? 2 : 1); + counter = counter + uint256( + holderData.restrictedHolders[holderData.restrictedAddresses[i]].typeOfPeriod == TypeOfPeriod.Both ? TypeOfPeriod.Both : TypeOfPeriod.OneDay + ); } allAddresses = new address[](counter); allowedTokens = new uint256[](counter); startTime = new uint256[](counter); rollingPeriodInDays = new uint256[](counter); endTime = new uint256[](counter); - typeOfRestriction = new uint8[](counter); + typeOfRestriction = new RestrictionType[](counter); counter = 0; for (i = 0; i < holderData.restrictedAddresses.length; i++) { allAddresses[counter] = holderData.restrictedAddresses[i]; - if (holderData.restrictedHolders[holderData.restrictedAddresses[i]].typeOfPeriod == uint8(TypeOfPeriod.MultipleDays)) { + if (holderData.restrictedHolders[holderData.restrictedAddresses[i]].typeOfPeriod == TypeOfPeriod.MultipleDays) { _setValues(individualRestriction[holderData.restrictedAddresses[i]], allowedTokens, startTime, rollingPeriodInDays, endTime, typeOfRestriction, counter); } - else if (holderData.restrictedHolders[holderData.restrictedAddresses[i]].typeOfPeriod == uint8(TypeOfPeriod.OneDay)) { + else if (holderData.restrictedHolders[holderData.restrictedAddresses[i]].typeOfPeriod == TypeOfPeriod.OneDay) { _setValues(individualDailyRestriction[holderData.restrictedAddresses[i]], allowedTokens, startTime, rollingPeriodInDays, endTime, typeOfRestriction, counter); } - else if (holderData.restrictedHolders[holderData.restrictedAddresses[i]].typeOfPeriod == uint8(TypeOfPeriod.Both)) { + else if (holderData.restrictedHolders[holderData.restrictedAddresses[i]].typeOfPeriod == TypeOfPeriod.Both) { _setValues(individualRestriction[holderData.restrictedAddresses[i]], allowedTokens, startTime, rollingPeriodInDays, endTime, typeOfRestriction, counter); counter = counter + 1; allAddresses[counter] = holderData.restrictedAddresses[i]; @@ -1186,7 +1130,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { uint256[] memory startTime, uint256[] memory rollingPeriodInDays, uint256[] memory endTime, - uint8[] memory typeOfRestriction, + RestrictionType[] memory typeOfRestriction, uint256 index ) internal @@ -1196,7 +1140,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { startTime[index] = restriction.startTime; rollingPeriodInDays[index] = restriction.rollingPeriodInDays; endTime[index] = restriction.endTime; - typeOfRestriction[index] = uint8(restriction.typeOfRestriction); + typeOfRestriction[index] = restriction.typeOfRestriction; } /** diff --git a/contracts/storage/VolumeRestrictionTMStorage.sol b/contracts/storage/VolumeRestrictionTMStorage.sol index 9718c2c09..b8d62c988 100644 --- a/contracts/storage/VolumeRestrictionTMStorage.sol +++ b/contracts/storage/VolumeRestrictionTMStorage.sol @@ -13,7 +13,7 @@ contract VolumeRestrictionTMStorage { // 1 represent true & 0 for false uint8 seen; // Type of period will be enum index of TypeOfPeriod enum - uint8 typeOfPeriod; + TypeOfPeriod typeOfPeriod; // Index of the array where the holder address lives uint128 index; } @@ -51,6 +51,8 @@ contract VolumeRestrictionTMStorage { mapping(address => VolumeRestriction) public individualDailyRestriction; // Storing _from => day's timestamp => total amount transact in a day --individual mapping(address => mapping(uint256 => uint256)) internal bucket; + // Storing _from => day's timestamp => total amount transact in a day --default + mapping(address => mapping(uint256 => uint256)) internal defaultBucket; // Storing the information that used to validate the transaction mapping(address => BucketDetails) internal userToBucket; // Storing the information related to default restriction diff --git a/package.json b/package.json index fbaf43ed0..4d905c166 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "fs": "0.0.2", "openzeppelin-solidity": "1.10.0", "prompt": "^1.0.0", - "truffle-hdwallet-provider-privkey": "0.3.0", + "truffle-hdwallet-provider-privkey": "^0.3.0", "web3": "1.0.0-beta.34" }, "devDependencies": { diff --git a/test/y_volume_restriction_tm.js b/test/y_volume_restriction_tm.js index 59b5adaa2..7074d1afa 100644 --- a/test/y_volume_restriction_tm.js +++ b/test/y_volume_restriction_tm.js @@ -543,7 +543,7 @@ contract('VolumeRestrictionTransferManager', accounts => { await I_VolumeRestrictionTM.addIndividualRestrictionMulti( [account_investor2, account_delegate3, account_investor4], [web3.utils.toWei("12"), web3.utils.toWei("10"), web3.utils.toWei("15")], - [0, 0, 0], + [latestTime() + duration.minutes(1), latestTime() + duration.minutes(1), latestTime() + duration.minutes(1)], [3, 4, 5], [latestTime() + duration.days(5), latestTime() + duration.days(6), latestTime() + duration.days(7)], [0, 0, 0], @@ -608,7 +608,7 @@ contract('VolumeRestrictionTransferManager', accounts => { ${await I_VolumeRestrictionTM.addIndividualRestriction.estimateGas( account_investor1, web3.utils.toWei("12"), - latestTime() + duration.seconds(2), + latestTime() + duration.seconds(5), 3, latestTime() + duration.days(6), 0, @@ -621,7 +621,7 @@ contract('VolumeRestrictionTransferManager', accounts => { let tx = await I_VolumeRestrictionTM.addIndividualRestriction( account_investor1, web3.utils.toWei("12"), - latestTime() + duration.seconds(2), + latestTime() + duration.seconds(5), 3, latestTime() + duration.days(6), 0, @@ -739,7 +739,7 @@ contract('VolumeRestrictionTransferManager', accounts => { let tx = await I_VolumeRestrictionTM.addIndividualDailyRestriction( account_investor3, web3.utils.toWei("6"), - latestTime() + duration.seconds(1), + latestTime() + duration.seconds(10), latestTime() + duration.days(4), 0, { @@ -767,7 +767,7 @@ contract('VolumeRestrictionTransferManager', accounts => { it("Should transfer the tokens within the individual daily restriction limits", async () => { // transfer 2 tokens as per the limit - await increaseTime(5); // increase 5 seconds to layoff the time gap + await increaseTime(15); // increase 5 seconds to layoff the time gap let startTime = (await I_VolumeRestrictionTM.individualDailyRestriction.call(account_investor3))[1].toNumber(); console.log(` Gas Estimation for the Individual daily tx - ${await I_SecurityToken.transfer.estimateGas(account_investor2, web3.utils.toWei("2"), { from: account_investor3 })} @@ -819,7 +819,7 @@ contract('VolumeRestrictionTransferManager', accounts => { let tx = await I_VolumeRestrictionTM.addIndividualDailyRestriction( account_investor1, new BigNumber(5).times(new BigNumber(10).pow(16)), - 0, + latestTime() + duration.seconds(5), latestTime() + duration.days(4), 1, { @@ -847,6 +847,7 @@ contract('VolumeRestrictionTransferManager', accounts => { }); it("Should transfer tokens on the 2nd day by investor1 (Individual + Individual daily)", async () => { + await increaseTime(6); let startTime = (await I_VolumeRestrictionTM.individualRestriction.call(account_investor1))[1].toNumber(); let rollingPeriod = (await I_VolumeRestrictionTM.individualRestriction.call(account_investor1))[2].toNumber(); @@ -888,7 +889,7 @@ contract('VolumeRestrictionTransferManager', accounts => { let tx = await I_VolumeRestrictionTM.addIndividualRestriction( account_investor3, new BigNumber(15.36).times(new BigNumber(10).pow(16)), // 15.36 tokens as totalsupply is 1000 - latestTime() + duration.seconds(2), + latestTime() + duration.seconds(10), 6, latestTime() + duration.days(15), 1, @@ -908,7 +909,7 @@ contract('VolumeRestrictionTransferManager', accounts => { }); it("Should transfer the token by the investor 3 with in the (Individual + Individual daily limit)", async () => { - await increaseTime(4); + await increaseTime(duration.seconds(15)); // Allowed 4 tokens to transfer let startTime = (await I_VolumeRestrictionTM.individualRestriction.call(account_investor3))[1].toNumber(); let rollingPeriod = (await I_VolumeRestrictionTM.individualRestriction.call(account_investor3))[2].toNumber(); @@ -1058,7 +1059,7 @@ contract('VolumeRestrictionTransferManager', accounts => { await I_VolumeRestrictionTM.modifyIndividualDailyRestriction( account_investor3, web3.utils.toWei('3'), - 0, + latestTime() + duration.seconds(10), latestTime() + duration.days(5), 0, { @@ -1078,6 +1079,7 @@ contract('VolumeRestrictionTransferManager', accounts => { }); it("Should allow to sell to transfer more tokens by investor3", async () => { + await increaseTime(duration.seconds(15)); let startTime = (await I_VolumeRestrictionTM.individualRestriction.call(account_investor3))[1].toNumber(); let startTimedaily = (await I_VolumeRestrictionTM.individualDailyRestriction.call(account_investor3))[1].toNumber(); let rollingPeriod = (await I_VolumeRestrictionTM.individualRestriction.call(account_investor3))[2].toNumber(); @@ -1285,7 +1287,7 @@ contract('VolumeRestrictionTransferManager', accounts => { it("Should add the default daily restriction successfully", async () => { await I_VolumeRestrictionTM.addDefaultDailyRestriction( new BigNumber(2.75).times(new BigNumber(10).pow(16)), - 0, + latestTime() + duration.seconds(10), latestTime() + duration.days(3), 1, { @@ -1305,6 +1307,7 @@ contract('VolumeRestrictionTransferManager', accounts => { }); it("Should fail to transfer above the daily limit", async () => { + await increaseTime(duration.seconds(15)); await catchRevert( I_SecurityToken.transfer(account_investor3, web3.utils.toWei("5"), { from: account_investor4 }) ) @@ -1342,7 +1345,7 @@ contract('VolumeRestrictionTransferManager', accounts => { it("Should successfully add the default restriction", async () => { await I_VolumeRestrictionTM.addDefaultRestriction( web3.utils.toWei("10"), - 0, + latestTime() + duration.seconds(10), 5, latestTime() + duration.days(10), 0, @@ -1366,7 +1369,7 @@ contract('VolumeRestrictionTransferManager', accounts => { }); it("Should transfer tokens on by investor 3 (comes under the Default restriction)", async () => { - await increaseTime(10); + await increaseTime(15); tempArray3.length = 0; let startTime = (await I_VolumeRestrictionTM.defaultRestriction.call())[1].toNumber(); let startTimedaily = (await I_VolumeRestrictionTM.defaultDailyRestriction.call())[1].toNumber(); @@ -1454,7 +1457,7 @@ contract('VolumeRestrictionTransferManager', accounts => { it("Should add the daily default restriction again", async () => { await I_VolumeRestrictionTM.addDefaultDailyRestriction( web3.utils.toWei("2"), - 0, + latestTime() + duration.seconds(10), latestTime() + duration.days(3), 0, { @@ -1474,6 +1477,7 @@ contract('VolumeRestrictionTransferManager', accounts => { }); it("Should not able to transfer tokens more than the default daily restriction", async () => { + await increaseTime(duration.seconds(15)); await catchRevert( I_SecurityToken.transfer(account_investor2, web3.utils.toWei("3"), { from: account_investor3 }) ); diff --git a/yarn.lock b/yarn.lock index 99f339018..f3d31f1f4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5,14 +5,12 @@ "@babel/code-frame@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8" - integrity sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA== dependencies: "@babel/highlight" "^7.0.0" "@babel/highlight@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0.tgz#f710c38c8d458e6dd9a201afb637fcb781ce99e4" - integrity sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw== dependencies: chalk "^2.0.0" esutils "^2.0.2" @@ -21,36 +19,30 @@ "@types/node@^10.3.2": version "10.12.18" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67" - integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ== abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== abbrev@1.0.x: version "1.0.9" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" - integrity sha1-kbR5JYinc4wl813W9jdSovh3YTU= 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== dependencies: xtend "~4.0.0" accepts@~1.3.5: version "1.3.5" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2" - integrity sha1-63d99gEXI6OxTopywIBcjoZ0a9I= dependencies: mime-types "~2.1.18" negotiator "0.6.1" @@ -58,27 +50,22 @@ accepts@~1.3.5: acorn-jsx@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.1.tgz#32a064fd925429216a09b141102bfdd185fae40e" - integrity sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg== acorn@^6.0.2: version "6.0.5" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.0.5.tgz#81730c0815f3f3b34d8efa95cb7430965f4d887a" - integrity sha512-i33Zgp3XWtmZBMNvCr4azvOFeWVw1Rk6p3hfi3LUDvIFraOMywb1kAtrbi+med14m4Xfpqm3zRZMT+c0FNE7kg== aes-js@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" - integrity sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0= aes-js@^3.1.1: version "3.1.2" resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.1.2.tgz#db9aabde85d5caabbfc0d4f2a4446960f627146a" - integrity sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ== ajv@^5.2.2: version "5.5.2" resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" - integrity sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU= dependencies: co "^4.6.0" fast-deep-equal "^1.0.0" @@ -88,7 +75,6 @@ ajv@^5.2.2: ajv@^6.5.3, ajv@^6.5.5, ajv@^6.6.1: version "6.6.2" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.6.2.tgz#caceccf474bf3fc3ce3b147443711a24063cc30d" - integrity sha512-FBHEW6Jf5TB9MGBgUUA9XHkTbjXYfAUjY43ACMfmdMRHniyoMHjHjzD50OK8LGDWQwp4rWEsIq5kEqq7rvIM1g== dependencies: fast-deep-equal "^2.0.1" fast-json-stable-stringify "^2.0.0" @@ -98,7 +84,6 @@ ajv@^6.5.3, ajv@^6.5.5, ajv@^6.6.1: ambi@^2.2.0: version "2.5.0" resolved "https://registry.yarnpkg.com/ambi/-/ambi-2.5.0.tgz#7c8e372be48891157e7cea01cb6f9143d1f74220" - integrity sha1-fI43K+SIkRV+fOoBy2+RQ9H3QiA= dependencies: editions "^1.1.1" typechecker "^4.3.0" @@ -106,49 +91,40 @@ ambi@^2.2.0: amdefine@>=0.0.4: version "1.0.1" resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" - integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= ansi-escapes@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" - integrity sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw== ansi-regex@^2.0.0, ansi-regex@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= ansi-regex@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= ansi-regex@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.0.0.tgz#70de791edf021404c3fd615aa89118ae0432e5a9" - integrity sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w== ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" - integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== 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= anymatch@^1.3.0: version "1.3.2" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a" - integrity sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA== dependencies: micromatch "^2.1.5" normalize-path "^2.0.0" @@ -156,12 +132,10 @@ anymatch@^1.3.0: aproba@^1.0.3: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== are-we-there-yet@~1.1.2: version "1.1.5" resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" - integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== dependencies: delegates "^1.0.0" readable-stream "^2.0.6" @@ -169,51 +143,42 @@ are-we-there-yet@~1.1.2: argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== dependencies: sprintf-js "~1.0.2" arr-diff@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" - integrity sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8= dependencies: arr-flatten "^1.0.1" arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" - integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= arr-flatten@^1.0.1, arr-flatten@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" - integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== arr-union@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" - integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= array-flatten@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= array-unique@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" - integrity sha1-odl8yvy8JiXMcPrc6zalDFiwGlM= array-unique@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" - integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= asn1.js@^4.0.0: version "4.10.1" resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" - integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== dependencies: bn.js "^4.0.0" inherits "^2.0.1" @@ -222,34 +187,28 @@ asn1.js@^4.0.0: asn1@~0.2.3: version "0.2.4" resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" - integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== dependencies: safer-buffer "~2.1.0" assert-plus@1.0.0, assert-plus@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= assign-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" - integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= astral-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" - integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== async-each@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" - integrity sha1-GdOGodntxufByF04iu28xW0zYC0= 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" @@ -262,54 +221,44 @@ async-eventemitter@ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a 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== async@1.x, async@^1.4.2, async@~1.5.2: 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.4.1, async@^2.5.0: version "2.6.1" resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610" - integrity sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ== dependencies: lodash "^4.17.10" async@~0.9.0: version "0.9.2" resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" - integrity sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0= async@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/async/-/async-1.0.0.tgz#f8fc04ca3a13784ade9e1641af98578cfbd647a9" - integrity sha1-+PwEyjoTeErenhZBr5hXjPvWR6k= asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= atob@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" - integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== aws-sign2@~0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= aws4@^1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" - integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== babel-code-frame@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" - integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s= dependencies: chalk "^1.1.3" esutils "^2.0.2" @@ -318,7 +267,6 @@ babel-code-frame@^6.26.0: babel-core@^6.0.14, babel-core@^6.26.0: version "6.26.3" resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" - integrity sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA== dependencies: babel-code-frame "^6.26.0" babel-generator "^6.26.0" @@ -343,7 +291,6 @@ babel-core@^6.0.14, babel-core@^6.26.0: babel-generator@^6.26.0: version "6.26.1" resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" - integrity sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA== dependencies: babel-messages "^6.23.0" babel-runtime "^6.26.0" @@ -357,7 +304,6 @@ babel-generator@^6.26.0: babel-helper-bindify-decorators@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz#14c19e5f142d7b47f19a52431e52b1ccbc40a330" - integrity sha1-FMGeXxQte0fxmlJDHlKxzLxAozA= dependencies: babel-runtime "^6.22.0" babel-traverse "^6.24.1" @@ -366,7 +312,6 @@ babel-helper-bindify-decorators@^6.24.1: babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" - integrity sha1-zORReto1b0IgvK6KAsKzRvmlZmQ= dependencies: babel-helper-explode-assignable-expression "^6.24.1" babel-runtime "^6.22.0" @@ -375,7 +320,6 @@ babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: babel-helper-call-delegate@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" - integrity sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340= dependencies: babel-helper-hoist-variables "^6.24.1" babel-runtime "^6.22.0" @@ -385,7 +329,6 @@ babel-helper-call-delegate@^6.24.1: babel-helper-define-map@^6.24.1: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" - integrity sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8= dependencies: babel-helper-function-name "^6.24.1" babel-runtime "^6.26.0" @@ -395,7 +338,6 @@ babel-helper-define-map@^6.24.1: babel-helper-explode-assignable-expression@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" - integrity sha1-8luCz33BBDPFX3BZLVdGQArCLKo= dependencies: babel-runtime "^6.22.0" babel-traverse "^6.24.1" @@ -404,7 +346,6 @@ babel-helper-explode-assignable-expression@^6.24.1: babel-helper-explode-class@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz#7dc2a3910dee007056e1e31d640ced3d54eaa9eb" - integrity sha1-fcKjkQ3uAHBW4eMdZAztPVTqqes= dependencies: babel-helper-bindify-decorators "^6.24.1" babel-runtime "^6.22.0" @@ -414,7 +355,6 @@ babel-helper-explode-class@^6.24.1: babel-helper-function-name@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" - integrity sha1-00dbjAPtmCQqJbSDUasYOZ01gKk= dependencies: babel-helper-get-function-arity "^6.24.1" babel-runtime "^6.22.0" @@ -425,7 +365,6 @@ babel-helper-function-name@^6.24.1: babel-helper-get-function-arity@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" - integrity sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0= dependencies: babel-runtime "^6.22.0" babel-types "^6.24.1" @@ -433,7 +372,6 @@ babel-helper-get-function-arity@^6.24.1: babel-helper-hoist-variables@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" - integrity sha1-HssnaJydJVE+rbyZFKc/VAi+enY= dependencies: babel-runtime "^6.22.0" babel-types "^6.24.1" @@ -441,7 +379,6 @@ babel-helper-hoist-variables@^6.24.1: babel-helper-optimise-call-expression@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" - integrity sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc= dependencies: babel-runtime "^6.22.0" babel-types "^6.24.1" @@ -449,7 +386,6 @@ babel-helper-optimise-call-expression@^6.24.1: babel-helper-regex@^6.24.1: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" - integrity sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI= dependencies: babel-runtime "^6.26.0" babel-types "^6.26.0" @@ -458,7 +394,6 @@ babel-helper-regex@^6.24.1: babel-helper-remap-async-to-generator@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" - integrity sha1-XsWBgnrXI/7N04HxySg5BnbkVRs= dependencies: babel-helper-function-name "^6.24.1" babel-runtime "^6.22.0" @@ -469,7 +404,6 @@ babel-helper-remap-async-to-generator@^6.24.1: babel-helper-replace-supers@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" - integrity sha1-v22/5Dk40XNpohPKiov3S2qQqxo= dependencies: babel-helper-optimise-call-expression "^6.24.1" babel-messages "^6.23.0" @@ -481,7 +415,6 @@ babel-helper-replace-supers@^6.24.1: babel-helpers@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" - integrity sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI= dependencies: babel-runtime "^6.22.0" babel-template "^6.24.1" @@ -489,61 +422,50 @@ babel-helpers@^6.24.1: babel-messages@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" - integrity sha1-8830cDhYA1sqKVHG7F7fbGLyYw4= dependencies: babel-runtime "^6.22.0" babel-plugin-check-es2015-constants@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" - integrity sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o= dependencies: babel-runtime "^6.22.0" babel-plugin-syntax-async-functions@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" - integrity sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU= babel-plugin-syntax-async-generators@^6.5.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz#6bc963ebb16eccbae6b92b596eb7f35c342a8b9a" - integrity sha1-a8lj67FuzLrmuStZbrfzXDQqi5o= babel-plugin-syntax-class-properties@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de" - integrity sha1-1+sjt5oxf4VDlixQW4J8fWysJ94= babel-plugin-syntax-decorators@^6.13.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz#312563b4dbde3cc806cee3e416cceeaddd11ac0b" - integrity sha1-MSVjtNvePMgGzuPkFszurd0RrAs= babel-plugin-syntax-dynamic-import@^6.18.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da" - integrity sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo= babel-plugin-syntax-exponentiation-operator@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" - integrity sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4= babel-plugin-syntax-object-rest-spread@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" - integrity sha1-/WU28rzhODb/o6VFjEkDpZe7O/U= babel-plugin-syntax-trailing-function-commas@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" - integrity sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM= babel-plugin-transform-async-generator-functions@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz#f058900145fd3e9907a6ddf28da59f215258a5db" - integrity sha1-8FiQAUX9PpkHpt3yjaWfIVJYpds= dependencies: babel-helper-remap-async-to-generator "^6.24.1" babel-plugin-syntax-async-generators "^6.5.0" @@ -552,7 +474,6 @@ babel-plugin-transform-async-generator-functions@^6.24.1: babel-plugin-transform-async-to-generator@^6.22.0, babel-plugin-transform-async-to-generator@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" - integrity sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E= dependencies: babel-helper-remap-async-to-generator "^6.24.1" babel-plugin-syntax-async-functions "^6.8.0" @@ -561,7 +482,6 @@ babel-plugin-transform-async-to-generator@^6.22.0, babel-plugin-transform-async- babel-plugin-transform-class-properties@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz#6a79763ea61d33d36f37b611aa9def81a81b46ac" - integrity sha1-anl2PqYdM9NvN7YRqp3vgagbRqw= dependencies: babel-helper-function-name "^6.24.1" babel-plugin-syntax-class-properties "^6.8.0" @@ -571,7 +491,6 @@ babel-plugin-transform-class-properties@^6.24.1: babel-plugin-transform-decorators@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz#788013d8f8c6b5222bdf7b344390dfd77569e24d" - integrity sha1-eIAT2PjGtSIr33s0Q5Df13Vp4k0= dependencies: babel-helper-explode-class "^6.24.1" babel-plugin-syntax-decorators "^6.13.0" @@ -582,21 +501,18 @@ babel-plugin-transform-decorators@^6.24.1: babel-plugin-transform-es2015-arrow-functions@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" - integrity sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE= dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" - integrity sha1-u8UbSflk1wy42OC5ToICRs46YUE= dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-block-scoping@^6.23.0, babel-plugin-transform-es2015-block-scoping@^6.24.1: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" - integrity sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8= dependencies: babel-runtime "^6.26.0" babel-template "^6.26.0" @@ -607,7 +523,6 @@ babel-plugin-transform-es2015-block-scoping@^6.23.0, babel-plugin-transform-es20 babel-plugin-transform-es2015-classes@^6.23.0, babel-plugin-transform-es2015-classes@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" - integrity sha1-WkxYpQyclGHlZLSyo7+ryXolhNs= dependencies: babel-helper-define-map "^6.24.1" babel-helper-function-name "^6.24.1" @@ -622,7 +537,6 @@ babel-plugin-transform-es2015-classes@^6.23.0, babel-plugin-transform-es2015-cla babel-plugin-transform-es2015-computed-properties@^6.22.0, babel-plugin-transform-es2015-computed-properties@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" - integrity sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM= dependencies: babel-runtime "^6.22.0" babel-template "^6.24.1" @@ -630,14 +544,12 @@ babel-plugin-transform-es2015-computed-properties@^6.22.0, babel-plugin-transfor babel-plugin-transform-es2015-destructuring@^6.22.0, babel-plugin-transform-es2015-destructuring@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" - integrity sha1-mXux8auWf2gtKwh2/jWNYOdlxW0= dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-duplicate-keys@^6.22.0, babel-plugin-transform-es2015-duplicate-keys@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" - integrity sha1-c+s9MQypaePvnskcU3QabxV2Qj4= dependencies: babel-runtime "^6.22.0" babel-types "^6.24.1" @@ -645,14 +557,12 @@ babel-plugin-transform-es2015-duplicate-keys@^6.22.0, babel-plugin-transform-es2 babel-plugin-transform-es2015-for-of@^6.22.0, babel-plugin-transform-es2015-for-of@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" - integrity sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE= dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-function-name@^6.22.0, babel-plugin-transform-es2015-function-name@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" - integrity sha1-g0yJhTvDaxrw86TF26qU/Y6sqos= dependencies: babel-helper-function-name "^6.24.1" babel-runtime "^6.22.0" @@ -661,14 +571,12 @@ babel-plugin-transform-es2015-function-name@^6.22.0, babel-plugin-transform-es20 babel-plugin-transform-es2015-literals@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" - integrity sha1-T1SgLWzWbPkVKAAZox0xklN3yi4= dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" - integrity sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ= dependencies: babel-plugin-transform-es2015-modules-commonjs "^6.24.1" babel-runtime "^6.22.0" @@ -677,7 +585,6 @@ babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015 babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: version "6.26.2" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz#58a793863a9e7ca870bdc5a881117ffac27db6f3" - integrity sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q== dependencies: babel-plugin-transform-strict-mode "^6.24.1" babel-runtime "^6.26.0" @@ -687,7 +594,6 @@ babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-e babel-plugin-transform-es2015-modules-systemjs@^6.23.0, babel-plugin-transform-es2015-modules-systemjs@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" - integrity sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM= dependencies: babel-helper-hoist-variables "^6.24.1" babel-runtime "^6.22.0" @@ -696,7 +602,6 @@ babel-plugin-transform-es2015-modules-systemjs@^6.23.0, babel-plugin-transform-e babel-plugin-transform-es2015-modules-umd@^6.23.0, babel-plugin-transform-es2015-modules-umd@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" - integrity sha1-rJl+YoXNGO1hdq22B9YCNErThGg= dependencies: babel-plugin-transform-es2015-modules-amd "^6.24.1" babel-runtime "^6.22.0" @@ -705,7 +610,6 @@ babel-plugin-transform-es2015-modules-umd@^6.23.0, babel-plugin-transform-es2015 babel-plugin-transform-es2015-object-super@^6.22.0, babel-plugin-transform-es2015-object-super@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" - integrity sha1-JM72muIcuDp/hgPa0CH1cusnj40= dependencies: babel-helper-replace-supers "^6.24.1" babel-runtime "^6.22.0" @@ -713,7 +617,6 @@ babel-plugin-transform-es2015-object-super@^6.22.0, babel-plugin-transform-es201 babel-plugin-transform-es2015-parameters@^6.23.0, babel-plugin-transform-es2015-parameters@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" - integrity sha1-V6w1GrScrxSpfNE7CfZv3wpiXys= dependencies: babel-helper-call-delegate "^6.24.1" babel-helper-get-function-arity "^6.24.1" @@ -725,7 +628,6 @@ babel-plugin-transform-es2015-parameters@^6.23.0, babel-plugin-transform-es2015- babel-plugin-transform-es2015-shorthand-properties@^6.22.0, babel-plugin-transform-es2015-shorthand-properties@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" - integrity sha1-JPh11nIch2YbvZmkYi5R8U3jiqA= dependencies: babel-runtime "^6.22.0" babel-types "^6.24.1" @@ -733,14 +635,12 @@ babel-plugin-transform-es2015-shorthand-properties@^6.22.0, babel-plugin-transfo babel-plugin-transform-es2015-spread@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" - integrity sha1-1taKmfia7cRTbIGlQujdnxdG+NE= dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-sticky-regex@^6.22.0, babel-plugin-transform-es2015-sticky-regex@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" - integrity sha1-AMHNsaynERLN8M9hJsLta0V8zbw= dependencies: babel-helper-regex "^6.24.1" babel-runtime "^6.22.0" @@ -749,21 +649,18 @@ babel-plugin-transform-es2015-sticky-regex@^6.22.0, babel-plugin-transform-es201 babel-plugin-transform-es2015-template-literals@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" - integrity sha1-qEs0UPfp+PH2g51taH2oS7EjbY0= dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-typeof-symbol@^6.22.0, babel-plugin-transform-es2015-typeof-symbol@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" - integrity sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I= dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-unicode-regex@^6.22.0, babel-plugin-transform-es2015-unicode-regex@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" - integrity sha1-04sS9C6nMj9yk4fxinxa4frrNek= dependencies: babel-helper-regex "^6.24.1" babel-runtime "^6.22.0" @@ -772,7 +669,6 @@ babel-plugin-transform-es2015-unicode-regex@^6.22.0, babel-plugin-transform-es20 babel-plugin-transform-exponentiation-operator@^6.22.0, babel-plugin-transform-exponentiation-operator@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" - integrity sha1-KrDJx/MJj6SJB3cruBP+QejeOg4= dependencies: babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" babel-plugin-syntax-exponentiation-operator "^6.8.0" @@ -781,7 +677,6 @@ babel-plugin-transform-exponentiation-operator@^6.22.0, babel-plugin-transform-e babel-plugin-transform-object-rest-spread@^6.22.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz#0f36692d50fef6b7e2d4b3ac1478137a963b7b06" - integrity sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY= dependencies: babel-plugin-syntax-object-rest-spread "^6.8.0" babel-runtime "^6.26.0" @@ -789,14 +684,12 @@ babel-plugin-transform-object-rest-spread@^6.22.0: babel-plugin-transform-regenerator@^6.22.0, babel-plugin-transform-regenerator@^6.24.1: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" - integrity sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8= dependencies: regenerator-transform "^0.10.0" babel-plugin-transform-strict-mode@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" - integrity sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g= dependencies: babel-runtime "^6.22.0" babel-types "^6.24.1" @@ -804,7 +697,6 @@ babel-plugin-transform-strict-mode@^6.24.1: babel-polyfill@6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153" - integrity sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM= dependencies: babel-runtime "^6.26.0" core-js "^2.5.0" @@ -813,7 +705,6 @@ babel-polyfill@6.26.0: babel-preset-env@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.7.0.tgz#dea79fa4ebeb883cd35dab07e260c1c9c04df77a" - integrity sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg== dependencies: babel-plugin-check-es2015-constants "^6.22.0" babel-plugin-syntax-trailing-function-commas "^6.22.0" @@ -849,7 +740,6 @@ babel-preset-env@^1.7.0: babel-preset-es2015@6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz#d44050d6bc2c9feea702aaf38d727a0210538939" - integrity sha1-1EBQ1rwsn+6nAqrzjXJ6AhBTiTk= dependencies: babel-plugin-check-es2015-constants "^6.22.0" babel-plugin-transform-es2015-arrow-functions "^6.22.0" @@ -879,7 +769,6 @@ babel-preset-es2015@6.24.1: babel-preset-stage-2@6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz#d9e2960fb3d71187f0e64eec62bc07767219bdc1" - integrity sha1-2eKWD7PXEYfw5k7sYrwHdnIZvcE= dependencies: babel-plugin-syntax-dynamic-import "^6.18.0" babel-plugin-transform-class-properties "^6.24.1" @@ -889,7 +778,6 @@ babel-preset-stage-2@6.24.1: babel-preset-stage-3@6.24.1, babel-preset-stage-3@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz#836ada0a9e7a7fa37cb138fb9326f87934a48395" - integrity sha1-g2raCp56f6N8sTj7kyb4eTSkg5U= dependencies: babel-plugin-syntax-trailing-function-commas "^6.22.0" babel-plugin-transform-async-generator-functions "^6.24.1" @@ -900,7 +788,6 @@ babel-preset-stage-3@6.24.1, babel-preset-stage-3@^6.24.1: babel-register@6.26.0, babel-register@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" - integrity sha1-btAhFz4vy0htestFxgCahW9kcHE= dependencies: babel-core "^6.26.0" babel-runtime "^6.26.0" @@ -913,7 +800,6 @@ babel-register@6.26.0, babel-register@^6.26.0: babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" - integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= dependencies: core-js "^2.4.0" regenerator-runtime "^0.11.0" @@ -921,7 +807,6 @@ babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: babel-template@^6.24.1, babel-template@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" - integrity sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI= dependencies: babel-runtime "^6.26.0" babel-traverse "^6.26.0" @@ -932,7 +817,6 @@ babel-template@^6.24.1, babel-template@^6.26.0: babel-traverse@^6.24.1, babel-traverse@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" - integrity sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4= dependencies: babel-code-frame "^6.26.0" babel-messages "^6.23.0" @@ -947,7 +831,6 @@ babel-traverse@^6.24.1, babel-traverse@^6.26.0: babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" - integrity sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc= dependencies: babel-runtime "^6.26.0" esutils "^2.0.2" @@ -957,7 +840,6 @@ babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: babelify@^7.3.0: version "7.3.0" resolved "https://registry.yarnpkg.com/babelify/-/babelify-7.3.0.tgz#aa56aede7067fd7bd549666ee16dc285087e88e5" - integrity sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU= dependencies: babel-core "^6.0.14" object-assign "^4.0.0" @@ -965,34 +847,28 @@ babelify@^7.3.0: babylon@^6.18.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" - integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== balanced-match@^1.0.0: version "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.5" resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.5.tgz#d3ada59afed05b921ab581ec3112e6444ba0795a" - integrity sha512-C3picSgzPSLE+jW3tcBzJoGwitOtazb5B+5YmAxZm2ybmTi9LNgAtDO/jjVEBZwHoXmDBZ9m/IELj3elJVRBcA== dependencies: safe-buffer "^5.0.1" base64-js@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-0.0.8.tgz#1101e9544f4a76b1bc3b26d452ca96d7a35e7978" - integrity sha1-EQHpVE9KdrG8OybUUsqW16NeeXg= base64-js@^1.0.2: version "1.3.0" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3" - integrity sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw== base@^0.11.1: version "0.11.2" resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" - integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== dependencies: cache-base "^1.0.1" class-utils "^0.3.5" @@ -1005,24 +881,20 @@ base@^0.11.1: bcrypt-pbkdf@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= dependencies: tweetnacl "^0.14.3" bignumber.js@5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-5.0.0.tgz#fbce63f09776b3000a83185badcde525daf34833" - integrity sha512-KWTu6ZMVk9sxlDJQh2YH1UOnfDP8O8TpxUxgQG/vKASoSnEjK9aVuOueFaPcQEYQ5fyNXNTOYwYw3099RYebWg== bignumber.js@^4.0.2: version "4.1.0" resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-4.1.0.tgz#db6f14067c140bd46624815a7916c92d9b6c24b1" - integrity sha512-eJzYkFYy9L4JzXsbymsFn3p54D+llV27oTQ+ziJG7WFRheJcNZilgVXMG0LoZtlQSKBsJdWtLFqOD0u+U0jZKA== bignumber.js@^8.0.1: version "8.0.1" resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-8.0.1.tgz#5d419191370fb558c64e3e5f70d68e5947138832" - integrity sha512-zAySveTJXkgLYCBi0b14xzfnOs+f3G6x36I8w2a1+PFQpWk/dp0mI0F+ZZK2bu+3ELewDcSyP+Cfq++NcHX7sg== "bignumber.js@git+https://github.com/debris/bignumber.js#master": version "2.0.7" @@ -1039,31 +911,26 @@ bignumber.js@^8.0.1: binary-extensions@^1.0.0: version "1.12.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.12.0.tgz#c2d780f53d45bba8317a8902d4ceeaf3a6385b14" - integrity sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg== bindings@^1.2.1: version "1.3.1" resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.3.1.tgz#21fc7c6d67c18516ec5aaa2815b145ff77b26ea5" - integrity sha512-i47mqjF9UbjxJhxGf+pZ6kSxrnI3wBLlnGI2ArWJ4r0VrvDS7ZYXkprq/pLaBWYq4GM0r4zdHY+NNRqEMU7uew== bindings@^1.3.1: version "1.4.0" resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.4.0.tgz#909efa49f2ebe07ecd3cb136778f665052040127" - integrity sha512-7znEVX22Djn+nYjxCWKDne0RRloa9XfYa84yk3s+HkE3LpDYZmhArYr9O9huBoHY3/oXispx5LorIX7Sl2CgSQ== dependencies: file-uri-to-path "1.0.0" bip66@^1.1.3: version "1.1.5" resolved "https://registry.yarnpkg.com/bip66/-/bip66-1.1.5.tgz#01fa8748785ca70955d5011217d1b3139969ca22" - integrity sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI= dependencies: safe-buffer "^5.0.1" bitcore-lib@^0.15.0: version "0.15.0" resolved "https://registry.yarnpkg.com/bitcore-lib/-/bitcore-lib-0.15.0.tgz#f924be13869f2aab7e04aeec5642ad3359b6cec2" - integrity sha512-AeXLWhiivF6CDFzrABZHT4jJrflyylDWTi32o30rF92HW9msfuKpjzrHtFKYGa9w0kNVv5HABQjCB3OEav4PhQ== dependencies: bn.js "=4.11.8" bs58 "=4.0.1" @@ -1075,7 +942,6 @@ bitcore-lib@^0.15.0: bitcore-lib@^0.16.0: version "0.16.0" resolved "https://registry.yarnpkg.com/bitcore-lib/-/bitcore-lib-0.16.0.tgz#a2c3ec1108cdb90386f728282ab833e0c77c9533" - integrity sha512-CEtcrPAH2gwgaMN+OPMJc18TBEak1+TtzMyafrqrIbK9PIa3kat195qBJhC0liJSHRiRr6IE2eLcXeIFFs+U8w== dependencies: bn.js "=4.11.8" bs58 "=4.0.1" @@ -1087,7 +953,6 @@ bitcore-lib@^0.16.0: bitcore-mnemonic@^1.5.0: version "1.7.0" resolved "https://registry.yarnpkg.com/bitcore-mnemonic/-/bitcore-mnemonic-1.7.0.tgz#253295a773135e1a0b455871de614996afc8f5e1" - integrity sha512-1JV1okgz9Vv+Y4fG2m3ToR+BGdKA6tSoqjepIxA95BZjW6YaeopVW4iOe/dY9dnkZH4+LA2AJ4YbDE6H3ih3Yw== dependencies: bitcore-lib "^0.16.0" unorm "^1.4.1" @@ -1095,7 +960,6 @@ bitcore-mnemonic@^1.5.0: bl@^1.0.0: version "1.2.2" resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.2.tgz#a160911717103c07410cef63ef51b397c025af9c" - integrity sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA== dependencies: readable-stream "^2.3.5" safe-buffer "^5.1.1" @@ -1103,39 +967,32 @@ bl@^1.0.0: 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.4.6, bluebird@^3.5.0, bluebird@^3.5.3: version "3.5.3" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.3.tgz#7d01c6f9616c9a51ab0f8c549a79dfe6ec33efa7" - integrity sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw== bn.js@4.11.6: version "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.11.8, bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.10.0, bn.js@^4.11.0, bn.js@^4.11.3, bn.js@^4.11.6, bn.js@^4.4.0, bn.js@^4.8.0: version "4.11.8" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" - integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== bn.js@^2.0.3: version "2.2.0" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-2.2.0.tgz#12162bc2ae71fc40a5626c33438f3a875cd37625" - integrity sha1-EhYrwq5x/EClYmwzQ486h1zTdiU= body-parser@1.18.3, body-parser@^1.16.0: version "1.18.3" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.3.tgz#5b292198ffdd553b3a0f20ded0592b956955c8b4" - integrity sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ= dependencies: bytes "3.0.0" content-type "~1.0.4" @@ -1151,7 +1008,6 @@ body-parser@1.18.3, body-parser@^1.16.0: borc@^2.0.2: version "2.1.0" resolved "https://registry.yarnpkg.com/borc/-/borc-2.1.0.tgz#2def2fc69868633b965a9750e7f210d778190303" - integrity sha512-hKTxeYt3AIzIG45epJHv8xJYSF0ktp7nZgFsqi5cPzoL3T8qKMPeUlqydORy6j3NWZvRDANx30PjpTmGho69Gw== dependencies: bignumber.js "^8.0.1" commander "^2.15.0" @@ -1162,7 +1018,6 @@ borc@^2.0.2: brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== dependencies: balanced-match "^1.0.0" concat-map "0.0.1" @@ -1170,7 +1025,6 @@ brace-expansion@^1.1.7: braces@^1.8.2: version "1.8.5" resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" - integrity sha1-uneWLhLf+WnWt2cR6RS3N4V79qc= dependencies: expand-range "^1.8.1" preserve "^0.2.0" @@ -1179,7 +1033,6 @@ braces@^1.8.2: braces@^2.3.1: version "2.3.2" resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" - integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== dependencies: arr-flatten "^1.1.0" array-unique "^0.3.2" @@ -1195,22 +1048,18 @@ braces@^2.3.1: brorand@^1.0.1: version "1.1.0" 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" - integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== browserify-aes@^1.0.0, browserify-aes@^1.0.4, browserify-aes@^1.0.6: version "1.2.0" resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" - integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== dependencies: buffer-xor "^1.0.3" cipher-base "^1.0.0" @@ -1222,7 +1071,6 @@ browserify-aes@^1.0.0, browserify-aes@^1.0.4, browserify-aes@^1.0.6: browserify-cipher@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" - integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== dependencies: browserify-aes "^1.0.4" browserify-des "^1.0.0" @@ -1231,7 +1079,6 @@ browserify-cipher@^1.0.0: browserify-des@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" - integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== dependencies: cipher-base "^1.0.1" des.js "^1.0.0" @@ -1241,7 +1088,6 @@ browserify-des@^1.0.0: browserify-rsa@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" - integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= dependencies: bn.js "^4.1.0" randombytes "^2.0.1" @@ -1249,7 +1095,6 @@ browserify-rsa@^4.0.0: browserify-sha3@^0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/browserify-sha3/-/browserify-sha3-0.0.4.tgz#086c47b8c82316c9d47022c26185954576dd8e26" - integrity sha1-CGxHuMgjFsnUcCLCYYWVRXbdjiY= dependencies: js-sha3 "^0.6.1" safe-buffer "^5.1.1" @@ -1257,7 +1102,6 @@ browserify-sha3@^0.0.4: browserify-sign@^4.0.0: version "4.0.4" resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" - integrity sha1-qk62jl17ZYuqa/alfmMMvXqT0pg= dependencies: bn.js "^4.1.1" browserify-rsa "^4.0.0" @@ -1270,7 +1114,6 @@ browserify-sign@^4.0.0: browserslist@^3.2.6: version "3.2.8" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-3.2.8.tgz#b0005361d6471f0f5952797a76fc985f1f978fc6" - integrity sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ== dependencies: caniuse-lite "^1.0.30000844" electron-to-chromium "^1.3.47" @@ -1278,19 +1121,16 @@ browserslist@^3.2.6: bs58@=4.0.1, bs58@^4.0.0, bs58@^4.0.1: 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" bs58@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/bs58/-/bs58-2.0.1.tgz#55908d58f1982aba2008fa1bed8f91998a29bf8d" - integrity sha1-VZCNWPGYKrogCPob7Y+RmYopv40= bs58check@^2.1.2: 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" @@ -1299,17 +1139,14 @@ bs58check@^2.1.2: bson@^1.0.4: version "1.1.0" resolved "https://registry.yarnpkg.com/bson/-/bson-1.1.0.tgz#bee57d1fb6a87713471af4e32bcae36de814b5b0" - integrity sha512-9Aeai9TacfNtWXOYarkFJRW2CWo+dRon+fuLZYJmvLV3+MiUp0bEI6IAZfXEIg7/Pl/7IWlLaDnhzTsD81etQA== 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" - integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== buffer-alloc@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" - integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== dependencies: buffer-alloc-unsafe "^1.1.0" buffer-fill "^1.0.0" @@ -1317,37 +1154,30 @@ buffer-alloc@^1.2.0: buffer-compare@=1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-compare/-/buffer-compare-1.1.1.tgz#5be7be853af89198d1f4ddc090d1d66a48aef596" - integrity sha1-W+e+hTr4kZjR9N3AkNHWakiu9ZY= buffer-crc32@~0.2.3: version "0.2.13" resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" - integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= buffer-fill@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" - integrity sha1-+PeLdniYiO858gXNY39o5wISKyw= buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" - integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== buffer-to-arraybuffer@^0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz#6064a40fa76eb43c723aba9ef8f6e1216d10511a" - integrity sha1-YGSkD6dutDxyOrqe+PbhIW0QURo= buffer-xor@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" - integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= buffer@^3.0.1: version "3.6.0" resolved "https://registry.yarnpkg.com/buffer/-/buffer-3.6.0.tgz#a72c936f77b96bf52f5f7e7b467180628551defb" - integrity sha1-pyyTb3e5a/UvX357RnGAYoVR3vs= dependencies: base64-js "0.0.8" ieee754 "^1.1.4" @@ -1356,7 +1186,6 @@ buffer@^3.0.1: buffer@^4.9.0: version "4.9.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" - integrity sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg= dependencies: base64-js "^1.0.2" ieee754 "^1.1.4" @@ -1365,7 +1194,6 @@ buffer@^4.9.0: buffer@^5.0.5: version "5.2.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.2.1.tgz#dd57fa0f109ac59c602479044dca7b8b3d0b71d6" - integrity sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg== dependencies: base64-js "^1.0.2" ieee754 "^1.1.4" @@ -1373,17 +1201,14 @@ buffer@^5.0.5: builtin-modules@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" - integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" - integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= cache-base@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" - integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== dependencies: collection-visit "^1.0.0" component-emitter "^1.2.1" @@ -1398,29 +1223,24 @@ cache-base@^1.0.1: caller-path@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" - integrity sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8= dependencies: callsites "^0.2.0" callsites@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" - integrity sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo= camelcase@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" - integrity sha1-MvxLn82vhF/N9+c7uXysImHwqwo= camelcase@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" - integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= caminte@0.3.7: version "0.3.7" resolved "https://registry.yarnpkg.com/caminte/-/caminte-0.3.7.tgz#ec1ec0457664a0f092643b7c646c457d5cd6f693" - integrity sha1-7B7ARXZkoPCSZDt8ZGxFfVzW9pM= dependencies: bluebird "^3.4.6" uuid "^3.0.1" @@ -1428,17 +1248,14 @@ caminte@0.3.7: caniuse-lite@^1.0.30000844: version "1.0.30000926" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000926.tgz#4361a99d818ca6e521dbe89a732de62a194a789c" - integrity sha512-diMkEvxfFw09SkbErCLmw/1Fx1ZZe9xfWm4aeA2PUffB48x1tfZeMsK5j4BW7zN7Y4PdqmPVVdG2eYjE5IRTag== caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" - integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= dependencies: ansi-styles "^2.2.1" escape-string-regexp "^1.0.2" @@ -1449,7 +1266,6 @@ chalk@^1.1.3: chalk@^2.0.0, chalk@^2.1.0, chalk@^2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" - integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ== dependencies: ansi-styles "^3.2.1" escape-string-regexp "^1.0.5" @@ -1458,24 +1274,20 @@ chalk@^2.0.0, chalk@^2.1.0, chalk@^2.4.1: chardet@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" - integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== charenc@~0.0.1: version "0.0.2" resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" - integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc= 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" chokidar@^1.6.0: version "1.7.0" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" - integrity sha1-eY5ol3gVHIB2tLNg5e3SjNortGg= dependencies: anymatch "^1.3.0" async-each "^1.0.0" @@ -1491,12 +1303,10 @@ chokidar@^1.6.0: chownr@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" - integrity sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g== cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" - integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== dependencies: inherits "^2.0.1" safe-buffer "^5.0.1" @@ -1504,12 +1314,10 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: circular-json@^0.3.1: version "0.3.3" resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" - integrity sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A== class-utils@^0.3.5: version "0.3.6" resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" - integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== dependencies: arr-union "^3.1.0" define-property "^0.2.5" @@ -1519,7 +1327,6 @@ class-utils@^0.3.5: cli-color@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/cli-color/-/cli-color-1.4.0.tgz#7d10738f48526824f8fe7da51857cb0f572fe01f" - integrity sha512-xu6RvQqqrWEo6MPR1eixqGPywhYBHRs653F9jfXB2Hx4jdM/3WxiNE1vppRmxtMIfl16SFYTpYlrnqH/HsK/2w== dependencies: ansi-regex "^2.1.1" d "1" @@ -1531,19 +1338,16 @@ cli-color@^1.4.0: cli-cursor@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" - integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= dependencies: restore-cursor "^2.0.0" cli-width@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" - integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= cliui@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" - integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0= dependencies: string-width "^1.0.1" strip-ansi "^3.0.1" @@ -1552,7 +1356,6 @@ cliui@^3.2.0: cliui@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" - integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ== dependencies: string-width "^2.1.1" strip-ansi "^4.0.0" @@ -1561,22 +1364,18 @@ cliui@^4.0.0: clone@2.x, clone@^2.0.0: version "2.1.2" resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" - integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= coinstring@^2.0.0: version "2.3.0" resolved "https://registry.yarnpkg.com/coinstring/-/coinstring-2.3.0.tgz#cdb63363a961502404a25afb82c2e26d5ff627a4" - integrity sha1-zbYzY6lhUCQEolr7gsLibV/2J6Q= dependencies: bs58 "^2.0.1" create-hash "^1.1.1" @@ -1584,7 +1383,6 @@ coinstring@^2.0.0: collection-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" - integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= dependencies: map-visit "^1.0.0" object-visit "^1.0.0" @@ -1592,135 +1390,110 @@ collection-visit@^1.0.0: color-convert@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== dependencies: color-name "1.1.3" color-name@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= colors@1.0.x: version "1.0.3" resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" - integrity sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs= colors@^1.1.2: version "1.3.3" resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.3.tgz#39e005d546afe01e01f9c4ca8fa50f686a01205d" - integrity sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg== combined-stream@^1.0.6, combined-stream@~1.0.6: version "1.0.7" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828" - integrity sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w== dependencies: delayed-stream "~1.0.0" 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.14.1, commander@^2.15.0, commander@^2.19.0, commander@^2.8.1, commander@^2.9.0: version "2.19.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" - integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== commander@~2.17.1: version "2.17.1" resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" - integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg== commander@~2.8.1: version "2.8.1" resolved "https://registry.yarnpkg.com/commander/-/commander-2.8.1.tgz#06be367febfda0c330aa1e2a072d3dc9762425d4" - integrity sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ= dependencies: graceful-readlink ">= 1.0.0" compare-versions@^3.0.1: version "3.4.0" resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.4.0.tgz#e0747df5c9cb7f054d6d3dc3e1dbc444f9e92b26" - integrity sha512-tK69D7oNXXqUW3ZNo/z7NXTEz22TCF0pTE+YF9cxvaAM9XnkLo1fV621xCLrRR6aevJlKxExkss0vWqUCUpqdg== component-emitter@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" - integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY= concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= console-control-strings@^1.0.0, console-control-strings@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= contains-path@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" - integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= content-disposition@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" - integrity sha1-DPaLud318r55YcOoUXjLhdunjLQ= content-type@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" - integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== convert-source-map@^1.5.1: version "1.6.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" - integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A== dependencies: safe-buffer "~5.1.1" cookie-signature@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= cookie@0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" - integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= cookiejar@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.2.tgz#dd8a235530752f988f9a0844f3fc589e3111125c" - integrity sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA== copy-descriptor@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" - integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= core-js@^2.4.0, core-js@^2.5.0: version "2.6.1" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.1.tgz#87416ae817de957a3f249b3b5ca475d4aaed6042" - integrity sha512-L72mmmEayPJBejKIWe2pYtGis5r0tQ5NaJekdhyXgeMQTpJoBsH0NL4ElY2LfSoV15xeQWKQ+XTTOZdyero5Xg== core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= cors@^2.8.1: version "2.8.5" resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" - integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== dependencies: object-assign "^4" vary "^1" @@ -1728,7 +1501,6 @@ cors@^2.8.1: coveralls@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/coveralls/-/coveralls-3.0.2.tgz#f5a0bcd90ca4e64e088b710fa8dda640aea4884f" - integrity sha512-Tv0LKe/MkBOilH2v7WBiTBdudg2ChfGbdXafc/s330djpF3zKOmuehTeRwjXWc7pzfj9FrDUTA7tEx6Div8NFw== dependencies: growl "~> 1.10.0" js-yaml "^3.11.0" @@ -1740,7 +1512,6 @@ coveralls@^3.0.2: create-ecdh@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" - integrity sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw== dependencies: bn.js "^4.1.0" elliptic "^6.0.0" @@ -1748,7 +1519,6 @@ create-ecdh@^4.0.0: create-hash@^1.1.0, create-hash@^1.1.1, create-hash@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" - integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== dependencies: cipher-base "^1.0.1" inherits "^2.0.1" @@ -1759,7 +1529,6 @@ create-hash@^1.1.0, create-hash@^1.1.1, create-hash@^1.1.2: create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: 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== dependencies: cipher-base "^1.0.3" create-hash "^1.1.0" @@ -1771,7 +1540,6 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: cron-parser@^2.7.3: version "2.7.3" resolved "https://registry.yarnpkg.com/cron-parser/-/cron-parser-2.7.3.tgz#12603f89f5375af353a9357be2543d3172eac651" - integrity sha512-t9Kc7HWBWPndBzvbdQ1YG9rpPRB37Tb/tTviziUOh1qs3TARGh3b1p+tnkOHNe1K5iI3oheBPgLqwotMM7+lpg== dependencies: is-nan "^1.2.1" moment-timezone "^0.5.23" @@ -1779,7 +1547,6 @@ cron-parser@^2.7.3: cross-spawn@^5.0.1: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" - integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= dependencies: lru-cache "^4.0.1" shebang-command "^1.2.0" @@ -1788,7 +1555,6 @@ cross-spawn@^5.0.1: cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== dependencies: nice-try "^1.0.4" path-key "^2.0.1" @@ -1799,12 +1565,10 @@ cross-spawn@^6.0.5: 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" - integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== dependencies: browserify-cipher "^1.0.0" browserify-sign "^4.0.0" @@ -1821,96 +1585,80 @@ crypto-browserify@3.12.0: crypto-js@^3.1.4, crypto-js@^3.1.5: version "3.1.8" resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-3.1.8.tgz#715f070bf6014f2ae992a98b3929258b713f08d5" - integrity sha1-cV8HC/YBTyrpkqmLOSkli3E/CNU= crypto-random-string@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" - integrity sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4= csextends@^1.0.3: version "1.2.0" resolved "https://registry.yarnpkg.com/csextends/-/csextends-1.2.0.tgz#6374b210984b54d4495f29c99d3dd069b80543e5" - integrity sha512-S/8k1bDTJIwuGgQYmsRoE+8P+ohV32WhQ0l4zqrc0XDdxOhjQQD7/wTZwCzoZX53jSX3V/qwjT+OkPTxWQcmjg== csv-parse@^4.2.0: version "4.3.0" resolved "https://registry.yarnpkg.com/csv-parse/-/csv-parse-4.3.0.tgz#e27cc1c4c5426201a896389c9f97273a0d47dad4" - integrity sha512-vrZTSMG/6a5EI30ICFU8IQ1kR3xXXoC3Z7jaUv76E5uCgFahr2sffRoTAffvEd1JZNssAgalI4DaEFUnXqQCGw== cycle@1.0.x: version "1.0.3" resolved "https://registry.yarnpkg.com/cycle/-/cycle-1.0.3.tgz#21e80b2be8580f98b468f379430662b046c34ad2" - integrity sha1-IegLK+hYD5i0aPN5QwZisEbDStI= d@1: version "1.0.0" resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" - integrity sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8= dependencies: es5-ext "^0.10.9" dashdash@^1.12.0: version "1.14.1" resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= dependencies: assert-plus "^1.0.0" death@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/death/-/death-1.1.0.tgz#01aa9c401edd92750514470b8266390c66c67318" - integrity sha1-AaqcQB7dknUFFEcLgmY5DGbGcxg= debug@*, debug@^4.0.1: version "4.1.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" - integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== dependencies: ms "^2.1.1" debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms "2.0.0" debug@3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" - integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== dependencies: ms "2.0.0" debug@^3.2.6: version "3.2.6" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== dependencies: ms "^2.1.1" decamelize@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= decode-uri-component@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" - integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= decompress-response@^3.2.0, decompress-response@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" - integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= dependencies: mimic-response "^1.0.0" decompress-tar@^4.0.0, decompress-tar@^4.1.0, decompress-tar@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/decompress-tar/-/decompress-tar-4.1.1.tgz#718cbd3fcb16209716e70a26b84e7ba4592e5af1" - integrity sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ== dependencies: file-type "^5.2.0" is-stream "^1.1.0" @@ -1919,7 +1667,6 @@ decompress-tar@^4.0.0, decompress-tar@^4.1.0, decompress-tar@^4.1.1: decompress-tarbz2@^4.0.0: version "4.1.1" resolved "https://registry.yarnpkg.com/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz#3082a5b880ea4043816349f378b56c516be1a39b" - integrity sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A== dependencies: decompress-tar "^4.1.0" file-type "^6.1.0" @@ -1930,7 +1677,6 @@ decompress-tarbz2@^4.0.0: decompress-targz@^4.0.0: version "4.1.1" resolved "https://registry.yarnpkg.com/decompress-targz/-/decompress-targz-4.1.1.tgz#c09bc35c4d11f3de09f2d2da53e9de23e7ce1eee" - integrity sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w== dependencies: decompress-tar "^4.1.1" file-type "^5.2.0" @@ -1939,7 +1685,6 @@ decompress-targz@^4.0.0: decompress-unzip@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/decompress-unzip/-/decompress-unzip-4.0.1.tgz#deaaccdfd14aeaf85578f733ae8210f9b4848f69" - integrity sha1-3qrM39FK6vhVePczroIQ+bSEj2k= dependencies: file-type "^3.8.0" get-stream "^2.2.0" @@ -1949,7 +1694,6 @@ decompress-unzip@^4.0.1: decompress@^4.0.0: version "4.2.0" resolved "https://registry.yarnpkg.com/decompress/-/decompress-4.2.0.tgz#7aedd85427e5a92dacfe55674a7c505e96d01f9d" - integrity sha1-eu3YVCflqS2s/lVnSnxQXpbQH50= dependencies: decompress-tar "^4.0.0" decompress-tarbz2 "^4.0.0" @@ -1963,55 +1707,46 @@ decompress@^4.0.0: deep-equal@~0.2.1: version "0.2.2" resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-0.2.2.tgz#84b745896f34c684e98f2ce0e42abaf43bba017d" - integrity sha1-hLdFiW80xoTpjyzg5Cq69Du6AX0= deep-equal@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" - integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU= deep-extend@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" - integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= 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" define-properties@^1.1.1, define-properties@^1.1.2: 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== dependencies: object-keys "^1.0.12" define-property@^0.2.5: version "0.2.5" resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" - integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= dependencies: is-descriptor "^0.1.0" define-property@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" - integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= dependencies: is-descriptor "^1.0.0" define-property@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" - integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== dependencies: is-descriptor "^1.0.2" isobject "^3.0.1" @@ -2019,32 +1754,26 @@ define-property@^2.0.2: defined@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" - integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM= delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= delegates@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= delimit-stream@0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/delimit-stream/-/delimit-stream-0.1.0.tgz#9b8319477c0e5f8aeb3ce357ae305fc25ea1cd2b" - integrity sha1-m4MZR3wOX4rrPONXrjBfwl6hzSs= depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= des.js@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" - integrity sha1-wHTS4qpqipoH29YfmhXCzYPsjsw= dependencies: inherits "^2.0.1" minimalistic-assert "^1.0.0" @@ -2052,34 +1781,28 @@ des.js@^1.0.0: destroy@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" - integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= detect-indent@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" - integrity sha1-920GQ1LN9Docts5hnE7jqUdd4gg= dependencies: repeating "^2.0.0" detect-libc@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" - integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= 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, diff@^3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" - integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== diffie-hellman@^5.0.0: version "5.0.3" resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" - integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== dependencies: bn.js "^4.1.0" miller-rabin "^4.0.0" @@ -2088,7 +1811,6 @@ diffie-hellman@^5.0.0: doctrine@1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" - integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo= dependencies: esutils "^2.0.2" isarray "^1.0.0" @@ -2096,19 +1818,16 @@ doctrine@1.5.0: doctrine@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" - integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== dependencies: esutils "^2.0.2" dom-walk@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018" - integrity sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg= drbg.js@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/drbg.js/-/drbg.js-1.0.1.tgz#3e36b6c42b37043823cdbc332d58f31e2445480b" - integrity sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs= dependencies: browserify-aes "^1.0.6" create-hash "^1.1.2" @@ -2117,19 +1836,16 @@ drbg.js@^1.0.1: duplexer3@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" - integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= eachr@^2.0.2: version "2.0.4" resolved "https://registry.yarnpkg.com/eachr/-/eachr-2.0.4.tgz#466f7caa10708f610509e32c807aafe57fc122bf" - integrity sha1-Rm98qhBwj2EFCeMsgHqv5X/BIr8= dependencies: typechecker "^2.0.8" ecc-jsbn@~0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= dependencies: jsbn "~0.1.0" safer-buffer "^2.1.0" @@ -2137,12 +1853,10 @@ ecc-jsbn@~0.1.1: editions@^1.1.1, editions@^1.3.3: version "1.3.4" resolved "https://registry.yarnpkg.com/editions/-/editions-1.3.4.tgz#3662cb592347c3168eb8e498a0ff73271d67f50b" - integrity sha512-gzao+mxnYDzIysXKMQi/+M1mjy/rjestjg6OPoYTtI+3Izp23oiGZitsl9lPDPiTGXbcSIk1iJWhliSaglxnUg== editions@^2.1.0, editions@^2.1.2: version "2.1.3" resolved "https://registry.yarnpkg.com/editions/-/editions-2.1.3.tgz#727ccf3ec2c7b12dcc652c71000f16c4824d6f7d" - integrity sha512-xDZyVm0A4nLgMNWVVLJvcwMjI80ShiH/27RyLiCnW1L273TcJIA25C4pwJ33AWV01OX6UriP35Xu+lH4S7HWQw== dependencies: errlop "^1.1.1" semver "^5.6.0" @@ -2150,17 +1864,14 @@ editions@^2.1.0, editions@^2.1.2: ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= electron-to-chromium@^1.3.47: version "1.3.96" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.96.tgz#25770ec99b8b07706dedf3a5f43fa50cb54c4f9a" - integrity sha512-ZUXBUyGLeoJxp4Nt6G/GjBRLnyz8IKQGexZ2ndWaoegThgMGFO1tdDYID5gBV32/1S83osjJHyfzvanE/8HY4Q== elliptic@6.3.3: version "6.3.3" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.3.3.tgz#5482d9646d54bcb89fd7d994fc9e2e9568876e3f" - integrity sha1-VILZZG1UvLif19mU/J4ulWiHbj8= dependencies: bn.js "^4.4.0" brorand "^1.0.1" @@ -2170,7 +1881,6 @@ elliptic@6.3.3: elliptic@=6.4.0: version "6.4.0" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.0.tgz#cac9af8762c85836187003c8dfe193e5e2eae5df" - integrity sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8= dependencies: bn.js "^4.4.0" brorand "^1.0.1" @@ -2183,7 +1893,6 @@ elliptic@=6.4.0: elliptic@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-3.1.0.tgz#c21682ef762769b56a74201609105da11d5f60cc" - integrity sha1-whaC73YnabVqdCAWCRBdoR1fYMw= dependencies: bn.js "^2.0.3" brorand "^1.0.1" @@ -2193,7 +1902,6 @@ elliptic@^3.1.0: elliptic@^6.0.0, elliptic@^6.2.3, elliptic@^6.4.0: version "6.4.1" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.1.tgz#c2d0b7776911b86722c632c3c06c60f2f819939a" - integrity sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ== dependencies: bn.js "^4.4.0" brorand "^1.0.1" @@ -2206,52 +1914,44 @@ elliptic@^6.0.0, elliptic@^6.2.3, elliptic@^6.4.0: encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= encoding@^0.1.11: version "0.1.12" resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" - integrity sha1-U4tm8+5izRq1HsMjgp0flIDHS+s= dependencies: iconv-lite "~0.4.13" end-of-stream@^1.0.0: version "1.4.1" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" - integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q== dependencies: once "^1.4.0" eol@^0.9.1: version "0.9.1" resolved "https://registry.yarnpkg.com/eol/-/eol-0.9.1.tgz#f701912f504074be35c6117a5c4ade49cd547acd" - integrity sha512-Ds/TEoZjwggRoz/Q2O7SE3i4Jm66mqTDfmdHdq/7DKVk3bro9Q8h6WdXKdPqFLMoqxrDK5SVRzHVPOS6uuGtrg== errlop@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/errlop/-/errlop-1.1.1.tgz#d9ae4c76c3e64956c5d79e6e035d6343bfd62250" - integrity sha512-WX7QjiPHhsny7/PQvrhS5VMizXXKoKCS3udaBp8gjlARdbn+XmK300eKBAAN0hGyRaTCtRpOaxK+xFVPUJ3zkw== dependencies: editions "^2.1.2" 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" error-ex@^1.2.0: version "1.3.2" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== dependencies: is-arrayish "^0.2.1" es-abstract@^1.5.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== dependencies: es-to-primitive "^1.2.0" function-bind "^1.1.1" @@ -2263,7 +1963,6 @@ es-abstract@^1.5.0: es-to-primitive@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" - integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg== dependencies: is-callable "^1.1.4" is-date-object "^1.0.1" @@ -2272,7 +1971,6 @@ es-to-primitive@^1.2.0: es5-ext@^0.10.14, es5-ext@^0.10.35, es5-ext@^0.10.45, es5-ext@^0.10.46, es5-ext@^0.10.9, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46: version "0.10.46" resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.46.tgz#efd99f67c5a7ec789baa3daa7f79870388f7f572" - integrity sha512-24XxRvJXNFwEMpJb3nOkiRJKRoupmjYmOPVlI65Qy2SrtxwOTB+g6ODjBKOtwEHbYrhWRty9xxOWLNdClT2djw== dependencies: es6-iterator "~2.0.3" es6-symbol "~3.1.1" @@ -2281,7 +1979,6 @@ es5-ext@^0.10.14, es5-ext@^0.10.35, es5-ext@^0.10.45, es5-ext@^0.10.46, es5-ext@ es6-iterator@^2.0.1, es6-iterator@^2.0.3, es6-iterator@~2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" - integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= dependencies: d "1" es5-ext "^0.10.35" @@ -2290,7 +1987,6 @@ es6-iterator@^2.0.1, es6-iterator@^2.0.3, es6-iterator@~2.0.3: es6-symbol@^3.1.1, es6-symbol@~3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" - integrity sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc= dependencies: d "1" es5-ext "~0.10.14" @@ -2298,7 +1994,6 @@ es6-symbol@^3.1.1, es6-symbol@~3.1.1: es6-weak-map@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.2.tgz#5e3ab32251ffd1538a1f8e5ffa1357772f92d96f" - integrity sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8= dependencies: d "1" es5-ext "^0.10.14" @@ -2308,17 +2003,14 @@ es6-weak-map@^2.0.2: escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= escodegen@1.8.x: version "1.8.1" resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018" - integrity sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg= dependencies: esprima "^2.7.1" estraverse "^1.9.1" @@ -2330,12 +2022,10 @@ escodegen@1.8.x: eslint-config-standard@^12.0.0: version "12.0.0" resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-12.0.0.tgz#638b4c65db0bd5a41319f96bba1f15ddad2107d9" - integrity sha512-COUz8FnXhqFitYj4DTqHzidjIL/t4mumGZto5c7DrBpvWoie+Sn3P4sLEzUGeYhRElWuFEf8K1S1EfvD1vixCQ== eslint-import-resolver-node@^0.3.1: version "0.3.2" resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz#58f15fb839b8d0576ca980413476aab2472db66a" - integrity sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q== dependencies: debug "^2.6.9" resolve "^1.5.0" @@ -2343,7 +2033,6 @@ eslint-import-resolver-node@^0.3.1: eslint-module-utils@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.2.0.tgz#b270362cd88b1a48ad308976ce7fa54e98411746" - integrity sha1-snA2LNiLGkitMIl2zn+lTphBF0Y= dependencies: debug "^2.6.8" pkg-dir "^1.0.0" @@ -2351,7 +2040,6 @@ eslint-module-utils@^2.2.0: eslint-plugin-es@^1.3.1: version "1.4.0" resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-1.4.0.tgz#475f65bb20c993fc10e8c8fe77d1d60068072da6" - integrity sha512-XfFmgFdIUDgvaRAlaXUkxrRg5JSADoRC8IkKLc/cISeR3yHVMefFHQZpcyXXEUUPHfy5DwviBcrfqlyqEwlQVw== dependencies: eslint-utils "^1.3.0" regexpp "^2.0.1" @@ -2359,7 +2047,6 @@ eslint-plugin-es@^1.3.1: eslint-plugin-import@^2.14.0: version "2.14.0" resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.14.0.tgz#6b17626d2e3e6ad52cfce8807a845d15e22111a8" - integrity sha512-FpuRtniD/AY6sXByma2Wr0TXvXJ4nA/2/04VPlfpmUDPOpOY264x+ILiwnrk/k4RINgDAyFZByxqPUbSQ5YE7g== dependencies: contains-path "^0.1.0" debug "^2.6.8" @@ -2375,7 +2062,6 @@ eslint-plugin-import@^2.14.0: eslint-plugin-node@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-8.0.0.tgz#fb9e8911f4543514f154bb6a5924b599aa645568" - integrity sha512-Y+ln8iQ52scz9+rSPnSWRaAxeWaoJZ4wIveDR0vLHkuSZGe44Vk1J4HX7WvEP5Cm+iXPE8ixo7OM7gAO3/OKpQ== dependencies: eslint-plugin-es "^1.3.1" eslint-utils "^1.3.1" @@ -2387,17 +2073,14 @@ eslint-plugin-node@^8.0.0: eslint-plugin-promise@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.0.1.tgz#2d074b653f35a23d1ba89d8e976a985117d1c6a2" - integrity sha512-Si16O0+Hqz1gDHsys6RtFRrW7cCTB6P7p3OJmKp3Y3dxpQE2qwOA7d3xnV+0mBmrPoi0RBnxlCKvqu70te6wjg== eslint-plugin-standard@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-4.0.0.tgz#f845b45109c99cd90e77796940a344546c8f6b5c" - integrity sha512-OwxJkR6TQiYMmt1EsNRMe5qG3GsbjlcOhbGUBY4LtavF9DsLaTcoR+j2Tdjqi23oUwKNUqX7qcn5fPStafMdlA== eslint-scope@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.0.tgz#50bf3071e9338bcdc43331794a0cb533f0136172" - integrity sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA== dependencies: esrecurse "^4.1.0" estraverse "^4.1.1" @@ -2405,17 +2088,14 @@ eslint-scope@^4.0.0: eslint-utils@^1.3.0, eslint-utils@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.3.1.tgz#9a851ba89ee7c460346f97cf8939c7298827e512" - integrity sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q== eslint-visitor-keys@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" - integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ== eslint@^5.10.0: version "5.11.1" resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.11.1.tgz#8deda83db9f354bf9d3f53f9677af7e0e13eadda" - integrity sha512-gOKhM8JwlFOc2acbOrkYR05NW8M6DCMSvfcJiBB5NDxRE1gv8kbvxKaC9u69e6ZGEMWXcswA/7eKR229cEIpvg== dependencies: "@babel/code-frame" "^7.0.0" ajv "^6.5.3" @@ -2458,7 +2138,6 @@ eslint@^5.10.0: espree@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/espree/-/espree-5.0.0.tgz#fc7f984b62b36a0f543b13fb9cd7b9f4a7f5b65c" - integrity sha512-1MpUfwsdS9MMoN7ZXqAr9e9UKdVHDcvrJpyx7mm1WuQlx/ygErEQBzgi5Nh5qBHIoYweprhtMkTCb9GhcAIcsA== dependencies: acorn "^6.0.2" acorn-jsx "^5.0.0" @@ -2467,51 +2146,42 @@ espree@^5.0.0: esprima@2.7.x, esprima@^2.7.1: version "2.7.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" - integrity sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE= esprima@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== esquery@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708" - integrity sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA== dependencies: estraverse "^4.0.0" esrecurse@^4.1.0: version "4.2.1" resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" - integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== dependencies: estraverse "^4.1.0" estraverse@^1.9.1: version "1.9.3" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44" - integrity sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q= estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: version "4.2.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" - integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" - integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs= etag@~1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= eth-block-tracker@^2.2.2: version "2.3.1" resolved "https://registry.yarnpkg.com/eth-block-tracker/-/eth-block-tracker-2.3.1.tgz#ab6d177e5b50128fa06d7ae9e0489c7484bac95e" - integrity sha512-NamWuMBIl8kmkJFVj8WzGatySTzQPQag4Xr677yFxdVtIxACFbL/dQowk0MzEqIKk93U1TwY3MjVU6mOcwZnKA== dependencies: async-eventemitter ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c eth-query "^2.1.0" @@ -2525,7 +2195,6 @@ eth-block-tracker@^2.2.2: 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== dependencies: bn.js "^4.11.6" elliptic "^6.4.0" @@ -2538,7 +2207,6 @@ eth-lib@0.1.27, eth-lib@^0.1.26: 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: bn.js "^4.11.6" elliptic "^6.4.0" @@ -2547,7 +2215,6 @@ eth-lib@0.2.7: eth-lightwallet@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/eth-lightwallet/-/eth-lightwallet-3.0.1.tgz#297022932aa568f4e4eb0873bff257f5e5b78709" - integrity sha512-79vVCETy+4l1b6wuOWwjqPW3Bom5ZK46BgkUNwaXhiMG1rrMRHjpjYEWMqH0JHeCzOzB4HBIFz7eK1/4s6w5nA== dependencies: bitcore-lib "^0.15.0" bitcore-mnemonic "^1.5.0" @@ -2564,7 +2231,6 @@ eth-lightwallet@^3.0.1: eth-query@^2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/eth-query/-/eth-query-2.1.2.tgz#d6741d9000106b51510c72db92d6365456a6da5e" - integrity sha1-1nQdkAAQa1FRDHLbktY2VFam2l4= dependencies: json-rpc-random-id "^1.0.0" xtend "^4.0.1" @@ -2572,7 +2238,6 @@ eth-query@^2.1.0: eth-sig-util@^1.4.2: version "1.4.2" resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-1.4.2.tgz#8d958202c7edbaae839707fba6f09ff327606210" - integrity sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA= dependencies: ethereumjs-abi "git+https://github.com/ethereumjs/ethereumjs-abi.git" ethereumjs-util "^5.1.1" @@ -2580,7 +2245,6 @@ eth-sig-util@^1.4.2: ethereum-bridge@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/ethereum-bridge/-/ethereum-bridge-0.6.1.tgz#53c93ed7c0e21752a91e5f089a5997e1d6fea228" - integrity sha512-yDTivI85618BoLI71yNRzW6iVcVN2rjnviCIzs0QOCOENj4XpYQhMDGhdqDi8XWDdzTd0Ja/Canuuh3vfE2IcA== dependencies: async "^2.4.1" borc "^2.0.2" @@ -2611,17 +2275,14 @@ ethereum-bridge@^0.6.1: ethereum-common@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/ethereum-common/-/ethereum-common-0.2.0.tgz#13bf966131cce1eeade62a1b434249bb4cb120ca" - integrity sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA== 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-abi@0.6.4: version "0.6.4" resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.4.tgz#9ba1bb056492d00c27279f6eccd4d58275912c1a" - integrity sha1-m6G7BWSS0AwnJ59uzNTVgnWRLBo= dependencies: bn.js "^4.10.0" ethereumjs-util "^4.3.0" @@ -2636,7 +2297,6 @@ ethereumjs-abi@^0.6.5, "ethereumjs-abi@git+https://github.com/ethereumjs/ethereu ethereumjs-account@^2.0.3: version "2.0.5" resolved "https://registry.yarnpkg.com/ethereumjs-account/-/ethereumjs-account-2.0.5.tgz#eeafc62de544cb07b0ee44b10f572c9c49e00a84" - integrity sha512-bgDojnXGjhMwo6eXQC0bY6UK2liSFUSMwwylOmQvZbSl/D7NXQ3+vrGO46ZeOgjGfxXmgIeVNDIiHw7fNZM4VA== dependencies: ethereumjs-util "^5.0.0" rlp "^2.0.0" @@ -2645,7 +2305,6 @@ ethereumjs-account@^2.0.3: ethereumjs-block@^1.2.2: version "1.7.1" resolved "https://registry.yarnpkg.com/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz#78b88e6cc56de29a6b4884ee75379b6860333c3f" - integrity sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg== dependencies: async "^2.0.1" ethereum-common "0.2.0" @@ -2656,7 +2315,6 @@ ethereumjs-block@^1.2.2: ethereumjs-block@~2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/ethereumjs-block/-/ethereumjs-block-2.1.0.tgz#71d1b19e18061f14cf6371bf34ba31a359931360" - integrity sha512-ip+x4/7hUInX+TQfhEKsQh9MJK1Dbjp4AuPjf1UdX3udAV4beYD4EMCNIPzBLCsGS8WQZYXLpo83tVTISYNpow== dependencies: async "^2.0.1" ethereumjs-common "^0.6.0" @@ -2667,19 +2325,16 @@ ethereumjs-block@~2.1.0: ethereumjs-common@^0.6.0: version "0.6.1" resolved "https://registry.yarnpkg.com/ethereumjs-common/-/ethereumjs-common-0.6.1.tgz#ec98edf315a7f107afb6acc48e937a8266979fae" - integrity sha512-4jOrfDu9qOBTTGGb3zrfT1tE1Hyc6a8LJpEk0Vk9AYlLkBY7crjVICyJpRvjNI+KLDMpMITMw3eWVZOLMtZdhw== ethereumjs-testrpc-sc@6.1.6: version "6.1.6" resolved "https://registry.yarnpkg.com/ethereumjs-testrpc-sc/-/ethereumjs-testrpc-sc-6.1.6.tgz#290595380b5182814564d4aa38f35b7788aab070" - integrity sha512-iv2qiGBFgk9mn5Nq2enX8dG5WQ7Lk+FCqpnxfPfH4Ns8KLPwttmNOy264nh3SXDJJvcQwz/XnlLteDQVILotbg== dependencies: source-map-support "^0.5.3" ethereumjs-tx@^1.2.0, ethereumjs-tx@^1.2.2, ethereumjs-tx@^1.3.1, ethereumjs-tx@^1.3.3, ethereumjs-tx@^1.3.4: version "1.3.7" resolved "https://registry.yarnpkg.com/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz#88323a2d875b10549b8347e09f4862b546f3d89a" - integrity sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA== dependencies: ethereum-common "^0.0.18" ethereumjs-util "^5.0.0" @@ -2687,7 +2342,6 @@ ethereumjs-tx@^1.2.0, ethereumjs-tx@^1.2.2, ethereumjs-tx@^1.3.1, ethereumjs-tx@ ethereumjs-util@^4.3.0: 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" @@ -2698,7 +2352,6 @@ ethereumjs-util@^4.3.0: ethereumjs-util@^5.0.0, ethereumjs-util@^5.0.1, ethereumjs-util@^5.1.1, ethereumjs-util@^5.1.3, ethereumjs-util@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz#3e0c0d1741471acf1036052d048623dee54ad642" - integrity sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA== dependencies: bn.js "^4.11.0" create-hash "^1.1.2" @@ -2711,7 +2364,6 @@ ethereumjs-util@^5.0.0, ethereumjs-util@^5.0.1, ethereumjs-util@^5.1.1, ethereum 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== dependencies: bn.js "^4.11.0" create-hash "^1.1.2" @@ -2724,7 +2376,6 @@ ethereumjs-util@^6.0.0: ethereumjs-vm@^2.0.2: version "2.5.0" resolved "https://registry.yarnpkg.com/ethereumjs-vm/-/ethereumjs-vm-2.5.0.tgz#71dde54a093bd813c9defdc6d45ceb8fcca2f603" - integrity sha512-Cp1do4J2FIJFnbofqLsKb/aoZKG+Q8NBIbTa1qwZPQkQxzeR3DZVpFk/VbE1EUO6Ha0kSClJ1jzfj07z3cScSQ== dependencies: async "^2.1.2" async-eventemitter "^0.2.2" @@ -2741,7 +2392,6 @@ ethereumjs-vm@^2.0.2: ethereumjs-wallet@^0.6.0: version "0.6.3" resolved "https://registry.yarnpkg.com/ethereumjs-wallet/-/ethereumjs-wallet-0.6.3.tgz#b0eae6f327637c2aeb9ccb9047b982ac542e6ab1" - integrity sha512-qiXPiZOsStem+Dj/CQHbn5qex+FVkuPmGH7SvSnA9F3tdRDt8dLMyvIj3+U05QzVZNPYh4HXEdnzoYI4dZkr9w== dependencies: aes-js "^3.1.1" bs58check "^2.1.2" @@ -2756,7 +2406,6 @@ ethereumjs-wallet@^0.6.0: ethers@^4.0.20: version "4.0.20" resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.20.tgz#2b072b283bb19f4870daf42cf5593e5375697504" - integrity sha512-1XEejqGYWlcXoVCPFPRfJmf1QQGHW7TNfprtdT1Up66nSuqWE/lYSLgvTNvH/nbSTMRFZqM6ANAbv/1+eUDb7g== dependencies: "@types/node" "^10.3.2" aes-js "3.0.0" @@ -2772,7 +2421,6 @@ ethers@^4.0.20: 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= dependencies: bn.js "4.11.6" number-to-bn "1.7.0" @@ -2780,7 +2428,6 @@ ethjs-unit@0.1.6: ethjs-util@^0.1.3, 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== dependencies: is-hex-prefixed "1.0.0" strip-hex-prefix "1.0.0" @@ -2788,7 +2435,6 @@ ethjs-util@^0.1.3, ethjs-util@^0.1.6: event-emitter@^0.3.5: version "0.3.5" resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" - integrity sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk= dependencies: d "1" es5-ext "~0.10.14" @@ -2796,17 +2442,14 @@ event-emitter@^0.3.5: eventemitter3@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-1.1.1.tgz#47786bdaa087caf7b1b75e73abc5c7d540158cd0" - integrity sha1-R3hr2qCHyvext15zq8XH1UAVjNA= events@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/events/-/events-3.0.0.tgz#9a0a0dfaf62893d92b875b8f2698ca4114973e88" - integrity sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA== evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" - integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== dependencies: md5.js "^1.3.4" safe-buffer "^5.1.1" @@ -2814,7 +2457,6 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: execa@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" - integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c= dependencies: cross-spawn "^5.0.1" get-stream "^3.0.0" @@ -2827,14 +2469,12 @@ execa@^0.7.0: expand-brackets@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" - integrity sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s= dependencies: is-posix-bracket "^0.1.0" expand-brackets@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" - integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= dependencies: debug "^2.3.3" define-property "^0.2.5" @@ -2847,14 +2487,12 @@ expand-brackets@^2.1.4: expand-range@^1.8.1: version "1.8.2" resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" - integrity sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc= dependencies: fill-range "^2.1.0" express@^4.14.0: version "4.16.4" resolved "https://registry.yarnpkg.com/express/-/express-4.16.4.tgz#fddef61926109e24c515ea97fd2f1bdbf62df12e" - integrity sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg== dependencies: accepts "~1.3.5" array-flatten "1.1.1" @@ -2890,14 +2528,12 @@ express@^4.14.0: extend-shallow@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" - integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= dependencies: is-extendable "^0.1.0" extend-shallow@^3.0.0, extend-shallow@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" - integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= dependencies: assign-symbols "^1.0.0" is-extendable "^1.0.1" @@ -2905,19 +2541,16 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: extend@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== extendr@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/extendr/-/extendr-2.1.0.tgz#301aa0bbea565f4d2dc8f570f2a22611a8527b56" - integrity sha1-MBqgu+pWX00tyPVw8qImEahSe1Y= dependencies: typechecker "~2.0.1" external-editor@^3.0.0: version "3.0.3" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.3.tgz#5866db29a97826dbe4bf3afd24070ead9ea43a27" - integrity sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA== dependencies: chardet "^0.7.0" iconv-lite "^0.4.24" @@ -2926,14 +2559,12 @@ external-editor@^3.0.0: extglob@^0.3.1: version "0.3.2" resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" - integrity sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE= dependencies: is-extglob "^1.0.0" extglob@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" - integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== dependencies: array-unique "^0.3.2" define-property "^1.0.0" @@ -2947,77 +2578,64 @@ extglob@^2.0.4: extract-opts@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/extract-opts/-/extract-opts-2.2.0.tgz#1fa28eba7352c6db480f885ceb71a46810be6d7d" - integrity sha1-H6KOunNSxttID4hc63GkaBC+bX0= dependencies: typechecker "~2.0.1" extsprintf@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= extsprintf@^1.2.0: version "1.4.0" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= eyes@0.1.x: version "0.1.8" resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0" - integrity sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A= 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@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614" - integrity sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ= 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" - integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= fast-json-stable-stringify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" - integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= fast-levenshtein@~2.0.4: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= fd-slicer@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" - integrity sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4= dependencies: pend "~1.2.0" fetch-ponyfill@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/fetch-ponyfill/-/fetch-ponyfill-4.1.0.tgz#ae3ce5f732c645eab87e4ae8793414709b239893" - integrity sha1-rjzl9zLGReq4fkroeTQUcJsjmJM= dependencies: node-fetch "~1.7.1" figures@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" - integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= dependencies: escape-string-regexp "^1.0.5" file-entry-cache@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" - integrity sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E= dependencies: flat-cache "^1.2.1" object-assign "^4.0.1" @@ -3025,32 +2643,26 @@ file-entry-cache@^2.0.0: file-type@^3.8.0: version "3.9.0" resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9" - integrity sha1-JXoHg4TR24CHvESdEH1SpSZyuek= file-type@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/file-type/-/file-type-5.2.0.tgz#2ddbea7c73ffe36368dfae49dc338c058c2b8ad6" - integrity sha1-LdvqfHP/42No365J3DOMBYwritY= file-type@^6.1.0: version "6.2.0" resolved "https://registry.yarnpkg.com/file-type/-/file-type-6.2.0.tgz#e50cd75d356ffed4e306dc4f5bcf52a79903a919" - integrity sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg== 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-regex@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" - integrity sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY= fill-range@^2.1.0: version "2.2.4" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565" - integrity sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q== dependencies: is-number "^2.1.0" isobject "^2.0.0" @@ -3061,7 +2673,6 @@ fill-range@^2.1.0: fill-range@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" - integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= dependencies: extend-shallow "^2.0.1" is-number "^3.0.0" @@ -3071,7 +2682,6 @@ fill-range@^4.0.0: finalhandler@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105" - integrity sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg== dependencies: debug "2.6.9" encodeurl "~1.0.2" @@ -3084,7 +2694,6 @@ finalhandler@1.1.1: find-up@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" - integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= dependencies: path-exists "^2.0.0" pinkie-promise "^2.0.0" @@ -3092,14 +2701,12 @@ find-up@^1.0.0: find-up@^2.0.0, find-up@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= dependencies: locate-path "^2.0.0" flat-cache@^1.2.1: version "1.3.4" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.4.tgz#2c2ef77525cc2929007dfffa1dd314aa9c9dee6f" - integrity sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg== dependencies: circular-json "^0.3.1" graceful-fs "^4.1.2" @@ -3109,31 +2716,26 @@ flat-cache@^1.2.1: for-each@^0.3.2, for-each@~0.3.3: version "0.3.3" resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" - integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== dependencies: is-callable "^1.1.3" for-in@^1.0.1, for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= for-own@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" - integrity sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4= dependencies: for-in "^1.0.1" forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= form-data@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== dependencies: asynckit "^0.4.0" combined-stream "^1.0.6" @@ -3142,29 +2744,24 @@ form-data@~2.3.2: forwarded@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" - integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= fragment-cache@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" - integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= dependencies: map-cache "^0.2.2" fresh@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= fs-constants@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" - integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== fs-extra@^0.30.0: version "0.30.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0" - integrity sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A= dependencies: graceful-fs "^4.1.2" jsonfile "^2.1.0" @@ -3175,7 +2772,6 @@ fs-extra@^0.30.0: 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" @@ -3183,7 +2779,6 @@ fs-extra@^2.0.0, fs-extra@^2.1.2: 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" @@ -3192,14 +2787,12 @@ fs-extra@^7.0.1: fs-minipass@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" - integrity sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ== 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" @@ -3209,17 +2802,14 @@ fs-promise@^2.0.0: fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= fs@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/fs/-/fs-0.0.2.tgz#e1f244ef3933c1b2a64bd4799136060d0f5914f8" - integrity sha1-4fJE7zkzwbKmS9R5kTYGDQ9ZFPg= fsevents@^1.0.0: version "1.2.4" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426" - integrity sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg== dependencies: nan "^2.9.2" node-pre-gyp "^0.10.0" @@ -3227,7 +2817,6 @@ fsevents@^1.0.0: fstream@^1.0.2, fstream@^1.0.8: version "1.0.11" resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" - integrity sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE= dependencies: graceful-fs "^4.1.2" inherits "~2.0.0" @@ -3237,17 +2826,14 @@ fstream@^1.0.2, fstream@^1.0.8: function-bind@^1.0.2, function-bind@^1.1.1, 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: 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.2.5: version "6.2.5" resolved "https://registry.yarnpkg.com/ganache-cli/-/ganache-cli-6.2.5.tgz#efda5115fa3a0c62d7f5729fdd78da70ca55b1ad" - integrity sha512-E4SP8QNeuc2N/ojFoCK+08OYHX8yrtGeFtipZmJPPTQ6U8Hmq3JcbXZDxQfChPQUY5mtbRSwptJa4EtiQyJjAQ== dependencies: bn.js "4.11.8" source-map-support "0.5.9" @@ -3256,7 +2842,6 @@ ganache-cli@^6.2.5: gauge@~2.7.3: version "2.7.4" resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= dependencies: aproba "^1.0.3" console-control-strings "^1.0.0" @@ -3270,12 +2855,10 @@ gauge@~2.7.3: get-caller-file@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" - integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== get-stream@^2.2.0: version "2.3.1" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de" - integrity sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4= dependencies: object-assign "^4.0.1" pinkie-promise "^2.0.0" @@ -3283,24 +2866,20 @@ get-stream@^2.2.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-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" - integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= getpass@^0.1.1: version "0.1.7" resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= dependencies: assert-plus "^1.0.0" glob-base@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" - integrity sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q= dependencies: glob-parent "^2.0.0" is-glob "^2.0.0" @@ -3308,14 +2887,12 @@ glob-base@^0.3.0: glob-parent@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" - integrity sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg= dependencies: is-glob "^2.0.0" glob@7.1.2: version "7.1.2" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" - integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -3327,7 +2904,6 @@ glob@7.1.2: glob@^5.0.15: version "5.0.15" resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" - integrity sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E= dependencies: inflight "^1.0.4" inherits "2" @@ -3338,7 +2914,6 @@ glob@^5.0.15: glob@^7.0.0, glob@^7.1.2, glob@^7.1.3, glob@~7.1.2: version "7.1.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" - integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -3350,7 +2925,6 @@ glob@^7.0.0, glob@^7.1.2, glob@^7.1.3, glob@~7.1.2: glob@~6.0.4: version "6.0.4" resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22" - integrity sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI= dependencies: inflight "^1.0.4" inherits "2" @@ -3361,7 +2935,6 @@ glob@~6.0.4: global@~4.3.0: version "4.3.2" resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f" - integrity sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8= dependencies: min-document "^2.19.0" process "~0.5.1" @@ -3369,17 +2942,14 @@ global@~4.3.0: globals@^11.7.0: version "11.9.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.9.0.tgz#bde236808e987f290768a93d065060d78e6ab249" - integrity sha512-5cJVtyXWH8PiJPVLZzzoIizXx944O4OmRro5MWKx5fT4MgcN7OfaMutPeaTdJCCURwbWdhhcCWcKIffPnmTzBg== globals@^9.18.0: version "9.18.0" resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" - integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ== 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== dependencies: decompress-response "^3.2.0" duplexer3 "^0.1.4" @@ -3399,27 +2969,22 @@ got@7.1.0, got@^7.1.0: graceful-fs@*, graceful-fs@^4.1.10, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9: version "4.1.15" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" - integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== "graceful-readlink@>= 1.0.0": version "1.0.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, "growl@~> 1.10.0": version "1.10.5" resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" - integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== handlebars@^4.0.1: version "4.0.12" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.12.tgz#2c15c8a96d46da5e266700518ba8cb8d919d5bc5" - integrity sha512-RhmTekP+FZL+XNhwS1Wf+bTTZpdLougwt5pcgA1tuz6Jcx0fpH/7z0qd71RKnZHBCxIRBHfBOnio4gViPemNzA== dependencies: async "^2.5.0" optimist "^0.6.1" @@ -3430,12 +2995,10 @@ handlebars@^4.0.1: har-schema@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= har-validator@~5.1.0: version "5.1.3" resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" - integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== dependencies: ajv "^6.5.5" har-schema "^2.0.0" @@ -3443,51 +3006,42 @@ har-validator@~5.1.0: has-ansi@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" - integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= dependencies: ansi-regex "^2.0.0" has-flag@^1.0.0: version "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" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= has-symbol-support-x@^1.4.1: version "1.4.2" resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" - integrity sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw== has-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" - integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q= has-to-string-tag-x@^1.2.0: version "1.4.1" resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" - integrity sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw== dependencies: has-symbol-support-x "^1.4.1" has-unicode@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= has-value@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" - integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= dependencies: get-value "^2.0.3" has-values "^0.1.4" @@ -3496,7 +3050,6 @@ has-value@^0.3.1: has-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" - integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= dependencies: get-value "^2.0.6" has-values "^1.0.0" @@ -3505,12 +3058,10 @@ has-value@^1.0.0: has-values@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" - integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= has-values@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" - integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= dependencies: is-number "^3.0.0" kind-of "^4.0.0" @@ -3518,14 +3069,12 @@ has-values@^1.0.0: has@^1.0.1, has@^1.0.3, has@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== dependencies: function-bind "^1.1.1" hash-base@^3.0.0: version "3.0.4" resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" - integrity sha1-X8hoaEfs1zSZQDMZprCj8/auSRg= dependencies: inherits "^2.0.1" safe-buffer "^5.0.1" @@ -3533,7 +3082,6 @@ hash-base@^3.0.0: hash.js@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.3.tgz#340dedbe6290187151c1ea1d777a3448935df846" - integrity sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA== dependencies: inherits "^2.0.3" minimalistic-assert "^1.0.0" @@ -3541,7 +3089,6 @@ hash.js@1.1.3: hash.js@^1.0.0, hash.js@^1.0.3: version "1.1.7" resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" - integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== dependencies: inherits "^2.0.3" minimalistic-assert "^1.0.1" @@ -3549,7 +3096,6 @@ hash.js@^1.0.0, hash.js@^1.0.3: hdkey@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/hdkey/-/hdkey-1.1.0.tgz#e74e7b01d2c47f797fa65d1d839adb7a44639f29" - integrity sha512-E7aU8pNlWUJbXGjTz/+lKf1LkMcA3hUrC5ZleeizrmLSd++kvf8mSOe3q8CmBDA9j4hdfXO5iY6hGiTUCOV2jQ== dependencies: coinstring "^2.0.0" safe-buffer "^5.1.1" @@ -3558,12 +3104,10 @@ hdkey@^1.1.0: he@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" - integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0= hmac-drbg@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" - integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= dependencies: hash.js "^1.0.3" minimalistic-assert "^1.0.0" @@ -3572,7 +3116,6 @@ hmac-drbg@^1.0.0: home-or-tmp@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" - integrity sha1-42w/LSyufXRqhX440Y1fMqeILbg= dependencies: os-homedir "^1.0.0" os-tmpdir "^1.0.1" @@ -3580,12 +3123,10 @@ home-or-tmp@^2.0.0: hosted-git-info@^2.1.4: version "2.7.1" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" - integrity sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w== http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3: version "1.6.3" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" - integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= dependencies: depd "~1.1.2" inherits "2.0.3" @@ -3595,12 +3136,10 @@ http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3: 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-signature@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= dependencies: assert-plus "^1.0.0" jsprim "^1.2.2" @@ -3609,7 +3148,6 @@ http-signature@~1.2.0: i18n@^0.8.3: version "0.8.3" resolved "https://registry.yarnpkg.com/i18n/-/i18n-0.8.3.tgz#2d8cf1c24722602c2041d01ba6ae5eaa51388f0e" - integrity sha1-LYzxwkciYCwgQdAbpq5eqlE4jw4= dependencies: debug "*" make-plural "^3.0.3" @@ -3621,48 +3159,40 @@ i18n@^0.8.3: i@0.3.x: version "0.3.6" resolved "https://registry.yarnpkg.com/i/-/i-0.3.6.tgz#d96c92732076f072711b6b10fd7d4f65ad8ee23d" - integrity sha1-2WyScyB28HJxG2sQ/X1PZa2O4j0= iconv-lite@0.4.23: version "0.4.23" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" - integrity sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA== dependencies: safer-buffer ">= 2.1.2 < 3" iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== dependencies: safer-buffer ">= 2.1.2 < 3" ieee754@^1.1.4, ieee754@^1.1.8: version "1.1.12" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.12.tgz#50bf24e5b9c8bb98af4964c941cdb0918da7b60b" - integrity sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA== ignore-walk@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" - integrity sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ== dependencies: minimatch "^3.0.4" ignore@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" - integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== ignore@^5.0.2: version "5.0.4" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.0.4.tgz#33168af4a21e99b00c5d41cbadb6a6cb49903a45" - integrity sha512-WLsTMEhsQuXpCiG173+f3aymI43SXa+fB1rSfbzyP4GkPP+ZFVuO0/3sFUGNBtifisPeDcl/uD/Y2NxZ7xFq4g== ignorefs@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/ignorefs/-/ignorefs-1.2.0.tgz#da59fb858976e4a5e43702ccd1f282fdbc9e5756" - integrity sha1-2ln7hYl25KXkNwLM0fKC/byeV1Y= dependencies: editions "^1.3.3" ignorepatterns "^1.1.0" @@ -3670,22 +3200,18 @@ ignorefs@^1.0.0: ignorepatterns@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/ignorepatterns/-/ignorepatterns-1.1.0.tgz#ac8f436f2239b5dfb66d5f0d3a904a87ac67cc5e" - integrity sha1-rI9DbyI5td+2bV8NOpBKh6xnzF4= immediate@^3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.2.3.tgz#d140fa8f614659bd6541233097ddaac25cdd991c" - integrity sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw= imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= dependencies: once "^1.3.0" wrappy "1" @@ -3693,22 +3219,18 @@ inflight@^1.0.4: inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= inherits@=2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" - integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= ini@~1.3.0: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" - integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== inquirer@^6.1.0: version "6.2.1" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.1.tgz#9943fc4882161bdb0b0c9276769c75b32dbfcd52" - integrity sha512-088kl3DRT2dLU5riVMKKr1DlImd6X7smDhpXUCkJDCKvTEJeRiXh0G132HG9u5a+6Ylw9plFRY7RuTnwohYSpg== dependencies: ansi-escapes "^3.0.0" chalk "^2.0.0" @@ -3727,91 +3249,76 @@ inquirer@^6.1.0: interpret@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296" - integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw== invariant@^2.2.2: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" - integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== dependencies: loose-envify "^1.0.0" invert-kv@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" - integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= ipaddr.js@1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.8.0.tgz#eaa33d6ddd7ace8f7f6fe0c9ca0440e706738b1e" - integrity sha1-6qM9bd16zo9/b+DJygRA5wZzix4= is-accessor-descriptor@^0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" - integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= dependencies: kind-of "^3.0.2" is-accessor-descriptor@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" - integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== dependencies: kind-of "^6.0.0" is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= is-binary-path@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" - integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= dependencies: binary-extensions "^1.0.0" is-buffer@^1.1.5, is-buffer@~1.1.1: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== is-builtin-module@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" - integrity sha1-VAVy0096wxGfj3bDDLwbHgN6/74= dependencies: builtin-modules "^1.0.0" is-callable@^1.1.3, is-callable@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" - integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== is-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" - integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= dependencies: kind-of "^3.0.2" is-data-descriptor@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" - integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== dependencies: kind-of "^6.0.0" is-date-object@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" - integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY= is-descriptor@^0.1.0: version "0.1.6" resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" - integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== dependencies: is-accessor-descriptor "^0.1.6" is-data-descriptor "^0.1.4" @@ -3820,7 +3327,6 @@ is-descriptor@^0.1.0: is-descriptor@^1.0.0, is-descriptor@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" - integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== dependencies: is-accessor-descriptor "^1.0.0" is-data-descriptor "^1.0.0" @@ -3829,211 +3335,174 @@ is-descriptor@^1.0.0, is-descriptor@^1.0.2: is-dotfile@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" - integrity sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE= is-equal-shallow@^0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" - integrity sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ= dependencies: is-primitive "^2.0.0" is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= is-extendable@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" - integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== dependencies: is-plain-object "^2.0.4" is-extglob@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" - integrity sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA= is-finite@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" - integrity sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko= dependencies: number-is-nan "^1.0.0" is-fn@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-fn/-/is-fn-1.0.0.tgz#9543d5de7bcf5b08a22ec8a20bae6e286d510d8c" - integrity sha1-lUPV3nvPWwiiLsiiC65uKG1RDYw= is-fullwidth-code-point@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= dependencies: number-is-nan "^1.0.0" is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= is-function@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.1.tgz#12cfb98b65b57dd3d193a3121f5f6e2f437602b5" - integrity sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU= is-glob@^2.0.0, is-glob@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" - integrity sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM= dependencies: is-extglob "^1.0.0" is-hex-prefixed@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz#7d8d37e6ad77e5d127148913c573e082d777f554" - integrity sha1-fY035q135dEnFIkTxXPggtd39VQ= is-nan@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/is-nan/-/is-nan-1.2.1.tgz#9faf65b6fb6db24b7f5c0628475ea71f988401e2" - integrity sha1-n69ltvttskt/XAYoR16nH5iEAeI= dependencies: define-properties "^1.1.1" 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" - integrity sha1-q5124dtM7VHjXeDHLr7PCfc0zeg= is-number@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" - integrity sha1-Afy7s5NGOlSPL0ZszhbezknbkI8= dependencies: kind-of "^3.0.2" is-number@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" - integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= dependencies: kind-of "^3.0.2" is-number@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" - integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== is-object@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" - integrity sha1-iVJojF7C/9awPsyF52ngKQMINHA= 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= is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" - integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== dependencies: isobject "^3.0.1" is-posix-bracket@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" - integrity sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q= is-primitive@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" - integrity sha1-IHurkWOEmcB7Kt8kCkGochADRXU= is-promise@^2.1, is-promise@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" - integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= is-regex@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" - integrity sha1-VRdIm1RwkbCTDglWVM7SXul+lJE= dependencies: has "^1.0.1" is-retry-allowed@^1.0.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= is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= is-symbol@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" - integrity sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw== dependencies: has-symbols "^1.0.0" is-typedarray@^1.0.0, is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= is-utf8@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" - integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" - integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== 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, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= iso-url@~0.4.4: version "0.4.4" resolved "https://registry.yarnpkg.com/iso-url/-/iso-url-0.4.4.tgz#473a45569b6015da0c23f831010aeff69e3841e8" - integrity sha512-mR7/oy5PRtuWaynQ+QRNGbGNg7j3VLIc99DvrSfjmretWTS5zwC3p/D5iX7UvtFU1dBB501wibJIwUuNeo3Rfw== isobject@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= dependencies: isarray "1.0.0" isobject@^3.0.0, isobject@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= isomorphic-fetch@^2.2.0: version "2.2.1" resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" - integrity sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk= dependencies: node-fetch "^1.0.1" whatwg-fetch ">=0.10.0" @@ -4041,12 +3510,10 @@ isomorphic-fetch@^2.2.0: isstream@0.1.x, isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= istanbul@^0.4.5: version "0.4.5" resolved "https://registry.yarnpkg.com/istanbul/-/istanbul-0.4.5.tgz#65c7d73d4c4da84d4f3ac310b918fb0b8033733b" - integrity sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs= dependencies: abbrev "1.0.x" async "1.x" @@ -4066,7 +3533,6 @@ istanbul@^0.4.5: isurl@^1.0.0-alpha5: version "1.0.0" resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" - integrity sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w== dependencies: has-to-string-tag-x "^1.2.0" is-object "^1.0.1" @@ -4074,32 +3540,26 @@ isurl@^1.0.0-alpha5: js-sha3@0.5.7: version "0.5.7" resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.7.tgz#0d4ffd8002d5333aabaf4a23eed2f6374c9f28e7" - integrity sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc= js-sha3@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.6.1.tgz#5b89f77a7477679877f58c4a075240934b1f95c0" - integrity sha1-W4n3enR3Z5h39YxKB1JAk0sflcA= js-string-escape@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef" - integrity sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8= "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== js-tokens@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" - integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= js-yaml@3.x, js-yaml@^3.11.0, js-yaml@^3.12.0: version "3.12.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" - integrity sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A== dependencies: argparse "^1.0.7" esprima "^4.0.0" @@ -4107,22 +3567,18 @@ js-yaml@3.x, js-yaml@^3.11.0, js-yaml@^3.12.0: jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= jsesc@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" - integrity sha1-RsP+yMGJKxKwgz25vHYiF226s0s= jsesc@~0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" - integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= json-rpc-engine@^3.6.0: version "3.8.0" resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-3.8.0.tgz#9d4ff447241792e1d0a232f6ef927302bb0c62a9" - integrity sha512-6QNcvm2gFuuK4TKU1uwfH0Qd/cOSb9c1lls0gbnIhciktIUQJwz6NQNAW4B1KiGPenv7IKu97V222Yo1bNhGuA== dependencies: async "^2.0.1" babel-preset-env "^1.7.0" @@ -4134,82 +3590,68 @@ json-rpc-engine@^3.6.0: json-rpc-error@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/json-rpc-error/-/json-rpc-error-2.0.0.tgz#a7af9c202838b5e905c7250e547f1aff77258a02" - integrity sha1-p6+cICg4tekFxyUOVH8a/3cligI= dependencies: inherits "^2.0.1" json-rpc-random-id@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/json-rpc-random-id/-/json-rpc-random-id-1.0.1.tgz#ba49d96aded1444dbb8da3d203748acbbcdec8c8" - integrity sha1-uknZat7RRE27jaPSA3SKy7zeyMg= json-schema-traverse@^0.3.0: version "0.3.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" - integrity sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A= json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== json-schema@0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= json-stable-stringify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" - integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= dependencies: jsonify "~0.0.0" json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= json-text-sequence@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/json-text-sequence/-/json-text-sequence-0.1.1.tgz#a72f217dc4afc4629fff5feb304dc1bd51a2f3d2" - integrity sha1-py8hfcSvxGKf/1/rME3BvVGi89I= dependencies: delimit-stream "0.1.0" json5@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" - integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= jsonfile@^2.1.0: version "2.4.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" - integrity sha1-NzaitCi4e72gzIO1P6PWM6NcKug= optionalDependencies: graceful-fs "^4.1.6" jsonfile@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" - integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= optionalDependencies: graceful-fs "^4.1.6" jsonify@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" - integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= jsprim@^1.2.2: version "1.4.1" resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= dependencies: assert-plus "1.0.0" extsprintf "1.3.0" @@ -4219,7 +3661,6 @@ jsprim@^1.2.2: keccak@^1.0.2: version "1.4.0" resolved "https://registry.yarnpkg.com/keccak/-/keccak-1.4.0.tgz#572f8a6dbee8e7b3aa421550f9e6408ca2186f80" - integrity sha512-eZVaCpblK5formjPjeTBik7TAg+pqnDrMHIffSvi9Lh7PQgM1+hSzakUeZFCk9DVVG0dacZJuaz2ntwlzZUIBw== dependencies: bindings "^1.2.1" inherits "^2.0.3" @@ -4229,7 +3670,6 @@ keccak@^1.0.2: keccakjs@^0.2.0, keccakjs@^0.2.1: version "0.2.3" resolved "https://registry.yarnpkg.com/keccakjs/-/keccakjs-0.2.3.tgz#5e4e969ce39689a3861f445d7752ee3477f9fe72" - integrity sha512-BjLkNDcfaZ6l8HBG9tH0tpmDv3sS2mA7FNQxFHpCdzP3Gb2MVruXBSuoM66SnVxKJpAr5dKGdkHD+bDokt8fTg== dependencies: browserify-sha3 "^0.0.4" sha3 "^1.2.2" @@ -4237,69 +3677,58 @@ keccakjs@^0.2.0, keccakjs@^0.2.1: kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= dependencies: is-buffer "^1.1.5" kind-of@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" - integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= dependencies: is-buffer "^1.1.5" kind-of@^5.0.0: version "5.1.0" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" - integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== kind-of@^6.0.0, kind-of@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" - integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== klaw@^1.0.0: version "1.3.1" resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" - integrity sha1-QIhDO0azsbolnXh4XY6W9zugJDk= optionalDependencies: graceful-fs "^4.1.9" lcid@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" - integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= dependencies: invert-kv "^1.0.0" lcov-parse@^0.0.10: version "0.0.10" resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-0.0.10.tgz#1b0b8ff9ac9c7889250582b70b71315d9da6d9a3" - integrity sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM= 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@~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" @@ -4309,7 +3738,6 @@ level-iterator-stream@~1.3.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" @@ -4317,7 +3745,6 @@ level-ws@0.0.0: 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" @@ -4330,7 +3757,6 @@ levelup@^1.2.1: levn@^0.3.0, levn@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= dependencies: prelude-ls "~1.1.2" type-check "~0.3.2" @@ -4338,7 +3764,6 @@ levn@^0.3.0, levn@~0.3.0: load-json-file@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" - integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= dependencies: graceful-fs "^4.1.2" parse-json "^2.2.0" @@ -4349,7 +3774,6 @@ load-json-file@^1.0.0: load-json-file@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" - integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= dependencies: graceful-fs "^4.1.2" parse-json "^2.2.0" @@ -4359,7 +3783,6 @@ load-json-file@^2.0.0: locate-path@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= dependencies: p-locate "^2.0.0" path-exists "^3.0.0" @@ -4367,44 +3790,36 @@ locate-path@^2.0.0: lodash.assign@^4.0.3, lodash.assign@^4.0.6: version "4.2.0" resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" - integrity sha1-DZnzzNem0mHRm9rrkkUAXShYCOc= lodash@4.x, lodash@=4.17.11, lodash@^4.13.1, lodash@^4.14.2, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5: version "4.17.11" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" - integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== lodash@=4.17.4: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" - integrity sha1-eCA6TRwyiuHYbcpkYONptX9AVa4= log-driver@^1.2.7: version "1.2.7" resolved "https://registry.yarnpkg.com/log-driver/-/log-driver-1.2.7.tgz#63b95021f0702fedfa2c9bb0a24e7797d71871d8" - integrity sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg== long-timeout@0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/long-timeout/-/long-timeout-0.1.1.tgz#9721d788b47e0bcb5a24c2e2bee1a0da55dab514" - integrity sha1-lyHXiLR+C8taJMLivuGg2lXatRQ= loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== dependencies: js-tokens "^3.0.0 || ^4.0.0" lowercase-keys@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" - integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== lru-cache@^4.0.1: version "4.1.5" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" - integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== dependencies: pseudomap "^1.0.2" yallist "^2.1.2" @@ -4412,57 +3827,48 @@ lru-cache@^4.0.1: lru-queue@0.1: version "0.1.0" resolved "https://registry.yarnpkg.com/lru-queue/-/lru-queue-0.1.0.tgz#2738bd9f0d3cf4f84490c5736c48699ac632cda3" - integrity sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM= dependencies: es5-ext "~0.10.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: version "1.3.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" - integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== dependencies: pify "^3.0.0" make-plural@^3.0.3, make-plural@~3.0.3: version "3.0.6" resolved "https://registry.yarnpkg.com/make-plural/-/make-plural-3.0.6.tgz#2033a03bac290b8f3bb91258f65b9df7e8b01ca7" - integrity sha1-IDOgO6wpC487uRJY9lud9+iwHKc= optionalDependencies: minimist "^1.2.0" map-cache@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" - integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= map-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" - integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= dependencies: object-visit "^1.0.0" math-interval-parser@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/math-interval-parser/-/math-interval-parser-1.1.0.tgz#dbeda5b06b3249973c6df6170fde2386f0afd893" - integrity sha1-2+2lsGsySZc8bfYXD94jhvCv2JM= dependencies: xregexp "^2.0.0" math-random@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.1.tgz#8b3aac588b8a66e4975e3cdea67f7bb329601fac" - integrity sha1-izqsWIuKZuSXXjzepn97sylgH6w= md5.js@^1.3.4: version "1.3.5" resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" - integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== dependencies: hash-base "^3.0.0" inherits "^2.0.1" @@ -4471,7 +3877,6 @@ md5.js@^1.3.4: md5@^2.1.0: version "2.2.1" resolved "https://registry.yarnpkg.com/md5/-/md5-2.2.1.tgz#53ab38d5fe3c8891ba465329ea23fac0540126f9" - integrity sha1-U6s41f48iJG6RlMp6iP6wFQBJvk= dependencies: charenc "~0.0.1" crypt "~0.0.1" @@ -4480,19 +3885,16 @@ md5@^2.1.0: media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= mem@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" - integrity sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y= dependencies: mimic-fn "^1.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" @@ -4504,7 +3906,6 @@ memdown@^1.0.0: memoizee@^0.4.14: version "0.4.14" resolved "https://registry.yarnpkg.com/memoizee/-/memoizee-0.4.14.tgz#07a00f204699f9a95c2d9e77218271c7cd610d57" - integrity sha512-/SWFvWegAIYAO4NQMpcX+gcra0yEZu4OntmUdrBaWrJncxOqAziGFlHxc7yjKVK2uu3lpPW27P27wkR82wA8mg== dependencies: d "1" es5-ext "^0.10.45" @@ -4518,17 +3919,14 @@ memoizee@^0.4.14: memorystream@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" - integrity sha1-htcJCzDORV1j+64S3aUaR93K+bI= merge-descriptors@1.0.1: version "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: 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" @@ -4542,7 +3940,6 @@ merkle-patricia-tree@^2.1.2: messageformat@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/messageformat/-/messageformat-0.3.1.tgz#e58fff8245e9b3971799e5b43db58b3e9417f5a2" - integrity sha1-5Y//gkXps5cXmeW0PbWLPpQX9aI= dependencies: async "~1.5.2" glob "~6.0.4" @@ -4553,12 +3950,10 @@ messageformat@^0.3.1: methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= micromatch@^2.1.5: version "2.3.11" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" - integrity sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU= dependencies: arr-diff "^2.0.0" array-unique "^0.2.1" @@ -4577,7 +3972,6 @@ micromatch@^2.1.5: micromatch@^3.1.10: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" - integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== dependencies: arr-diff "^4.0.0" array-unique "^0.3.2" @@ -4596,7 +3990,6 @@ micromatch@^3.1.10: miller-rabin@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" - integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== dependencies: bn.js "^4.0.0" brorand "^1.0.1" @@ -4604,73 +3997,60 @@ miller-rabin@^4.0.0: mime-db@~1.37.0: version "1.37.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.37.0.tgz#0b6a0ce6fdbe9576e25f1f2d2fde8830dc0ad0d8" - integrity sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg== mime-types@^2.1.12, mime-types@^2.1.16, mime-types@~2.1.18, mime-types@~2.1.19: version "2.1.21" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.21.tgz#28995aa1ecb770742fe6ae7e58f9181c744b3f96" - integrity sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg== dependencies: mime-db "~1.37.0" mime@1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" - integrity sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ== mimic-fn@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" - integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== mimic-response@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" - integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== min-document@^2.19.0: version "2.19.0" resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" - integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU= dependencies: dom-walk "^0.1.0" minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" - integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= "minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.3, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== dependencies: brace-expansion "^1.1.7" minimist@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= minimist@^1.2.0, minimist@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= minimist@~0.0.1: version "0.0.10" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" - integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= minipass@^2.2.1, minipass@^2.3.4: version "2.3.5" resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" - integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA== dependencies: safe-buffer "^5.1.2" yallist "^3.0.0" @@ -4678,14 +4058,12 @@ minipass@^2.2.1, minipass@^2.3.4: minizlib@^1.1.1: version "1.2.1" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614" - integrity sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA== dependencies: minipass "^2.2.1" mixin-deep@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" - integrity sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ== dependencies: for-in "^1.0.2" is-extendable "^1.0.1" @@ -4693,21 +4071,18 @@ mixin-deep@^1.2.0: mkdirp-promise@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz#e9b8f68e552c68a9c1713b84883f7a1dd039b8a1" - integrity sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE= dependencies: mkdirp "*" mkdirp@*, mkdirp@0.5.1, mkdirp@0.5.x, mkdirp@0.x.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, 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-junit-reporter@^1.18.0: version "1.18.0" resolved "https://registry.yarnpkg.com/mocha-junit-reporter/-/mocha-junit-reporter-1.18.0.tgz#9209a3fba30025ae3ae5e6bfe7f9c5bc3c2e8ee2" - integrity sha512-y3XuqKa2+HRYtg0wYyhW/XsLm2Ps+pqf9HaTAt7+MVUAKFJaNAHOrNseTZo9KCxjfIbxUWwckP5qCDDPUmjSWA== dependencies: debug "^2.2.0" md5 "^2.1.0" @@ -4718,7 +4093,6 @@ mocha-junit-reporter@^1.18.0: mocha@^4.0.1, 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" @@ -4734,7 +4108,6 @@ mocha@^4.0.1, mocha@^4.1.0: mocha@^5.0.1: version "5.2.0" resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.2.0.tgz#6d8ae508f59167f940f2b5b3c4a612ae50c90ae6" - integrity sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ== dependencies: browser-stdout "1.3.1" commander "2.15.1" @@ -4751,39 +4124,32 @@ mocha@^5.0.1: mock-fs@^4.1.0: version "4.7.0" resolved "https://registry.yarnpkg.com/mock-fs/-/mock-fs-4.7.0.tgz#9f17e219cacb8094f4010e0a8c38589e2b33c299" - integrity sha512-WlQNtUlzMRpvLHf8dqeUmNqfdPjGY29KrJF50Ldb4AcL+vQeR8QH3wQcFMgrhTwb1gHjZn9xggho+84tBskLgA== moment-timezone@^0.5.23: version "0.5.23" resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.23.tgz#7cbb00db2c14c71b19303cb47b0fb0a6d8651463" - integrity sha512-WHFH85DkCfiNMDX5D3X7hpNH3/PUhjTGcD0U1SgfBGZxJ3qUmJh5FdvaFjcClxOvB3rzdfj4oRffbI38jEnC1w== dependencies: moment ">= 2.9.0" "moment@>= 2.9.0", moment@^2.22.2: version "2.23.0" resolved "https://registry.yarnpkg.com/moment/-/moment-2.23.0.tgz#759ea491ac97d54bac5ad776996e2a58cc1bc225" - integrity sha512-3IE39bHVqFbWWaPOMHZF98Q9c3LDKGTmypMiTM2QygGXXElkFWIH7GxfmlwmY2vwa+wmNsoYZmG2iusf1ZjJoA== 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= ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= ms@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" - integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== multihashes@^0.4.5: version "0.4.14" resolved "https://registry.yarnpkg.com/multihashes/-/multihashes-0.4.14.tgz#774db9a161f81a8a27dc60788f91248e020f5244" - integrity sha512-V/g/EIN6nALXfS/xHUAgtfPP3mn3sPIF/i9beuGKf25QXS2QZYCpeVJbDPEannkz32B2fihzCe2D/KMrbcmefg== dependencies: bs58 "^4.0.1" varint "^5.0.0" @@ -4791,27 +4157,22 @@ multihashes@^0.4.5: mustache@*: version "3.0.1" resolved "https://registry.yarnpkg.com/mustache/-/mustache-3.0.1.tgz#873855f23aa8a95b150fb96d9836edbc5a1d248a" - integrity sha512-jFI/4UVRsRYdUbuDTKT7KzfOp7FiD5WzYmmwNwXyUVypC0xjoTL78Fqc0jHUPIvvGD+6DQSPHIt1NE7D1ArsqA== mustache@^2.3.0: version "2.3.2" resolved "https://registry.yarnpkg.com/mustache/-/mustache-2.3.2.tgz#a6d4d9c3f91d13359ab889a812954f9230a3d0c5" - integrity sha512-KpMNwdQsYz3O/SBS1qJ/o3sqUJ5wSb8gb0pul8CO0S56b9Y2ALm8zCfsjPXsqGFfoNBkDwZuZIAjhsZI03gYVQ== mute-stream@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" - integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= mute-stream@~0.0.4: version "0.0.8" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" - integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== 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" @@ -4820,22 +4181,18 @@ mz@^2.6.0: nan@2.10.0: version "2.10.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f" - integrity sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA== nan@^2.0.8, nan@^2.11.0, nan@^2.2.1, nan@^2.3.3, nan@^2.9.2: version "2.12.1" resolved "https://registry.yarnpkg.com/nan/-/nan-2.12.1.tgz#7b1aa193e9aa86057e3c7bbd0ac448e770925552" - integrity sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw== nano-json-stream-parser@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz#0cc8f6d0e2b622b479c40d499c46d64b755c6f5f" - integrity sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18= nanomatch@^1.2.9: version "1.2.13" resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" - integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== dependencies: arr-diff "^4.0.0" array-unique "^0.3.2" @@ -4852,17 +4209,14 @@ nanomatch@^1.2.9: natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= ncp@1.0.x: version "1.0.1" resolved "https://registry.yarnpkg.com/ncp/-/ncp-1.0.1.tgz#d15367e5cb87432ba117d2bf80fdf45aecfb4246" - integrity sha1-0VNn5cuHQyuhF9K/gP30Wuz7QkY= needle@^2.2.1: version "2.2.4" resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.4.tgz#51931bff82533b1928b7d1d69e01f1b00ffd2a4e" - integrity sha512-HyoqEb4wr/rsoaIDfTH2aVL9nWtQqba2/HvMv+++m8u0dz808MaagKILxtfeSN7QU7nvbQ79zk3vYOJp9zsNEA== dependencies: debug "^2.1.2" iconv-lite "^0.4.4" @@ -4871,27 +4225,22 @@ needle@^2.2.1: negotiator@0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" - integrity sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk= next-tick@1: version "1.0.0" resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" - integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= nice-try@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" - integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== node-async-loop@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/node-async-loop/-/node-async-loop-1.2.2.tgz#c5870299bf6477b780c88b431aa5b37733f55a3d" - integrity sha1-xYcCmb9kd7eAyItDGqWzdzP1Wj0= node-cache@^4.1.1: version "4.2.0" resolved "https://registry.yarnpkg.com/node-cache/-/node-cache-4.2.0.tgz#48ac796a874e762582692004a376d26dfa875811" - integrity sha512-obRu6/f7S024ysheAjoYFEEBqqDWv4LOMNJEuO8vMeEw2AT4z+NCzO4hlc2lhI4vATzbCQv6kke9FVdx0RbCOw== dependencies: clone "2.x" lodash "4.x" @@ -4899,7 +4248,6 @@ node-cache@^4.1.1: node-fetch@^1.0.1, node-fetch@~1.7.1: version "1.7.3" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" - integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ== dependencies: encoding "^0.1.11" is-stream "^1.0.1" @@ -4907,7 +4255,6 @@ node-fetch@^1.0.1, node-fetch@~1.7.1: node-pre-gyp@^0.10.0: version "0.10.3" resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc" - integrity sha512-d1xFs+C/IPS8Id0qPTZ4bUT8wWryfR/OzzAFxweG+uLN85oPzyo2Iw6bVlLQ/JOdgNonXLCoRyqDzDWq4iw72A== dependencies: detect-libc "^1.0.2" mkdirp "^0.5.1" @@ -4923,7 +4270,6 @@ node-pre-gyp@^0.10.0: node-schedule@^1.2.3: version "1.3.1" resolved "https://registry.yarnpkg.com/node-schedule/-/node-schedule-1.3.1.tgz#6909dd644211bca153b15afc62e1dc0afa7d28be" - integrity sha512-cdNNePwKoisAi4DT00BB11H6IJ/WtA603YZ7+tLJcb/zCmCSxYKcvc+/GTyxC46jN/0ft7741vmMQrvxP8Sd+A== dependencies: cron-parser "^2.7.3" long-timeout "0.1.1" @@ -4932,14 +4278,12 @@ node-schedule@^1.2.3: nopt@3.x, nopt@~3.0.6: version "3.0.6" resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" - integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k= dependencies: abbrev "1" nopt@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" - integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00= dependencies: abbrev "1" osenv "^0.1.4" @@ -4947,7 +4291,6 @@ nopt@^4.0.1: normalize-package-data@^2.3.2: version "2.4.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" - integrity sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw== dependencies: hosted-git-info "^2.1.4" is-builtin-module "^1.0.0" @@ -4957,19 +4300,16 @@ normalize-package-data@^2.3.2: normalize-path@^2.0.0, normalize-path@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= dependencies: remove-trailing-separator "^1.0.1" npm-bundled@^1.0.1: version "1.0.5" resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.5.tgz#3c1732b7ba936b3a10325aef616467c0ccbcc979" - integrity sha512-m/e6jgWu8/v5niCUKQi9qQl8QdeEduFA96xHDDzFGqly0OOjI7c+60KM/2sppfnUU9JJagf+zs+yGhqSOFj71g== npm-packlist@^1.1.6: version "1.1.12" resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.12.tgz#22bde2ebc12e72ca482abd67afc51eb49377243a" - integrity sha512-WJKFOVMeAlsU/pjXuqVdzU0WfgtIBCupkEVwn+1Y0ERAbUfWw8R4GjgVbaKnUjRoD2FoQbHOCbOyT5Mbs9Lw4g== dependencies: ignore-walk "^3.0.1" npm-bundled "^1.0.1" @@ -4977,14 +4317,12 @@ npm-packlist@^1.1.6: npm-run-path@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" - integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= dependencies: path-key "^2.0.0" npmlog@^4.0.2: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" - integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== dependencies: are-we-there-yet "~1.1.2" console-control-strings "~1.1.0" @@ -4994,12 +4332,10 @@ npmlog@^4.0.2: number-is-nan@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= number-to-bn@1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/number-to-bn/-/number-to-bn-1.7.0.tgz#bb3623592f7e5f9e0030b1977bd41a0c53fe1ea0" - integrity sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA= dependencies: bn.js "4.11.6" strip-hex-prefix "1.0.0" @@ -5007,17 +4343,14 @@ number-to-bn@1.7.0: oauth-sign@~0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== object-assign@^4, object-assign@^4.0.0, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= object-copy@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" - integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= dependencies: copy-descriptor "^0.1.0" define-property "^0.2.5" @@ -5026,29 +4359,24 @@ object-copy@^0.1.0: object-inspect@~1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.6.0.tgz#c70b6cbf72f274aab4c34c0c82f5167bf82cf15b" - integrity sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ== object-keys@^1.0.12: version "1.0.12" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.12.tgz#09c53855377575310cca62f55bb334abff7b3ed2" - integrity sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag== 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= object-visit@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" - integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= dependencies: isobject "^3.0.0" object.omit@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" - integrity sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo= dependencies: for-own "^0.1.4" is-extendable "^0.1.1" @@ -5056,47 +4384,40 @@ object.omit@^2.0.0: object.pick@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" - integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= dependencies: isobject "^3.0.1" 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" on-finished@~2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" - integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= dependencies: ee-first "1.1.1" once@1.x, once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= dependencies: wrappy "1" onetime@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" - integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= dependencies: mimic-fn "^1.0.0" openzeppelin-solidity@1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/openzeppelin-solidity/-/openzeppelin-solidity-1.10.0.tgz#d77eee6653f5958d051318a61ba0b436f92216c0" - integrity sha512-igkrumQQ2lrN2zjeQV4Dnb0GpTBj1fzMcd8HPyBUqwI0hhuscX/HzXiqKT6gFQl1j9Wy/ppVVs9fqL/foF7Gmg== optimist@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" - integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY= dependencies: minimist "~0.0.1" wordwrap "~0.0.2" @@ -5104,7 +4425,6 @@ optimist@^0.6.1: optionator@^0.8.1, optionator@^0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" - integrity sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q= dependencies: deep-is "~0.1.3" fast-levenshtein "~2.0.4" @@ -5116,24 +4436,20 @@ optionator@^0.8.1, optionator@^0.8.2: original-require@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/original-require/-/original-require-1.0.1.tgz#0f130471584cd33511c5ec38c8d59213f9ac5e20" - integrity sha1-DxMEcVhM0zURxew4yNWSE/msXiA= os-homedir@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= os-locale@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" - integrity sha1-IPnxeuKe00XoveWDsT0gCYA8FNk= dependencies: lcid "^1.0.0" os-locale@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" - integrity sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA== dependencies: execa "^0.7.0" lcid "^1.0.0" @@ -5142,12 +4458,10 @@ os-locale@^2.0.0: os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= osenv@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" - integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== dependencies: os-homedir "^1.0.0" os-tmpdir "^1.0.0" @@ -5155,43 +4469,36 @@ osenv@^0.1.4: p-cancelable@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa" - integrity sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw== 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-limit@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" - integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== dependencies: p-try "^1.0.0" p-locate@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= dependencies: p-limit "^1.1.0" p-timeout@^1.1.1: version "1.2.1" resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-1.2.1.tgz#5eb3b353b7fce99f101a1038880bb054ebbea386" - integrity sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y= 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" - integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= parse-asn1@^5.0.0: version "5.1.1" resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.1.tgz#f6bf293818332bd0dab54efb16087724745e6ca8" - integrity sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw== dependencies: asn1.js "^4.0.0" browserify-aes "^1.0.0" @@ -5202,7 +4509,6 @@ parse-asn1@^5.0.0: parse-glob@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" - integrity sha1-ssN2z7EfNVE7rdFz7wu246OIORw= dependencies: glob-base "^0.3.0" is-dotfile "^1.0.0" @@ -5212,7 +4518,6 @@ parse-glob@^3.0.4: parse-headers@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.1.tgz#6ae83a7aa25a9d9b700acc28698cd1f1ed7e9536" - integrity sha1-aug6eqJanZtwCswoaYzR8e1+lTY= dependencies: for-each "^0.3.2" trim "0.0.1" @@ -5220,61 +4525,50 @@ parse-headers@^2.0.0: parse-json@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= dependencies: error-ex "^1.2.0" parseurl@~1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" - integrity sha1-/CidTtiZMRlGDBViUyYs3I3mW/M= pascalcase@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" - integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= path-exists@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" - integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= dependencies: pinkie-promise "^2.0.0" path-exists@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: version "1.0.1" 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.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= path-key@^2.0.0, path-key@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= path-parse@^1.0.5, path-parse@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" - integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" - integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= path-type@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" - integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= dependencies: graceful-fs "^4.1.2" pify "^2.0.0" @@ -5283,14 +4577,12 @@ path-type@^1.0.0: path-type@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" - integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= dependencies: pify "^2.0.0" pbkdf2@^3.0.3: version "3.0.17" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" - integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA== dependencies: create-hash "^1.1.2" create-hmac "^1.1.4" @@ -5301,116 +4593,94 @@ pbkdf2@^3.0.3: pegjs@^0.10.0: version "0.10.0" resolved "https://registry.yarnpkg.com/pegjs/-/pegjs-0.10.0.tgz#cf8bafae6eddff4b5a7efb185269eaaf4610ddbd" - integrity sha1-z4uvrm7d/0tafvsYUmnqr0YQ3b0= pend@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" - integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= performance-now@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= pify@^2.0.0, pify@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= pify@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= pinkie-promise@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= dependencies: pinkie "^2.0.0" pinkie@^2.0.0: version "2.0.4" resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= pkg-dir@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" - integrity sha1-ektQio1bstYp1EcFb/TpyTFM89Q= dependencies: find-up "^1.0.0" pkginfo@0.3.x: version "0.3.1" resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.3.1.tgz#5b29f6a81f70717142e09e765bbeab97b4f81e21" - integrity sha1-Wyn2qB9wcXFC4J52W76rl7T4HiE= pkginfo@0.x.x: version "0.4.1" resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.4.1.tgz#b5418ef0439de5425fc4995042dced14fb2a84ff" - integrity sha1-tUGO8EOd5UJfxJlQQtztFPsqhP8= pluralize@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" - integrity sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow== posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" - integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= pragma-singleton@1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/pragma-singleton/-/pragma-singleton-1.0.3.tgz#6894317bb8d47157e59de2a4a009db7e6f63e30e" - integrity sha1-aJQxe7jUcVflneKkoAnbfm9j4w4= prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= prepend-http@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" - integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= preserve@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" - integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks= prettier@^1.15.3: version "1.15.3" resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.15.3.tgz#1feaac5bdd181237b54dbe65d874e02a1472786a" - integrity sha512-gAU9AGAPMaKb3NNSUUuhhFAS7SCO4ALTN4nRIn6PJ075Qd28Yn2Ig2ahEJWdJwJmlEBTUfC7mMUSFy8MwsOCfg== private@^0.1.6, private@^0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" - integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== process-nextick-args@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" - integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw== process@~0.5.1: version "0.5.2" resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf" - integrity sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8= progress@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== promise-to-callback@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/promise-to-callback/-/promise-to-callback-1.0.0.tgz#5d2a749010bfb67d963598fcd3960746a68feef7" - integrity sha1-XSp0kBC/tn2WNZj805YHRqaP7vc= dependencies: is-fn "^1.0.0" set-immediate-shim "^1.0.1" @@ -5418,7 +4688,6 @@ promise-to-callback@^1.0.0: prompt@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/prompt/-/prompt-1.0.0.tgz#8e57123c396ab988897fb327fd3aedc3e735e4fe" - integrity sha1-jlcSPDlquYiJf7Mn/Trtw+c15P4= dependencies: colors "^1.1.2" pkginfo "0.x.x" @@ -5430,7 +4699,6 @@ prompt@^1.0.0: prop-types@^15.6.2: version "15.6.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.2.tgz#05d5ca77b4453e985d60fc7ff8c859094a497102" - integrity sha512-3pboPvLiWD7dkI3qf3KbUe6hKFKa52w+AE0VCqECtf+QHAKgOL37tTaNCnuX1nAAQ4ZhyP+kYVKf8rLmJ/feDQ== dependencies: loose-envify "^1.3.1" object-assign "^4.1.1" @@ -5438,7 +4706,6 @@ prop-types@^15.6.2: proxy-addr@~2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.4.tgz#ecfc733bf22ff8c6f407fa275327b9ab67e48b93" - integrity sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA== dependencies: forwarded "~0.1.2" ipaddr.js "1.8.0" @@ -5446,22 +4713,18 @@ proxy-addr@~2.0.4: 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, psl@^1.1.28: version "1.1.31" resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.31.tgz#e9aa86d0101b5b105cbe93ac6b784cd547276184" - integrity sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw== public-encrypt@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" - integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== dependencies: bn.js "^4.1.0" browserify-rsa "^4.0.0" @@ -5473,22 +4736,18 @@ public-encrypt@^4.0.0: punycode@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= punycode@^2.1.0, punycode@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== qs@6.5.2, qs@~6.5.2: version "6.5.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" - integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== query-string@^5.0.1: version "5.1.1" resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" - integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw== dependencies: decode-uri-component "^0.2.0" object-assign "^4.1.0" @@ -5497,7 +4756,6 @@ query-string@^5.0.1: randomatic@^3.0.0: version "3.1.1" resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.1.tgz#b776efc59375984e36c537b2f51a1f0aff0da1ed" - integrity sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw== dependencies: is-number "^4.0.0" kind-of "^6.0.0" @@ -5506,14 +4764,12 @@ randomatic@^3.0.0: randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.6.tgz#d302c522948588848a8d300c932b44c24231da80" - integrity sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A== dependencies: safe-buffer "^5.1.0" randomfill@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" - integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== dependencies: randombytes "^2.0.5" safe-buffer "^5.1.0" @@ -5521,17 +4777,14 @@ randomfill@^1.0.3: randomhex@0.1.5: version "0.1.5" resolved "https://registry.yarnpkg.com/randomhex/-/randomhex-0.1.5.tgz#baceef982329091400f2a2912c6cd02f1094f585" - integrity sha1-us7vmCMpCRQA8qKRLGzQLxCU9YU= range-parser@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" - integrity sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4= raw-body@2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.3.tgz#1b324ece6b5706e153855bc1148c65bb7f6ea0c3" - integrity sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw== dependencies: bytes "3.0.0" http-errors "1.6.3" @@ -5541,7 +4794,6 @@ raw-body@2.3.3: rc@^1.2.7: version "1.2.8" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" - integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== dependencies: deep-extend "^0.6.0" ini "~1.3.0" @@ -5551,7 +4803,6 @@ rc@^1.2.7: react-dom@^16.2.0: version "16.7.0" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.7.0.tgz#a17b2a7ca89ee7390bc1ed5eb81783c7461748b8" - integrity sha512-D0Ufv1ExCAmF38P2Uh1lwpminZFRXEINJe53zRAbm4KPwSyd6DY/uDoS0Blj9jvPpn1+wivKpZYc8aAAN/nAkg== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" @@ -5561,7 +4812,6 @@ react-dom@^16.2.0: react@^16.2.0: version "16.7.0" resolved "https://registry.yarnpkg.com/react/-/react-16.7.0.tgz#b674ec396b0a5715873b350446f7ea0802ab6381" - integrity sha512-StCz3QY8lxTb5cl2HJxjwLFOXPIFQp+p+hxQfc8WE0QiLfCtIlKj8/+5tjjKm8uSTlAW+fCPaavGFS06V9Ar3A== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" @@ -5571,7 +4821,6 @@ react@^16.2.0: read-pkg-up@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" - integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= dependencies: find-up "^1.0.0" read-pkg "^1.0.0" @@ -5579,7 +4828,6 @@ read-pkg-up@^1.0.1: read-pkg-up@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" - integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= dependencies: find-up "^2.0.0" read-pkg "^2.0.0" @@ -5587,7 +4835,6 @@ read-pkg-up@^2.0.0: read-pkg@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" - integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= dependencies: load-json-file "^1.0.0" normalize-package-data "^2.3.2" @@ -5596,7 +4843,6 @@ read-pkg@^1.0.0: read-pkg@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" - integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= dependencies: load-json-file "^2.0.0" normalize-package-data "^2.3.2" @@ -5605,14 +4851,12 @@ read-pkg@^2.0.0: read@1.0.x: version "1.0.7" resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" - integrity sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ= dependencies: mute-stream "~0.0.4" 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" @@ -5622,7 +4866,6 @@ readable-stream@^1.0.33: readable-stream@^2.0.0, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.2.9, readable-stream@^2.3.0, readable-stream@^2.3.5: version "2.3.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" - integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== dependencies: core-util-is "~1.0.0" inherits "~2.0.3" @@ -5635,7 +4878,6 @@ readable-stream@^2.0.0, readable-stream@^2.0.2, readable-stream@^2.0.6, readable 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" @@ -5645,7 +4887,6 @@ readable-stream@~1.0.15: readdirp@^2.0.0: version "2.2.1" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" - integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== dependencies: graceful-fs "^4.1.11" micromatch "^3.1.10" @@ -5654,29 +4895,24 @@ readdirp@^2.0.0: rechoir@^0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" - integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q= dependencies: resolve "^1.1.6" regenerate@^1.2.1: version "1.4.0" resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" - integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg== regenerator-runtime@^0.10.5: version "0.10.5" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" - integrity sha1-M2w+/BIgrc7dosn6tntaeVWjNlg= regenerator-runtime@^0.11.0: version "0.11.1" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" - integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== regenerator-transform@^0.10.0: version "0.10.1" resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" - integrity sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q== dependencies: babel-runtime "^6.18.0" babel-types "^6.19.0" @@ -5685,14 +4921,12 @@ regenerator-transform@^0.10.0: regex-cache@^0.4.2: version "0.4.4" resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" - integrity sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ== dependencies: is-equal-shallow "^0.1.3" regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" - integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== dependencies: extend-shallow "^3.0.2" safe-regex "^1.1.0" @@ -5700,12 +4934,10 @@ regex-not@^1.0.0, regex-not@^1.0.2: regexpp@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" - integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== regexpu-core@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" - integrity sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA= dependencies: regenerate "^1.2.1" regjsgen "^0.2.0" @@ -5714,62 +4946,52 @@ regexpu-core@^2.0.0: regjsgen@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" - integrity sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc= regjsparser@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" - integrity sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw= dependencies: jsesc "~0.5.0" remove-trailing-separator@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" - integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= repeat-element@^1.1.2: version "1.1.3" resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" - integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== repeat-string@^1.5.2, repeat-string@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= repeating@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" - integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= dependencies: is-finite "^1.0.0" req-cwd@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/req-cwd/-/req-cwd-1.0.1.tgz#0d73aeae9266e697a78f7976019677e76acf0fff" - integrity sha1-DXOurpJm5penj3l2AZZ352rPD/8= dependencies: req-from "^1.0.1" req-from@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/req-from/-/req-from-1.0.1.tgz#bf81da5147947d32d13b947dc12a58ad4587350e" - integrity sha1-v4HaUUeUfTLRO5R9wSpYrUWHNQ4= dependencies: resolve-from "^2.0.0" request-promise-core@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.1.tgz#3eee00b2c5aa83239cfb04c5700da36f81cd08b6" - integrity sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY= dependencies: lodash "^4.13.1" request-promise@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/request-promise/-/request-promise-4.2.2.tgz#d1ea46d654a6ee4f8ee6a4fea1018c22911904b4" - integrity sha1-0epG1lSm7k+O5qT+oQGMIpEZBLQ= dependencies: bluebird "^3.5.0" request-promise-core "1.1.1" @@ -5779,7 +5001,6 @@ request-promise@^4.2.2: request@^2.67.0, request@^2.79.0, request@^2.81.0, request@^2.85.0, request@^2.88.0: version "2.88.0" resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" - integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== dependencies: aws-sign2 "~0.7.0" aws4 "^1.8.0" @@ -5805,22 +5026,18 @@ request@^2.67.0, request@^2.79.0, request@^2.81.0, request@^2.85.0, request@^2.8 require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= require-from-string@^1.1.0: version "1.2.1" resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-1.2.1.tgz#529c9ccef27380adfec9a2f965b649bbee636418" - integrity sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg= require-main-filename@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" - integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= require-uncached@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" - integrity sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM= dependencies: caller-path "^0.1.0" resolve-from "^1.0.0" @@ -5828,41 +5045,34 @@ require-uncached@^1.0.3: resolve-from@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" - integrity sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY= resolve-from@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57" - integrity sha1-lICrIOlP+h2egKgEx+oUdhGWa1c= resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" - integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= resolve@1.1.x: version "1.1.7" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" - integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= resolve@^1.1.6, resolve@^1.5.0, resolve@^1.6.0, resolve@^1.8.1: version "1.9.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.9.0.tgz#a14c6fdfa8f92a7df1d996cb7105fa744658ea06" - integrity sha512-TZNye00tI67lwYvzxCxHGjwTNlUV70io54/Ed4j6PscB8xVfuBJpRenI/o6dVk0cY0PYTY27AgCoGGxRnYuItQ== dependencies: path-parse "^1.0.6" resolve@~1.7.1: version "1.7.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.7.1.tgz#aadd656374fd298aee895bc026b8297418677fd3" - integrity sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw== dependencies: path-parse "^1.0.5" restore-cursor@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" - integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= dependencies: onetime "^2.0.0" signal-exit "^3.0.2" @@ -5870,31 +5080,26 @@ restore-cursor@^2.0.0: resumer@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/resumer/-/resumer-0.0.0.tgz#f1e8f461e4064ba39e82af3cdc2a8c893d076759" - integrity sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k= dependencies: through "~2.3.4" ret@~0.1.10: version "0.1.15" resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" - integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== revalidator@0.1.x: version "0.1.8" resolved "https://registry.yarnpkg.com/revalidator/-/revalidator-0.1.8.tgz#fece61bfa0c1b52a206bd6b18198184bdd523a3b" - integrity sha1-/s5hv6DBtSoga9axgZgYS91SOjs= rimraf@2, rimraf@2.x.x, rimraf@^2.2.8, rimraf@^2.6.1, rimraf@~2.6.2: version "2.6.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" - integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== dependencies: glob "^7.1.3" ripemd160@^2.0.0, ripemd160@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" - integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== dependencies: hash-base "^3.0.0" inherits "^2.0.1" @@ -5902,74 +5107,62 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: rlp@^2.0.0: version "2.2.1" resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.2.1.tgz#9cacf53ad2579163cc56fba64b1f4336f1f2fa46" - integrity sha512-nqB/qy+YjXdp/zj1CjCiDwfLMBPv/XFDol0ir/7O/+Ix90++rvi+QoK1CDJcn8JoqCu2WrPPeRucu4qyIDzALg== dependencies: safe-buffer "^5.1.1" run-async@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" - integrity sha1-A3GrSuC91yDUFm19/aZP96RFpsA= dependencies: is-promise "^2.1.0" 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.1.0: version "6.3.3" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.3.3.tgz#3c6a7fa420e844a81390fb1158a9ec614f4bad55" - integrity sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw== dependencies: tslib "^1.9.0" safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, 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" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== safe-event-emitter@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/safe-event-emitter/-/safe-event-emitter-1.0.1.tgz#5b692ef22329ed8f69fdce607e50ca734f6f20af" - integrity sha512-e1wFe99A91XYYxoQbcq2ZJUWurxEyP8vfz7A7vuUe1s95q8r5ebraVaA1BukYJcpM6V16ugWoD9vngi8Ccu5fg== dependencies: events "^3.0.0" safe-regex@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" - integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= dependencies: ret "~0.1.10" safe@^0.4.5: version "0.4.6" resolved "https://registry.yarnpkg.com/safe/-/safe-0.4.6.tgz#1d5580cf2635c5cb940ea48fb5081ae3c25b1be1" - integrity sha1-HVWAzyY1xcuUDqSPtQga48JbG+E= safefs@^3.1.2: version "3.2.2" resolved "https://registry.yarnpkg.com/safefs/-/safefs-3.2.2.tgz#8170c1444d7038e08caea05a374fae2fa349e15c" - integrity sha1-gXDBRE1wOOCMrqBaN0+uL6NJ4Vw= dependencies: graceful-fs "*" "safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== sax@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== scandirectory@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/scandirectory/-/scandirectory-2.5.0.tgz#6ce03f54a090b668e3cbedbf20edf9e310593e72" - integrity sha1-bOA/VKCQtmjjy+2/IO354xBZPnI= dependencies: ignorefs "^1.0.0" safefs "^3.1.2" @@ -5978,7 +5171,6 @@ scandirectory@^2.5.0: scheduler@^0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.12.0.tgz#8ab17699939c0aedc5a196a657743c496538647b" - integrity sha512-t7MBR28Akcp4Jm+QoR63XgAi9YgCUmgvDHqf5otgAj4QvdoBE4ImCX0ffehefePPG+aitiYHp0g/mW6s4Tp+dw== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" @@ -5986,17 +5178,14 @@ scheduler@^0.12.0: scrypt-async@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/scrypt-async/-/scrypt-async-1.3.1.tgz#a11fd6fac981b4b823ee01dee0221169500ddae9" - integrity sha1-oR/W+smBtLgj7gHe4CIRaVAN2uk= scrypt-js@2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-2.0.4.tgz#32f8c5149f0797672e551c07e230f834b6af5f16" - integrity sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw== scrypt.js@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/scrypt.js/-/scrypt.js-0.2.0.tgz#af8d1465b71e9990110bedfc593b9479e03a8ada" - integrity sha1-r40UZbcemZARC+38WTuUeeA6ito= dependencies: scrypt "^6.0.2" scryptsy "^1.2.1" @@ -6004,7 +5193,6 @@ scrypt.js@0.2.0: 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: @@ -6013,21 +5201,18 @@ scrypt.js@^0.3.0: scrypt@^6.0.2: version "6.0.3" resolved "https://registry.yarnpkg.com/scrypt/-/scrypt-6.0.3.tgz#04e014a5682b53fa50c2d5cce167d719c06d870d" - integrity sha1-BOAUpWgrU/pQwtXM4WfXGcBthw0= dependencies: nan "^2.0.8" scryptsy@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/scryptsy/-/scryptsy-1.2.1.tgz#a3225fa4b2524f802700761e2855bdf3b2d92163" - integrity sha1-oyJfpLJST4AnAHYeKFW987LZIWM= dependencies: pbkdf2 "^3.0.3" secp256k1@^3.0.1: version "3.6.1" resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-3.6.1.tgz#f0475d42096218ff00e45a127242abdff9285335" - integrity sha512-utLpWv4P4agEw7hakR73wlWX0NBmC5t/vkJ0TAfTyvETAUzo0tm6aFKPYetVYRaVubxMeWm5Ekv9ETwOgcDCqw== dependencies: bindings "^1.2.1" bip66 "^1.1.3" @@ -6041,29 +5226,24 @@ secp256k1@^3.0.1: seek-bzip@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/seek-bzip/-/seek-bzip-1.0.5.tgz#cfe917cb3d274bcffac792758af53173eb1fabdc" - integrity sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w= dependencies: commander "~2.8.1" semaphore@>=1.0.1, semaphore@^1.0.3: version "1.1.0" resolved "https://registry.yarnpkg.com/semaphore/-/semaphore-1.1.0.tgz#aaad8b86b20fe8e9b32b16dc2ee682a8cd26a8aa" - integrity sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA== "semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: version "5.6.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" - integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== 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== send@0.16.2: version "0.16.2" resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" - integrity sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw== dependencies: debug "2.6.9" depd "~1.1.2" @@ -6082,7 +5262,6 @@ send@0.16.2: serve-static@1.13.2: version "1.13.2" resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1" - integrity sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw== dependencies: encodeurl "~1.0.2" escape-html "~1.0.3" @@ -6092,7 +5271,6 @@ serve-static@1.13.2: servify@^0.1.12: version "0.1.12" resolved "https://registry.yarnpkg.com/servify/-/servify-0.1.12.tgz#142ab7bee1f1d033b66d0707086085b17c06db95" - integrity sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw== dependencies: body-parser "^1.16.0" cors "^2.8.1" @@ -6103,17 +5281,14 @@ servify@^0.1.12: set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= set-immediate-shim@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" - integrity sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E= set-value@^0.4.3: version "0.4.3" resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" - integrity sha1-fbCPnT0i3H945Trzw79GZuzfzPE= dependencies: extend-shallow "^2.0.1" is-extendable "^0.1.1" @@ -6123,7 +5298,6 @@ set-value@^0.4.3: set-value@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" - integrity sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg== dependencies: extend-shallow "^2.0.1" is-extendable "^0.1.1" @@ -6133,22 +5307,18 @@ set-value@^2.0.0: setimmediate@1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.4.tgz#20e81de622d4a02588ce0c8da8973cbcf1d3138f" - integrity sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48= setimmediate@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= setprototypeof@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" - integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== sha.js@^2.4.0, sha.js@^2.4.8: version "2.4.11" resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" - integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== dependencies: inherits "^2.0.1" safe-buffer "^5.0.1" @@ -6156,26 +5326,22 @@ sha.js@^2.4.0, sha.js@^2.4.8: sha3@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/sha3/-/sha3-1.2.2.tgz#a66c5098de4c25bc88336ec8b4817d005bca7ba9" - integrity sha1-pmxQmN5MJbyIM27ItIF9AFvKe6k= dependencies: nan "2.10.0" shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= dependencies: shebang-regex "^1.0.0" shebang-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= shelljs@^0.7.4: version "0.7.8" resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.8.tgz#decbcf874b0d1e5fb72e14b164a9683048e9acb3" - integrity sha1-3svPh0sNHl+3LhSxZKloMEjprLM= dependencies: glob "^7.0.0" interpret "^1.0.0" @@ -6184,7 +5350,6 @@ shelljs@^0.7.4: shelljs@^0.8.1: version "0.8.3" resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.3.tgz#a7f3319520ebf09ee81275b2368adb286659b097" - integrity sha512-fc0BKlAWiLpwZljmOvAOTE/gXawtCoNrP5oaY7KIaQbbyHeQVg01pSEuEGvGh3HEdBU4baCD7wQBwADmM/7f7A== dependencies: glob "^7.0.0" interpret "^1.0.0" @@ -6193,17 +5358,14 @@ shelljs@^0.8.1: signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= simple-concat@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.0.tgz#7344cbb8b6e26fb27d66b2fc86f9f6d5997521c6" - integrity sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY= simple-get@^2.7.0: version "2.8.1" resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-2.8.1.tgz#0e22e91d4575d87620620bc91308d57a77f44b5d" - integrity sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw== dependencies: decompress-response "^3.3.0" once "^1.3.1" @@ -6212,12 +5374,10 @@ simple-get@^2.7.0: slash@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" - integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= slice-ansi@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.0.0.tgz#5373bdb8559b45676e8541c66916cdd6251612e7" - integrity sha512-4j2WTWjp3GsZ+AOagyzVbzp4vWGtZ0hEZ/gDY/uTvm6MTxUfTUIsnMIFb1bn8o0RuXiqUw15H1bue8f22Vw2oQ== dependencies: ansi-styles "^3.2.0" astral-regex "^1.0.0" @@ -6226,7 +5386,6 @@ slice-ansi@2.0.0: snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" - integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== dependencies: define-property "^1.0.0" isobject "^3.0.0" @@ -6235,14 +5394,12 @@ snapdragon-node@^2.0.1: snapdragon-util@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" - integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== dependencies: kind-of "^3.2.0" snapdragon@^0.8.1: version "0.8.2" resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" - integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== dependencies: base "^0.11.1" debug "^2.2.0" @@ -6256,22 +5413,18 @@ snapdragon@^0.8.1: sol-digger@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/sol-digger/-/sol-digger-0.0.2.tgz#406c4a9d31e269e7f88eb1c2ea101318e5e09025" - integrity sha1-QGxKnTHiaef4jrHC6hATGOXgkCU= sol-explore@1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/sol-explore/-/sol-explore-1.6.1.tgz#b59f073c69fe332560d5a10c32ba8ca7f2986cfb" - integrity sha1-tZ8HPGn+MyVg1aEMMrqMp/KYbPs= 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= sol-merger@^0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/sol-merger/-/sol-merger-0.1.3.tgz#184284ba4811aebe8950f510df4e8218f568b35f" - integrity sha512-mEirUbl1mZJt2iNBqptsBpxb8n7ZD0trNlnV/+CBAQH8TIFhHIKXdBE8ykD1v+8My18sq7GqHYPmpHE9ckB2Jw== dependencies: bluebird "^3.5.3" cli-color "^1.4.0" @@ -6283,7 +5436,6 @@ sol-merger@^0.1.3: solc@0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/solc/-/solc-0.4.24.tgz#354f14b269b38cbaa82a47d1ff151723502b954e" - integrity sha512-2xd7Cf1HeVwrIb6Bu1cwY2/TaLRodrppCq3l7rhLimFQgmxptXhTC3+/wesVLpB09F1A2kZgvbMOgH7wvhFnBQ== dependencies: fs-extra "^0.30.0" memorystream "^0.3.1" @@ -6294,7 +5446,6 @@ solc@0.4.24: solc@^0.4.2: version "0.4.25" resolved "https://registry.yarnpkg.com/solc/-/solc-0.4.25.tgz#06b8321f7112d95b4b903639b1138a4d292f5faa" - integrity sha512-jU1YygRVy6zatgXrLY2rRm7HW1d7a8CkkEgNJwvH2VLpWhMFsMdWcJn6kUqZwcSz/Vm+w89dy7Z/aB5p6AFTrg== dependencies: fs-extra "^0.30.0" memorystream "^0.3.1" @@ -6305,7 +5456,6 @@ solc@^0.4.2: solidity-coverage@^0.5.11: version "0.5.11" resolved "https://registry.yarnpkg.com/solidity-coverage/-/solidity-coverage-0.5.11.tgz#1ee45f6d98b75a615aadb8f9aa7db4a2b32258e7" - integrity sha512-qikdsSi6+9XbfvwA0aI7HUVpF9fIFNqRWTw23M89GMDY+b6Gj0wWU9IngJS0fimoZIAdEp3bfChxvpfVcrUesg== dependencies: death "^1.1.0" ethereumjs-testrpc-sc "6.1.6" @@ -6321,7 +5471,6 @@ solidity-coverage@^0.5.11: solidity-docgen@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/solidity-docgen/-/solidity-docgen-0.1.0.tgz#f3a56ff074e8c7d832af3a3d462c3b5abf0f64cb" - integrity sha512-F7ufNWmlP5c5hIi66Ijv9tc+HNosyO7ijWq6pRtyBR1WqyJBH/0DJkD6QZI8HkE8p6LEXiPKxGBWbAeVT9Nu9g== dependencies: commander "^2.14.1" lodash "^4.17.5" @@ -6334,7 +5483,6 @@ solidity-docgen@^0.1.0: solidity-parser-sc@0.4.11: version "0.4.11" resolved "https://registry.yarnpkg.com/solidity-parser-sc/-/solidity-parser-sc-0.4.11.tgz#86734c9205537007f4d6201b57176e41696ee607" - integrity sha512-1kV5iC7m3CtMDfmHaVNwz2saSGQVIuF16rIxU417Al38MVCWHMQQ5vT6cmLsNwDe60S74auobWij9vNawSeOyw== dependencies: mocha "^4.1.0" pegjs "^0.10.0" @@ -6343,12 +5491,10 @@ solidity-parser-sc@0.4.11: solium-plugin-security@0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/solium-plugin-security/-/solium-plugin-security-0.1.1.tgz#2a87bcf8f8c3abf7d198e292e4ac080284e3f3f6" - integrity sha512-kpLirBwIq4mhxk0Y/nn5cQ6qdJTI+U1LO3gpoNIcqNaW+sI058moXBe2UiHs+9wvF9IzYD49jcKhFTxcR9u9SQ== solium@^1.1.8: version "1.2.1" resolved "https://registry.yarnpkg.com/solium/-/solium-1.2.1.tgz#ead11f2921ba2337461752155cc96149ea08f247" - integrity sha512-PnNOx3BfYvghJE5aV2lWBcbNIa9g9eXQaGPpQPiYixmF7kVR27J2tmSetdsdpwKMVf2Y+H4JEEL7zyfsRjOMFA== dependencies: ajv "^5.2.2" chokidar "^1.6.0" @@ -6367,7 +5513,6 @@ solium@^1.1.8: solparse@2.2.7: version "2.2.7" resolved "https://registry.yarnpkg.com/solparse/-/solparse-2.2.7.tgz#5479ff4ba4ca6900df89b902b5af1ee23b816250" - integrity sha512-s2DKdvVxXcWefPgBSb+HgTylomzbNjsKdZDN6PsWi9h+UYdyw7DFozpPCGETNEz523tIjrqBRnSPIoDVL1zv5Q== dependencies: mocha "^4.0.1" pegjs "^0.10.0" @@ -6376,12 +5521,10 @@ solparse@2.2.7: sorted-array-functions@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/sorted-array-functions/-/sorted-array-functions-1.2.0.tgz#43265b21d6e985b7df31621b1c11cc68d8efc7c3" - integrity sha512-sWpjPhIZJtqO77GN+LD8dDsDKcWZ9GCOJNqKzi1tvtjGIzwfoyuRH8S0psunmc6Z5P+qfDqztSbwYR5X/e1UTg== source-map-resolve@^0.5.0: version "0.5.2" resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" - integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== dependencies: atob "^2.1.1" decode-uri-component "^0.2.0" @@ -6392,7 +5535,6 @@ source-map-resolve@^0.5.0: source-map-support@0.5.9, source-map-support@^0.5.3: version "0.5.9" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.9.tgz#41bc953b2534267ea2d605bccfa7bfa3111ced5f" - integrity sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA== dependencies: buffer-from "^1.0.0" source-map "^0.6.0" @@ -6400,36 +5542,30 @@ source-map-support@0.5.9, source-map-support@^0.5.3: source-map-support@^0.4.15: version "0.4.18" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" - integrity sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA== dependencies: source-map "^0.5.6" source-map-url@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" - integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= source-map@^0.5.6, source-map@^0.5.7: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= 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" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== source-map@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d" - integrity sha1-2rc/vPwrqBm03gO9b26qSBZLP50= dependencies: amdefine ">=0.0.4" spdx-correct@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" - integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q== dependencies: spdx-expression-parse "^3.0.0" spdx-license-ids "^3.0.0" @@ -6437,12 +5573,10 @@ spdx-correct@^3.0.0: spdx-exceptions@^2.1.0: version "2.2.0" resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" - integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA== spdx-expression-parse@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" - integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== dependencies: spdx-exceptions "^2.1.0" spdx-license-ids "^3.0.0" @@ -6450,29 +5584,24 @@ spdx-expression-parse@^3.0.0: spdx-license-ids@^3.0.0: version "3.0.3" resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz#81c0ce8f21474756148bbb5f3bfc0f36bf15d76e" - integrity sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g== split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" - integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== dependencies: extend-shallow "^3.0.0" sprintf-js@>=1.0.3: version "1.1.2" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673" - integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug== sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= sshpk@^1.7.0: version "1.16.0" resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.0.tgz#1d4963a2fbffe58050aa9084ca20be81741c07de" - integrity sha512-Zhev35/y7hRMcID/upReIvRse+I9SVhyVre/KTJSJQWMz3C3+G+HpO7m1wK/yckEtujKZ7dS4hkVxAnmHaIGVQ== dependencies: asn1 "~0.2.3" assert-plus "^1.0.0" @@ -6487,12 +5616,10 @@ sshpk@^1.7.0: stack-trace@0.0.x: version "0.0.10" resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" - integrity sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA= static-extend@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" - integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= dependencies: define-property "^0.2.5" object-copy "^0.1.0" @@ -6500,32 +5627,26 @@ static-extend@^0.1.1: "statuses@>= 1.4.0 < 2": version "1.5.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= statuses@~1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" - integrity sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew== stdio@^0.2.7: version "0.2.7" resolved "https://registry.yarnpkg.com/stdio/-/stdio-0.2.7.tgz#a1c57da10fe1cfaa0c3bf683c9d0743d1b660839" - integrity sha1-ocV9oQ/hz6oMO/aDydB0PRtmCDk= stealthy-require@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" - integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= strict-uri-encode@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" - integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= string-width@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= dependencies: code-point-at "^1.0.0" is-fullwidth-code-point "^1.0.0" @@ -6534,7 +5655,6 @@ string-width@^1.0.1: "string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== dependencies: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" @@ -6542,7 +5662,6 @@ string-width@^1.0.1: 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= dependencies: define-properties "^1.1.2" es-abstract "^1.5.0" @@ -6551,109 +5670,92 @@ string.prototype.trim@~1.1.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= string_decoder@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== dependencies: safe-buffer "~5.1.0" strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= dependencies: ansi-regex "^2.0.0" strip-ansi@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= dependencies: ansi-regex "^3.0.0" strip-ansi@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.0.0.tgz#f78f68b5d0866c20b2c9b8c61b5298508dc8756f" - integrity sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow== dependencies: ansi-regex "^4.0.0" strip-bom@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" - integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= dependencies: is-utf8 "^0.2.0" strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= strip-dirs@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/strip-dirs/-/strip-dirs-2.1.0.tgz#4987736264fc344cf20f6c34aca9d13d1d4ed6c5" - integrity sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g== dependencies: is-natural-number "^4.0.1" strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= strip-hex-prefix@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz#0c5f155fef1151373377de9dbb588da05500e36f" - integrity sha1-DF8VX+8RUTczd96du1iNoFUA428= dependencies: is-hex-prefixed "1.0.0" strip-json-comments@^2.0.1, strip-json-comments@~2.0.1: version "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== dependencies: has-flag "^2.0.0" supports-color@5.4.0: version "5.4.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" - integrity sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w== dependencies: has-flag "^3.0.0" supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= supports-color@^3.1.0: version "3.2.3" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" - integrity sha1-ZawFBLOVQXHYpklGsq48u4pfVPY= dependencies: has-flag "^1.0.0" supports-color@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== dependencies: has-flag "^3.0.0" 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" @@ -6672,7 +5774,6 @@ swarm-js@0.1.37: table@^5.0.2: version "5.1.1" resolved "https://registry.yarnpkg.com/table/-/table-5.1.1.tgz#92030192f1b7b51b6eeab23ed416862e47b70837" - integrity sha512-NUjapYb/qd4PeFW03HnAuOJ7OMcBkJlqeClWxeNlQ0lXGSb52oZXGzkO0/I0ARegQ2eUT1g2VDJH0eUxDRcHmw== dependencies: ajv "^6.6.1" lodash "^4.17.11" @@ -6682,7 +5783,6 @@ table@^5.0.2: tape@^4.4.0, tape@^4.6.3: version "4.9.2" resolved "https://registry.yarnpkg.com/tape/-/tape-4.9.2.tgz#f233e40f09dc7e00fcf9b26755453c3822ad28c0" - integrity sha512-lPXKRKILZ1kZaUy5ynWKs8ATGSUO7HAFHCFnBam6FaGSqPdOwMWbxXHq4EXFLE8WRTleo/YOMXkaUTRmTB1Fiw== dependencies: deep-equal "~1.0.1" defined "~1.0.0" @@ -6701,7 +5801,6 @@ tape@^4.4.0, tape@^4.6.3: tar-stream@^1.5.2: version "1.6.2" resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555" - integrity sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A== dependencies: bl "^1.0.0" buffer-alloc "^1.2.0" @@ -6714,7 +5813,6 @@ tar-stream@^1.5.2: 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" @@ -6725,7 +5823,6 @@ tar.gz@^1.0.5: tar@^2.1.1: version "2.2.1" resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" - integrity sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE= dependencies: block-stream "*" fstream "^1.0.2" @@ -6734,7 +5831,6 @@ tar@^2.1.1: tar@^4: version "4.4.8" resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.8.tgz#b19eec3fde2a96e64666df9fdb40c5ca1bc3747d" - integrity sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ== dependencies: chownr "^1.1.1" fs-minipass "^1.2.5" @@ -6747,7 +5843,6 @@ tar@^4: taskgroup@^4.0.5, taskgroup@^4.2.0: version "4.3.1" resolved "https://registry.yarnpkg.com/taskgroup/-/taskgroup-4.3.1.tgz#7de193febd768273c457730497024d512c27915a" - integrity sha1-feGT/r12gnPEV3MElwJNUSwnkVo= dependencies: ambi "^2.2.0" csextends "^1.0.3" @@ -6755,36 +5850,30 @@ taskgroup@^4.0.5, taskgroup@^4.2.0: text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= 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" through@^2.3.6, through@~2.3.4, through@~2.3.8: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= timed-out@^4.0.0, timed-out@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" - integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= timers-ext@^0.1.5: version "0.1.7" resolved "https://registry.yarnpkg.com/timers-ext/-/timers-ext-0.1.7.tgz#6f57ad8578e07a3fb9f91d9387d65647555e25c6" - integrity sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ== dependencies: es5-ext "~0.10.46" next-tick "1" @@ -6792,7 +5881,6 @@ timers-ext@^0.1.5: tingodb@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/tingodb/-/tingodb-0.6.1.tgz#f63336259af7dfa6c90dfe2556a0dfb0d4eede59" - integrity sha1-9jM2JZr336bJDf4lVqDfsNTu3lk= dependencies: lodash "^4.17.5" safe "^0.4.5" @@ -6803,31 +5891,26 @@ tingodb@^0.6.1: tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== dependencies: os-tmpdir "~1.0.2" to-buffer@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80" - integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg== to-fast-properties@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" - integrity sha1-uDVx+k2MJbguIxsG46MFXeTKGkc= to-object-path@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" - integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= dependencies: kind-of "^3.0.2" to-regex-range@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" - integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= dependencies: is-number "^3.0.0" repeat-string "^1.6.1" @@ -6835,7 +5918,6 @@ to-regex-range@^2.1.0: to-regex@^3.0.1, to-regex@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" - integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== dependencies: define-property "^2.0.2" extend-shallow "^3.0.2" @@ -6845,7 +5927,6 @@ to-regex@^3.0.1, to-regex@^3.0.2: tough-cookie@>=2.3.3: version "2.5.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== dependencies: psl "^1.1.28" punycode "^2.1.1" @@ -6853,7 +5934,6 @@ tough-cookie@>=2.3.3: tough-cookie@~2.4.3: version "2.4.3" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" - integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ== dependencies: psl "^1.1.24" punycode "^1.4.1" @@ -6861,22 +5941,18 @@ tough-cookie@~2.4.3: 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-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" - integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= trim@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd" - integrity sha1-WFhUf2spB1fulczMZm+1AITEYN0= -truffle-hdwallet-provider-privkey@0.3.0: +truffle-hdwallet-provider-privkey@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/truffle-hdwallet-provider-privkey/-/truffle-hdwallet-provider-privkey-0.3.0.tgz#6688f5f3db5dce2cb9f502f7b52dab7b5e2522a3" - integrity sha512-rXwYWz9/lgmZQft0lAwj1JTATzG9FErhvI4xy/Vz5gNFjQCGC7yu3aYBc3XI8g2nrIyYUFqaZbrgHmYcAjw/1A== dependencies: ethereumjs-tx "^1.3.4" ethereumjs-wallet "^0.6.0" @@ -6886,7 +5962,6 @@ truffle-hdwallet-provider-privkey@0.3.0: truffle-hdwallet-provider@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/truffle-hdwallet-provider/-/truffle-hdwallet-provider-1.0.3.tgz#4ae845f9b2de23f47c4f0fbc6ef2d4b13b494604" - integrity sha512-Lm4MrXHnWg8wHNUoumUBc8AhlCBg05x7wZA81JOFfO0j3QU53A/hhSfV7v8gANbRsvpF5Su0s3SNQGJjewtnYw== dependencies: any-promise "^1.3.0" bindings "^1.3.1" @@ -6895,7 +5970,6 @@ truffle-hdwallet-provider@^1.0.3: truffle-wallet-provider@0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/truffle-wallet-provider/-/truffle-wallet-provider-0.0.5.tgz#db59ce6fa1c558766011137509a94dfca8d1408e" - integrity sha1-21nOb6HFWHZgERN1CalN/KjRQI4= dependencies: ethereumjs-wallet "^0.6.0" web3 "^0.18.2" @@ -6904,7 +5978,6 @@ truffle-wallet-provider@0.0.5: truffle@4.1.14: version "4.1.14" resolved "https://registry.yarnpkg.com/truffle/-/truffle-4.1.14.tgz#8d2c298e29abf9b1e486e44ff9faca6d34bb9030" - integrity sha512-e7tTLvKP3bN9dE7MagfWyFjy4ZgoEGbeujECy1me1ENBzbj/aO/+45gs72qsL3+3IkCNNcWNOJjjrm8BYZZNNg== dependencies: mocha "^4.1.0" original-require "1.0.1" @@ -6913,36 +5986,30 @@ truffle@4.1.14: tslib@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" - integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== tunnel-agent@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= dependencies: safe-buffer "^5.0.1" tweetnacl@0.13.2: version "0.13.2" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.13.2.tgz#453161770469d45cd266c36404e2bc99a8fa9944" - integrity sha1-RTFhdwRp1FzSZsNkBOK8maj6mUQ= tweetnacl@^0.14.3, tweetnacl@~0.14.0: version "0.14.5" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= type-check@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= dependencies: prelude-ls "~1.1.2" type-is@~1.6.16: version "1.6.16" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" - integrity sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q== dependencies: media-typer "0.3.0" mime-types "~2.1.18" @@ -6950,31 +6017,26 @@ type-is@~1.6.16: typechecker@^2.0.8: version "2.1.0" resolved "https://registry.yarnpkg.com/typechecker/-/typechecker-2.1.0.tgz#d1c2093a54ff8a19f58cff877eeaa54f2242d383" - integrity sha1-0cIJOlT/ihn1jP+HfuqlTyJC04M= typechecker@^4.3.0: version "4.7.0" resolved "https://registry.yarnpkg.com/typechecker/-/typechecker-4.7.0.tgz#5249f427358f45b7250c4924fd4d01ed9ba435e9" - integrity sha512-4LHc1KMNJ6NDGO+dSM/yNfZQRtp8NN7psYrPHUblD62Dvkwsp3VShsbM78kOgpcmMkRTgvwdKOTjctS+uMllgQ== dependencies: editions "^2.1.0" typechecker@~2.0.1: version "2.0.8" resolved "https://registry.yarnpkg.com/typechecker/-/typechecker-2.0.8.tgz#e83da84bb64c584ccb345838576c40b0337db82e" - integrity sha1-6D2oS7ZMWEzLNFg4V2xAsDN9uC4= typedarray-to-buffer@^3.1.2, typedarray-to-buffer@^3.1.5: version "3.1.5" resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" - integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== dependencies: is-typedarray "^1.0.0" uglify-js@^3.1.4: version "3.4.9" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.9.tgz#af02f180c1207d76432e473ed24a28f4a782bae3" - integrity sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q== dependencies: commander "~2.17.1" source-map "~0.6.1" @@ -6982,12 +6044,10 @@ uglify-js@^3.1.4: ultron@~1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" - integrity sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og== unbzip2-stream@^1.0.9: version "1.3.1" resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.3.1.tgz#7854da51622a7e63624221196357803b552966a1" - integrity sha512-fIZnvdjblYs7Cru/xC6tCPVhz7JkYcVQQkePwMLyQELzYTds2Xn8QefPVnvdVhhZqubxNA1cASXEH5wcK0Bucw== dependencies: buffer "^3.0.1" through "^2.3.6" @@ -6995,17 +6055,14 @@ unbzip2-stream@^1.0.9: 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.8.3: 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== union-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" - integrity sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ= dependencies: arr-union "^3.1.0" get-value "^2.0.6" @@ -7015,22 +6072,18 @@ union-value@^1.0.0: universalify@^0.1.0: version "0.1.2" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" - integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== unorm@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/unorm/-/unorm-1.4.1.tgz#364200d5f13646ca8bcd44490271335614792300" - integrity sha1-NkIA1fE2RsqLzURJAnEzVhR5IwA= unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= unset-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" - integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= dependencies: has-value "^0.3.1" isobject "^3.0.0" @@ -7038,61 +6091,50 @@ unset-value@^1.0.0: uri-js@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" - integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== dependencies: punycode "^2.1.0" urix@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" - integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= url-parse-lax@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" - integrity sha1-evjzA2Rem9eaJy56FKxovAYJ2nM= dependencies: prepend-http "^1.0.1" 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" - integrity sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk= url-to-options@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" - integrity sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k= use@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" - integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== utf8@2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/utf8/-/utf8-2.1.1.tgz#2e01db02f7d8d0944f77104f1609eb0c304cf768" - integrity sha1-LgHbAvfY0JRPdxBPFgnrDDBM92g= utf8@^2.1.1, utf8@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/utf8/-/utf8-2.1.2.tgz#1fa0d9270e9be850d9b05027f63519bf46457d96" - integrity sha1-H6DZJw6b6FDZsFAn9jUZv0ZFfZY= 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" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= utile@0.3.x: version "0.3.0" resolved "https://registry.yarnpkg.com/utile/-/utile-0.3.0.tgz#1352c340eb820e4d8ddba039a4fbfaa32ed4ef3a" - integrity sha1-E1LDQOuCDk2N26A5pPv6oy7U7zo= dependencies: async "~0.9.0" deep-equal "~0.2.1" @@ -7104,22 +6146,18 @@ utile@0.3.x: utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= uuid@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.1.tgz#c2a30dedb3e535d72ccf82e343941a50ba8533ac" - integrity sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w= uuid@^3.0.1, uuid@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" - integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== validate-npm-package-license@^3.0.1: version "3.0.4" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" - integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== dependencies: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" @@ -7127,17 +6165,14 @@ validate-npm-package-license@^3.0.1: varint@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/varint/-/varint-5.0.0.tgz#d826b89f7490732fabc0c0ed693ed475dcb29ebf" - integrity sha1-2Ca4n3SQcy+rwMDtaT7Uddyynr8= vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= verror@1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= dependencies: assert-plus "^1.0.0" core-util-is "1.0.2" @@ -7146,7 +6181,6 @@ verror@1.10.0: watchr@~2.4.13: version "2.4.13" resolved "https://registry.yarnpkg.com/watchr/-/watchr-2.4.13.tgz#d74847bb4d6f90f61fe2c74f9f68662aa0e07601" - integrity sha1-10hHu01vkPYf4sdPn2hmKqDgdgE= dependencies: eachr "^2.0.2" extendr "^2.1.0" @@ -7160,7 +6194,6 @@ watchr@~2.4.13: web3-bzz@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.0.0-beta.34.tgz#068d37777ab65e5c60f8ec8b9a50cfe45277929c" - integrity sha1-Bo03d3q2Xlxg+OyLmlDP5FJ3kpw= dependencies: got "7.1.0" swarm-js "0.1.37" @@ -7169,7 +6202,6 @@ web3-bzz@1.0.0-beta.34: web3-core-helpers@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.0.0-beta.34.tgz#b168da00d3e19e156bc15ae203203dd4dfee2d03" - integrity sha1-sWjaANPhnhVrwVriAyA91N/uLQM= dependencies: underscore "1.8.3" web3-eth-iban "1.0.0-beta.34" @@ -7178,7 +6210,6 @@ web3-core-helpers@1.0.0-beta.34: web3-core-method@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.0.0-beta.34.tgz#ec163c8a2c490fa02a7ec15559fa7307fc7cc6dd" - integrity sha1-7BY8iixJD6AqfsFVWfpzB/x8xt0= dependencies: underscore "1.8.3" web3-core-helpers "1.0.0-beta.34" @@ -7189,7 +6220,6 @@ web3-core-method@1.0.0-beta.34: web3-core-promievent@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.0.0-beta.34.tgz#a4f4fa6784bb293e82c60960ae5b56a94cd03edc" - integrity sha1-pPT6Z4S7KT6CxglgrltWqUzQPtw= dependencies: any-promise "1.3.0" eventemitter3 "1.1.1" @@ -7197,7 +6227,6 @@ web3-core-promievent@1.0.0-beta.34: web3-core-requestmanager@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.0.0-beta.34.tgz#01f8f6cf2ae6b6f0b70c38bae1ef741b5bab215c" - integrity sha1-Afj2zyrmtvC3DDi64e90G1urIVw= dependencies: underscore "1.8.3" web3-core-helpers "1.0.0-beta.34" @@ -7208,7 +6237,6 @@ web3-core-requestmanager@1.0.0-beta.34: web3-core-subscriptions@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.0.0-beta.34.tgz#9fed144033f221c3cf21060302ffdaf5ef2de2de" - integrity sha1-n+0UQDPyIcPPIQYDAv/a9e8t4t4= dependencies: eventemitter3 "1.1.1" underscore "1.8.3" @@ -7217,7 +6245,6 @@ web3-core-subscriptions@1.0.0-beta.34: web3-core@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.0.0-beta.34.tgz#121be8555e9fb00d2c5d05ddd3381d0c9e46987e" - integrity sha1-EhvoVV6fsA0sXQXd0zgdDJ5GmH4= dependencies: web3-core-helpers "1.0.0-beta.34" web3-core-method "1.0.0-beta.34" @@ -7227,7 +6254,6 @@ web3-core@1.0.0-beta.34: web3-eth-abi@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.0.0-beta.34.tgz#034533e3aa2f7e59ff31793eaea685c0ed5af67a" - integrity sha1-A0Uz46ovfln/MXk+rqaFwO1a9no= dependencies: bn.js "4.11.6" underscore "1.8.3" @@ -7237,7 +6263,6 @@ web3-eth-abi@1.0.0-beta.34: web3-eth-accounts@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.0.0-beta.34.tgz#e09142eeecc797ac3459b75e9b23946d3695f333" - integrity sha1-4JFC7uzHl6w0WbdemyOUbTaV8zM= dependencies: any-promise "1.3.0" crypto-browserify "3.12.0" @@ -7253,7 +6278,6 @@ web3-eth-accounts@1.0.0-beta.34: web3-eth-contract@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.0.0-beta.34.tgz#9dbb38fae7643a808427a20180470ec7415c91e6" - integrity sha1-nbs4+udkOoCEJ6IBgEcOx0FckeY= dependencies: underscore "1.8.3" web3-core "1.0.0-beta.34" @@ -7267,7 +6291,6 @@ web3-eth-contract@1.0.0-beta.34: web3-eth-iban@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.0.0-beta.34.tgz#9af458605867ccf74ea979aaf326b38ba6a5ba0c" - integrity sha1-mvRYYFhnzPdOqXmq8yazi6alugw= dependencies: bn.js "4.11.6" web3-utils "1.0.0-beta.34" @@ -7275,7 +6298,6 @@ web3-eth-iban@1.0.0-beta.34: web3-eth-personal@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.0.0-beta.34.tgz#9afba167342ebde5420bcd5895c3f6c34388f205" - integrity sha1-mvuhZzQuveVCC81YlcP2w0OI8gU= dependencies: web3-core "1.0.0-beta.34" web3-core-helpers "1.0.0-beta.34" @@ -7286,7 +6308,6 @@ web3-eth-personal@1.0.0-beta.34: web3-eth@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.0.0-beta.34.tgz#74086000850c6fe6f535ef49837d6d4bb6113268" - integrity sha1-dAhgAIUMb+b1Ne9Jg31tS7YRMmg= dependencies: underscore "1.8.3" web3-core "1.0.0-beta.34" @@ -7304,7 +6325,6 @@ web3-eth@1.0.0-beta.34: web3-net@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.0.0-beta.34.tgz#427cea2f431881449c8e38d523290f173f9ff63d" - integrity sha1-QnzqL0MYgUScjjjVIykPFz+f9j0= dependencies: web3-core "1.0.0-beta.34" web3-core-method "1.0.0-beta.34" @@ -7313,7 +6333,6 @@ web3-net@1.0.0-beta.34: web3-provider-engine@^13.8.0: version "13.8.0" resolved "https://registry.yarnpkg.com/web3-provider-engine/-/web3-provider-engine-13.8.0.tgz#4c7c1ad2af5f1fe10343b8a65495879a2f9c00df" - integrity sha512-fZXhX5VWwWpoFfrfocslyg6P7cN3YWPG/ASaevNfeO80R+nzgoPUBXcWQekSGSsNDkeRTis4aMmpmofYf1TNtQ== dependencies: async "^2.5.0" clone "^2.0.0" @@ -7338,7 +6357,6 @@ web3-provider-engine@^13.8.0: web3-provider-engine@^8.4.0: version "8.6.1" resolved "https://registry.yarnpkg.com/web3-provider-engine/-/web3-provider-engine-8.6.1.tgz#4d86e19e30caaf97df351511ec0f60136e5b30eb" - integrity sha1-TYbhnjDKr5ffNRUR7A9gE25bMOs= dependencies: async "^2.1.2" clone "^2.0.0" @@ -7358,7 +6376,6 @@ web3-provider-engine@^8.4.0: web3-providers-http@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.0.0-beta.34.tgz#e561b52bbb43766282007d40285bfe3550c27e7a" - integrity sha1-5WG1K7tDdmKCAH1AKFv+NVDCfno= dependencies: web3-core-helpers "1.0.0-beta.34" xhr2 "0.1.4" @@ -7366,7 +6383,6 @@ web3-providers-http@1.0.0-beta.34: web3-providers-ipc@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.0.0-beta.34.tgz#a1b77f1a306d73649a9c039052e40cb71328d00a" - integrity sha1-obd/GjBtc2SanAOQUuQMtxMo0Ao= dependencies: oboe "2.1.3" underscore "1.8.3" @@ -7375,7 +6391,6 @@ web3-providers-ipc@1.0.0-beta.34: web3-providers-ws@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.0.0-beta.34.tgz#7de70f1b83f2de36476772156becfef6e3516eb3" - integrity sha1-fecPG4Py3jZHZ3IVa+z+9uNRbrM= dependencies: underscore "1.8.3" web3-core-helpers "1.0.0-beta.34" @@ -7384,7 +6399,6 @@ web3-providers-ws@1.0.0-beta.34: web3-shh@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.0.0-beta.34.tgz#975061d71eaec42ccee576f7bd8f70f03844afe0" - integrity sha1-l1Bh1x6uxCzO5Xb3vY9w8DhEr+A= dependencies: web3-core "1.0.0-beta.34" web3-core-method "1.0.0-beta.34" @@ -7394,7 +6408,6 @@ web3-shh@1.0.0-beta.34: web3-utils@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.0.0-beta.34.tgz#9411fc39aaef39ca4e06169f762297d9ff020970" - integrity sha1-lBH8OarvOcpOBhafdiKX2f8CCXA= dependencies: bn.js "4.11.6" eth-lib "0.1.27" @@ -7407,7 +6420,6 @@ web3-utils@1.0.0-beta.34: web3@0.19.1: version "0.19.1" resolved "https://registry.yarnpkg.com/web3/-/web3-0.19.1.tgz#e763d5b1107c4bc24abd4f8cbee1ba3659e6eb31" - integrity sha1-52PVsRB8S8JKvU+MvuG6Nlnm6zE= dependencies: bignumber.js "^4.0.2" crypto-js "^3.1.4" @@ -7418,7 +6430,6 @@ web3@0.19.1: web3@0.20.2: version "0.20.2" resolved "https://registry.yarnpkg.com/web3/-/web3-0.20.2.tgz#c54dac5fc0e377399c04c1a6ecbb12e4513278d6" - integrity sha1-xU2sX8DjdzmcBMGm7LsS5FEyeNY= dependencies: bignumber.js "git+https://github.com/frozeman/bignumber.js-nolookahead.git" crypto-js "^3.1.4" @@ -7429,7 +6440,6 @@ web3@0.20.2: web3@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3/-/web3-1.0.0-beta.34.tgz#347e561b784098cb5563315f490479a1d91f2ab1" - integrity sha1-NH5WG3hAmMtVYzFfSQR5odkfKrE= dependencies: web3-bzz "1.0.0-beta.34" web3-core "1.0.0-beta.34" @@ -7442,7 +6452,6 @@ web3@1.0.0-beta.34: web3@^0.16.0: version "0.16.0" resolved "https://registry.yarnpkg.com/web3/-/web3-0.16.0.tgz#a4554175cd462943035b1f1d39432f741c6b6019" - integrity sha1-pFVBdc1GKUMDWx8dOUMvdBxrYBk= dependencies: bignumber.js "git+https://github.com/debris/bignumber.js#master" crypto-js "^3.1.4" @@ -7452,7 +6461,6 @@ web3@^0.16.0: web3@^0.18.2, web3@^0.18.4: version "0.18.4" resolved "https://registry.yarnpkg.com/web3/-/web3-0.18.4.tgz#81ec1784145491f2eaa8955b31c06049e07c5e7d" - integrity sha1-gewXhBRUkfLqqJVbMcBgSeB8Xn0= dependencies: bignumber.js "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2" crypto-js "^3.1.4" @@ -7463,7 +6471,6 @@ web3@^0.18.2, web3@^0.18.4: web3@^0.20.6: version "0.20.7" resolved "https://registry.yarnpkg.com/web3/-/web3-0.20.7.tgz#1605e6d81399ed6f85a471a4f3da0c8be57df2f7" - integrity sha512-VU6/DSUX93d1fCzBz7WP/SGCQizO1rKZi4Px9j/3yRyfssHyFcZamMw2/sj4E8TlfMXONvZLoforR8B4bRoyTQ== dependencies: bignumber.js "git+https://github.com/frozeman/bignumber.js-nolookahead.git" crypto-js "^3.1.4" @@ -7474,7 +6481,6 @@ web3@^0.20.6: websocket@^1.0.28: version "1.0.28" resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.28.tgz#9e5f6fdc8a3fe01d4422647ef93abdd8d45a78d3" - integrity sha512-00y/20/80P7H4bCYkzuuvvfDvh+dgtXi5kzDf3UcZwN6boTYaKvsrtZ5lIYm1Gsg48siMErd9M4zjSYfYFHTrA== dependencies: debug "^2.2.0" nan "^2.11.0" @@ -7493,41 +6499,34 @@ websocket@^1.0.28: whatwg-fetch@>=0.10.0: version "3.0.0" resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb" - integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q== which-module@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" - integrity sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8= which-module@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= which@^1.1.1, which@^1.2.9: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== dependencies: isexe "^2.0.0" wide-align@^1.1.0: version "1.1.3" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" - integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== dependencies: string-width "^1.0.2 || 2" window-size@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075" - integrity sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU= winston@2.1.x: version "2.1.1" resolved "https://registry.yarnpkg.com/winston/-/winston-2.1.1.tgz#3c9349d196207fd1bdff9d4bc43ef72510e3a12e" - integrity sha1-PJNJ0ZYgf9G9/51LxD73JRDjoS4= dependencies: async "~1.0.0" colors "1.0.x" @@ -7540,7 +6539,6 @@ winston@2.1.x: winston@^2.3.1: version "2.4.4" resolved "https://registry.yarnpkg.com/winston/-/winston-2.4.4.tgz#a01e4d1d0a103cf4eada6fc1f886b3110d71c34b" - integrity sha512-NBo2Pepn4hK4V01UfcWcDlmiVTs7VTB1h7bgnB0rgP146bYhMxX0ypCz3lBOfNxCO4Zuek7yeT+y/zM1OfMw4Q== dependencies: async "~1.0.0" colors "1.0.x" @@ -7552,17 +6550,14 @@ winston@^2.3.1: wordwrap@^1.0.0, wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" - integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= wordwrap@~0.0.2: version "0.0.3" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" - integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc= wrap-ansi@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" - integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= dependencies: string-width "^1.0.1" strip-ansi "^3.0.1" @@ -7570,19 +6565,16 @@ wrap-ansi@^2.0.0: wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= write@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" - integrity sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c= dependencies: mkdirp "^0.5.1" ws@^3.0.0: version "3.3.3" resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" - integrity sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA== dependencies: async-limiter "~1.0.0" safe-buffer "~5.1.0" @@ -7591,14 +6583,12 @@ ws@^3.0.0: xhr-request-promise@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/xhr-request-promise/-/xhr-request-promise-0.1.2.tgz#343c44d1ee7726b8648069682d0f840c83b4261d" - integrity sha1-NDxE0e53JrhkgGloLQ+EDIO0Jh0= dependencies: xhr-request "^1.0.1" xhr-request@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/xhr-request/-/xhr-request-1.1.0.tgz#f4a7c1868b9f198723444d82dcae317643f2e2ed" - integrity sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA== dependencies: buffer-to-arraybuffer "^0.0.5" object-assign "^4.1.1" @@ -7611,19 +6601,16 @@ xhr-request@^1.0.1: xhr2-cookies@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz#7d77449d0999197f155cb73b23df72505ed89d48" - integrity sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg= dependencies: cookiejar "^2.1.1" xhr2@*, xhr2@0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/xhr2/-/xhr2-0.1.4.tgz#7f87658847716db5026323812f818cadab387a5f" - integrity sha1-f4dliEdxbbUCYyOBL4GMras4el8= xhr@^2.0.4, xhr@^2.2.0, xhr@^2.3.3: version "2.5.0" resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.5.0.tgz#bed8d1676d5ca36108667692b74b316c496e49dd" - integrity sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ== dependencies: global "~4.3.0" is-function "^1.0.1" @@ -7633,54 +6620,44 @@ xhr@^2.0.4, xhr@^2.2.0, xhr@^2.3.3: xml@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5" - integrity sha1-eLpyAgApxbyHuKgaPPzXS0ovweU= xmlhttprequest@*, xmlhttprequest@1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc" - integrity sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw= xregexp@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-2.0.0.tgz#52a63e56ca0b84a7f3a5f3d61872f126ad7a5943" - integrity sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM= xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" - integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68= 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" - integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= yaeti@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/yaeti/-/yaeti-0.0.6.tgz#f26f484d72684cf42bedfb76970aa1608fbf9577" - integrity sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc= yallist@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= yallist@^3.0.0, yallist@^3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" - integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== yargs-parser@^2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-2.4.1.tgz#85568de3cf150ff49fa51825f03a8c880ddcc5c4" - integrity sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ= dependencies: camelcase "^3.0.0" lodash.assign "^4.0.6" @@ -7688,21 +6665,18 @@ yargs-parser@^2.4.1: yargs-parser@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-8.1.0.tgz#f1376a33b6629a5d063782944da732631e966950" - integrity sha512-yP+6QqN8BmrgW2ggLtTbdrOyBNSI7zBa4IykmiV5R1wl1JWNxQvWhMfMdmzIYtKU7oP3OOInY/tl2ov3BDjnJQ== dependencies: camelcase "^4.1.0" yargs-parser@^9.0.2: version "9.0.2" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-9.0.2.tgz#9ccf6a43460fe4ed40a9bb68f48d43b8a68cc077" - integrity sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc= dependencies: camelcase "^4.1.0" yargs@11.1.0: version "11.1.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-11.1.0.tgz#90b869934ed6e871115ea2ff58b03f4724ed2d77" - integrity sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A== dependencies: cliui "^4.0.0" decamelize "^1.1.1" @@ -7720,7 +6694,6 @@ yargs@11.1.0: yargs@^10.0.3: version "10.1.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-10.1.2.tgz#454d074c2b16a51a43e2fb7807e4f9de69ccb5c5" - integrity sha512-ivSoxqBGYOqQVruxD35+EyCFDYNEFL/Uo6FcOnz+9xZdZzK0Zzw4r4KhbrME1Oo2gOggwJod2MnsdamSG7H9ig== dependencies: cliui "^4.0.0" decamelize "^1.1.1" @@ -7738,7 +6711,6 @@ yargs@^10.0.3: yargs@^4.6.0, yargs@^4.7.1: version "4.8.1" resolved "https://registry.yarnpkg.com/yargs/-/yargs-4.8.1.tgz#c0c42924ca4aaa6b0e6da1739dfb216439f9ddc0" - integrity sha1-wMQpJMpKqmsObaFznfshZDn53cA= dependencies: cliui "^3.2.0" decamelize "^1.1.1" @@ -7758,7 +6730,6 @@ yargs@^4.6.0, yargs@^4.7.1: yauzl@^2.4.2: version "2.10.0" resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" - integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk= dependencies: buffer-crc32 "~0.2.3" fd-slicer "~1.1.0" From 95e7b2cf2686ef6d420ed1c663cb16dde8a48fec Mon Sep 17 00:00:00 2001 From: satyam Date: Tue, 26 Mar 2019 19:34:44 +0530 Subject: [PATCH 68/83] add test cases for the major issue --- test/y_volume_restriction_tm.js | 148 +++++++++++++++++++++++++++++++- 1 file changed, 147 insertions(+), 1 deletion(-) diff --git a/test/y_volume_restriction_tm.js b/test/y_volume_restriction_tm.js index 7074d1afa..f536ac8da 100644 --- a/test/y_volume_restriction_tm.js +++ b/test/y_volume_restriction_tm.js @@ -72,6 +72,7 @@ contract('VolumeRestrictionTransferManager', accounts => { let tempArray = new Array(); let tempArray3 = new Array(); let tempArrayGlobal = new Array(); + let delegateArray = new Array(); // Initial fee for ticker registry and security token registry const initRegFee = web3.utils.toWei("250"); @@ -1359,7 +1360,7 @@ contract('VolumeRestrictionTransferManager', accounts => { assert.equal(data[2].toNumber(), 5); let dataRestriction = await I_VolumeRestrictionTM.defaultRestriction.call(); console.log(` - *** Add Individual restriction data *** + *** Add Default restriction data *** Allowed Tokens: ${dataRestriction[0].dividedBy(new BigNumber(10).pow(18)).toNumber()} StartTime : ${dataRestriction[1].toNumber()} Rolling Period in days : ${dataRestriction[2].toNumber()} @@ -1633,6 +1634,151 @@ contract('VolumeRestrictionTransferManager', accounts => { }); + describe("Test the major issue from the audit", async() => { + + it("Should add the individual restriction for the delegate 2 address", async() => { + await I_GeneralTransferManager.modifyWhitelist( + account_delegate2, + latestTime(), + latestTime(), + latestTime() + duration.days(30), + true, + { + from: token_owner + } + ); + + await I_SecurityToken.mint(account_delegate2, web3.utils.toWei("20"), { from: token_owner }); + + await I_VolumeRestrictionTM.addIndividualRestriction( + account_delegate2, + web3.utils.toWei("12"), + latestTime() + duration.minutes(1), + 2, + latestTime() + duration.days(5.5), + 0, + { + from: token_owner + } + ); + assert.equal((await I_VolumeRestrictionTM.individualRestriction.call(account_delegate2))[2].toNumber(), 2); + + let data = await I_VolumeRestrictionTM.getRestrictedData.call(); + console.log(data[0].length); + await printRestrictedData(data); + + // Add default restriction as well + + await I_VolumeRestrictionTM.removeDefaultRestriction({from: token_owner}); + await I_VolumeRestrictionTM.addDefaultRestriction( + web3.utils.toWei("5"), + latestTime() + duration.minutes(1), + 5, + latestTime() + duration.days(10), + 0, + { + from: token_owner + } + ); + + data = await I_VolumeRestrictionTM.defaultRestriction.call(); + assert.equal(data[0].toNumber(), web3.utils.toWei("5")); + assert.equal(data[2].toNumber(), 5); + let dataRestriction = await I_VolumeRestrictionTM.defaultRestriction.call(); + console.log(` + *** Add Default restriction data *** + Allowed Tokens: ${dataRestriction[0].dividedBy(new BigNumber(10).pow(18)).toNumber()} + StartTime : ${dataRestriction[1].toNumber()} + Rolling Period in days : ${dataRestriction[2].toNumber()} + EndTime : ${dataRestriction[3].toNumber()} + Type of Restriction: ${dataRestriction[4].toNumber()} + `); + }); + + it("Should transact with delegate address 2", async() => { + await increaseTime(duration.minutes(2)); + + let startTime = (await I_VolumeRestrictionTM.individualRestriction.call(account_delegate2))[1].toNumber(); + let rollingPeriod = (await I_VolumeRestrictionTM.individualRestriction.call(account_delegate2))[2].toNumber(); + //sell tokens upto the limit + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei("6"), {from: account_delegate2}); + delegateArray.push(6); + + console.log(`Print the default bucket details`); + let data = await I_VolumeRestrictionTM.getDefaultBucketDetailsToUser.call(account_delegate2); + await print(data, account_delegate2); + assert.equal(data[0].toNumber(), 0); + assert.equal(data[1].toNumber(), 0); + + console.log(`Print the individual bucket details`); + data = await I_VolumeRestrictionTM.getIndividualBucketDetailsToUser.call(account_delegate2); + await print(data, account_delegate2); + + // get the trade amount using the timestamp + let amt = (await I_VolumeRestrictionTM.getTotalTradedByUser.call(account_delegate2, data[0].toNumber())) + .dividedBy(new BigNumber(10).pow(18)).toNumber(); + + // Verify the storage changes + assert.equal(data[0].toNumber(), startTime + duration.days(data[2].toNumber())); + assert.equal(data[1].dividedBy(new BigNumber(10).pow(18)).toNumber(), await calculateSum(rollingPeriod, delegateArray)); + assert.equal(data[2].toNumber(), 0); + assert.equal(amt, 6); + + // Sell more tokens + await increaseTime(duration.days(5.1)); + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei("9"), {from: account_delegate2}); + + delegateArray.push(9); + + console.log(`Print the default bucket details`); + let dataDefault = await I_VolumeRestrictionTM.getDefaultBucketDetailsToUser.call(account_delegate2); + await print(dataDefault, account_delegate2); + assert.equal(dataDefault[0].toNumber(), 0); + assert.equal(dataDefault[1].toNumber(), 0); + console.log(`Print the individual bucket details`); + let dataIndividual = await I_VolumeRestrictionTM.getIndividualBucketDetailsToUser.call(account_delegate2); + await print(dataIndividual, account_delegate2); + + // get the trade amount using the timestamp + let amtTraded = (await I_VolumeRestrictionTM.getTotalTradedByUser.call(account_delegate2, dataIndividual[0])) + .dividedBy(new BigNumber(10).pow(18)).toNumber(); + // Verify the storage changes + assert.equal(dataIndividual[0].toNumber(), startTime + duration.days(dataIndividual[2].toNumber())); + assert.equal(dataIndividual[2].toNumber(), 5); + assert.equal(amtTraded, 9); + }); + + it("Should transact under the default restriction and check whether the bucket data affected or not", async() => { + await increaseTime(duration.days(0.6)); + let individualStartTime = (await I_VolumeRestrictionTM.individualRestriction.call(account_delegate2))[1].toNumber(); + let startTime = (await I_VolumeRestrictionTM.defaultRestriction.call())[1].toNumber(); + let rollingPeriod = (await I_VolumeRestrictionTM.defaultRestriction.call())[2].toNumber(); + + //sell tokens upto the limit + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei("5"), {from: account_delegate2}); + + console.log(`Print the individual bucket details`); + let dataIndividual = await I_VolumeRestrictionTM.getIndividualBucketDetailsToUser.call(account_delegate2); + await print(dataIndividual, account_delegate2); + + // Verify the storage changes + assert.equal(dataIndividual[0].toNumber(), individualStartTime + duration.days(dataIndividual[2].toNumber())); + assert.equal(dataIndividual[2].toNumber(), 5); + + console.log(`Print the default bucket details`); + let data = await I_VolumeRestrictionTM.getDefaultBucketDetailsToUser.call(account_delegate2); + await print(data, account_delegate2); + + // get the trade amount using the timestamp + let amt = (await I_VolumeRestrictionTM.getTotalTradedByUser.call(account_delegate2, data[0].toNumber())) + .dividedBy(new BigNumber(10).pow(18)).toNumber(); + // Verify the storage changes + assert.equal(data[0].toNumber(), dataIndividual[0].toNumber()); + assert.equal(data[2].toNumber(), 0); + assert.equal(amt, 14); + }) + }) + describe("VolumeRestriction Transfer Manager Factory test cases", async () => { it("Should get the exact details of the factory", async () => { From de6decc7ef5e1ecc8277a7be9d7b27218e73a759 Mon Sep 17 00:00:00 2001 From: satyam Date: Tue, 26 Mar 2019 23:32:53 +0530 Subject: [PATCH 69/83] test fix --- test/y_volume_restriction_tm.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/y_volume_restriction_tm.js b/test/y_volume_restriction_tm.js index f536ac8da..e0ee12fd9 100644 --- a/test/y_volume_restriction_tm.js +++ b/test/y_volume_restriction_tm.js @@ -1773,9 +1773,9 @@ contract('VolumeRestrictionTransferManager', accounts => { let amt = (await I_VolumeRestrictionTM.getTotalTradedByUser.call(account_delegate2, data[0].toNumber())) .dividedBy(new BigNumber(10).pow(18)).toNumber(); // Verify the storage changes - assert.equal(data[0].toNumber(), dataIndividual[0].toNumber()); - assert.equal(data[2].toNumber(), 0); - assert.equal(amt, 14); + assert.equal(data[0].toNumber(), dataIndividual[0].toNumber() + 1); + assert.equal(data[2].toNumber(), 5); + assert.equal(amt, 5); }) }) From 1191f3839e2e627c7b448bcc78832c46b06ed92d Mon Sep 17 00:00:00 2001 From: satyam Date: Wed, 27 Mar 2019 10:19:24 +0530 Subject: [PATCH 70/83] improve the test run --- test/y_volume_restriction_tm.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/y_volume_restriction_tm.js b/test/y_volume_restriction_tm.js index e0ee12fd9..0b73b68ff 100644 --- a/test/y_volume_restriction_tm.js +++ b/test/y_volume_restriction_tm.js @@ -1773,7 +1773,7 @@ contract('VolumeRestrictionTransferManager', accounts => { let amt = (await I_VolumeRestrictionTM.getTotalTradedByUser.call(account_delegate2, data[0].toNumber())) .dividedBy(new BigNumber(10).pow(18)).toNumber(); // Verify the storage changes - assert.equal(data[0].toNumber(), dataIndividual[0].toNumber() + 1); + assert.equal(data[0].toNumber(), startTime + duration.days(data[2].toNumber())); assert.equal(data[2].toNumber(), 5); assert.equal(amt, 5); }) From 60b2aa057c8d93623caf3937f2b8370553ed0ae7 Mon Sep 17 00:00:00 2001 From: satyam Date: Thu, 28 Mar 2019 16:58:57 +0530 Subject: [PATCH 71/83] add the startTime == 0 check --- .../TransferManager/VolumeRestrictionTM.sol | 74 +++++++++++-------- 1 file changed, 44 insertions(+), 30 deletions(-) diff --git a/contracts/modules/TransferManager/VolumeRestrictionTM.sol b/contracts/modules/TransferManager/VolumeRestrictionTM.sol index fdb691223..7a2e9ef58 100644 --- a/contracts/modules/TransferManager/VolumeRestrictionTM.sol +++ b/contracts/modules/TransferManager/VolumeRestrictionTM.sol @@ -193,14 +193,15 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { internal { require(_holder != address(0) && exemptIndex[_holder] == 0, "Invalid address"); - _checkInputParams(_allowedTokens, _startTime, _rollingPeriodInDays, _endTime, _restrictionType, now, false); + uint256 startTime = _getValidStartTime(_startTime); + _checkInputParams(_allowedTokens, startTime, _rollingPeriodInDays, _endTime, _restrictionType, now, false); if (individualRestriction[_holder].endTime != 0) { _removeIndividualRestriction(_holder); } individualRestriction[_holder] = VolumeRestriction( _allowedTokens, - _startTime, + startTime, _rollingPeriodInDays, _endTime, _restrictionType @@ -209,7 +210,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { emit AddIndividualRestriction( _holder, _allowedTokens, - _startTime, + startTime, _rollingPeriodInDays, _endTime, _restrictionType @@ -252,14 +253,15 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { RestrictionType _restrictionType ) internal - { - _checkInputParams(_allowedTokens, _startTime, 1, _endTime, _restrictionType, now, false); + { + uint256 startTime = _getValidStartTime(_startTime); + _checkInputParams(_allowedTokens, startTime, 1, _endTime, _restrictionType, now, false); if (individualDailyRestriction[_holder].endTime != 0) { _removeIndividualDailyRestriction(_holder); } individualDailyRestriction[_holder] = VolumeRestriction( _allowedTokens, - _startTime, + startTime, 1, _endTime, _restrictionType @@ -268,7 +270,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { emit AddIndividualDailyRestriction( _holder, _allowedTokens, - _startTime, + startTime, 1, _endTime, _restrictionType @@ -356,18 +358,19 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { ) external withPerm(ADMIN) - { - _checkInputParams(_allowedTokens, _startTime, _rollingPeriodInDays, _endTime, _restrictionType, now, false); + { + uint256 startTime = _getValidStartTime(_startTime); + _checkInputParams(_allowedTokens, startTime, _rollingPeriodInDays, _endTime, _restrictionType, now, false); defaultRestriction = VolumeRestriction( _allowedTokens, - _startTime, + startTime, _rollingPeriodInDays, _endTime, _restrictionType ); emit AddDefaultRestriction( _allowedTokens, - _startTime, + startTime, _rollingPeriodInDays, _endTime, _restrictionType @@ -389,18 +392,19 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { ) external withPerm(ADMIN) - { - _checkInputParams(_allowedTokens, _startTime, 1, _endTime, _restrictionType, now, false); + { + uint256 startTime = _getValidStartTime(_startTime); + _checkInputParams(_allowedTokens, startTime, 1, _endTime, _restrictionType, now, false); defaultDailyRestriction = VolumeRestriction( _allowedTokens, - _startTime, + startTime, 1, _endTime, _restrictionType ); emit AddDefaultDailyRestriction( _allowedTokens, - _startTime, + startTime, 1, _endTime, _restrictionType @@ -525,10 +529,11 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { internal { _isAllowedToModify(individualRestriction[_holder].startTime); - _checkInputParams(_allowedTokens, _startTime, _rollingPeriodInDays, _endTime, _restrictionType, now, false); + uint256 startTime = _getValidStartTime(_startTime); + _checkInputParams(_allowedTokens, startTime, _rollingPeriodInDays, _endTime, _restrictionType, now, false); individualRestriction[_holder] = VolumeRestriction( _allowedTokens, - _startTime, + startTime, _rollingPeriodInDays, _endTime, _restrictionType @@ -536,7 +541,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { emit ModifyIndividualRestriction( _holder, _allowedTokens, - _startTime, + startTime, _rollingPeriodInDays, _endTime, _restrictionType @@ -581,14 +586,15 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { RestrictionType _restrictionType ) internal - { - _checkInputParams(_allowedTokens, _startTime, 1, _endTime, _restrictionType, + { + uint256 startTime = _getValidStartTime(_startTime); + _checkInputParams(_allowedTokens, startTime, 1, _endTime, _restrictionType, (individualDailyRestriction[_holder].startTime <= now ? individualDailyRestriction[_holder].startTime : now), true ); individualDailyRestriction[_holder] = VolumeRestriction( _allowedTokens, - _startTime, + startTime, 1, _endTime, _restrictionType @@ -596,7 +602,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { emit ModifyIndividualDailyRestriction( _holder, _allowedTokens, - _startTime, + startTime, 1, _endTime, _restrictionType @@ -684,19 +690,20 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { ) external withPerm(ADMIN) - { + { _isAllowedToModify(defaultRestriction.startTime); - _checkInputParams(_allowedTokens, _startTime, _rollingPeriodInDays, _endTime, _restrictionType, now, false); + uint256 startTime = _getValidStartTime(_startTime); + _checkInputParams(_allowedTokens, startTime, _rollingPeriodInDays, _endTime, _restrictionType, now, false); defaultRestriction = VolumeRestriction( _allowedTokens, - _startTime, + startTime, _rollingPeriodInDays, _endTime, _restrictionType ); emit ModifyDefaultRestriction( _allowedTokens, - _startTime, + startTime, _rollingPeriodInDays, _endTime, _restrictionType @@ -720,23 +727,24 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { ) external withPerm(ADMIN) - { + { + uint256 startTime = _getValidStartTime(_startTime); // If old startTime is already passed then new startTime should be greater than or equal to the // old startTime otherwise any past startTime can be allowed in compare to earlier startTime. - _checkInputParams(_allowedTokens, _startTime, 1, _endTime, _restrictionType, + _checkInputParams(_allowedTokens, startTime, 1, _endTime, _restrictionType, (defaultDailyRestriction.startTime <= now ? defaultDailyRestriction.startTime : now), true ); defaultDailyRestriction = VolumeRestriction( _allowedTokens, - _startTime, + startTime, 1, _endTime, _restrictionType ); emit ModifyDefaultDailyRestriction( _allowedTokens, - _startTime, + startTime, 1, _endTime, _restrictionType @@ -1017,6 +1025,12 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { require(_startTime > now, "Not Allowed to modify after startTime passed"); } + function _getValidStartTime(uint256 _startTime) internal view returns(uint256) { + if (_startTime == 0) + _startTime = now + 1; + return _startTime; + } + /** * @notice Use to get the bucket details for a given address * @param _user Address of the token holder for whom the bucket details has queried From 031f5dd9e3b403b2604f805e8f38893a9ffdadde Mon Sep 17 00:00:00 2001 From: satyam Date: Fri, 29 Mar 2019 15:37:59 +0530 Subject: [PATCH 72/83] resolve the edge case when the investors restriction changes --- contracts/libraries/VolumeRestrictionLib.sol | 56 ++++++++ .../TransferManager/VolumeRestrictionTM.sol | 122 +++++++++++------- .../storage/VolumeRestrictionTMStorage.sol | 2 + test/y_volume_restriction_tm.js | 90 +++++++++++-- 4 files changed, 212 insertions(+), 58 deletions(-) diff --git a/contracts/libraries/VolumeRestrictionLib.sol b/contracts/libraries/VolumeRestrictionLib.sol index 7129eecca..2bc38ef51 100644 --- a/contracts/libraries/VolumeRestrictionLib.sol +++ b/contracts/libraries/VolumeRestrictionLib.sol @@ -89,5 +89,61 @@ library VolumeRestrictionLib { return _callFrom; } + function _isValidAmountAfterRestrictionChanges( + uint256 _amountTradedLastDay, + uint256 _amount, + uint256 _sumOfLastPeriod, + uint256 _allowedAmount, + uint256 _lastTradedTimestamp + ) + internal + view + returns(bool) + { + if (BokkyPooBahsDateTimeLibrary.diffSeconds(_lastTradedTimestamp, now) < 86400) { + (uint256 lastTxYear, uint256 lastTxMonth, uint256 lastTxDay) = BokkyPooBahsDateTimeLibrary.timestampToDate(_lastTradedTimestamp); + (uint256 currentTxYear, uint256 currentTxMonth, uint256 currentTxDay) = BokkyPooBahsDateTimeLibrary.timestampToDate(now); + // This if statement is to check whether the last transaction timestamp (of `individualRestriction[_from]` + // when `_isDefault` is true or defaultRestriction when `_isDefault` is false) is comes within the same day of the current + // transaction timestamp or not. + if (lastTxYear == currentTxYear && lastTxMonth == currentTxMonth && lastTxDay == currentTxDay) { + if ((_sumOfLastPeriod.add(_amount)).add(_amountTradedLastDay) > _allowedAmount) + return false; + } + } + return true; + } + + function getAllowedAmount( + VolumeRestrictionTMStorage.RestrictionType _typeOfRestriction, + uint256 _allowedTokens, + address _securityToken + ) + public + view + returns(uint256 allowedAmount) + { + if (_typeOfRestriction == VolumeRestrictionTMStorage.RestrictionType.Percentage) { + allowedAmount = (_allowedTokens.mul(ISecurityToken(_securityToken).totalSupply())) / uint256(10) ** 18; + } else { + allowedAmount = _allowedTokens; + } + } + + function _getBucketDetails(VolumeRestrictionTMStorage.BucketDetails storage _bucket) internal view returns( + uint256, + uint256, + uint256, + uint256, + uint256 + ) { + return( + _bucket.lastTradedDayTime, + _bucket.sumOfLastPeriod, + _bucket.daysCovered, + _bucket.dailyLastTradedDayTime, + _bucket.lastTradedTimestamp + ); + } } diff --git a/contracts/modules/TransferManager/VolumeRestrictionTM.sol b/contracts/modules/TransferManager/VolumeRestrictionTM.sol index 7a2e9ef58..ea009b94c 100644 --- a/contracts/modules/TransferManager/VolumeRestrictionTM.sol +++ b/contracts/modules/TransferManager/VolumeRestrictionTM.sol @@ -191,7 +191,12 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { RestrictionType _restrictionType ) internal - { + { + // It will help to reduce the chances of transaction failure (Specially when the issuer + // wants to set the startTime near to the current block.timestamp) and minting delayed because + // of the gas fee or network congestion that lead to the process block timestamp may grater + // than the given startTime. + _startTime = _getValidStartTime(_startTime); require(_holder != address(0) && exemptIndex[_holder] == 0, "Invalid address"); uint256 startTime = _getValidStartTime(_startTime); _checkInputParams(_allowedTokens, startTime, _rollingPeriodInDays, _endTime, _restrictionType, now, false); @@ -759,7 +764,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { bool _isTransfer, address _from, uint256 _amount, - BucketDetails storage _bucketDetails, + BucketDetails memory _bucketDetails, VolumeRestriction memory _restriction, bool _isDefault ) @@ -767,10 +772,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { returns (Result) { // using the variable to avoid stack too deep error - VolumeRestriction memory dailyRestriction = individualDailyRestriction[_from]; - if (_isDefault) - dailyRestriction = defaultDailyRestriction; - + VolumeRestriction memory dailyRestriction = _isDefault ? defaultDailyRestriction :individualDailyRestriction[_from]; uint256 daysCovered = _restriction.rollingPeriodInDays; uint256 fromTimestamp = 0; uint256 sumOfLastPeriod = 0; @@ -798,7 +800,11 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { _isDefault ); // validation of the transaction amount - if (!_checkValidAmountToTransact(sumOfLastPeriod, _amount, _restriction)) { + if ( + !_checkValidAmountToTransact( + _isDefault, _from, sumOfLastPeriod, _amount, _restriction.typeOfRestriction, _restriction.allowedTokens + ) + ) { allowedDefault = false; } } @@ -819,11 +825,60 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { return ((allowedDaily && allowedDefault) == true ? Result.NA : Result.INVALID); } + /** + * @notice The function is used to check specific edge case where the user restriction type change from + * default to individual or vice versa. It will return true when last transaction traded by the user + * and the current txn timestamp lies in the same day. + */ + function _isValidAmountAfterRestrictionChanges( + bool _isDefault, + address _from, + uint256 _amount, + uint256 _sumOfLastPeriod, + uint256 _allowedAmount + ) + internal + view + returns(bool) + { + BucketDetails storage bucketDetails = _isDefault ? userToBucket[_from] : defaultUserToBucket[_from]; + uint256 amountTradedLastDay = _isDefault ? bucket[_from][bucketDetails.lastTradedDayTime]: defaultBucket[_from][bucketDetails.lastTradedDayTime]; + return VolumeRestrictionLib._isValidAmountAfterRestrictionChanges( + amountTradedLastDay, + _amount, + _sumOfLastPeriod, + _allowedAmount, + bucketDetails.lastTradedTimestamp + ); + } + + function _checkValidAmountToTransact( + bool _isDefault, + address _from, + uint256 _sumOfLastPeriod, + uint256 _amountToTransact, + RestrictionType _typeOfRestriction, + uint256 _allowedTokens + ) + internal + view + returns (bool) + { + uint256 allowedAmount = VolumeRestrictionLib.getAllowedAmount( + _typeOfRestriction, + _allowedTokens, + securityToken + ); + // Validation on the amount to transact + bool allowed = allowedAmount >= _sumOfLastPeriod.add(_amountToTransact); + return (allowed && _isValidAmountAfterRestrictionChanges(_isDefault, _from, _amountToTransact, _sumOfLastPeriod, allowedAmount)); + } + function _dailyTxCheck( address from, uint256 amount, uint256 dailyLastTradedDayTime, - VolumeRestriction restriction, + VolumeRestriction memory restriction, bool isDefault ) internal @@ -834,8 +889,8 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { // the total amount get traded on a particular day (~ _fromTime) if ( now <= restriction.endTime && now >= restriction.startTime) { uint256 txSumOfDay = 0; + // This if condition will be executed when the individual daily restriction executed first time if (dailyLastTradedDayTime == 0 || dailyLastTradedDayTime < restriction.startTime) - // This if condition will be executed when the individual daily restriction executed first time dailyLastTradedDayTime = restriction.startTime.add(BokkyPooBahsDateTimeLibrary.diffDays(restriction.startTime, now).mul(1 days)); else if (now.sub(dailyLastTradedDayTime) >= 1 days) dailyLastTradedDayTime = dailyLastTradedDayTime.add(BokkyPooBahsDateTimeLibrary.diffDays(dailyLastTradedDayTime, now).mul(1 days)); @@ -844,7 +899,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { txSumOfDay = defaultBucket[from][dailyLastTradedDayTime]; else txSumOfDay = bucket[from][dailyLastTradedDayTime]; - return (_checkValidAmountToTransact(txSumOfDay, amount, restriction), dailyLastTradedDayTime); + return (_checkValidAmountToTransact(isDefault, from, txSumOfDay, amount, restriction.typeOfRestriction, restriction.allowedTokens), dailyLastTradedDayTime); } return (true, dailyLastTradedDayTime); } @@ -899,25 +954,6 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { return (sumOfLastPeriod, _fromTime, counter); } - function _checkValidAmountToTransact( - uint256 _sumOfLastPeriod, - uint256 _amountToTransact, - VolumeRestriction _restriction - ) - internal - view - returns (bool) - { - uint256 _allowedAmount = 0; - if (_restriction.typeOfRestriction == RestrictionType.Percentage) { - _allowedAmount = (_restriction.allowedTokens.mul(ISecurityToken(securityToken).totalSupply())) / uint256(10) ** 18; - } else { - _allowedAmount = _restriction.allowedTokens; - } - // Validation on the amount to transact - return (_allowedAmount >= _sumOfLastPeriod.add(_amountToTransact)); - } - function _updateStorage( address _from, uint256 _amount, @@ -966,6 +1002,8 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { if (details.daysCovered != _daysCovered) { details.daysCovered = _daysCovered; } + // Assigning the latest transaction timestamp + details.lastTradedTimestamp = now; if (_amount != 0) { if (_lastTradedDayTime !=0) { details.sumOfLastPeriod = _sumOfLastPeriod.add(_amount); @@ -999,18 +1037,18 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { pure { require(_restrictionType == RestrictionType.Fixed || _restrictionType == RestrictionType.Percentage, - "Invalid restriction type" + "Invalid type" ); if (isModifyDaily) require(_startTime >= _earliestStartTime, "Invalid startTime"); else require(_startTime > _earliestStartTime, "Invalid startTime"); if (_restrictionType == RestrictionType.Fixed) { - require(_allowedTokens > 0, "Invalid tokens value"); + require(_allowedTokens > 0, "Invalid value"); } else { require( _allowedTokens > 0 && _allowedTokens <= 100 * 10 ** 16, - "Invalid tokens value" + "Invalid value" ); } // Maximum limit for the rollingPeriod is 365 days @@ -1022,7 +1060,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { } function _isAllowedToModify(uint256 _startTime) internal view { - require(_startTime > now, "Not Allowed to modify after startTime passed"); + require(_startTime > now, "Start time already passed"); } function _getValidStartTime(uint256 _startTime) internal view returns(uint256) { @@ -1039,13 +1077,8 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { * @return uint256 days covered * @return uint256 24h lastTradedDayTime */ - function getIndividualBucketDetailsToUser(address _user) external view returns(uint256, uint256, uint256, uint256) { - return( - userToBucket[_user].lastTradedDayTime, - userToBucket[_user].sumOfLastPeriod, - userToBucket[_user].daysCovered, - userToBucket[_user].dailyLastTradedDayTime - ); + function getIndividualBucketDetailsToUser(address _user) external view returns(uint256, uint256, uint256, uint256, uint256) { + return VolumeRestrictionLib._getBucketDetails(userToBucket[_user]); } /** @@ -1056,13 +1089,8 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { * @return uint256 days covered * @return uint256 24h lastTradedDayTime */ - function getDefaultBucketDetailsToUser(address _user) external view returns(uint256, uint256, uint256, uint256) { - return( - defaultUserToBucket[_user].lastTradedDayTime, - defaultUserToBucket[_user].sumOfLastPeriod, - defaultUserToBucket[_user].daysCovered, - defaultUserToBucket[_user].dailyLastTradedDayTime - ); + function getDefaultBucketDetailsToUser(address _user) external view returns(uint256, uint256, uint256, uint256, uint256) { + return VolumeRestrictionLib._getBucketDetails(defaultUserToBucket[_user]); } /** diff --git a/contracts/storage/VolumeRestrictionTMStorage.sol b/contracts/storage/VolumeRestrictionTMStorage.sol index b8d62c988..bf6555ac9 100644 --- a/contracts/storage/VolumeRestrictionTMStorage.sol +++ b/contracts/storage/VolumeRestrictionTMStorage.sol @@ -39,6 +39,8 @@ contract VolumeRestrictionTMStorage { uint256 sumOfLastPeriod; // It is the sum of transacted amount within the last rollingPeriodDays uint256 daysCovered; // No of days covered till (from the startTime of VolumeRestriction) uint256 dailyLastTradedDayTime; + uint256 lastTradedTimestamp; // It is the timestamp at which last transaction get executed + uint256 lastTradedAmount; // It is the timestamp at which last transaction get executed } // Global restriction that applies to all token holders diff --git a/test/y_volume_restriction_tm.js b/test/y_volume_restriction_tm.js index 0b73b68ff..97e8feda0 100644 --- a/test/y_volume_restriction_tm.js +++ b/test/y_volume_restriction_tm.js @@ -87,6 +87,7 @@ contract('VolumeRestrictionTransferManager', accounts => { .dividedBy(new BigNumber(10).pow(18)).toNumber()} Individual Total Trade on daily latestTimestamp : ${(await I_VolumeRestrictionTM.getTotalTradedByUser.call(account, data[3])) .dividedBy(new BigNumber(10).pow(18)).toNumber()} + Last Transaction time in UTC: ${(new Date((data[4].toNumber()) * 1000 )).toUTCString()} `) } @@ -115,6 +116,14 @@ contract('VolumeRestrictionTransferManager', accounts => { return sum; } + async function setTime() { + let currentTime = latestTime(); + let currentHour = (new Date(currentTime * 1000)).getUTCHours(); + console.log(`Earlier time ${new Date(latestTime() * 1000).toUTCString()}`); + await increaseTime(duration.hours(24 - currentHour)); + console.log(`Current time ${new Date(latestTime() * 1000).toUTCString()}`); + } + before(async () => { // Accounts setup account_polymath = accounts[0]; @@ -1634,8 +1643,8 @@ contract('VolumeRestrictionTransferManager', accounts => { }); - describe("Test the major issue from the audit", async() => { - + describe("Test the major issue from the audit ( Possible accounting corruption between individualRestriction​ and ​defaultRestriction)", async() => { + it("Should add the individual restriction for the delegate 2 address", async() => { await I_GeneralTransferManager.modifyWhitelist( account_delegate2, @@ -1648,7 +1657,9 @@ contract('VolumeRestrictionTransferManager', accounts => { } ); - await I_SecurityToken.mint(account_delegate2, web3.utils.toWei("20"), { from: token_owner }); + await I_SecurityToken.mint(account_delegate2, web3.utils.toWei("50"), { from: token_owner }); + // Use to set the time to start of the day 0:00 to test the edge case properly + await setTime(); await I_VolumeRestrictionTM.addIndividualRestriction( account_delegate2, @@ -1664,7 +1675,6 @@ contract('VolumeRestrictionTransferManager', accounts => { assert.equal((await I_VolumeRestrictionTM.individualRestriction.call(account_delegate2))[2].toNumber(), 2); let data = await I_VolumeRestrictionTM.getRestrictedData.call(); - console.log(data[0].length); await printRestrictedData(data); // Add default restriction as well @@ -1674,7 +1684,7 @@ contract('VolumeRestrictionTransferManager', accounts => { web3.utils.toWei("5"), latestTime() + duration.minutes(1), 5, - latestTime() + duration.days(10), + latestTime() + duration.days(20), 0, { from: token_owner @@ -1748,18 +1758,27 @@ contract('VolumeRestrictionTransferManager', accounts => { assert.equal(amtTraded, 9); }); - it("Should transact under the default restriction and check whether the bucket data affected or not", async() => { + it("Should fail to transact -- edge case when user restriction changes and do the transfer on the same day", async() => { await increaseTime(duration.days(0.6)); + //sell tokens upto the limit + await catchRevert( + I_SecurityToken.transfer(account_investor2, web3.utils.toWei("5"), {from: account_delegate2}) + ); + }); + + it("Should transact under the default restriction unaffected from the edge case", async() => { + await increaseTime(duration.days(0.5)); let individualStartTime = (await I_VolumeRestrictionTM.individualRestriction.call(account_delegate2))[1].toNumber(); let startTime = (await I_VolumeRestrictionTM.defaultRestriction.call())[1].toNumber(); let rollingPeriod = (await I_VolumeRestrictionTM.defaultRestriction.call())[2].toNumber(); //sell tokens upto the limit - await I_SecurityToken.transfer(account_investor2, web3.utils.toWei("5"), {from: account_delegate2}); + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei("4"), {from: account_delegate2}); console.log(`Print the individual bucket details`); let dataIndividual = await I_VolumeRestrictionTM.getIndividualBucketDetailsToUser.call(account_delegate2); await print(dataIndividual, account_delegate2); + console.log(dataIndividual[4].toString()); // Verify the storage changes assert.equal(dataIndividual[0].toNumber(), individualStartTime + duration.days(dataIndividual[2].toNumber())); @@ -1768,16 +1787,65 @@ contract('VolumeRestrictionTransferManager', accounts => { console.log(`Print the default bucket details`); let data = await I_VolumeRestrictionTM.getDefaultBucketDetailsToUser.call(account_delegate2); await print(data, account_delegate2); + console.log(data[4].toString()); // get the trade amount using the timestamp let amt = (await I_VolumeRestrictionTM.getTotalTradedByUser.call(account_delegate2, data[0].toNumber())) .dividedBy(new BigNumber(10).pow(18)).toNumber(); // Verify the storage changes assert.equal(data[0].toNumber(), startTime + duration.days(data[2].toNumber())); - assert.equal(data[2].toNumber(), 5); - assert.equal(amt, 5); - }) - }) + assert.equal(data[2].toNumber(), 6); + assert.equal(amt, 4); + }); + + it("Should check whether user is able to transfer when amount is less than the restriction limit (when restriction change)", async() => { + + await I_VolumeRestrictionTM.addIndividualRestriction( + account_delegate2, + web3.utils.toWei("7"), + latestTime() + duration.minutes(1), + 1, + latestTime() + duration.days(2), + 0, + { + from: token_owner + } + ); + assert.equal((await I_VolumeRestrictionTM.individualRestriction.call(account_delegate2))[2].toNumber(), 1); + let individualStartTime = (await I_VolumeRestrictionTM.individualRestriction.call(account_delegate2))[1].toNumber(); + let startTime = (await I_VolumeRestrictionTM.defaultRestriction.call())[1].toNumber(); + let rollingPeriod = (await I_VolumeRestrictionTM.defaultRestriction.call())[2].toNumber(); + + await increaseTime(duration.minutes(2)); + + // sell tokens when user restriction changes from the default restriction to individual restriction + await catchRevert (I_SecurityToken.transfer(account_investor1, web3.utils.toWei("5")), {from: account_delegate2}); + + // allow to transact when the day limit is with in the restriction. default allow to transact maximum 5 tokens within + // a given rolling period. 4 tokens are already sold here user trying to sell 1 more token on the same day + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei("1"), {from: account_delegate2}); + + console.log(`Print the individual bucket details`); + let dataIndividual = await I_VolumeRestrictionTM.getIndividualBucketDetailsToUser.call(account_delegate2); + await print(dataIndividual, account_delegate2); + + // Verify the storage changes + assert.equal(dataIndividual[0].toNumber(), individualStartTime + duration.days(dataIndividual[2].toNumber())); + assert.equal(dataIndividual[2].toNumber(), 0); + // get the trade amount using the timestamp + let amt = (await I_VolumeRestrictionTM.getTotalTradedByUser.call(account_delegate2, dataIndividual[0].toNumber())) + .dividedBy(new BigNumber(10).pow(18)).toNumber(); + assert.equal(amt, 1); + + console.log(`Print the default bucket details`); + let data = await I_VolumeRestrictionTM.getDefaultBucketDetailsToUser.call(account_delegate2); + await print(data, account_delegate2); + + // Verify the storage changes + assert.equal(data[0].toNumber(), startTime + duration.days(data[2].toNumber())); + assert.equal(data[2].toNumber(), 6); + }); + }); describe("VolumeRestriction Transfer Manager Factory test cases", async () => { From 36723052ac4b79c097f418e18cd834b9a4135dca Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Fri, 29 Mar 2019 16:03:42 +0530 Subject: [PATCH 73/83] Minor change --- .../TransferManager/VolumeRestrictionTM.sol | 59 +++++++++---------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/contracts/modules/TransferManager/VolumeRestrictionTM.sol b/contracts/modules/TransferManager/VolumeRestrictionTM.sol index ea009b94c..1c0cb6792 100644 --- a/contracts/modules/TransferManager/VolumeRestrictionTM.sol +++ b/contracts/modules/TransferManager/VolumeRestrictionTM.sol @@ -118,13 +118,13 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { // Checking the individual restriction if the `_from` comes in the individual category if ((individualRestriction[_from].endTime >= now && individualRestriction[_from].startTime <= now) || (individualDailyRestriction[_from].endTime >= now && individualDailyRestriction[_from].startTime <= now)) { - + return _restrictionCheck(_isTransfer, _from, _amount, userToBucket[_from], individualRestriction[_from], false); - + // If the `_from` doesn't fall under the individual category. It will processed with in the global category automatically } else if ((defaultRestriction.endTime >= now && defaultRestriction.startTime <= now) || (defaultDailyRestriction.endTime >= now && defaultDailyRestriction.startTime <= now)) { - + return _restrictionCheck(_isTransfer, _from, _amount, defaultUserToBucket[_from], defaultRestriction, true); } } @@ -191,22 +191,21 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { RestrictionType _restrictionType ) internal - { + { // It will help to reduce the chances of transaction failure (Specially when the issuer // wants to set the startTime near to the current block.timestamp) and minting delayed because // of the gas fee or network congestion that lead to the process block timestamp may grater - // than the given startTime. + // than the given startTime. _startTime = _getValidStartTime(_startTime); require(_holder != address(0) && exemptIndex[_holder] == 0, "Invalid address"); - uint256 startTime = _getValidStartTime(_startTime); - _checkInputParams(_allowedTokens, startTime, _rollingPeriodInDays, _endTime, _restrictionType, now, false); + _checkInputParams(_allowedTokens, _startTime, _rollingPeriodInDays, _endTime, _restrictionType, now, false); if (individualRestriction[_holder].endTime != 0) { _removeIndividualRestriction(_holder); } individualRestriction[_holder] = VolumeRestriction( _allowedTokens, - startTime, + _startTime, _rollingPeriodInDays, _endTime, _restrictionType @@ -215,7 +214,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { emit AddIndividualRestriction( _holder, _allowedTokens, - startTime, + _startTime, _rollingPeriodInDays, _endTime, _restrictionType @@ -258,15 +257,15 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { RestrictionType _restrictionType ) internal - { - uint256 startTime = _getValidStartTime(_startTime); - _checkInputParams(_allowedTokens, startTime, 1, _endTime, _restrictionType, now, false); + { + _startTime = _getValidStartTime(_startTime); + _checkInputParams(_allowedTokens, _startTime, 1, _endTime, _restrictionType, now, false); if (individualDailyRestriction[_holder].endTime != 0) { _removeIndividualDailyRestriction(_holder); } individualDailyRestriction[_holder] = VolumeRestriction( _allowedTokens, - startTime, + _startTime, 1, _endTime, _restrictionType @@ -275,7 +274,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { emit AddIndividualDailyRestriction( _holder, _allowedTokens, - startTime, + _startTime, 1, _endTime, _restrictionType @@ -363,7 +362,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { ) external withPerm(ADMIN) - { + { uint256 startTime = _getValidStartTime(_startTime); _checkInputParams(_allowedTokens, startTime, _rollingPeriodInDays, _endTime, _restrictionType, now, false); defaultRestriction = VolumeRestriction( @@ -397,7 +396,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { ) external withPerm(ADMIN) - { + { uint256 startTime = _getValidStartTime(_startTime); _checkInputParams(_allowedTokens, startTime, 1, _endTime, _restrictionType, now, false); defaultDailyRestriction = VolumeRestriction( @@ -591,7 +590,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { RestrictionType _restrictionType ) internal - { + { uint256 startTime = _getValidStartTime(_startTime); _checkInputParams(_allowedTokens, startTime, 1, _endTime, _restrictionType, (individualDailyRestriction[_holder].startTime <= now ? individualDailyRestriction[_holder].startTime : now), @@ -695,7 +694,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { ) external withPerm(ADMIN) - { + { _isAllowedToModify(defaultRestriction.startTime); uint256 startTime = _getValidStartTime(_startTime); _checkInputParams(_allowedTokens, startTime, _rollingPeriodInDays, _endTime, _restrictionType, now, false); @@ -732,7 +731,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { ) external withPerm(ADMIN) - { + { uint256 startTime = _getValidStartTime(_startTime); // If old startTime is already passed then new startTime should be greater than or equal to the // old startTime otherwise any past startTime can be allowed in compare to earlier startTime. @@ -767,9 +766,9 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { BucketDetails memory _bucketDetails, VolumeRestriction memory _restriction, bool _isDefault - ) + ) internal - returns (Result) + returns (Result) { // using the variable to avoid stack too deep error VolumeRestriction memory dailyRestriction = _isDefault ? defaultDailyRestriction :individualDailyRestriction[_from]; @@ -808,7 +807,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { allowedDefault = false; } } - + (allowedDaily, dailyTime) = _dailyTxCheck(_from, _amount, _bucketDetails.dailyLastTradedDayTime, dailyRestriction, _isDefault); if (_isTransfer) { @@ -827,7 +826,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { /** * @notice The function is used to check specific edge case where the user restriction type change from - * default to individual or vice versa. It will return true when last transaction traded by the user + * default to individual or vice versa. It will return true when last transaction traded by the user * and the current txn timestamp lies in the same day. */ function _isValidAmountAfterRestrictionChanges( @@ -836,9 +835,9 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { uint256 _amount, uint256 _sumOfLastPeriod, uint256 _allowedAmount - ) + ) internal - view + view returns(bool) { BucketDetails storage bucketDetails = _isDefault ? userToBucket[_from] : defaultUserToBucket[_from]; @@ -895,7 +894,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { else if (now.sub(dailyLastTradedDayTime) >= 1 days) dailyLastTradedDayTime = dailyLastTradedDayTime.add(BokkyPooBahsDateTimeLibrary.diffDays(dailyLastTradedDayTime, now).mul(1 days)); // Assgining total sum traded on dailyLastTradedDayTime timestamp - if (isDefault) + if (isDefault) txSumOfDay = defaultBucket[from][dailyLastTradedDayTime]; else txSumOfDay = bucket[from][dailyLastTradedDayTime]; @@ -1010,16 +1009,16 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { // Increasing the total amount of the day by `_amount` if (isDefault) defaultBucket[_from][_lastTradedDayTime] = defaultBucket[_from][_lastTradedDayTime].add(_amount); - else + else bucket[_from][_lastTradedDayTime] = bucket[_from][_lastTradedDayTime].add(_amount); } if ((_dailyLastTradedDayTime != _lastTradedDayTime) && _dailyLastTradedDayTime != 0 && now <= _endTime) { // Increasing the total amount of the day by `_amount` if (isDefault) defaultBucket[_from][_dailyLastTradedDayTime] = defaultBucket[_from][_dailyLastTradedDayTime].add(_amount); - else + else bucket[_from][_dailyLastTradedDayTime] = bucket[_from][_dailyLastTradedDayTime].add(_amount); - + } } } @@ -1036,7 +1035,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { internal pure { - require(_restrictionType == RestrictionType.Fixed || _restrictionType == RestrictionType.Percentage, + require(_restrictionType == RestrictionType.Fixed || _restrictionType == RestrictionType.Percentage, "Invalid type" ); if (isModifyDaily) From 6aba6b94aab414ba797574069e1c9556f2ee24b5 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Fri, 29 Mar 2019 16:44:06 +0530 Subject: [PATCH 74/83] VRTM size reduction to 24.21KB --- contracts/libraries/VolumeRestrictionLib.sol | 26 ++++---- .../TransferManager/VolumeRestrictionTM.sol | 60 +++++++++---------- 2 files changed, 41 insertions(+), 45 deletions(-) diff --git a/contracts/libraries/VolumeRestrictionLib.sol b/contracts/libraries/VolumeRestrictionLib.sol index 2bc38ef51..98c9d4205 100644 --- a/contracts/libraries/VolumeRestrictionLib.sol +++ b/contracts/libraries/VolumeRestrictionLib.sol @@ -34,8 +34,8 @@ library VolumeRestrictionLib { VolumeRestrictionTMStorage.RestrictedData storage data, address _holder, VolumeRestrictionTMStorage.TypeOfPeriod _typeOfPeriod - ) - public + ) + public { // Deleting the holder if holder's type of Period is `Both` type otherwise // it will assign the given type `_typeOfPeriod` to the _holder typeOfPeriod @@ -60,10 +60,10 @@ library VolumeRestrictionLib { function addRestrictionData( VolumeRestrictionTMStorage.RestrictedData storage data, address _holder, - VolumeRestrictionTMStorage.TypeOfPeriod _callFrom, + VolumeRestrictionTMStorage.TypeOfPeriod _callFrom, uint256 _endTime - ) - public + ) + public { uint128 index = data.restrictedHolders[_holder].index; if (data.restrictedHolders[_holder].seen == 0) { @@ -78,7 +78,7 @@ library VolumeRestrictionLib { VolumeRestrictionTMStorage.TypeOfPeriod _currentTypeOfPeriod, VolumeRestrictionTMStorage.TypeOfPeriod _callFrom, uint256 _endTime - ) + ) internal pure returns(VolumeRestrictionTMStorage.TypeOfPeriod) @@ -89,14 +89,14 @@ library VolumeRestrictionLib { return _callFrom; } - function _isValidAmountAfterRestrictionChanges( + function isValidAmountAfterRestrictionChanges( uint256 _amountTradedLastDay, uint256 _amount, uint256 _sumOfLastPeriod, uint256 _allowedAmount, uint256 _lastTradedTimestamp ) - internal + public view returns(bool) { @@ -111,16 +111,16 @@ library VolumeRestrictionLib { return false; } } - return true; + return true; } function getAllowedAmount( - VolumeRestrictionTMStorage.RestrictionType _typeOfRestriction, + VolumeRestrictionTMStorage.RestrictionType _typeOfRestriction, uint256 _allowedTokens, address _securityToken - ) - public - view + ) + internal + view returns(uint256 allowedAmount) { if (_typeOfRestriction == VolumeRestrictionTMStorage.RestrictionType.Percentage) { diff --git a/contracts/modules/TransferManager/VolumeRestrictionTM.sol b/contracts/modules/TransferManager/VolumeRestrictionTM.sol index 1c0cb6792..5a06b4b2b 100644 --- a/contracts/modules/TransferManager/VolumeRestrictionTM.sol +++ b/contracts/modules/TransferManager/VolumeRestrictionTM.sol @@ -10,7 +10,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { using SafeMath for uint256; // permission definition - bytes32 public constant ADMIN = "ADMIN"; + bytes32 internal constant ADMIN = "ADMIN"; // Emit when the token holder is added/removed from the exemption list event ChangedExemptWalletList(address indexed _wallet, bool _change); @@ -138,13 +138,14 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { */ function changeExemptWalletList(address _wallet, bool _change) external withPerm(ADMIN) { require(_wallet != address(0)); - require((exemptIndex[_wallet] == 0) == _change); + uint256 exemptIndexWallet = exemptIndex[_wallet]; + require((exemptIndexWallet == 0) == _change); if (_change) { exemptAddresses.push(_wallet); exemptIndex[_wallet] = exemptAddresses.length; } else { - exemptAddresses[exemptIndex[_wallet] - 1] = exemptAddresses[exemptAddresses.length - 1]; - exemptIndex[exemptAddresses[exemptIndex[_wallet] - 1]] = exemptIndex[_wallet]; + exemptAddresses[exemptIndexWallet - 1] = exemptAddresses[exemptAddresses.length - 1]; + exemptIndex[exemptAddresses[exemptIndexWallet - 1]] = exemptIndexWallet; delete exemptIndex[_wallet]; exemptAddresses.length --; } @@ -196,16 +197,16 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { // wants to set the startTime near to the current block.timestamp) and minting delayed because // of the gas fee or network congestion that lead to the process block timestamp may grater // than the given startTime. - _startTime = _getValidStartTime(_startTime); + uint256 startTime = _getValidStartTime(_startTime); require(_holder != address(0) && exemptIndex[_holder] == 0, "Invalid address"); - _checkInputParams(_allowedTokens, _startTime, _rollingPeriodInDays, _endTime, _restrictionType, now, false); + _checkInputParams(_allowedTokens, startTime, _rollingPeriodInDays, _endTime, _restrictionType, now, false); if (individualRestriction[_holder].endTime != 0) { _removeIndividualRestriction(_holder); } individualRestriction[_holder] = VolumeRestriction( _allowedTokens, - _startTime, + startTime, _rollingPeriodInDays, _endTime, _restrictionType @@ -214,7 +215,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { emit AddIndividualRestriction( _holder, _allowedTokens, - _startTime, + startTime, _rollingPeriodInDays, _endTime, _restrictionType @@ -258,14 +259,14 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { ) internal { - _startTime = _getValidStartTime(_startTime); - _checkInputParams(_allowedTokens, _startTime, 1, _endTime, _restrictionType, now, false); + uint256 startTime = _getValidStartTime(_startTime); + _checkInputParams(_allowedTokens, startTime, 1, _endTime, _restrictionType, now, false); if (individualDailyRestriction[_holder].endTime != 0) { _removeIndividualDailyRestriction(_holder); } individualDailyRestriction[_holder] = VolumeRestriction( _allowedTokens, - _startTime, + startTime, 1, _endTime, _restrictionType @@ -274,7 +275,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { emit AddIndividualDailyRestriction( _holder, _allowedTokens, - _startTime, + startTime, 1, _endTime, _restrictionType @@ -296,7 +297,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { uint256[] _endTimes, RestrictionType[] _restrictionTypes ) - external + public //Marked public to save code size withPerm(ADMIN) { //NB - we duplicate _startTimes below to allow function reuse @@ -329,7 +330,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { uint256[] _endTimes, RestrictionType[] _restrictionTypes ) - public + public //Marked public to save code size withPerm(ADMIN) { VolumeRestrictionLib._checkLengthOfArray(_holders, _allowedTokens, _startTimes, _rollingPeriodInDays, _endTimes, _restrictionTypes); @@ -360,7 +361,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { uint256 _endTime, RestrictionType _restrictionType ) - external + public //Marked public to save code size withPerm(ADMIN) { uint256 startTime = _getValidStartTime(_startTime); @@ -394,7 +395,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { uint256 _endTime, RestrictionType _restrictionType ) - external + public //Marked public to save code size withPerm(ADMIN) { uint256 startTime = _getValidStartTime(_startTime); @@ -628,7 +629,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { uint256[] _endTimes, RestrictionType[] _restrictionTypes ) - external + public //Marked public to save code size withPerm(ADMIN) { //NB - we duplicate _startTimes below to allow function reuse @@ -661,7 +662,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { uint256[] _endTimes, RestrictionType[] _restrictionTypes ) - public + public //Marked public to save code size withPerm(ADMIN) { VolumeRestrictionLib._checkLengthOfArray(_holders, _allowedTokens, _startTimes, _rollingPeriodInDays, _endTimes, _restrictionTypes); @@ -692,7 +693,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { uint256 _endTime, RestrictionType _restrictionType ) - external + public //Marked public to save code size withPerm(ADMIN) { _isAllowedToModify(defaultRestriction.startTime); @@ -729,7 +730,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { uint256 _endTime, RestrictionType _restrictionType ) - external + public //Marked public to save code size withPerm(ADMIN) { uint256 startTime = _getValidStartTime(_startTime); @@ -842,7 +843,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { { BucketDetails storage bucketDetails = _isDefault ? userToBucket[_from] : defaultUserToBucket[_from]; uint256 amountTradedLastDay = _isDefault ? bucket[_from][bucketDetails.lastTradedDayTime]: defaultBucket[_from][bucketDetails.lastTradedDayTime]; - return VolumeRestrictionLib._isValidAmountAfterRestrictionChanges( + return VolumeRestrictionLib.isValidAmountAfterRestrictionChanges( amountTradedLastDay, _amount, _sumOfLastPeriod, @@ -1042,13 +1043,9 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { require(_startTime >= _earliestStartTime, "Invalid startTime"); else require(_startTime > _earliestStartTime, "Invalid startTime"); - if (_restrictionType == RestrictionType.Fixed) { - require(_allowedTokens > 0, "Invalid value"); - } else { - require( - _allowedTokens > 0 && _allowedTokens <= 100 * 10 ** 16, - "Invalid value" - ); + require(_allowedTokens > 0, "Invalid value"); + if (_restrictionType != RestrictionType.Fixed) { + require(_allowedTokens <= 100 * 10 ** 16, "Invalid value"); } // Maximum limit for the rollingPeriod is 365 days require(_rollingPeriodDays >= 1 && _rollingPeriodDays <= 365, "Invalid rollingperiod"); @@ -1059,7 +1056,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { } function _isAllowedToModify(uint256 _startTime) internal view { - require(_startTime > now, "Start time already passed"); + require(_startTime > now, "Invalid startTime"); } function _getValidStartTime(uint256 _startTime) internal view returns(uint256) { @@ -1187,10 +1184,9 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { /** * @notice Returns the permissions flag that are associated with Percentage transfer Manager */ - function getPermissions() public view returns(bytes32[]) { - bytes32[] memory allPermissions = new bytes32[](1); + function getPermissions() public view returns(bytes32[] memory allPermissions) { + allPermissions = new bytes32[](1); allPermissions[0] = ADMIN; - return allPermissions; } } From 5a2231a548d7763b7b7a8145f100469ecde18daa Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Fri, 29 Mar 2019 17:19:24 +0530 Subject: [PATCH 75/83] Reduced VRTM size to be under the limit --- contracts/libraries/VolumeRestrictionLib.sol | 53 ------------- .../TransferManager/VolumeRestrictionTM.sol | 76 ++++++++++++++----- 2 files changed, 55 insertions(+), 74 deletions(-) diff --git a/contracts/libraries/VolumeRestrictionLib.sol b/contracts/libraries/VolumeRestrictionLib.sol index 98c9d4205..d0d9de06d 100644 --- a/contracts/libraries/VolumeRestrictionLib.sol +++ b/contracts/libraries/VolumeRestrictionLib.sol @@ -9,27 +9,6 @@ library VolumeRestrictionLib { using SafeMath for uint256; - function _checkLengthOfArray( - address[] _holders, - uint256[] _allowedTokens, - uint256[] _startTimes, - uint256[] _rollingPeriodInDays, - uint256[] _endTimes, - VolumeRestrictionTMStorage.RestrictionType[] _restrictionTypes - ) - internal - pure - { - require( - _holders.length == _allowedTokens.length && - _allowedTokens.length == _startTimes.length && - _startTimes.length == _rollingPeriodInDays.length && - _rollingPeriodInDays.length == _endTimes.length && - _endTimes.length == _restrictionTypes.length, - "Length mismatch" - ); - } - function deleteHolderFromList( VolumeRestrictionTMStorage.RestrictedData storage data, address _holder, @@ -114,36 +93,4 @@ library VolumeRestrictionLib { return true; } - function getAllowedAmount( - VolumeRestrictionTMStorage.RestrictionType _typeOfRestriction, - uint256 _allowedTokens, - address _securityToken - ) - internal - view - returns(uint256 allowedAmount) - { - if (_typeOfRestriction == VolumeRestrictionTMStorage.RestrictionType.Percentage) { - allowedAmount = (_allowedTokens.mul(ISecurityToken(_securityToken).totalSupply())) / uint256(10) ** 18; - } else { - allowedAmount = _allowedTokens; - } - } - - function _getBucketDetails(VolumeRestrictionTMStorage.BucketDetails storage _bucket) internal view returns( - uint256, - uint256, - uint256, - uint256, - uint256 - ) { - return( - _bucket.lastTradedDayTime, - _bucket.sumOfLastPeriod, - _bucket.daysCovered, - _bucket.dailyLastTradedDayTime, - _bucket.lastTradedTimestamp - ); - } - } diff --git a/contracts/modules/TransferManager/VolumeRestrictionTM.sol b/contracts/modules/TransferManager/VolumeRestrictionTM.sol index 5a06b4b2b..6ff35e166 100644 --- a/contracts/modules/TransferManager/VolumeRestrictionTM.sol +++ b/contracts/modules/TransferManager/VolumeRestrictionTM.sol @@ -301,7 +301,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { withPerm(ADMIN) { //NB - we duplicate _startTimes below to allow function reuse - VolumeRestrictionLib._checkLengthOfArray(_holders, _allowedTokens, _startTimes, _startTimes, _endTimes, _restrictionTypes); + _checkLengthOfArray(_holders, _allowedTokens, _startTimes, _startTimes, _endTimes, _restrictionTypes); for (uint256 i = 0; i < _holders.length; i++) { _addIndividualDailyRestriction( _holders[i], @@ -333,7 +333,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { public //Marked public to save code size withPerm(ADMIN) { - VolumeRestrictionLib._checkLengthOfArray(_holders, _allowedTokens, _startTimes, _rollingPeriodInDays, _endTimes, _restrictionTypes); + _checkLengthOfArray(_holders, _allowedTokens, _startTimes, _rollingPeriodInDays, _endTimes, _restrictionTypes); for (uint256 i = 0; i < _holders.length; i++) { _addIndividualRestriction( _holders[i], @@ -633,7 +633,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { withPerm(ADMIN) { //NB - we duplicate _startTimes below to allow function reuse - VolumeRestrictionLib._checkLengthOfArray(_holders, _allowedTokens, _startTimes, _startTimes, _endTimes, _restrictionTypes); + _checkLengthOfArray(_holders, _allowedTokens, _startTimes, _startTimes, _endTimes, _restrictionTypes); for (uint256 i = 0; i < _holders.length; i++) { _modifyIndividualDailyRestriction( _holders[i], @@ -665,7 +665,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { public //Marked public to save code size withPerm(ADMIN) { - VolumeRestrictionLib._checkLengthOfArray(_holders, _allowedTokens, _startTimes, _rollingPeriodInDays, _endTimes, _restrictionTypes); + _checkLengthOfArray(_holders, _allowedTokens, _startTimes, _rollingPeriodInDays, _endTimes, _restrictionTypes); for (uint256 i = 0; i < _holders.length; i++) { _modifyIndividualRestriction( _holders[i], @@ -864,11 +864,12 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { view returns (bool) { - uint256 allowedAmount = VolumeRestrictionLib.getAllowedAmount( - _typeOfRestriction, - _allowedTokens, - securityToken - ); + uint256 allowedAmount; + if (_typeOfRestriction == RestrictionType.Percentage) { + allowedAmount = (_allowedTokens.mul(ISecurityToken(securityToken).totalSupply())) / uint256(10) ** 18; + } else { + allowedAmount = _allowedTokens; + } // Validation on the amount to transact bool allowed = allowedAmount >= _sumOfLastPeriod.add(_amountToTransact); return (allowed && _isValidAmountAfterRestrictionChanges(_isDefault, _from, _amountToTransact, _sumOfLastPeriod, allowedAmount)); @@ -919,14 +920,12 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { { uint256 counter = _bucketDetails.daysCovered; uint256 sumOfLastPeriod = _bucketDetails.sumOfLastPeriod; - uint256 i = 0; if (_diffDays >= _rollingPeriodInDays) { // If the difference of days is greater than the rollingPeriod then sumOfLastPeriod will always be zero sumOfLastPeriod = 0; counter = counter.add(_diffDays); } else { - for (i = 0; i < _diffDays; i++) { - counter++; + for (uint256 diffDaysPlusDaysCovered = _diffDays + counter; counter < diffDaysPlusDaysCovered; counter++) { // This condition is to check whether the first rolling period is covered or not // if not then it continues and adding 0 value into sumOfLastPeriod without subtracting // the earlier value at that index @@ -1000,7 +999,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { details.dailyLastTradedDayTime = _dailyLastTradedDayTime; } if (details.daysCovered != _daysCovered) { - details.daysCovered = _daysCovered; + details.daysCovered = _daysCovered; } // Assigning the latest transaction timestamp details.lastTradedTimestamp = now; @@ -1036,27 +1035,25 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { internal pure { - require(_restrictionType == RestrictionType.Fixed || _restrictionType == RestrictionType.Percentage, - "Invalid type" - ); + require(uint256(_restrictionType) < 2); if (isModifyDaily) require(_startTime >= _earliestStartTime, "Invalid startTime"); else require(_startTime > _earliestStartTime, "Invalid startTime"); - require(_allowedTokens > 0, "Invalid value"); + require(_allowedTokens > 0); if (_restrictionType != RestrictionType.Fixed) { require(_allowedTokens <= 100 * 10 ** 16, "Invalid value"); } // Maximum limit for the rollingPeriod is 365 days require(_rollingPeriodDays >= 1 && _rollingPeriodDays <= 365, "Invalid rollingperiod"); require( - BokkyPooBahsDateTimeLibrary.diffDays(_startTime, _endTime) >= _rollingPeriodDays && _endTime > _startTime, + BokkyPooBahsDateTimeLibrary.diffDays(_startTime, _endTime) >= _rollingPeriodDays, "Invalid times" ); } function _isAllowedToModify(uint256 _startTime) internal view { - require(_startTime > now, "Invalid startTime"); + require(_startTime > now); } function _getValidStartTime(uint256 _startTime) internal view returns(uint256) { @@ -1074,7 +1071,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { * @return uint256 24h lastTradedDayTime */ function getIndividualBucketDetailsToUser(address _user) external view returns(uint256, uint256, uint256, uint256, uint256) { - return VolumeRestrictionLib._getBucketDetails(userToBucket[_user]); + return _getBucketDetails(userToBucket[_user]); } /** @@ -1086,7 +1083,23 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { * @return uint256 24h lastTradedDayTime */ function getDefaultBucketDetailsToUser(address _user) external view returns(uint256, uint256, uint256, uint256, uint256) { - return VolumeRestrictionLib._getBucketDetails(defaultUserToBucket[_user]); + return _getBucketDetails(defaultUserToBucket[_user]); + } + + function _getBucketDetails(BucketDetails storage _bucket) internal view returns( + uint256, + uint256, + uint256, + uint256, + uint256 + ) { + return( + _bucket.lastTradedDayTime, + _bucket.sumOfLastPeriod, + _bucket.daysCovered, + _bucket.dailyLastTradedDayTime, + _bucket.lastTradedTimestamp + ); } /** @@ -1181,6 +1194,27 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { typeOfRestriction[index] = restriction.typeOfRestriction; } + function _checkLengthOfArray( + address[] _holders, + uint256[] _allowedTokens, + uint256[] _startTimes, + uint256[] _rollingPeriodInDays, + uint256[] _endTimes, + VolumeRestrictionTMStorage.RestrictionType[] _restrictionTypes + ) + internal + pure + { + require( + _holders.length == _allowedTokens.length && + _allowedTokens.length == _startTimes.length && + _startTimes.length == _rollingPeriodInDays.length && + _rollingPeriodInDays.length == _endTimes.length && + _endTimes.length == _restrictionTypes.length, + "Length mismatch" + ); + } + /** * @notice Returns the permissions flag that are associated with Percentage transfer Manager */ From 7309dcb2c638234897ac07086bb8aea90da881dd Mon Sep 17 00:00:00 2001 From: satyam Date: Fri, 29 Mar 2019 18:12:00 +0530 Subject: [PATCH 76/83] add the code comments --- contracts/libraries/VolumeRestrictionLib.sol | 5 ++++- contracts/modules/TransferManager/VolumeRestrictionTM.sol | 8 +++++++- test/y_volume_restriction_tm.js | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/contracts/libraries/VolumeRestrictionLib.sol b/contracts/libraries/VolumeRestrictionLib.sol index d0d9de06d..46e1ddb7e 100644 --- a/contracts/libraries/VolumeRestrictionLib.sol +++ b/contracts/libraries/VolumeRestrictionLib.sol @@ -78,7 +78,9 @@ library VolumeRestrictionLib { public view returns(bool) - { + { + // if restriction is to check whether the current transaction is performed within the 24 hours + // span after the last transaction performed by the user if (BokkyPooBahsDateTimeLibrary.diffSeconds(_lastTradedTimestamp, now) < 86400) { (uint256 lastTxYear, uint256 lastTxMonth, uint256 lastTxDay) = BokkyPooBahsDateTimeLibrary.timestampToDate(_lastTradedTimestamp); (uint256 currentTxYear, uint256 currentTxMonth, uint256 currentTxDay) = BokkyPooBahsDateTimeLibrary.timestampToDate(now); @@ -86,6 +88,7 @@ library VolumeRestrictionLib { // when `_isDefault` is true or defaultRestriction when `_isDefault` is false) is comes within the same day of the current // transaction timestamp or not. if (lastTxYear == currentTxYear && lastTxMonth == currentTxMonth && lastTxDay == currentTxDay) { + // Not allow to transact more than the current transaction restriction allowed amount if ((_sumOfLastPeriod.add(_amount)).add(_amountTradedLastDay) > _allowedAmount) return false; } diff --git a/contracts/modules/TransferManager/VolumeRestrictionTM.sol b/contracts/modules/TransferManager/VolumeRestrictionTM.sol index 6ff35e166..b651a4a7a 100644 --- a/contracts/modules/TransferManager/VolumeRestrictionTM.sol +++ b/contracts/modules/TransferManager/VolumeRestrictionTM.sol @@ -829,6 +829,9 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { * @notice The function is used to check specific edge case where the user restriction type change from * default to individual or vice versa. It will return true when last transaction traded by the user * and the current txn timestamp lies in the same day. + * NB - Instead of comparing the current day transaction amount, we are comparing the total amount traded + * on the lastTradedDayTime that makes the restriction strict. The reason is not availability of amount + * that transacted on the current day (because of bucket desgin). */ function _isValidAmountAfterRestrictionChanges( bool _isDefault, @@ -841,6 +844,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { view returns(bool) { + // Always use the alternate bucket details as per the current transaction restriction BucketDetails storage bucketDetails = _isDefault ? userToBucket[_from] : defaultUserToBucket[_from]; uint256 amountTradedLastDay = _isDefault ? bucket[_from][bucketDetails.lastTradedDayTime]: defaultBucket[_from][bucketDetails.lastTradedDayTime]; return VolumeRestrictionLib.isValidAmountAfterRestrictionChanges( @@ -920,12 +924,14 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { { uint256 counter = _bucketDetails.daysCovered; uint256 sumOfLastPeriod = _bucketDetails.sumOfLastPeriod; + uint256 i = 0; if (_diffDays >= _rollingPeriodInDays) { // If the difference of days is greater than the rollingPeriod then sumOfLastPeriod will always be zero sumOfLastPeriod = 0; counter = counter.add(_diffDays); } else { - for (uint256 diffDaysPlusDaysCovered = _diffDays + counter; counter < diffDaysPlusDaysCovered; counter++) { + for (i = 0; i < _diffDays; i++) { + counter++; // This condition is to check whether the first rolling period is covered or not // if not then it continues and adding 0 value into sumOfLastPeriod without subtracting // the earlier value at that index diff --git a/test/y_volume_restriction_tm.js b/test/y_volume_restriction_tm.js index 97e8feda0..2d8bc05f6 100644 --- a/test/y_volume_restriction_tm.js +++ b/test/y_volume_restriction_tm.js @@ -1182,7 +1182,7 @@ contract('VolumeRestrictionTransferManager', accounts => { ); }) - it("Should successfully to transact tokens in the second rolling period", async () => { + it("Should successfully transact tokens in the second rolling period", async () => { // Should transact freely tokens daily limit is also ended let startTime = (await I_VolumeRestrictionTM.individualRestriction.call(account_investor3))[1].toNumber(); From 4c43cf54c05c13fdd00142b04c910a3a26431025 Mon Sep 17 00:00:00 2001 From: satyam Date: Fri, 29 Mar 2019 19:20:45 +0530 Subject: [PATCH 77/83] increase the time to fix the coverage --- test/y_volume_restriction_tm.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/test/y_volume_restriction_tm.js b/test/y_volume_restriction_tm.js index 2d8bc05f6..e456d0c4a 100644 --- a/test/y_volume_restriction_tm.js +++ b/test/y_volume_restriction_tm.js @@ -422,7 +422,7 @@ contract('VolumeRestrictionTransferManager', accounts => { let tx = await I_VolumeRestrictionTM.addIndividualRestriction( account_investor1, web3.utils.toWei("12"), - latestTime() + duration.seconds(2), + latestTime() + duration.seconds(10), 3, latestTime() + duration.days(5), 0, @@ -442,7 +442,7 @@ contract('VolumeRestrictionTransferManager', accounts => { I_VolumeRestrictionTM.addIndividualRestrictionMulti( [account_investor2, account_delegate3, account_investor4], [web3.utils.toWei("12"), web3.utils.toWei("10"), web3.utils.toWei("15")], - [latestTime() + duration.seconds(2), latestTime() + duration.seconds(2), latestTime() + duration.seconds(2)], + [latestTime() + duration.seconds(5), latestTime() + duration.seconds(5), latestTime() + duration.seconds(5)], [3, 4, 5], [latestTime() + duration.days(5), latestTime() + duration.days(6), latestTime() + duration.days(7)], [0, 0, 0], @@ -458,7 +458,7 @@ contract('VolumeRestrictionTransferManager', accounts => { I_VolumeRestrictionTM.addIndividualRestrictionMulti( [account_investor2, account_delegate3], [web3.utils.toWei("12"), web3.utils.toWei("10"), web3.utils.toWei("15")], - [latestTime() + duration.seconds(2), latestTime() + duration.seconds(2), latestTime() + duration.seconds(2)], + [latestTime() + duration.seconds(5), latestTime() + duration.seconds(5), latestTime() + duration.seconds(5)], [3, 4, 5], [latestTime() + duration.days(5), latestTime() + duration.days(6), latestTime() + duration.days(7)], [0, 0, 0], @@ -474,7 +474,7 @@ contract('VolumeRestrictionTransferManager', accounts => { I_VolumeRestrictionTM.addIndividualRestrictionMulti( [account_investor2, account_delegate3, account_investor4], [web3.utils.toWei("12"), web3.utils.toWei("10")], - [latestTime() + duration.seconds(2), latestTime() + duration.seconds(2), latestTime() + duration.seconds(2)], + [latestTime() + duration.seconds(5), latestTime() + duration.seconds(5), latestTime() + duration.seconds(5)], [3, 4, 5], [latestTime() + duration.days(5), latestTime() + duration.days(6), latestTime() + duration.days(7)], [0, 0, 0], @@ -490,7 +490,7 @@ contract('VolumeRestrictionTransferManager', accounts => { I_VolumeRestrictionTM.addIndividualRestrictionMulti( [account_investor2, account_delegate3, account_investor4], [web3.utils.toWei("12"), web3.utils.toWei("10"), web3.utils.toWei("15")], - [latestTime() + duration.seconds(2), latestTime() + duration.seconds(2)], + [latestTime() + duration.seconds(5), latestTime() + duration.seconds(5)], [3, 4, 5], [latestTime() + duration.days(5), latestTime() + duration.days(6), latestTime() + duration.days(7)], [0, 0, 0], @@ -506,7 +506,7 @@ contract('VolumeRestrictionTransferManager', accounts => { I_VolumeRestrictionTM.addIndividualRestrictionMulti( [account_investor2, account_delegate3, account_investor4], [web3.utils.toWei("12"), web3.utils.toWei("10"), web3.utils.toWei("15")], - [latestTime() + duration.seconds(2), latestTime() + duration.seconds(2), latestTime() + duration.seconds(2)], + [latestTime() + duration.seconds(5), latestTime() + duration.seconds(5), latestTime() + duration.seconds(5)], [3], [latestTime() + duration.days(5), latestTime() + duration.days(6), latestTime() + duration.days(7)], [0, 0, 0], @@ -522,7 +522,7 @@ contract('VolumeRestrictionTransferManager', accounts => { I_VolumeRestrictionTM.addIndividualRestrictionMulti( [account_investor2, account_delegate3, account_investor4], [web3.utils.toWei("12"), web3.utils.toWei("10"), web3.utils.toWei("15")], - [latestTime() + duration.seconds(2), latestTime() + duration.seconds(2), latestTime() + duration.seconds(2)], + [latestTime() + duration.seconds(5), latestTime() + duration.seconds(5), latestTime() + duration.seconds(5)], [3, 4, 5], [latestTime() + duration.days(5)], [0, 0, 0], @@ -538,7 +538,7 @@ contract('VolumeRestrictionTransferManager', accounts => { I_VolumeRestrictionTM.addIndividualRestrictionMulti( [account_investor2, account_delegate3, account_investor4], [web3.utils.toWei("12"), web3.utils.toWei("10"), web3.utils.toWei("15")], - [latestTime() + duration.seconds(2), latestTime() + duration.seconds(2), latestTime() + duration.seconds(2)], + [latestTime() + duration.seconds(5), latestTime() + duration.seconds(5), latestTime() + duration.seconds(5)], [3, 4, 5], [latestTime() + duration.days(5), latestTime() + duration.days(6), latestTime() + duration.days(7)], [], @@ -618,7 +618,7 @@ contract('VolumeRestrictionTransferManager', accounts => { ${await I_VolumeRestrictionTM.addIndividualRestriction.estimateGas( account_investor1, web3.utils.toWei("12"), - latestTime() + duration.seconds(5), + 0, 3, latestTime() + duration.days(6), 0, @@ -631,7 +631,7 @@ contract('VolumeRestrictionTransferManager', accounts => { let tx = await I_VolumeRestrictionTM.addIndividualRestriction( account_investor1, web3.utils.toWei("12"), - latestTime() + duration.seconds(5), + 0, 3, latestTime() + duration.days(6), 0, From 8d8760559404b2701a1e901b46b179ddcca4b7c5 Mon Sep 17 00:00:00 2001 From: satyam Date: Fri, 29 Mar 2019 21:42:16 +0530 Subject: [PATCH 78/83] optimize the code --- contracts/libraries/VolumeRestrictionLib.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contracts/libraries/VolumeRestrictionLib.sol b/contracts/libraries/VolumeRestrictionLib.sol index 46e1ddb7e..b0962f231 100644 --- a/contracts/libraries/VolumeRestrictionLib.sol +++ b/contracts/libraries/VolumeRestrictionLib.sol @@ -82,12 +82,12 @@ library VolumeRestrictionLib { // if restriction is to check whether the current transaction is performed within the 24 hours // span after the last transaction performed by the user if (BokkyPooBahsDateTimeLibrary.diffSeconds(_lastTradedTimestamp, now) < 86400) { - (uint256 lastTxYear, uint256 lastTxMonth, uint256 lastTxDay) = BokkyPooBahsDateTimeLibrary.timestampToDate(_lastTradedTimestamp); - (uint256 currentTxYear, uint256 currentTxMonth, uint256 currentTxDay) = BokkyPooBahsDateTimeLibrary.timestampToDate(now); + (,, uint256 lastTxDay) = BokkyPooBahsDateTimeLibrary.timestampToDate(_lastTradedTimestamp); + (,, uint256 currentTxDay) = BokkyPooBahsDateTimeLibrary.timestampToDate(now); // This if statement is to check whether the last transaction timestamp (of `individualRestriction[_from]` // when `_isDefault` is true or defaultRestriction when `_isDefault` is false) is comes within the same day of the current // transaction timestamp or not. - if (lastTxYear == currentTxYear && lastTxMonth == currentTxMonth && lastTxDay == currentTxDay) { + if (lastTxDay == currentTxDay) { // Not allow to transact more than the current transaction restriction allowed amount if ((_sumOfLastPeriod.add(_amount)).add(_amountTradedLastDay) > _allowedAmount) return false; From c4b537daa6600a418e8344b80039eea2eb6fbb82 Mon Sep 17 00:00:00 2001 From: Pablo Ruiz Date: Tue, 2 Apr 2019 08:42:34 -0300 Subject: [PATCH 79/83] updated readme with 2.1.0 mainnet addresses --- README.md | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index d310ec4e5..5e7d97328 100644 --- a/README.md +++ b/README.md @@ -117,7 +117,7 @@ You can easily navigate through it with the sidebar directory in order to run th ## Mainnet -### v2.0.0 +### v2.1.0 | Contract | Address | | ---------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | @@ -127,15 +127,15 @@ You can easily navigate through it with the sidebar directory in order to run th | Feature Registry: | [0xa3eacb03622bf1513880892b7270d965f693ffb5](https://etherscan.io/address/0xa3eacb03622bf1513880892b7270d965f693ffb5) | | ETHOracle: | [0x60055e9a93aae267da5a052e95846fa9469c0e7a](https://etherscan.io/address/0x60055e9a93aae267da5a052e95846fa9469c0e7a) | | POLYOracle: | [0x52cb4616E191Ff664B0bff247469ce7b74579D1B](https://etherscan.io/address/0x52cb4616E191Ff664B0bff247469ce7b74579D1B) | -| General Transfer Manager Factory: | [0xdc95598ef2bbfdb66d02d5f3eea98ea39fbc8b26](https://etherscan.io/address/0xdc95598ef2bbfdb66d02d5f3eea98ea39fbc8b26) | +| General Transfer Manager Factory (2.0.0): | [0xdc95598ef2bbfdb66d02d5f3eea98ea39fbc8b26](https://etherscan.io/address/0xdc95598ef2bbfdb66d02d5f3eea98ea39fbc8b26) | +| General Transfer Manager Factory (2.1.0): | [0xa8b60c9b7054782f46931e35e7012037a574ecee](https://etherscan.io/address/0xa8b60c9b7054782f46931e35e7012037a574ecee) | | General Permission Manager Factory: | [0xf0aa1856360277c60052d6095c5b787b01388cdd](https://etherscan.io/address/0xf0aa1856360277c60052d6095c5b787b01388cdd) | -| CappedSTOFactory: | [0x77d89663e8819023a87bfe2bc9baaa6922c0e57c](https://etherscan.io/address/0x77d89663e8819023a87bfe2bc9baaa6922c0e57c) | -| USDTieredSTO Factory: | [0x5a3a30bddae1f857a19b1aed93b5cdb3c3da809a](https://etherscan.io/address/0x5a3a30bddae1f857a19b1aed93b5cdb3c3da809a) | -| EthDividendsCheckpointFactory: | [0x968c74c52f15b2de323eca8c677f6c9266bfefd6](https://etherscan.io/address/0x968c74c52f15b2de323eca8c677f6c9266bfefd6) | -| ERC20 Dividends Checkpoint Factory: | [0x82f9f1ab41bacb1433c79492e54bf13bccd7f9ae](https://etherscan.io/address/0x82f9f1ab41bacb1433c79492e54bf13bccd7f9ae) | -| Count Transfer Manager Factory: | [0xd9fd7e34d6e2c47a69e02131cf8554d52c3445d5](https://etherscan.io/address/0xd9fd7e34d6e2c47a69e02131cf8554d52c3445d5) | +| CappedSTOFactory (2.1.0): | [0x26bcd18a748ade7fafb250bb014c7121a412870c](https://etherscan.io/address/0x26bcd18a748ade7fafb250bb014c7121a412870c) | +| USDTieredSTO Factory (2.1.0): | [0x0148ed61ffa8e0da7908a62aa2d1f266688656c4](https://etherscan.io/address/0x0148ed61ffa8e0da7908a62aa2d1f266688656c4) | +| ERC20 Dividends Checkpoint Factory (2.1.0): | [0x855152c9b98babadc996a0dd71c8b3682b8f4786](https://etherscan.io/address/0x855152c9b98babadc996a0dd71c8b3682b8f4786) | +| Count Transfer Manager Factory (2.1.0): | [0x575ed30ec5700f369115b079be8059001e79eb7b](https://etherscan.io/address/0x575ed30ec5700f369115b079be8059001e79eb7b) | | Percentage Transfer Manager Factory: | [0xe6267a9c0a227d21c95b782b1bd32bb41fc3b43b](https://etherscan.io/address/0xe6267a9c0a227d21c95b782b1bd32bb41fc3b43b) | -| Manual Approval Transfer Manager Factory (2.0.1): | [0x6af2afad53cb334e62b90ddbdcf3a086f654c298](https://etherscan.io/address/0x6af2afad53cb334e62b90ddbdcf3a086f654c298) | +| Manual Approval Transfer Manager Factory (2.1.0): | [0xe5b21cf83f5e49aba4601e8d8cf182f889208cfd](https://etherscan.io/address/0xe5b21cf83f5e49aba4601e8d8cf182f889208cfd) | New SecurityTokenRegistry (2.0.1): 0x538136ed73011a766bf0a126a27300c3a7a2e6a6 @@ -144,12 +144,9 @@ New SecurityTokenRegistry (2.0.1): 0x538136ed73011a766bf0a126a27300c3a7a2e6a6 New ModuleRegistry (2.0.1): 0xbc18f144ccf87f2d98e6fa0661799fcdc3170119 (fixed bug with missing transferOwnership function) -New ManualApprovalTransferManager 0x6af2afad53cb334e62b90ddbdcf3a086f654c298 -(Fixed 0x0 from bug) - ## KOVAN -### v2.0.0 +### v2.1.0 New Kovan PolyTokenFaucet: 0xb347b9f5b56b431b2cf4e1d90a5995f7519ca792 | Contract | Address | From 5b4f4293ccfe5be407ace75f42fbf46c91741701 Mon Sep 17 00:00:00 2001 From: Victor Date: Tue, 2 Apr 2019 12:15:39 -0300 Subject: [PATCH 80/83] Fix to keep transfer_manager compatible with GTM v1.0.0 --- CLI/commands/transfer_manager.js | 43 +++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/CLI/commands/transfer_manager.js b/CLI/commands/transfer_manager.js index 5a5b148ca..13f59b128 100644 --- a/CLI/commands/transfer_manager.js +++ b/CLI/commands/transfer_manager.js @@ -304,6 +304,11 @@ async function addTransferManagerModule() { async function generalTransferManager() { console.log('\n', chalk.blue(`General Transfer Manager at ${currentTransferManager.options.address}`), '\n'); + let moduleFactoryABI = abis.moduleFactory(); + let factoryAddress = await currentTransferManager.methods.factory().call(); + let moduleFactory = new web3.eth.Contract(moduleFactoryABI, factoryAddress); + let moduleVersion = await moduleFactory.methods.version().call(); + // Show current data let displayIssuanceAddress = await currentTransferManager.methods.issuanceAddress().call(); let displaySigningAddress = await currentTransferManager.methods.signingAddress().call(); @@ -311,27 +316,37 @@ async function generalTransferManager() { let displayAllowAllWhitelistTransfers = await currentTransferManager.methods.allowAllWhitelistTransfers().call(); let displayAllowAllWhitelistIssuances = await currentTransferManager.methods.allowAllWhitelistIssuances().call(); let displayAllowAllBurnTransfers = await currentTransferManager.methods.allowAllBurnTransfers().call(); - let displayDefaults = await currentTransferManager.methods.defaults().call(); - let displayInvestors = await currentTransferManager.methods.getInvestors().call(); - + let displayDefaults; + let displayInvestors; + if (moduleVersion != '1.0.0') { + displayDefaults = await currentTransferManager.methods.defaults().call(); + displayInvestors = await currentTransferManager.methods.getInvestors().call(); + } console.log(`- Issuance address: ${displayIssuanceAddress}`); console.log(`- Signing address: ${displaySigningAddress}`); console.log(`- Allow all transfers: ${displayAllowAllTransfers ? `YES` : `NO`}`); console.log(`- Allow all whitelist transfers: ${displayAllowAllWhitelistTransfers ? `YES` : `NO`}`); console.log(`- Allow all whitelist issuances: ${displayAllowAllWhitelistIssuances ? `YES` : `NO`}`); console.log(`- Allow all burn transfers: ${displayAllowAllBurnTransfers ? `YES` : `NO`}`); - console.log(`- Default times:`); - console.log(` - From time: ${displayDefaults.fromTime} (${moment.unix(displayDefaults.fromTime).format('MMMM Do YYYY, HH:mm:ss')})`); - console.log(` - To time: ${displayDefaults.toTime} (${moment.unix(displayDefaults.toTime).format('MMMM Do YYYY, HH:mm:ss')})`); - console.log(`- Investors: ${displayInvestors.length}`); + if (displayDefaults) { + console.log(`- Default times:`); + console.log(` - From time: ${displayDefaults.fromTime} (${moment.unix(displayDefaults.fromTime).format('MMMM Do YYYY, HH:mm:ss')})`); + console.log(` - To time: ${displayDefaults.toTime} (${moment.unix(displayDefaults.toTime).format('MMMM Do YYYY, HH:mm:ss')})`); + } + if (displayInvestors) { + console.log(`- Investors: ${displayInvestors.length}`); + } // ------------------ let options = []; - if (displayInvestors.length > 0) { + if (displayInvestors && displayInvestors.length > 0) { options.push(`Show investors`, `Show whitelist data`); } - options.push('Modify whitelist', 'Modify whitelist from CSV', /*'Modify Whitelist Signed',*/ - 'Change the default times used when they are zero', `Change issuance address`, 'Change signing address'); + options.push('Modify whitelist', 'Modify whitelist from CSV') /*'Modify Whitelist Signed',*/ + if (displayDefaults) { + options.push('Change the default times used when they are zero'); + } + options.push(`Change issuance address`, 'Change signing address'); if (displayAllowAllTransfers) { options.push('Disallow all transfers'); @@ -401,8 +416,12 @@ async function generalTransferManager() { let canBuyFromSTO = readlineSync.keyInYNStrict('Can the investor buy from security token offerings?'); let modifyWhitelistAction = currentTransferManager.methods.modifyWhitelist(investor, fromTime, toTime, expiryTime, canBuyFromSTO); let modifyWhitelistReceipt = await common.sendTransaction(modifyWhitelistAction); - let modifyWhitelistEvent = common.getEventFromLogs(currentTransferManager._jsonInterface, modifyWhitelistReceipt.logs, 'ModifyWhitelist'); - console.log(chalk.green(`${modifyWhitelistEvent._investor} has been whitelisted sucessfully!`)); + if (moduleVersion != '1.0.0') { + let modifyWhitelistEvent = common.getEventFromLogs(currentTransferManager._jsonInterface, modifyWhitelistReceipt.logs, 'ModifyWhitelist'); + console.log(chalk.green(`${modifyWhitelistEvent._investor} has been whitelisted sucessfully!`)); + } else { + console.log(chalk.green(`${investor} has been whitelisted sucessfully!`)); + } break; case 'Modify whitelist from CSV': await modifyWhitelistInBatch(); From 2e481ac1d904a3b86e67d878dc2010eaa11aaa68 Mon Sep 17 00:00:00 2001 From: satyam Date: Fri, 5 Apr 2019 13:37:09 +0530 Subject: [PATCH 81/83] docs update & minor improvements --- .../TransferManager/VolumeRestrictionTM.sol | 101 +++++++++++------- 1 file changed, 61 insertions(+), 40 deletions(-) diff --git a/contracts/modules/TransferManager/VolumeRestrictionTM.sol b/contracts/modules/TransferManager/VolumeRestrictionTM.sol index b651a4a7a..0c6818c03 100644 --- a/contracts/modules/TransferManager/VolumeRestrictionTM.sol +++ b/contracts/modules/TransferManager/VolumeRestrictionTM.sol @@ -159,7 +159,8 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { * @param _startTime Unix timestamp at which restriction get into effect * @param _rollingPeriodInDays Rolling period in days (Minimum value should be 1 day) * @param _endTime Unix timestamp at which restriction effects will gets end. - * @param _restrictionType It will be 0 or 1 (i.e 0 for fixed while 1 for Percentage) + * @param _restrictionType Whether it will be `Fixed` (fixed no. of tokens allowed to transact) + * or `Percentage` (tokens are calculated as per the totalSupply in the fly). */ function addIndividualRestriction( address _holder, @@ -228,7 +229,8 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { * @param _allowedTokens Amount of tokens allowed to be traded for all token holder. * @param _startTime Unix timestamp at which restriction get into effect * @param _endTime Unix timestamp at which restriction effects will gets end. - * @param _restrictionType It will be 0 or 1 (i.e 0 for fixed while 1 for Percentage) + * @param _restrictionType Whether it will be `Fixed` (fixed no. of tokens allowed to transact) + * or `Percentage` (tokens are calculated as per the totalSupply in the fly). */ function addIndividualDailyRestriction( address _holder, @@ -288,7 +290,8 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { * @param _allowedTokens Array of amount of tokens allowed to be trade for a given address. * @param _startTimes Array of unix timestamps at which restrictions get into effect * @param _endTimes Array of unix timestamps at which restriction effects will gets end. - * @param _restrictionTypes Array of restriction types value will be 0 or 1 (i.e 0 for fixed while 1 for Percentage) + * @param _restrictionTypes Array of restriction types value whether it will be `Fixed` (fixed no. of tokens allowed to transact) + * or `Percentage` (tokens are calculated as per the totalSupply in the fly). */ function addIndividualDailyRestrictionMulti( address[] _holders, @@ -320,7 +323,8 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { * @param _startTimes Array of unix timestamps at which restrictions get into effect * @param _rollingPeriodInDays Array of rolling period in days (Minimum value should be 1 day) * @param _endTimes Array of unix timestamps at which restriction effects will gets end. - * @param _restrictionTypes Array of restriction types value will be 0 or 1 (i.e 0 for fixed while 1 for Percentage) + * @param _restrictionTypes Array of restriction types value whether it will be `Fixed` (fixed no. of tokens allowed to transact) + * or `Percentage` (tokens are calculated as per the totalSupply in the fly). */ function addIndividualRestrictionMulti( address[] _holders, @@ -352,7 +356,8 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { * @param _startTime Unix timestamp at which restriction get into effect * @param _rollingPeriodInDays Rolling period in days (Minimum value should be 1 day) * @param _endTime Unix timestamp at which restriction effects will gets end. - * @param _restrictionType It will be 0 or 1 (i.e 0 for fixed while 1 for Percentage) + * @param _restrictionType Whether it will be `Fixed` (fixed no. of tokens allowed to transact) + * or `Percentage` (tokens are calculated as per the totalSupply in the fly). */ function addDefaultRestriction( uint256 _allowedTokens, @@ -387,7 +392,8 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { * @param _allowedTokens Amount of tokens allowed to be traded for all token holder. * @param _startTime Unix timestamp at which restriction get into effect * @param _endTime Unix timestamp at which restriction effects will gets end. - * @param _restrictionType It will be 0 or 1 (i.e 0 for fixed while 1 for Percentage) + * @param _restrictionType Whether it will be `Fixed` (fixed no. of tokens allowed to transact) + * or `Percentage` (tokens are calculated as per the totalSupply in the fly). */ function addDefaultDailyRestriction( uint256 _allowedTokens, @@ -499,7 +505,8 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { * @param _startTime Unix timestamp at which restriction get into effect * @param _rollingPeriodInDays Rolling period in days (Minimum value should be 1 day) * @param _endTime Unix timestamp at which restriction effects will gets end. - * @param _restrictionType It will be 0 or 1 (i.e 0 for fixed while 1 for Percentage) + * @param _restrictionType Whether it will be `Fixed` (fixed no. of tokens allowed to transact) + * or `Percentage` (tokens are calculated as per the totalSupply in the fly). */ function modifyIndividualRestriction( address _holder, @@ -561,7 +568,8 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { * @param _allowedTokens Amount of tokens allowed to be trade for a given address. * @param _startTime Unix timestamp at which restriction get into effect * @param _endTime Unix timestamp at which restriction effects will gets end. - * @param _restrictionType It will be 0 or 1 (i.e 0 for fixed while 1 for Percentage) + * @param _restrictionType Whether it will be `Fixed` (fixed no. of tokens allowed to transact) + * or `Percentage` (tokens are calculated as per the totalSupply in the fly). */ function modifyIndividualDailyRestriction( address _holder, @@ -620,7 +628,8 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { * @param _allowedTokens Array of amount of tokens allowed to be trade for a given address. * @param _startTimes Array of unix timestamps at which restrictions get into effect * @param _endTimes Array of unix timestamps at which restriction effects will gets end. - * @param _restrictionTypes Array of restriction types value will be 0 or 1 (i.e 0 for fixed while 1 for Percentage) + * @param _restrictionTypes Array of restriction types value whether it will be `Fixed` (fixed no. of tokens allowed to transact) + * or `Percentage` (tokens are calculated as per the totalSupply in the fly). */ function modifyIndividualDailyRestrictionMulti( address[] _holders, @@ -652,7 +661,8 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { * @param _startTimes Array of unix timestamps at which restrictions get into effect * @param _rollingPeriodInDays Array of rolling period in days (Minimum value should be 1 day) * @param _endTimes Array of unix timestamps at which restriction effects will gets end. - * @param _restrictionTypes Array of restriction types value will be 0 or 1 (i.e 0 for fixed while 1 for Percentage) + * @param _restrictionTypes Array of restriction types value whether it will be `Fixed` (fixed no. of tokens allowed to transact) + * or `Percentage` (tokens are calculated as per the totalSupply in the fly). */ function modifyIndividualRestrictionMulti( address[] _holders, @@ -684,7 +694,8 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { * @param _startTime Unix timestamp at which restriction get into effect * @param _rollingPeriodInDays Rolling period in days (Minimum value should be 1 day) * @param _endTime Unix timestamp at which restriction effects will gets end. - * @param _restrictionType It will be 0 or 1 (i.e 0 for fixed while 1 for Percentage) + * @param _restrictionType Whether it will be `Fixed` (fixed no. of tokens allowed to transact) + * or `Percentage` (tokens are calculated as per the totalSupply in the fly). */ function modifyDefaultRestriction( uint256 _allowedTokens, @@ -722,7 +733,8 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { * @param _allowedTokens Amount of tokens allowed to be traded for all token holder. * @param _startTime Unix timestamp at which restriction get into effect * @param _endTime Unix timestamp at which restriction effects will gets end. - * @param _restrictionType It will be 0 or 1 (i.e 0 for fixed while 1 for Percentage) + * @param _restrictionType Whether it will be `Fixed` (fixed no. of tokens allowed to transact) + * or `Percentage` (tokens are calculated as per the totalSupply in the fly). */ function modifyDefaultDailyRestriction( uint256 _allowedTokens, @@ -880,11 +892,11 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { } function _dailyTxCheck( - address from, - uint256 amount, - uint256 dailyLastTradedDayTime, - VolumeRestriction memory restriction, - bool isDefault + address _from, + uint256 _amount, + uint256 _dailyLastTradedDayTime, + VolumeRestriction memory _restriction, + bool _isDefault ) internal view @@ -892,21 +904,31 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { { // Checking whether the daily restriction is added or not if yes then calculate // the total amount get traded on a particular day (~ _fromTime) - if ( now <= restriction.endTime && now >= restriction.startTime) { + if ( now <= _restriction.endTime && now >= _restriction.startTime) { uint256 txSumOfDay = 0; // This if condition will be executed when the individual daily restriction executed first time - if (dailyLastTradedDayTime == 0 || dailyLastTradedDayTime < restriction.startTime) - dailyLastTradedDayTime = restriction.startTime.add(BokkyPooBahsDateTimeLibrary.diffDays(restriction.startTime, now).mul(1 days)); - else if (now.sub(dailyLastTradedDayTime) >= 1 days) - dailyLastTradedDayTime = dailyLastTradedDayTime.add(BokkyPooBahsDateTimeLibrary.diffDays(dailyLastTradedDayTime, now).mul(1 days)); + if (_dailyLastTradedDayTime == 0 || _dailyLastTradedDayTime < _restriction.startTime) + _dailyLastTradedDayTime = _restriction.startTime.add(BokkyPooBahsDateTimeLibrary.diffDays(_restriction.startTime, now).mul(1 days)); + else if (now.sub(_dailyLastTradedDayTime) >= 1 days) + _dailyLastTradedDayTime = _dailyLastTradedDayTime.add(BokkyPooBahsDateTimeLibrary.diffDays(_dailyLastTradedDayTime, now).mul(1 days)); // Assgining total sum traded on dailyLastTradedDayTime timestamp - if (isDefault) - txSumOfDay = defaultBucket[from][dailyLastTradedDayTime]; + if (_isDefault) + txSumOfDay = defaultBucket[_from][_dailyLastTradedDayTime]; else - txSumOfDay = bucket[from][dailyLastTradedDayTime]; - return (_checkValidAmountToTransact(isDefault, from, txSumOfDay, amount, restriction.typeOfRestriction, restriction.allowedTokens), dailyLastTradedDayTime); + txSumOfDay = bucket[_from][_dailyLastTradedDayTime]; + return ( + _checkValidAmountToTransact( + _isDefault, + _from, + txSumOfDay, + _amount, + _restriction.typeOfRestriction, + _restriction.allowedTokens + ), + _dailyLastTradedDayTime + ); } - return (true, dailyLastTradedDayTime); + return (true, _dailyLastTradedDayTime); } /// Internal function for the bucket check @@ -1041,7 +1063,6 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { internal pure { - require(uint256(_restrictionType) < 2); if (isModifyDaily) require(_startTime >= _earliestStartTime, "Invalid startTime"); else @@ -1182,22 +1203,22 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, ITransferManager { } function _setValues( - VolumeRestriction memory restriction, - uint256[] memory allowedTokens, - uint256[] memory startTime, - uint256[] memory rollingPeriodInDays, - uint256[] memory endTime, - RestrictionType[] memory typeOfRestriction, - uint256 index + VolumeRestriction memory _restriction, + uint256[] memory _allowedTokens, + uint256[] memory _startTime, + uint256[] memory _rollingPeriodInDays, + uint256[] memory _endTime, + RestrictionType[] memory _typeOfRestriction, + uint256 _index ) internal pure { - allowedTokens[index] = restriction.allowedTokens; - startTime[index] = restriction.startTime; - rollingPeriodInDays[index] = restriction.rollingPeriodInDays; - endTime[index] = restriction.endTime; - typeOfRestriction[index] = restriction.typeOfRestriction; + _allowedTokens[_index] = _restriction.allowedTokens; + _startTime[_index] = _restriction.startTime; + _rollingPeriodInDays[_index] = _restriction.rollingPeriodInDays; + _endTime[_index] = _restriction.endTime; + _typeOfRestriction[_index] = _restriction.typeOfRestriction; } function _checkLengthOfArray( From 23f87ab1805bba571790da7749e4b518b967220b Mon Sep 17 00:00:00 2001 From: Dmitriy Kostin Date: Thu, 10 Jan 2019 15:33:42 +0200 Subject: [PATCH 82/83] Use bokky's timestamp library in scheduled checkpoint (#466) * added enum TimeUnit * update depends on timeUnit * test for monthly checkpoint * tests for monthly checkpoint * use UTC instead of local time * minor fix * Tests for yearly checkpoint * Tests for last day of month * Updated tests for last day of month * commented failed test * fix for end of month schedule * refactored _update function * added TimeUnits: DAYS, WEEKS --- .../Mixed/ScheduledCheckpoint.sol | 55 ++- test/x_scheduled_checkpoints.js | 461 +++++++++++++++++- 2 files changed, 489 insertions(+), 27 deletions(-) diff --git a/contracts/modules/Experimental/Mixed/ScheduledCheckpoint.sol b/contracts/modules/Experimental/Mixed/ScheduledCheckpoint.sol index 097a44f50..ae02123e7 100644 --- a/contracts/modules/Experimental/Mixed/ScheduledCheckpoint.sol +++ b/contracts/modules/Experimental/Mixed/ScheduledCheckpoint.sol @@ -4,6 +4,7 @@ import "./../../Checkpoint/ICheckpoint.sol"; import "../../TransferManager/ITransferManager.sol"; import "../../../interfaces/ISecurityToken.sol"; import "openzeppelin-solidity/contracts/math/SafeMath.sol"; +import "../../../libraries/BokkyPooBahsDateTimeLibrary.sol"; /** * @title Burn module for burning tokens and keeping track of burnt amounts @@ -11,22 +12,26 @@ import "openzeppelin-solidity/contracts/math/SafeMath.sol"; contract ScheduledCheckpoint is ICheckpoint, ITransferManager { using SafeMath for uint256; + enum TimeUnit {SECONDS, DAYS, WEEKS, MONTHS, YEARS} + struct Schedule { bytes32 name; uint256 startTime; uint256 nextTime; uint256 interval; + TimeUnit timeUnit; uint256 index; uint256[] checkpointIds; uint256[] timestamps; uint256[] periods; + uint256 totalPeriods; } bytes32[] public names; mapping (bytes32 => Schedule) public schedules; - event AddSchedule(bytes32 _name, uint256 _startTime, uint256 _interval, uint256 _timestamp); + event AddSchedule(bytes32 _name, uint256 _startTime, uint256 _interval, TimeUnit _timeUint, uint256 _timestamp); event RemoveSchedule(bytes32 _name, uint256 _timestamp); /** @@ -51,17 +56,19 @@ contract ScheduledCheckpoint is ICheckpoint, ITransferManager { * @param _name name of the new schedule (must be unused) * @param _startTime start time of the schedule (first checkpoint) * @param _interval interval at which checkpoints should be created + * @param _timeUnit unit of time at which checkpoints should be created */ - function addSchedule(bytes32 _name, uint256 _startTime, uint256 _interval) external onlyOwner { + function addSchedule(bytes32 _name, uint256 _startTime, uint256 _interval, TimeUnit _timeUnit) external onlyOwner { require(_startTime > now, "Start time must be in the future"); require(schedules[_name].name == bytes32(0), "Name already in use"); schedules[_name].name = _name; schedules[_name].startTime = _startTime; schedules[_name].nextTime = _startTime; schedules[_name].interval = _interval; + schedules[_name].timeUnit = _timeUnit; schedules[_name].index = names.length; names.push(_name); - emit AddSchedule(_name, _startTime, _interval, now); + emit AddSchedule(_name, _startTime, _interval, _timeUnit, now); } /** @@ -99,15 +106,18 @@ contract ScheduledCheckpoint is ICheckpoint, ITransferManager { * @notice gets schedule details * @param _name name of the schedule */ - function getSchedule(bytes32 _name) view external returns(bytes32, uint256, uint256, uint256, uint256[], uint256[], uint256[]) { + function getSchedule(bytes32 _name) view external returns(bytes32, uint256, uint256, uint256, TimeUnit, uint256[], uint256[], uint256[], uint256) { + Schedule storage schedule = schedules[_name]; return ( - schedules[_name].name, - schedules[_name].startTime, - schedules[_name].nextTime, - schedules[_name].interval, - schedules[_name].checkpointIds, - schedules[_name].timestamps, - schedules[_name].periods + schedule.name, + schedule.startTime, + schedule.nextTime, + schedule.interval, + schedule.timeUnit, + schedule.checkpointIds, + schedule.timestamps, + schedule.periods, + schedule.totalPeriods ); } @@ -123,10 +133,27 @@ contract ScheduledCheckpoint is ICheckpoint, ITransferManager { Schedule storage schedule = schedules[_name]; if (schedule.nextTime <= now) { uint256 checkpointId = ISecurityToken(securityToken).createCheckpoint(); - uint256 periods = now.sub(schedule.nextTime).div(schedule.interval).add(1); - schedule.timestamps.push(schedule.nextTime); - schedule.nextTime = periods.mul(schedule.interval).add(schedule.nextTime); schedule.checkpointIds.push(checkpointId); + schedule.timestamps.push(schedule.nextTime); + uint256 periods; + if (schedule.timeUnit == TimeUnit.SECONDS ) { + periods = now.sub(schedule.nextTime).div(schedule.interval).add(1); + schedule.nextTime = periods.mul(schedule.interval).add(schedule.nextTime); + } else if (schedule.timeUnit == TimeUnit.DAYS ) { + periods = BokkyPooBahsDateTimeLibrary.diffDays(schedule.nextTime, now).div(schedule.interval).add(1); + schedule.nextTime = BokkyPooBahsDateTimeLibrary.addDays(schedule.nextTime, periods.mul(schedule.interval)); + } else if (schedule.timeUnit == TimeUnit.WEEKS ) { + periods = BokkyPooBahsDateTimeLibrary.diffDays(schedule.nextTime, now).div(7).div(schedule.interval).add(1); + schedule.nextTime = BokkyPooBahsDateTimeLibrary.addDays(schedule.nextTime, periods.mul(schedule.interval).mul(7)); + } else if (schedule.timeUnit == TimeUnit.MONTHS ) { + periods = BokkyPooBahsDateTimeLibrary.diffMonths(schedule.nextTime, now).div(schedule.interval).add(1); + uint256 totalPeriods = schedule.totalPeriods.add(periods); + schedule.nextTime = BokkyPooBahsDateTimeLibrary.addMonths(schedule.startTime, totalPeriods.mul(schedule.interval)); + } else if (schedule.timeUnit == TimeUnit.YEARS ) { + periods = BokkyPooBahsDateTimeLibrary.diffYears(schedule.nextTime, now).div(schedule.interval).add(1); + schedule.nextTime = BokkyPooBahsDateTimeLibrary.addYears(schedule.nextTime, periods.mul(schedule.interval)); + } + schedule.totalPeriods = schedule.totalPeriods.add(periods); schedule.periods.push(periods); } } diff --git a/test/x_scheduled_checkpoints.js b/test/x_scheduled_checkpoints.js index 5fcc03a74..1592450a0 100644 --- a/test/x_scheduled_checkpoints.js +++ b/test/x_scheduled_checkpoints.js @@ -15,6 +15,12 @@ const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) contract('ScheduledCheckpoint', accounts => { + const SECONDS = 0; + const DAYS = 1; + const WEEKS = 2; + const MONTHS = 3; + const YEARS = 4; + // Accounts Variable declaration let account_polymath; let account_issuer; @@ -169,11 +175,12 @@ contract('ScheduledCheckpoint', accounts => { let startTime; let interval; + let timeUnit = SECONDS; it("Should create a daily checkpoint", async () => { startTime = latestTime() + 100; interval = 24 * 60 * 60; console.log("Creating scheduled CP: " + startTime, interval); - await I_ScheduledCheckpoint.addSchedule("CP1", startTime, interval, {from: token_owner}); + await I_ScheduledCheckpoint.addSchedule("CP1", startTime, interval, timeUnit, {from: token_owner}); console.log("2: " + latestTime()); }); @@ -222,7 +229,7 @@ contract('ScheduledCheckpoint', accounts => { it("Should have checkpoint created with correct balances", async() => { let cp1 = await I_ScheduledCheckpoint.getSchedule("CP1"); - checkSchedule(cp1, "CP1", startTime, startTime + interval, interval, [1], [startTime], [1]); + checkSchedule(cp1, "CP1", startTime, startTime + interval, interval, timeUnit, [1], [startTime], [1]); assert.equal((await I_SecurityToken.balanceOfAt(account_investor1, 0)).toNumber(), 0); assert.equal((await I_SecurityToken.balanceOfAt(account_investor1, 1)).toNumber(), 0); }); @@ -258,7 +265,7 @@ contract('ScheduledCheckpoint', accounts => { it("No additional checkpoints created", async() => { let cp1 = await I_ScheduledCheckpoint.getSchedule("CP1"); - checkSchedule(cp1, "CP1", startTime, startTime + interval, interval, [1], [startTime], [1]); + checkSchedule(cp1, "CP1", startTime, startTime + interval, interval, timeUnit, [1], [startTime], [1]); assert.equal((await I_SecurityToken.balanceOfAt(account_investor2, 0)).toNumber(), 0); assert.equal((await I_SecurityToken.balanceOfAt(account_investor2, 1)).toNumber(), 0); }); @@ -296,7 +303,7 @@ contract('ScheduledCheckpoint', accounts => { it("Should have new checkpoint created with correct balances", async() => { let cp1 = await I_ScheduledCheckpoint.getSchedule("CP1"); - checkSchedule(cp1, "CP1", startTime, startTime + (2 * interval), interval, [1, 2], [startTime, startTime + interval], [1, 1]); + checkSchedule(cp1, "CP1", startTime, startTime + (2 * interval), interval, timeUnit, [1, 2], [startTime, startTime + interval], [1, 1]); assert.equal((await I_SecurityToken.balanceOfAt(account_investor3, 0)).toNumber(), 0); assert.equal((await I_SecurityToken.balanceOfAt(account_investor3, 1)).toNumber(), 0); assert.equal((await I_SecurityToken.balanceOfAt(account_investor3, 2)).toNumber(), 0); @@ -316,7 +323,7 @@ contract('ScheduledCheckpoint', accounts => { assert.isTrue(latestTime() <= startTime + (4 * interval)); await I_SecurityToken.transfer(account_investor3, web3.utils.toWei('0.5', 'ether'), { from: account_investor1 }); let cp1 = await I_ScheduledCheckpoint.getSchedule("CP1"); - checkSchedule(cp1, "CP1", startTime, startTime + (4 * interval), interval, [1, 2, 3], [startTime, startTime + interval, startTime + (2 * interval)], [1, 1, 2]); + checkSchedule(cp1, "CP1", startTime, startTime + (4 * interval), interval, timeUnit, [1, 2, 3], [startTime, startTime + interval, startTime + (2 * interval)], [1, 1, 2]); assert.equal((await I_SecurityToken.balanceOfAt(account_investor3, 0)).toNumber(), 0); assert.equal((await I_SecurityToken.balanceOfAt(account_investor3, 1)).toNumber(), 0); assert.equal((await I_SecurityToken.balanceOfAt(account_investor3, 2)).toNumber(), 0); @@ -339,7 +346,7 @@ contract('ScheduledCheckpoint', accounts => { await I_ScheduledCheckpoint.updateAll({from: token_owner}); let cp1 = await I_ScheduledCheckpoint.getSchedule("CP1"); - checkSchedule(cp1, "CP1", startTime, startTime + (5 * interval), interval, [1, 2, 3, 4], [startTime, startTime + interval, startTime + (2 * interval), startTime + (4 * interval)], [1, 1, 2, 1]); + checkSchedule(cp1, "CP1", startTime, startTime + (5 * interval), interval, timeUnit, [1, 2, 3, 4], [startTime, startTime + interval, startTime + (2 * interval), startTime + (4 * interval)], [1, 1, 2, 1]); assert.equal((await I_SecurityToken.balanceOfAt(account_investor3, 0)).toNumber(), 0); assert.equal((await I_SecurityToken.balanceOfAt(account_investor3, 1)).toNumber(), 0); assert.equal((await I_SecurityToken.balanceOfAt(account_investor3, 2)).toNumber(), 0); @@ -365,25 +372,453 @@ contract('ScheduledCheckpoint', accounts => { assert.equal(perm.length, 0); }); + it("Remove daily checkpoint", async () => { + await I_ScheduledCheckpoint.removeSchedule("CP1", {from: token_owner}); + }); + + }); + + describe("Tests for monthly scheduled checkpoints", async() => { + + let name = "CP-M-1"; + let startTime; + let interval = 5; + let timeUnit = MONTHS; + + it("Should create a monthly checkpoint", async () => { + startTime = latestTime() + 100; + + let tx = await I_ScheduledCheckpoint.addSchedule(name, startTime, interval, timeUnit, {from: token_owner}); + checkScheduleLog(tx.logs[0], name, startTime, interval, timeUnit); + }); + + it("Check one monthly checkpoint", async() => { + await increaseTime(100); + await I_ScheduledCheckpoint.updateAll({from: token_owner}); + + let schedule = await I_ScheduledCheckpoint.getSchedule(name); + let checkpoints = [5]; + let timestamps = [startTime]; + let periods = [1]; + checkSchedule(schedule, name, startTime, addMonths(startTime, interval), interval, timeUnit, checkpoints, timestamps, periods); + }); + + it("Check two monthly checkpoints", async() => { + await increaseTime(duration.days(31 * interval)); + await I_ScheduledCheckpoint.updateAll({from: token_owner}); + + let schedule = await I_ScheduledCheckpoint.getSchedule(name); + let checkpoints = [5, 6]; + let timestamps = [startTime, addMonths(startTime, interval)]; + let periods = [1, 1]; + checkSchedule(schedule, name, startTime, addMonths(startTime, interval * 2), interval, timeUnit, checkpoints, timestamps, periods); + }); + + it("Check three monthly checkpoints", async() => { + await increaseTime(duration.days(31 * interval * 2)); + await I_ScheduledCheckpoint.updateAll({from: token_owner}); + + let schedule = await I_ScheduledCheckpoint.getSchedule(name); + let checkpoints = [5, 6, 7]; + let timestamps = [startTime, addMonths(startTime, interval), addMonths(startTime, interval * 2)]; + let periods = [1, 1, 2]; + checkSchedule(schedule, name, startTime, addMonths(startTime, interval * 4), interval, timeUnit, checkpoints, timestamps, periods); + }); + + it("Check four monthly checkpoints", async() => { + await increaseTime(duration.days(31 * interval)); + await I_ScheduledCheckpoint.updateAll({from: token_owner}); + + let schedule = await I_ScheduledCheckpoint.getSchedule(name); + let checkpoints = [5, 6, 7, 8]; + let timestamps = [startTime, addMonths(startTime, interval), addMonths(startTime, interval * 2), addMonths(startTime, interval * 4)]; + let periods = [1, 1, 2, 1]; + checkSchedule(schedule, name, startTime, addMonths(startTime, interval * 5), interval, timeUnit, checkpoints, timestamps, periods); + }); + + it("Check five monthly checkpoints", async() => { + await increaseTime(duration.days(31 * interval * 3)); + await I_ScheduledCheckpoint.updateAll({from: token_owner}); + + let schedule = await I_ScheduledCheckpoint.getSchedule(name); + let checkpoints = [5, 6, 7, 8, 9]; + let timestamps = [startTime, addMonths(startTime, interval), addMonths(startTime, interval * 2), addMonths(startTime, interval * 4), addMonths(startTime, interval * 5)]; + let periods = [1, 1, 2, 1, 3]; + checkSchedule(schedule, name, startTime, addMonths(startTime, interval * 8), interval, timeUnit, checkpoints, timestamps, periods); + }); + + it("Remove monthly checkpoint", async () => { + await I_ScheduledCheckpoint.removeSchedule(name, {from: token_owner}); + }); + + }); + + describe("Tests for yearly scheduled checkpoints", async() => { + + let name = "CP-Y-1"; + let startTime; + let interval = 3; + let timeUnit = YEARS; + + it("Should create a yearly checkpoint", async () => { + startTime = latestTime() + 100; + + let tx = await I_ScheduledCheckpoint.addSchedule(name, startTime, interval, timeUnit, {from: token_owner}); + checkScheduleLog(tx.logs[0], name, startTime, interval, timeUnit); + }); + + it("Check one yearly checkpoint", async() => { + await increaseTime(100); + await I_ScheduledCheckpoint.updateAll({from: token_owner}); + + let schedule = await I_ScheduledCheckpoint.getSchedule(name); + let checkpoints = [10]; + let timestamps = [startTime]; + let periods = [1]; + checkSchedule(schedule, name, startTime, addYears(startTime, interval), interval, timeUnit, checkpoints, timestamps, periods); + }); + + it("Check two yearly checkpoints", async() => { + await increaseTime(duration.days(366 * interval)); + await I_ScheduledCheckpoint.updateAll({from: token_owner}); + + let schedule = await I_ScheduledCheckpoint.getSchedule(name); + let checkpoints = [10, 11]; + let timestamps = [startTime, addYears(startTime, interval)]; + let periods = [1, 1]; + checkSchedule(schedule, name, startTime, addYears(startTime, interval * 2), interval, timeUnit, checkpoints, timestamps, periods); + }); + + it("Check three yearly checkpoints", async() => { + await increaseTime(duration.days(366 * interval * 2)); + await I_ScheduledCheckpoint.updateAll({from: token_owner}); + + let schedule = await I_ScheduledCheckpoint.getSchedule(name); + let checkpoints = [10, 11, 12]; + let timestamps = [startTime, addYears(startTime, interval), addYears(startTime, interval * 2)]; + let periods = [1, 1, 2]; + checkSchedule(schedule, name, startTime, addYears(startTime, interval * 4), interval, timeUnit, checkpoints, timestamps, periods); + }); + + it("Check four yearly checkpoints", async() => { + await increaseTime(duration.days(366 * interval)); + await I_ScheduledCheckpoint.updateAll({from: token_owner}); + + let schedule = await I_ScheduledCheckpoint.getSchedule(name); + let checkpoints = [10, 11, 12, 13]; + let timestamps = [startTime, addYears(startTime, interval), addYears(startTime, interval * 2), addYears(startTime, interval * 4)]; + let periods = [1, 1, 2, 1]; + checkSchedule(schedule, name, startTime, addYears(startTime, interval * 5), interval, timeUnit, checkpoints, timestamps, periods); + }); + + it("Check five yearly checkpoints", async() => { + await increaseTime(duration.days(366 * interval * 3)); + await I_ScheduledCheckpoint.updateAll({from: token_owner}); + + let schedule = await I_ScheduledCheckpoint.getSchedule(name); + let checkpoints = [10, 11, 12, 13, 14]; + let timestamps = [startTime, addYears(startTime, interval), addYears(startTime, interval * 2), addYears(startTime, interval * 4), addYears(startTime, interval * 5)]; + let periods = [1, 1, 2, 1, 3]; + checkSchedule(schedule, name, startTime, addYears(startTime, interval * 8), interval, timeUnit, checkpoints, timestamps, periods); + }); + + it("Remove monthly checkpoint", async () => { + await I_ScheduledCheckpoint.removeSchedule(name, {from: token_owner}); + }); + + }); + + describe("Tests for monthly scheduled checkpoints -- end of month", async() => { + let name = "CP-M-2"; + let previousTime; + let startDate; + let startTime; + let interval = 1; + let timeUnit = MONTHS; + + it("Should create a monthly checkpoint -- December 31", async () => { + previousTime = latestTime(); + + startDate = new Date(previousTime * 1000); + startDate.setUTCMonth(11, 31); + startTime = startDate.getTime() / 1000; + console.log("previousTime:" + previousTime); + console.log("startTime:" + startTime); + console.log("startDate:" + startDate.toUTCString()); + + let tx = await I_ScheduledCheckpoint.addSchedule(name, startTime, interval, timeUnit, {from: token_owner}); + checkScheduleLog(tx.logs[0], name, startTime, interval, timeUnit); + }); + + it("Check monthly checkpoint -- January 31", async() => { + await increaseTime(startTime - previousTime + 100); + await I_ScheduledCheckpoint.updateAll({from: token_owner}); + + let schedule = await I_ScheduledCheckpoint.getSchedule(name); + let checkpoints = [15]; + let nextTime = addMonths(startTime, interval); + let timestamps = [startTime]; + let periods = [1]; + checkSchedule(schedule, name, startTime, nextTime, interval, timeUnit, checkpoints, timestamps, periods); + }); + + function getDaysInFebruary() { + let days; + if ((startDate.getUTCFullYear() + 1) % 4 === 0) { + days = 29; + } else { + days = 28; + } + return days; + } + + function getEndOfFebruary(startTime, days) { + return setDate(addYears(startTime, 1), 1, days); //addMonths(startTime, interval * 2) + } + + it("Check monthly checkpoints -- February 28/29", async() => { + await increaseTime(duration.days(31 * interval)); + await I_ScheduledCheckpoint.updateAll({from: token_owner}); + + let schedule = await I_ScheduledCheckpoint.getSchedule(name); + let checkpoints = [15, 16]; + let days = getDaysInFebruary(); + let nextTime = getEndOfFebruary(startTime, days); + let timestamps = [startTime, addMonths(startTime, interval)]; + let periods = [1, 1]; + checkSchedule(schedule, name, startTime, nextTime, interval, timeUnit, checkpoints, timestamps, periods); + }); + + it("Check monthly checkpoints -- March 31", async() => { + let days = getDaysInFebruary(); + await increaseTime(duration.days(days * interval)); + await I_ScheduledCheckpoint.updateAll({from: token_owner}); + + let schedule = await I_ScheduledCheckpoint.getSchedule(name); + let checkpoints = [15, 16, 17]; + let nextTime = addMonths(startTime, interval * 3); + let timestamps = [startTime, addMonths(startTime, interval), getEndOfFebruary(startTime, days)]; + let periods = [1, 1, 1]; + + for (let i = 0; i < timestamps.length; i++) { + assert.equal(schedule[6][i].toNumber(), timestamps[i]); + console.log(new Date(schedule[6][i].toNumber() * 1000).toUTCString()); + } + console.log("expected:" + new Date(nextTime * 1000).toUTCString()); + console.log("actual:" + new Date(schedule[2].toNumber() * 1000).toUTCString()); + checkSchedule(schedule, name, startTime, nextTime, interval, timeUnit, checkpoints, timestamps, periods); + }); + + it("Remove monthly checkpoint", async () => { + await I_ScheduledCheckpoint.removeSchedule(name, {from: token_owner}); + }); + + }); + + describe("Tests for daily scheduled checkpoints", async() => { + + let name = "CP-D-1"; + let startTime; + let interval = 13; + let timeUnit = DAYS; + + it("Should create a daily checkpoint", async () => { + startTime = latestTime() + 100; + + let tx = await I_ScheduledCheckpoint.addSchedule(name, startTime, interval, timeUnit, {from: token_owner}); + checkScheduleLog(tx.logs[0], name, startTime, interval, timeUnit); + }); + + it("Check one daily checkpoint", async() => { + await increaseTime(100); + await I_ScheduledCheckpoint.updateAll({from: token_owner}); + + let schedule = await I_ScheduledCheckpoint.getSchedule(name); + let checkpoints = [18]; + let timestamps = [startTime]; + let periods = [1]; + checkSchedule(schedule, name, startTime, addDays(startTime, interval), interval, timeUnit, checkpoints, timestamps, periods); + }); + + it("Check two daily checkpoints", async() => { + await increaseTime(duration.days(interval)); + await I_ScheduledCheckpoint.updateAll({from: token_owner}); + + let schedule = await I_ScheduledCheckpoint.getSchedule(name); + let checkpoints = [18, 19]; + let timestamps = [startTime, addDays(startTime, interval)]; + let periods = [1, 1]; + checkSchedule(schedule, name, startTime, addDays(startTime, interval * 2), interval, timeUnit, checkpoints, timestamps, periods); + }); + + it("Check three daily checkpoints", async() => { + await increaseTime(duration.days(interval * 2)); + await I_ScheduledCheckpoint.updateAll({from: token_owner}); + + let schedule = await I_ScheduledCheckpoint.getSchedule(name); + let checkpoints = [18, 19, 20]; + let timestamps = [startTime, addDays(startTime, interval), addDays(startTime, interval * 2)]; + let periods = [1, 1, 2]; + checkSchedule(schedule, name, startTime, addDays(startTime, interval * 4), interval, timeUnit, checkpoints, timestamps, periods); + }); + + it("Check four daily checkpoints", async() => { + await increaseTime(duration.days(interval)); + await I_ScheduledCheckpoint.updateAll({from: token_owner}); + + let schedule = await I_ScheduledCheckpoint.getSchedule(name); + let checkpoints = [18, 19, 20, 21]; + let timestamps = [startTime, addDays(startTime, interval), addDays(startTime, interval * 2), addDays(startTime, interval * 4)]; + let periods = [1, 1, 2, 1]; + checkSchedule(schedule, name, startTime, addDays(startTime, interval * 5), interval, timeUnit, checkpoints, timestamps, periods); + }); + + it("Check five daily checkpoints", async() => { + await increaseTime(duration.days(interval * 3)); + await I_ScheduledCheckpoint.updateAll({from: token_owner}); + + let schedule = await I_ScheduledCheckpoint.getSchedule(name); + let checkpoints = [18, 19, 20, 21, 22]; + let timestamps = [startTime, addDays(startTime, interval), addDays(startTime, interval * 2), addDays(startTime, interval * 4), addDays(startTime, interval * 5)]; + let periods = [1, 1, 2, 1, 3]; + checkSchedule(schedule, name, startTime, addDays(startTime, interval * 8), interval, timeUnit, checkpoints, timestamps, periods); + }); + + it("Remove daily checkpoint", async () => { + await I_ScheduledCheckpoint.removeSchedule(name, {from: token_owner}); + }); + + }); + + describe("Tests for weekly scheduled checkpoints", async() => { + + let name = "CP-M-1"; + let startTime; + let interval = 9; + let timeUnit = WEEKS; + + it("Should create a weekly checkpoint", async () => { + startTime = latestTime() + 100; + + let tx = await I_ScheduledCheckpoint.addSchedule(name, startTime, interval, timeUnit, {from: token_owner}); + checkScheduleLog(tx.logs[0], name, startTime, interval, timeUnit); + }); + + it("Check one weekly checkpoint", async() => { + await increaseTime(100); + await I_ScheduledCheckpoint.updateAll({from: token_owner}); + + let schedule = await I_ScheduledCheckpoint.getSchedule(name); + let checkpoints = [23]; + let timestamps = [startTime]; + let periods = [1]; + + checkSchedule(schedule, name, startTime, addWeeks(startTime, interval), interval, timeUnit, checkpoints, timestamps, periods); + }); + + it("Check two weekly checkpoints", async() => { + await increaseTime(duration.days(7 * interval)); + await I_ScheduledCheckpoint.updateAll({from: token_owner}); + + let schedule = await I_ScheduledCheckpoint.getSchedule(name); + let checkpoints = [23, 24]; + let timestamps = [startTime, addWeeks(startTime, interval)]; + let periods = [1, 1]; + checkSchedule(schedule, name, startTime, addWeeks(startTime, interval * 2), interval, timeUnit, checkpoints, timestamps, periods); + }); + + it("Check three weekly checkpoints", async() => { + await increaseTime(duration.days(7 * interval * 2)); + await I_ScheduledCheckpoint.updateAll({from: token_owner}); + + let schedule = await I_ScheduledCheckpoint.getSchedule(name); + let checkpoints = [23, 24, 25]; + let timestamps = [startTime, addWeeks(startTime, interval), addWeeks(startTime, interval * 2)]; + let periods = [1, 1, 2]; + checkSchedule(schedule, name, startTime, addWeeks(startTime, interval * 4), interval, timeUnit, checkpoints, timestamps, periods); + }); + + it("Check four weekly checkpoints", async() => { + await increaseTime(duration.days(7 * interval)); + await I_ScheduledCheckpoint.updateAll({from: token_owner}); + + let schedule = await I_ScheduledCheckpoint.getSchedule(name); + let checkpoints = [23, 24, 25, 26]; + let timestamps = [startTime, addWeeks(startTime, interval), addWeeks(startTime, interval * 2), addWeeks(startTime, interval * 4)]; + let periods = [1, 1, 2, 1]; + checkSchedule(schedule, name, startTime, addWeeks(startTime, interval * 5), interval, timeUnit, checkpoints, timestamps, periods); + }); + + it("Check five weekly checkpoints", async() => { + await increaseTime(duration.days(7 * interval * 3)); + await I_ScheduledCheckpoint.updateAll({from: token_owner}); + + let schedule = await I_ScheduledCheckpoint.getSchedule(name); + let checkpoints = [23, 24, 25, 26, 27]; + let timestamps = [startTime, addWeeks(startTime, interval), addWeeks(startTime, interval * 2), addWeeks(startTime, interval * 4), addWeeks(startTime, interval * 5)]; + let periods = [1, 1, 2, 1, 3]; + checkSchedule(schedule, name, startTime, addWeeks(startTime, interval * 8), interval, timeUnit, checkpoints, timestamps, periods); + }); + + it("Remove weekly checkpoint", async () => { + await I_ScheduledCheckpoint.removeSchedule(name, {from: token_owner}); + }); + }); }); -function checkSchedule(schedule, name, startTime, nextTime, interval, checkpoints, timestamps, periods) { +function setDate(time, month, day) { + let startDate = new Date(time * 1000); + startDate.setUTCMonth(month, day); + return startDate.getTime() / 1000; +} + +function addDays(timestamp, days) { + let time = new Date(timestamp * 1000); + return time.setUTCDate(time.getUTCDate() + days) / 1000; +} + +function addWeeks(timestamp, weeks) { + return addDays(timestamp, weeks * 7); +} + +function addMonths(timestamp, months) { + let time = new Date(timestamp * 1000); + return time.setUTCMonth(time.getUTCMonth() + months) / 1000; +} + +function addYears(timestamp, years) { + let time = new Date(timestamp * 1000); + return time.setUTCFullYear(time.getUTCFullYear() + years) / 1000; +} + +function checkScheduleLog(log, name, startTime, interval, timeUnit) { + assert.equal(web3.utils.hexToUtf8(log.args._name), name); + assert.equal(log.args._startTime.toNumber(), startTime); + assert.equal(log.args._interval.toNumber(), interval); + assert.equal(log.args._timeUint.toNumber(), timeUnit); +} + +function checkSchedule(schedule, name, startTime, nextTime, interval, timeUnit, checkpoints, timestamps, periods) { assert.equal(web3.utils.toAscii(schedule[0]).replace(/\u0000/g, ''), name); assert.equal(schedule[1].toNumber(), startTime); assert.equal(schedule[2].toNumber(), nextTime); assert.equal(schedule[3].toNumber(), interval); - assert.equal(schedule[4].length, checkpoints.length); + assert.equal(schedule[4].toNumber(), timeUnit); + assert.equal(schedule[5].length, checkpoints.length); for (let i = 0; i < checkpoints.length; i++) { - assert.equal(schedule[4][i].toNumber(), checkpoints[i]); + assert.equal(schedule[5][i].toNumber(), checkpoints[i]); } - assert.equal(schedule[5].length, timestamps.length); + assert.equal(schedule[6].length, timestamps.length); for (let i = 0; i < timestamps.length; i++) { - assert.equal(schedule[5][i].toNumber(), timestamps[i]); + assert.equal(schedule[6][i].toNumber(), timestamps[i]); } - assert.equal(schedule[6].length, periods.length); + assert.equal(schedule[7].length, periods.length); + let totalPeriods = 0; for (let i = 0; i < periods.length; i++) { - assert.equal(schedule[6][i].toNumber(), periods[i]); + assert.equal(schedule[7][i].toNumber(), periods[i]); + totalPeriods += periods[i]; } + assert.equal(schedule[8].toNumber(), totalPeriods); } From a18d544d325bc3ddec738eedee620804e3c5d39d Mon Sep 17 00:00:00 2001 From: Adam Dossa Date: Mon, 11 Feb 2019 08:54:30 -0400 Subject: [PATCH 83/83] add getTokensByDelegate (#547) * Add getTokensByDelegate * Simple check * Add more test cases * Add interface file * minor fix --- contracts/SecurityTokenRegistry.sol | 206 ++++++++++++------ contracts/interfaces/ISecurityToken.sol | 4 +- .../interfaces/ISecurityTokenRegistry.sol | 7 + test/g_general_permission_manager.js | 59 ++++- 4 files changed, 205 insertions(+), 71 deletions(-) diff --git a/contracts/SecurityTokenRegistry.sol b/contracts/SecurityTokenRegistry.sol index 81f74abde..4ad8835e7 100644 --- a/contracts/SecurityTokenRegistry.sol +++ b/contracts/SecurityTokenRegistry.sol @@ -4,7 +4,9 @@ import "openzeppelin-solidity/contracts/math/SafeMath.sol"; import "./interfaces/IOwnable.sol"; import "./interfaces/ISTFactory.sol"; import "./interfaces/IERC20.sol"; +import "./interfaces/ISecurityToken.sol"; import "./interfaces/ISecurityTokenRegistry.sol"; +import "./modules/PermissionManager/IPermissionManager.sol"; import "./storage/EternalStorage.sol"; import "./libraries/Util.sol"; import "./libraries/Encoder.sol"; @@ -117,7 +119,7 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { - require(msg.sender == owner(),"sender must be owner"); + require(msg.sender == owner(),"Only owner"); _; } @@ -128,7 +130,7 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { if (msg.sender == owner()) _; else { - require(!isPaused(), "Already paused"); + require(!isPaused(), "Paused"); _; } } @@ -137,7 +139,7 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { * @notice Modifier to make a function callable only when the contract is not paused and ignore is msg.sender is owner. */ modifier whenNotPaused() { - require(!isPaused(), "Already paused"); + require(!isPaused(), "Paused"); _; } @@ -146,7 +148,7 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { * @notice Modifier to make a function callable only when the contract is paused. */ modifier whenPaused() { - require(isPaused(), "Should not be paused"); + require(isPaused(), "Not paused"); _; } @@ -175,12 +177,12 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { external payable { - require(!getBoolValue(INITIALIZE),"already initialized"); + require(!getBoolValue(INITIALIZE), "Initialized"); require( _STFactory != address(0) && _polyToken != address(0) && _owner != address(0) && _polymathRegistry != address(0), - "Invalid address" + "Bad address" ); - require(_stLaunchFee != 0 && _tickerRegFee != 0, "Fees should not be 0"); + require(_stLaunchFee != 0 && _tickerRegFee != 0, "Bad fee"); set(POLYTOKEN, _polyToken); set(STLAUNCHFEE, _stLaunchFee); set(TICKERREGFEE, _tickerRegFee); @@ -205,14 +207,14 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { * @param _tokenName is the name of the token */ function registerTicker(address _owner, string _ticker, string _tokenName) external whenNotPausedOrOwner { - require(_owner != address(0), "Owner should not be 0x"); - require(bytes(_ticker).length > 0 && bytes(_ticker).length <= 10, "Ticker length range (0,10]"); + require(_owner != address(0), "Bad address"); + require(bytes(_ticker).length > 0 && bytes(_ticker).length <= 10, "Bad ticker"); // Attempt to charge the reg fee if it is > 0 POLY uint256 tickerFee = getTickerRegistrationFee(); if (tickerFee > 0) require(IERC20(getAddressValue(POLYTOKEN)).transferFrom(msg.sender, address(this), tickerFee), "Insufficent allowance"); string memory ticker = Util.upper(_ticker); - require(_tickerAvailable(ticker), "Ticker is reserved"); + require(_tickerAvailable(ticker), "Ticker reserved"); // Check whether ticker was previously registered (and expired) address previousOwner = _tickerOwner(ticker); if (previousOwner != address(0)) { @@ -226,13 +228,13 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { * @notice Internal - Sets the details of the ticker */ function _addTicker( - address _owner, - string _ticker, - string _tokenName, - uint256 _registrationDate, - uint256 _expiryDate, - bool _status, - bool _fromAdmin, + address _owner, + string _ticker, + string _tokenName, + uint256 _registrationDate, + uint256 _expiryDate, + bool _status, + bool _fromAdmin, uint256 _fee ) internal { _setTickerOwnership(_owner, _ticker); @@ -258,10 +260,10 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { uint256 _expiryDate, bool _status ) external onlyOwner { - require(bytes(_ticker).length > 0 && bytes(_ticker).length <= 10, "Ticker length range (0,10]"); - require(_expiryDate != 0 && _registrationDate != 0, "Dates should not be 0"); - require(_registrationDate <= _expiryDate, "Registration date should < expiry date"); - require(_owner != address(0), "Invalid address"); + require(bytes(_ticker).length > 0 && bytes(_ticker).length <= 10, "Bad ticker"); + require(_expiryDate != 0 && _registrationDate != 0, "Bad dates"); + require(_registrationDate <= _expiryDate, "Bad dates"); + require(_owner != address(0), "Bad address"); string memory ticker = Util.upper(_ticker); _modifyTicker(_owner, ticker, _tokenName, _registrationDate, _expiryDate, _status); } @@ -286,7 +288,7 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { } // If status is true, there must be a security token linked to the ticker already if (_status) { - require(getAddressValue(Encoder.getKey("tickerToSecurityToken", _ticker)) != address(0), "Token not registered"); + require(getAddressValue(Encoder.getKey("tickerToSecurityToken", _ticker)) != address(0), "Not registered"); } _addTicker(_owner, _ticker, _tokenName, _registrationDate, _expiryDate, _status, true, uint256(0)); } @@ -302,7 +304,7 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { function removeTicker(string _ticker) external onlyOwner { string memory ticker = Util.upper(_ticker); address owner = _tickerOwner(ticker); - require(owner != address(0), "Ticker doesn't exist"); + require(owner != address(0), "Bad ticker"); _deleteTickerOwnership(owner, ticker); set(Encoder.getKey("tickerToSecurityToken", ticker), address(0)); _storeTickerDetails(ticker, address(0), 0, 0, "", false); @@ -382,11 +384,11 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { */ function transferTickerOwnership(address _newOwner, string _ticker) external whenNotPausedOrOwner { string memory ticker = Util.upper(_ticker); - require(_newOwner != address(0), "Invalid address"); + require(_newOwner != address(0), "Bad address"); bytes32 ownerKey = Encoder.getKey("registeredTickers_owner", ticker); - require(getAddressValue(ownerKey) == msg.sender, "Not authorised"); + require(getAddressValue(ownerKey) == msg.sender, "Only owner"); if (_tickerStatus(ticker)) - require(IOwnable(getAddressValue(Encoder.getKey("tickerToSecurityToken", ticker))).owner() == _newOwner, "New owner does not match token owner"); + require(IOwnable(getAddressValue(Encoder.getKey("tickerToSecurityToken", ticker))).owner() == _newOwner, "Onwer mismatch"); _deleteTickerOwnership(msg.sender, ticker); _setTickerOwnership(_newOwner, ticker); set(ownerKey, _newOwner); @@ -414,7 +416,7 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { * @param _newExpiry is the new expiry for newly generated tickers */ function changeExpiryLimit(uint256 _newExpiry) external onlyOwner { - require(_newExpiry >= 1 days, "Expiry should >= 1 day"); + require(_newExpiry >= 1 days, "Bad dates"); emit ChangeExpiryLimit(getUintValue(EXPIRYLIMIT), _newExpiry); set(EXPIRYLIMIT, _newExpiry); } @@ -424,27 +426,32 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { * @param _owner is the address which owns the list of tickers */ function getTickersByOwner(address _owner) external view returns(bytes32[]) { - uint counter = 0; + uint256 count = 0; // accessing the data structure userTotickers[_owner].length bytes32[] memory tickers = getArrayBytes32(Encoder.getKey("userToTickers", _owner)); for (uint i = 0; i < tickers.length; i++) { - string memory ticker = Util.bytes32ToString(tickers[i]); - /*solium-disable-next-line security/no-block-members*/ - if (getUintValue(Encoder.getKey("registeredTickers_expiryDate", ticker)) >= now || _tickerStatus(ticker)) { - counter ++; + if (_ownerInTicker(tickers[i])) { + count++; } } - bytes32[] memory tempList = new bytes32[](counter); - counter = 0; + bytes32[] memory result = new bytes32[](count); + count = 0; for (i = 0; i < tickers.length; i++) { - ticker = Util.bytes32ToString(tickers[i]); - /*solium-disable-next-line security/no-block-members*/ - if (getUintValue(Encoder.getKey("registeredTickers_expiryDate", ticker)) >= now || _tickerStatus(ticker)) { - tempList[counter] = tickers[i]; - counter ++; + if (_ownerInTicker(tickers[i])) { + result[count] = tickers[i]; + count++; } } - return tempList; + return result; + } + + function _ownerInTicker(bytes32 _ticker) internal view returns (bool) { + string memory ticker = Util.bytes32ToString(_ticker); + /*solium-disable-next-line security/no-block-members*/ + if (getUintValue(Encoder.getKey("registeredTickers_expiryDate", ticker)) >= now || _tickerStatus(ticker)) { + return true; + } + return false; } /** @@ -453,42 +460,107 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { * @dev Intention is that this is called off-chain so block gas limit is not relevant */ function getTokensByOwner(address _owner) external view returns(address[]) { + return _getTokens(false, _owner); + } + + /** + * @notice Returns the list of all tokens + * @dev Intention is that this is called off-chain so block gas limit is not relevant + */ + function getTokens() public view returns(address[]) { + return _getTokens(true, address(0)); + } + + /** + * @notice Returns the list of tokens owned by the selected address + * @param _allTokens if _allTokens is true returns all tokens despite on the second parameter + * @param _owner is the address which owns the list of tickers + */ + function _getTokens(bool _allTokens, address _owner) internal view returns(address[]) { // Loop over all active users, then all associated tickers of those users // This ensures we find tokens, even if their owner has been modified address[] memory activeUsers = getArrayAddress(Encoder.getKey("activeUsers")); bytes32[] memory tickers; - address token; uint256 count = 0; uint256 i = 0; uint256 j = 0; for (i = 0; i < activeUsers.length; i++) { tickers = getArrayBytes32(Encoder.getKey("userToTickers", activeUsers[i])); for (j = 0; j < tickers.length; j++) { - token = getAddressValue(Encoder.getKey("tickerToSecurityToken", Util.bytes32ToString(tickers[j]))); - if (token != address(0)) { - if (IOwnable(token).owner() == _owner) { - count = count + 1; - } + if (address(0) != _ownerInToken(tickers[j], _allTokens, _owner)) { + count++; } } } - uint256 index = 0; address[] memory result = new address[](count); + count = 0; + address token; for (i = 0; i < activeUsers.length; i++) { tickers = getArrayBytes32(Encoder.getKey("userToTickers", activeUsers[i])); for (j = 0; j < tickers.length; j++) { - token = getAddressValue(Encoder.getKey("tickerToSecurityToken", Util.bytes32ToString(tickers[j]))); - if (token != address(0)) { - if (IOwnable(token).owner() == _owner) { - result[index] = token; - index = index + 1; - } + token = _ownerInToken(tickers[j], _allTokens, _owner); + if (address(0) != token) { + result[count] = token; + count++; } } } return result; } + function _ownerInToken(bytes32 _ticker, bool _allTokens, address _owner) internal view returns(address) { + address token = getAddressValue(Encoder.getKey("tickerToSecurityToken", Util.bytes32ToString(_ticker))); + if (token != address(0)) { + if (_allTokens || IOwnable(token).owner() == _owner) { + return token; + } + } + return address(0); + } + + /** + * @notice Returns the list of tokens to which the delegate has some access + * @param _delegate is the address for the delegate + * @dev Intention is that this is called off-chain so block gas limit is not relevant + */ + function getTokensByDelegate(address _delegate) external view returns(address[]) { + // Loop over all active users, then all associated tickers of those users + // This ensures we find tokens, even if their owner has been modified + address[] memory tokens = getTokens(); + uint256 count = 0; + uint256 i = 0; + for (i = 0; i < tokens.length; i++) { + if (_delegateInToken(tokens[i], _delegate)) { + count++; + } + } + address[] memory result = new address[](count); + count = 0; + for (i = 0; i < tokens.length; i++) { + if (_delegateInToken(tokens[i], _delegate)) { + result[count] = tokens[i]; + count++; + } + } + return result; + } + + function _delegateInToken(address _token, address _delegate) internal view returns(bool) { + uint256 j = 0; + address[] memory permissionManagers; + bool isArchived; + permissionManagers = ISecurityToken(_token).getModulesByType(1); + for (j = 0; j < permissionManagers.length; j++) { + (,,, isArchived,) = ISecurityToken(_token).getModule(permissionManagers[j]); + if (!isArchived) { + if (IPermissionManager(permissionManagers[j]).checkDelegate(_delegate)) { + return true; + } + } + } + return false; + } + /** * @notice Returns the owner and timestamp for a given ticker * @param _ticker is the ticker symbol @@ -528,18 +600,18 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { * @param _divisible is whether or not the token is divisible */ function generateSecurityToken(string _name, string _ticker, string _tokenDetails, bool _divisible) external whenNotPausedOrOwner { - require(bytes(_name).length > 0 && bytes(_ticker).length > 0, "Ticker length > 0"); + require(bytes(_name).length > 0 && bytes(_ticker).length > 0, "Bad ticker"); string memory ticker = Util.upper(_ticker); bytes32 statusKey = Encoder.getKey("registeredTickers_status", ticker); require(!getBoolValue(statusKey), "Already deployed"); set(statusKey, true); require(_tickerOwner(ticker) == msg.sender, "Not authorised"); /*solium-disable-next-line security/no-block-members*/ - require(getUintValue(Encoder.getKey("registeredTickers_expiryDate", ticker)) >= now, "Ticker gets expired"); + require(getUintValue(Encoder.getKey("registeredTickers_expiryDate", ticker)) >= now, "Ticker expired"); uint256 launchFee = getSecurityTokenLaunchFee(); if (launchFee > 0) - require(IERC20(getAddressValue(POLYTOKEN)).transferFrom(msg.sender, address(this), launchFee), "Insufficient allowance"); + require(IERC20(getAddressValue(POLYTOKEN)).transferFrom(msg.sender, address(this), launchFee), "Insufficent allowance"); address newSecurityTokenAddress = ISTFactory(getSTFactoryAddress()).deployToken( _name, @@ -578,11 +650,11 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { external onlyOwner { - require(bytes(_name).length > 0 && bytes(_ticker).length > 0, "String length > 0"); - require(bytes(_ticker).length <= 10, "Ticker length range (0,10]"); - require(_deployedAt != 0 && _owner != address(0), "0 value params not allowed"); + require(bytes(_name).length > 0 && bytes(_ticker).length > 0, "Bad data"); + require(bytes(_ticker).length <= 10, "Bad ticker"); + require(_deployedAt != 0 && _owner != address(0), "Bad data"); string memory ticker = Util.upper(_ticker); - require(_securityToken != address(0), "ST address is 0x"); + require(_securityToken != address(0), "Bad address"); uint256 registrationTime = getUintValue(Encoder.getKey("registeredTickers_registrationDate", ticker)); uint256 expiryTime = getUintValue(Encoder.getKey("registeredTickers_expiryDate", ticker)); if (registrationTime == 0) { @@ -650,7 +722,7 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { * @param _newOwner The address to transfer ownership to. */ function transferOwnership(address _newOwner) external onlyOwner { - require(_newOwner != address(0), "Invalid address"); + require(_newOwner != address(0), "Bad address"); emit OwnershipTransferred(getAddressValue(OWNER), _newOwner); set(OWNER, _newOwner); } @@ -679,7 +751,7 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { */ function changeTickerRegistrationFee(uint256 _tickerRegFee) external onlyOwner { uint256 fee = getUintValue(TICKERREGFEE); - require(fee != _tickerRegFee, "Fee not changed"); + require(fee != _tickerRegFee, "Bad fee"); emit ChangeTickerRegistrationFee(fee, _tickerRegFee); set(TICKERREGFEE, _tickerRegFee); } @@ -690,7 +762,7 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { */ function changeSecurityLaunchFee(uint256 _stLaunchFee) external onlyOwner { uint256 fee = getUintValue(STLAUNCHFEE); - require(fee != _stLaunchFee, "Fee not changed"); + require(fee != _stLaunchFee, "Bad fee"); emit ChangeSecurityLaunchFee(fee, _stLaunchFee); set(STLAUNCHFEE, _stLaunchFee); } @@ -700,7 +772,7 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { * @param _tokenContract is the address of the token contract */ function reclaimERC20(address _tokenContract) external onlyOwner { - require(_tokenContract != address(0), "Invalid address"); + require(_tokenContract != address(0), "Bad address"); IERC20 token = IERC20(_tokenContract); uint256 balance = token.balanceOf(address(this)); require(token.transfer(owner(), balance), "Transfer failed"); @@ -716,7 +788,7 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { * @param _patch Patch version of the proxy */ function setProtocolVersion(address _STFactoryAddress, uint8 _major, uint8 _minor, uint8 _patch) external onlyOwner { - require(_STFactoryAddress != address(0), "0x address is not allowed"); + require(_STFactoryAddress != address(0), "Bad address"); _setProtocolVersion(_STFactoryAddress, _major, _minor, _patch); } @@ -729,7 +801,7 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { _version[1] = _minor; _version[2] = _patch; uint24 _packedVersion = VersionUtils.pack(_major, _minor, _patch); - require(VersionUtils.isValidVersion(getProtocolVersion(), _version),"In-valid version"); + require(VersionUtils.isValidVersion(getProtocolVersion(), _version),"Invalid version"); set(Encoder.getKey("latestVersion"), uint256(_packedVersion)); set(Encoder.getKey("protocolVersionST", getUintValue(Encoder.getKey("latestVersion"))), _STFactoryAddress); } @@ -753,7 +825,7 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { * @param _newAddress is the address of the polytoken. */ function updatePolyTokenAddress(address _newAddress) external onlyOwner { - require(_newAddress != address(0), "Invalid address"); + require(_newAddress != address(0), "Bad address"); set(POLYTOKEN, _newAddress); } diff --git a/contracts/interfaces/ISecurityToken.sol b/contracts/interfaces/ISecurityToken.sol index f280d6c19..4b3d5b900 100644 --- a/contracts/interfaces/ISecurityToken.sol +++ b/contracts/interfaces/ISecurityToken.sol @@ -73,7 +73,7 @@ interface ISecurityToken { * @return uint256 Name index */ - function getModule(address _module) external view returns(bytes32, address, address, bool, uint8, uint256, uint256); + function getModule(address _module) external view returns (bytes32, address, address, bool, uint8[]); /** * @notice Returns module list for a module name @@ -130,7 +130,7 @@ interface ISecurityToken { * @return list of investors */ function iterateInvestors(uint256 _start, uint256 _end) external view returns(address[]); - + /** * @notice Gets current checkpoint ID * @return Id diff --git a/contracts/interfaces/ISecurityTokenRegistry.sol b/contracts/interfaces/ISecurityTokenRegistry.sol index 8db01f8ad..2f44002f6 100644 --- a/contracts/interfaces/ISecurityTokenRegistry.sol +++ b/contracts/interfaces/ISecurityTokenRegistry.sol @@ -107,6 +107,13 @@ interface ISecurityTokenRegistry { */ function getTokensByOwner(address _owner) external view returns(address[]); + /** + * @notice Returns the list of tokens to which the delegate has some access + * @param _delegate is the address for the delegate + * @dev Intention is that this is called off-chain so block gas limit is not relevant + */ + function getTokensByDelegate(address _delegate) external view returns(address[]); + /** * @notice Returns the owner and timestamp for a given ticker * @param _ticker ticker diff --git a/test/g_general_permission_manager.js b/test/g_general_permission_manager.js index d554891ee..796800f56 100644 --- a/test/g_general_permission_manager.js +++ b/test/g_general_permission_manager.js @@ -311,13 +311,67 @@ contract('GeneralPermissionManager', accounts => { }); it("Should return all delegates", async() => { + assert.equal((await I_STRProxied.getTokensByDelegate.call(account_delegate))[0], I_SecurityToken.address); + assert.equal((await I_STRProxied.getTokensByDelegate.call(account_delegate)).length, 1); + assert.equal((await I_STRProxied.getTokensByDelegate.call(account_delegate2)).length, 0); await I_GeneralPermissionManager.addDelegate(account_delegate2, delegateDetails, { from: token_owner}); + assert.equal((await I_STRProxied.getTokensByDelegate.call(account_delegate))[0], I_SecurityToken.address); + assert.equal((await I_STRProxied.getTokensByDelegate.call(account_delegate)).length, 1); + assert.equal((await I_STRProxied.getTokensByDelegate.call(account_delegate2))[0], I_SecurityToken.address); + assert.equal((await I_STRProxied.getTokensByDelegate.call(account_delegate2)).length, 1); let tx = await I_GeneralPermissionManager.getAllDelegates.call(); assert.equal(tx.length, 2); - assert.equal(tx[0], account_delegate); + assert.equal(tx[0], account_delegate); assert.equal(tx[1], account_delegate2); }); + it("Should create a new token and add some more delegates, then get them", async() => { + await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let tx1 = await I_STRProxied.registerTicker(token_owner, "DEL", contact, { from: token_owner }); + assert.equal(tx1.logs[0].args._owner, token_owner); + assert.equal(tx1.logs[0].args._ticker, "DEL"); + + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let _blockNo = latestBlock(); + let tx2 = await I_STRProxied.generateSecurityToken(name, "DEL", tokenDetails, false, { from: token_owner }); + + // Verify the successful generation of the security token + assert.equal(tx2.logs[1].args._ticker, "DEL", "SecurityToken doesn't get deployed"); + + let I_SecurityToken_DEL = SecurityToken.at(tx2.logs[1].args._securityTokenAddress); + + const tx = await I_SecurityToken_DEL.addModule(I_GeneralPermissionManagerFactory.address, "0x", 0, 0, { from: token_owner }); + assert.equal(tx.logs[2].args._types[0].toNumber(), delegateManagerKey, "General Permission Manager doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ""), + "GeneralPermissionManager", + "GeneralPermissionManagerFactory module was not added" + ); + const log = await promisifyLogWatch(I_SecurityToken_DEL.ModuleAdded({ from: _blockNo }), 1); + + let I_GeneralPermissionManager_DEL = GeneralPermissionManager.at(tx.logs[2].args._module); + await I_GeneralPermissionManager_DEL.addDelegate(account_delegate3, delegateDetails, { from: token_owner}); + + assert.equal((await I_STRProxied.getTokensByDelegate.call(account_delegate))[0], I_SecurityToken.address); + assert.equal((await I_STRProxied.getTokensByDelegate.call(account_delegate2))[0], I_SecurityToken.address); + assert.equal((await I_STRProxied.getTokensByDelegate.call(account_delegate3))[0], I_SecurityToken_DEL.address); + assert.equal((await I_STRProxied.getTokensByDelegate.call(account_delegate)).length, 1); + assert.equal((await I_STRProxied.getTokensByDelegate.call(account_delegate2)).length, 1); + assert.equal((await I_STRProxied.getTokensByDelegate.call(account_delegate3)).length, 1); + await I_GeneralPermissionManager_DEL.addDelegate(account_delegate2, delegateDetails, { from: token_owner}); + assert.equal((await I_STRProxied.getTokensByDelegate.call(account_delegate))[0], I_SecurityToken.address); + assert.equal((await I_STRProxied.getTokensByDelegate.call(account_delegate2))[0], I_SecurityToken.address); + assert.equal((await I_STRProxied.getTokensByDelegate.call(account_delegate2))[1], I_SecurityToken_DEL.address); + assert.equal((await I_STRProxied.getTokensByDelegate.call(account_delegate3))[0], I_SecurityToken_DEL.address); + assert.equal((await I_STRProxied.getTokensByDelegate.call(account_delegate)).length, 1); + assert.equal((await I_STRProxied.getTokensByDelegate.call(account_delegate2)).length, 2); + assert.equal((await I_STRProxied.getTokensByDelegate.call(account_delegate3)).length, 1); + let tx4 = await I_GeneralPermissionManager_DEL.getAllDelegates.call(); + assert.equal(tx4.length, 2); + assert.equal(tx4[0], account_delegate3, account_delegate2); + }); + it("Should check is delegate for 0x address - failed 0x address is not allowed", async() => { await catchRevert( I_GeneralPermissionManager.checkDelegate.call("0x0000000000000000000000000000000000000000000000000") @@ -332,7 +386,7 @@ contract('GeneralPermissionManager', accounts => { assert.equal(await I_GeneralPermissionManager.checkDelegate.call(account_delegate), true); }); - + it("Should successfully provide the permissions in batch -- failed because of array length is 0", async() => { await I_GeneralPermissionManager.addDelegate(account_delegate3, delegateDetails, { from: token_owner}); await catchRevert( @@ -369,6 +423,7 @@ contract('GeneralPermissionManager', accounts => { it("Should provide all delegates with specified permission", async() => { await I_GeneralPermissionManager.changePermission(account_delegate2, I_GeneralTransferManager.address, "WHITELIST", true, {from: token_owner}); let tx = await I_GeneralPermissionManager.getAllDelegatesWithPerm.call(I_GeneralTransferManager.address, "WHITELIST"); + console.log(tx); assert.equal(tx.length, 3); assert.equal(tx[0], account_delegate); assert.equal(tx[1], account_delegate2);