diff --git a/.env.example b/.env.example deleted file mode 100644 index 889306334..000000000 --- a/.env.example +++ /dev/null @@ -1,5 +0,0 @@ -# configure your infura api key (not technically required) -INFURA_API_KEY= - -# change the mnemonic that your hd wallet is seeded with -MNEMONIC= diff --git a/.eslintrc b/.eslintrc index 117135b36..c06f6e872 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,22 +1,23 @@ { "extends" : [ "standard", - "plugin:promise/recommended" + "plugin:promise/recommended", ], "plugins": [ - "promise" + "mocha-no-only", + "promise", ], "env": { "browser" : true, "node" : true, "mocha" : true, - "jest" : true + "jest" : true, }, "globals" : { "artifacts": false, "contract": false, "assert": false, - "web3": false + "web3": false, }, "rules": { @@ -25,7 +26,7 @@ // Code style "camelcase": ["error", {"properties": "always"}], - "comma-dangle": ["warn", "always-multiline"], + "comma-dangle": ["error", "always-multiline"], "comma-spacing": ["error", {"before": false, "after": true}], "dot-notation": ["error", {"allowKeywords": true, "allowPattern": ""}], "eol-last": ["error", "always"], @@ -49,6 +50,8 @@ "semi": ["error", "always"], "space-before-function-paren": ["error", "always"], + "mocha-no-only/mocha-no-only": ["error"], + "promise/always-return": "off", "promise/avoid-new": "off", } diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index cafae1e9e..000000000 --- a/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,34 +0,0 @@ -## 🎉 Description - - - -- [ ] 🐛 This is a bug report. -- [ ] 📈 This is a feature request. - - - -## 💻 Environment - -Next, we need to know what your environment looks like. - -- Which version of OpenZeppelin are you using? -- What network are you deploying to? Ganache? Ropsten? -- How are you deploying your OpenZeppelin-backed contracts? truffle? Remix? Let us know! - -## 📝 Details - -Describe the problem you have been experiencing in more detail. Include as much information as you think is relevant. Keep in mind that transactions can fail for many reasons; context is key here. - -## 🔢 Code To Reproduce Issue [ Good To Have ] - -Please remember that with sample code it's easier to reproduce the bug and it's much faster to fix it. - -``` -insert short code snippets here -``` - - - -## 👍 Other Information - - diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..d932e7632 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,21 @@ +--- +name: Bug report +about: Report a bug in OpenZeppelin + +--- + + + + + +**💻 Environment** + + + +**📝 Details** + + + +**🔢 Code to reproduce bug** + + diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 000000000..404854c00 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,14 @@ +--- +name: Feature request +about: Suggest an idea for OpenZeppelin + +--- + +**🧐 Motivation** + + +**📝 Details** + + + + diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 72b331668..7ffea25e9 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,17 +1,21 @@ - + + + Fixes # -# 🚀 Description - - + - - -- [ ] 📘 I've reviewed the [OpenZeppelin Contributor Guidelines](../blob/master/CONTRIBUTING.md) -- [ ] ✅ I've added tests where applicable to test my new functionality. -- [ ] 📖 I've made sure that my contracts are well-documented. -- [ ] 🎨 I've run the JS/Solidity linters and fixed any issues (`npm run lint:fix`). + diff --git a/.gitignore b/.gitignore index 658655f76..9ec02fdd5 100644 --- a/.gitignore +++ b/.gitignore @@ -38,4 +38,9 @@ build/ # truffle .node-xmlhttprequest-* +<<<<<<< HEAD .zos.session +======= +# Temporary directory for 0.5.x compilation +solc-0.5 +>>>>>>> 8fc0a3af313d9372fc9b8d3e5dc57b804df0588e diff --git a/.solhint.json b/.solhint.json new file mode 100644 index 000000000..7a85f3cf2 --- /dev/null +++ b/.solhint.json @@ -0,0 +1,11 @@ +{ + "extends": "default", + "rules": { + "indent": ["error", 4], + + "bracket-align": false, + "compiler-fixed": false, + "no-simple-event-func-name": false, + "two-lines-top-level-separator": false + } +} diff --git a/.soliumignore b/.soliumignore deleted file mode 100644 index 3c3629e64..000000000 --- a/.soliumignore +++ /dev/null @@ -1 +0,0 @@ -node_modules diff --git a/.soliumrc.json b/.soliumrc.json deleted file mode 100644 index f25bd262f..000000000 --- a/.soliumrc.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "extends": "solium:all", - "plugins": ["security"], - "rules": { - "error-reason": "off", - "indentation": ["error", 2], - "lbrace": "off", - "linebreak-style": ["error", "unix"], - "max-len": ["error", 120], - "no-constant": ["error"], - "no-empty-blocks": "off", - "quotes": ["error", "double"], - "uppercase": "off", - "visibility-first": "error", - - "security/enforce-explicit-visibility": ["error"], - "security/no-block-members": ["warning"], - "security/no-inline-assembly": ["warning"] - } -} diff --git a/.travis.yml b/.travis.yml index 5cb0b63a3..fc6fc14cf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,38 +15,26 @@ jobs: # --elopio - 20180531 fast_finish: true allow_failures: - - env: SOLIDITY_COVERAGE=true - env: SOLC_NIGHTLY=true include: - - stage: install - script: true - install: - - npm install - - npx npm-install-peers - # Run the unit test suite three times in parallel. - # The first one gets results faster and is the only one required to pass. - # The second one generates the coverage report. - # The third one is to keep us informed about possible issues with the - # upcoming solidity release. - stage: tests - name: "unit tests" - install: npx npm-install-peers + name: "Linter" + script: npm run lint + + - stage: tests + name: "Unit tests" script: npm run test + - stage: tests - name: "unit tests with coverage" - install: npx npm-install-peers + name: "Unit tests with coverage report" script: npm run test env: SOLIDITY_COVERAGE=true + - stage: tests - name: "unit tests with solc nightly" - install: npx npm-install-peers + name: "Unit tests using solc nightly" script: npm run test env: SOLC_NIGHTLY=true - # solidity and javascript style tests. - - stage: tests - name: "static tests" - install: npx npm-install-peers - script: npm run lint + - stage: update docs if: tag =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ addons: diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..da3a89043 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,32 @@ +# Changelog + +## 2.1.1 (2019-04-01) + * Version bump to avoid conflict in the npm registry. + +## 2.1.0 (2019-04-01) + +### New features: + * Now targeting the 0.5.x line of Solidity compilers. For 0.4.24 support, use version 2.0 of OpenZeppelin. + * `WhitelistCrowdsale`: a crowdsale where only whitelisted accounts (`WhitelistedRole`) can purchase tokens. Adding or removing accounts from the whitelist is done by whitelist admins (`WhitelistAdminRole`). Similar to the pre-2.0 `WhitelistedCrowdsale`. ([#1525](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1525), [#1589](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1589)) + * `RefundablePostDeliveryCrowdsale`: replacement for `RefundableCrowdsale` (deprecated, see below) where tokens are only granted once the crowdsale ends (if it meets its goal). ([#1543](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1543)) + * `PausableCrowdsale`: allows for pausers (`PauserRole`) to pause token purchases. Other crowdsale operations (e.g. withdrawals and refunds, if applicable) are not affected. ([#832](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/832)) + * `ERC20`: `transferFrom` and `_burnFrom ` now emit `Approval` events, to represent the token's state comprehensively through events. ([#1524](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1524)) + * `ERC721`: added `_burn(uint256 tokenId)`, replacing the similar deprecated function (see below). ([#1550](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1550)) + * `ERC721`: added `_tokensOfOwner(address owner)`, allowing to internally retrieve the array of an account's owned tokens. ([#1522](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1522)) + * Crowdsales: all constructors are now `public`, meaning it is not necessary to extend these contracts in order to deploy them. The exception is `FinalizableCrowdsale`, since it is meaningless unless extended. ([#1564](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1564)) + * `SignedSafeMath`: added overflow-safe operations for signed integers (`int256`). ([#1559](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1559), [#1588](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1588)) + +### Improvements: + * The compiler version required by `Array` was behind the rest of the libray so it was updated to `v0.4.24`. ([#1553](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1553)) + * Now conforming to a 4-space indentation code style. ([1508](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1508)) + * `ERC20`: more gas efficient due to removed redundant `require`s. ([#1409](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1409)) + * `ERC721`: fixed a bug that prevented internal data structures from being properly cleaned, missing potential gas refunds. ([#1539](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1539) and [#1549](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1549)) + * `ERC721`: general gas savings on `transferFrom`, `_mint` and `_burn`, due to redudant `require`s and `SSTORE`s. ([#1549](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1549)) + +### Bugfixes: + +### Breaking changes: + +### Deprecations: + * `ERC721._burn(address owner, uint256 tokenId)`: due to the `owner` parameter being unnecessary. ([#1550](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1550)) + * `RefundableCrowdsale`: due to trading abuse potential on crowdsales that miss their goal. ([#1543](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1543)) diff --git a/CODE_STYLE.md b/CODE_STYLE.md index 2eaac05c9..0c00a15a5 100644 --- a/CODE_STYLE.md +++ b/CODE_STYLE.md @@ -16,11 +16,14 @@ Any exception or additions specific to our project are documented below. * Try to avoid acronyms and abbreviations. +* All state variables should be private. + * Private state variables should have an underscore prefix. ``` contract TestContract { uint256 private _privateVar; + uint256 internal _internalVar; } ``` diff --git a/README.md b/README.md index 0b8ef55e4..41e90aa41 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,24 @@ This fork of OpenZeppelin is set up as a **reusable EVM Package**. It is deploye npm install openzeppelin-eth ``` +## Usage + +To write your custom contracts, import ours and extend them through inheritance. + +```solidity +pragma solidity ^0.5.0; + +import 'zos-lib/contracts/Initializable.sol'; +import 'openzeppelin-solidity/contracts/token/ERC721/ERC721Full.sol'; +import 'openzeppelin-solidity/contracts/token/ERC721/ERC721Mintable.sol'; + +contract MyNFT is Initializable, ERC721Full, ERC721Mintable { + function initialize() public initializer { + ERC721Full.initialize("MyNFT", "MNFT"); + } +} +``` + ## Pre-deployed contracts - StandaloneERC20 diff --git a/RELEASING.md b/RELEASING.md index 6514b4cf5..20f1132ad 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -34,7 +34,7 @@ git push upstream vX.Y.Z-rc.R Draft the release notes in our [GitHub releases](https://github.com/OpenZeppelin/openzeppelin-solidity/releases). Make sure to mark it as a pre-release! Try to be consistent with our previous release notes in the title and format of the text. Release candidates don't need a detailed changelog, but make sure to include a link to GitHub's compare page. -Once the CI run for the new tag is green, publish on npm under the `next` tag. +Once the CI run for the new tag is green, publish on npm under the `next` tag. You should see the contracts compile automatically. ``` npm publish --tag next @@ -62,7 +62,7 @@ git push upstream vX.Y.Z Draft the release notes in GitHub releases. Try to be consistent with our previous release notes in the title and format of the text. Make sure to include a detailed changelog. -Once the CI run for the new tag is green, publish on npm. +Once the CI run for the new tag is green, publish on npm. You should see the contracts compile automatically. ``` npm publish diff --git a/contracts/ARCHITECTURE.md b/contracts/ARCHITECTURE.md index 3d0ebfdaa..bfb6cff8d 100644 --- a/contracts/ARCHITECTURE.md +++ b/contracts/ARCHITECTURE.md @@ -12,7 +12,7 @@ The following provides visibility into how OpenZeppelin's contracts are organize - **introspection** - An interface that can be used to make a contract comply with the ERC-165 standard as well as a contract that implements ERC-165 using a lookup table. - **lifecycle** - A collection of base contracts used to manage the existence and behavior of your contracts and their funds. - **math** - Libraries with safety checks on operations that throw on errors. -- **mocks** - A collection of abstract contracts that are primarily used for unit testing. They also serve as good usage examples and demonstrate how to combine contracts with inheritence when developing your own custom applications. +- **mocks** - A collection of abstract contracts that are primarily used for unit testing. They also serve as good usage examples and demonstrate how to combine contracts with inheritance when developing your own custom applications. - **ownership** - A collection of smart contracts that can be used to manage contract and token ownership - **payment** - A collection of smart contracts that can be used to manage payments through escrow arrangements, withdrawals, and claims. Includes support for both single payees and multiple payees. - **proposals** - A collection of smart contracts that reflect community Ethereum Improvement Proposals (EIPs). These contracts are under development and standardization. They are not recommended for production, but they are useful for experimentation with pending EIP standards. Go [here](https://github.com/OpenZeppelin/openzeppelin-solidity/wiki/ERC-Process) for more information. diff --git a/contracts/access/Roles.sol b/contracts/access/Roles.sol index b71aa8e29..63148d1f1 100644 --- a/contracts/access/Roles.sol +++ b/contracts/access/Roles.sol @@ -1,5 +1,4 @@ -pragma solidity ^0.4.24; - +pragma solidity ^0.5.0; /** * @title Roles @@ -15,6 +14,8 @@ library Roles { */ function add(Role storage role, address account) internal { require(account != address(0)); + require(!has(role, account)); + role.bearer[account] = true; } @@ -23,6 +24,8 @@ library Roles { */ function remove(Role storage role, address account) internal { require(account != address(0)); + require(has(role, account)); + role.bearer[account] = false; } @@ -30,11 +33,7 @@ library Roles { * @dev check if an account has this role * @return bool */ - function has(Role storage role, address account) - internal - view - returns (bool) - { + function has(Role storage role, address account) internal view returns (bool) { require(account != address(0)); return role.bearer[account]; } diff --git a/contracts/access/roles/CapperRole.sol b/contracts/access/roles/CapperRole.sol index 7347e0a6a..164720e18 100644 --- a/contracts/access/roles/CapperRole.sol +++ b/contracts/access/roles/CapperRole.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "../Roles.sol"; @@ -10,7 +10,7 @@ contract CapperRole is Initializable { event CapperAdded(address indexed account); event CapperRemoved(address indexed account); - Roles.Role private cappers; + Roles.Role private _cappers; function initialize(address sender) public initializer { if (!isCapper(sender)) { @@ -24,7 +24,7 @@ contract CapperRole is Initializable { } function isCapper(address account) public view returns (bool) { - return cappers.has(account); + return _cappers.has(account); } function addCapper(address account) public onlyCapper { @@ -36,12 +36,12 @@ contract CapperRole is Initializable { } function _addCapper(address account) internal { - cappers.add(account); + _cappers.add(account); emit CapperAdded(account); } function _removeCapper(address account) internal { - cappers.remove(account); + _cappers.remove(account); emit CapperRemoved(account); } diff --git a/contracts/access/roles/MinterRole.sol b/contracts/access/roles/MinterRole.sol index 4d451b971..a8378999a 100644 --- a/contracts/access/roles/MinterRole.sol +++ b/contracts/access/roles/MinterRole.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "../Roles.sol"; @@ -10,7 +10,7 @@ contract MinterRole is Initializable { event MinterAdded(address indexed account); event MinterRemoved(address indexed account); - Roles.Role private minters; + Roles.Role private _minters; function initialize(address sender) public initializer { if (!isMinter(sender)) { @@ -24,7 +24,7 @@ contract MinterRole is Initializable { } function isMinter(address account) public view returns (bool) { - return minters.has(account); + return _minters.has(account); } function addMinter(address account) public onlyMinter { @@ -36,12 +36,12 @@ contract MinterRole is Initializable { } function _addMinter(address account) internal { - minters.add(account); + _minters.add(account); emit MinterAdded(account); } function _removeMinter(address account) internal { - minters.remove(account); + _minters.remove(account); emit MinterRemoved(account); } diff --git a/contracts/access/roles/PauserRole.sol b/contracts/access/roles/PauserRole.sol index 4acf3737e..80fbc8471 100644 --- a/contracts/access/roles/PauserRole.sol +++ b/contracts/access/roles/PauserRole.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "../Roles.sol"; @@ -10,7 +10,7 @@ contract PauserRole is Initializable { event PauserAdded(address indexed account); event PauserRemoved(address indexed account); - Roles.Role private pausers; + Roles.Role private _pausers; function initialize(address sender) public initializer { if (!isPauser(sender)) { @@ -24,7 +24,7 @@ contract PauserRole is Initializable { } function isPauser(address account) public view returns (bool) { - return pausers.has(account); + return _pausers.has(account); } function addPauser(address account) public onlyPauser { @@ -36,12 +36,12 @@ contract PauserRole is Initializable { } function _addPauser(address account) internal { - pausers.add(account); + _pausers.add(account); emit PauserAdded(account); } function _removePauser(address account) internal { - pausers.remove(account); + _pausers.remove(account); emit PauserRemoved(account); } diff --git a/contracts/access/roles/SignerRole.sol b/contracts/access/roles/SignerRole.sol index 66ebcbedd..424d12b3d 100644 --- a/contracts/access/roles/SignerRole.sol +++ b/contracts/access/roles/SignerRole.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "../Roles.sol"; @@ -10,7 +10,7 @@ contract SignerRole is Initializable { event SignerAdded(address indexed account); event SignerRemoved(address indexed account); - Roles.Role private signers; + Roles.Role private _signers; function initialize(address sender) public initializer { if (!isSigner(sender)) { @@ -24,7 +24,7 @@ contract SignerRole is Initializable { } function isSigner(address account) public view returns (bool) { - return signers.has(account); + return _signers.has(account); } function addSigner(address account) public onlySigner { @@ -36,12 +36,12 @@ contract SignerRole is Initializable { } function _addSigner(address account) internal { - signers.add(account); + _signers.add(account); emit SignerAdded(account); } function _removeSigner(address account) internal { - signers.remove(account); + _signers.remove(account); emit SignerRemoved(account); } diff --git a/contracts/access/roles/WhitelistAdminRole.sol b/contracts/access/roles/WhitelistAdminRole.sol new file mode 100644 index 000000000..8af7412ba --- /dev/null +++ b/contracts/access/roles/WhitelistAdminRole.sol @@ -0,0 +1,47 @@ +pragma solidity ^0.5.0; + +import "../Roles.sol"; + +/** + * @title WhitelistAdminRole + * @dev WhitelistAdmins are responsible for assigning and removing Whitelisted accounts. + */ +contract WhitelistAdminRole { + using Roles for Roles.Role; + + event WhitelistAdminAdded(address indexed account); + event WhitelistAdminRemoved(address indexed account); + + Roles.Role private _whitelistAdmins; + + constructor () internal { + _addWhitelistAdmin(msg.sender); + } + + modifier onlyWhitelistAdmin() { + require(isWhitelistAdmin(msg.sender)); + _; + } + + function isWhitelistAdmin(address account) public view returns (bool) { + return _whitelistAdmins.has(account); + } + + function addWhitelistAdmin(address account) public onlyWhitelistAdmin { + _addWhitelistAdmin(account); + } + + function renounceWhitelistAdmin() public { + _removeWhitelistAdmin(msg.sender); + } + + function _addWhitelistAdmin(address account) internal { + _whitelistAdmins.add(account); + emit WhitelistAdminAdded(account); + } + + function _removeWhitelistAdmin(address account) internal { + _whitelistAdmins.remove(account); + emit WhitelistAdminRemoved(account); + } +} diff --git a/contracts/access/roles/WhitelistedRole.sol b/contracts/access/roles/WhitelistedRole.sol new file mode 100644 index 000000000..3ba5ae0cf --- /dev/null +++ b/contracts/access/roles/WhitelistedRole.sol @@ -0,0 +1,50 @@ +pragma solidity ^0.5.0; + +import "../Roles.sol"; +import "./WhitelistAdminRole.sol"; + +/** + * @title WhitelistedRole + * @dev Whitelisted accounts have been approved by a WhitelistAdmin to perform certain actions (e.g. participate in a + * crowdsale). This role is special in that the only accounts that can add it are WhitelistAdmins (who can also remove + * it), and not Whitelisteds themselves. + */ +contract WhitelistedRole is WhitelistAdminRole { + using Roles for Roles.Role; + + event WhitelistedAdded(address indexed account); + event WhitelistedRemoved(address indexed account); + + Roles.Role private _whitelisteds; + + modifier onlyWhitelisted() { + require(isWhitelisted(msg.sender)); + _; + } + + function isWhitelisted(address account) public view returns (bool) { + return _whitelisteds.has(account); + } + + function addWhitelisted(address account) public onlyWhitelistAdmin { + _addWhitelisted(account); + } + + function removeWhitelisted(address account) public onlyWhitelistAdmin { + _removeWhitelisted(account); + } + + function renounceWhitelisted() public { + _removeWhitelisted(msg.sender); + } + + function _addWhitelisted(address account) internal { + _whitelisteds.add(account); + emit WhitelistedAdded(account); + } + + function _removeWhitelisted(address account) internal { + _whitelisteds.remove(account); + emit WhitelistedRemoved(account); + } +} diff --git a/contracts/crowdsale/Crowdsale.sol b/contracts/crowdsale/Crowdsale.sol index d4fb398f6..2ab365033 100644 --- a/contracts/crowdsale/Crowdsale.sol +++ b/contracts/crowdsale/Crowdsale.sol @@ -1,10 +1,10 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "../token/ERC20/IERC20.sol"; import "../math/SafeMath.sol"; import "../token/ERC20/SafeERC20.sol"; - +import "../utils/ReentrancyGuard.sol"; /** * @title Crowdsale @@ -18,7 +18,7 @@ import "../token/ERC20/SafeERC20.sol"; * the methods to add functionality. Consider using 'super' where appropriate to concatenate * behavior. */ -contract Crowdsale is Initializable { +contract Crowdsale is Initializable, ReentrancyGuard { using SafeMath for uint256; using SafeERC20 for IERC20; @@ -26,7 +26,7 @@ contract Crowdsale is Initializable { IERC20 private _token; // Address where funds are collected - address private _wallet; + address payable private _wallet; // How many token units a buyer gets per wei. // The rate is the conversion between wei and the smallest and indivisible token unit. @@ -44,12 +44,7 @@ contract Crowdsale is Initializable { * @param value weis paid for purchase * @param amount amount of tokens purchased */ - event TokensPurchased( - address indexed purchaser, - address indexed beneficiary, - uint256 value, - uint256 amount - ); + event TokensPurchased(address indexed purchaser, address indexed beneficiary, uint256 value, uint256 amount); /** * @param rate Number of token units a buyer gets per wei @@ -62,19 +57,18 @@ contract Crowdsale is Initializable { function initialize(uint256 rate, address wallet, IERC20 token) public initializer { require(rate > 0); require(wallet != address(0)); - require(token != address(0)); + require(address(token) != address(0)); _rate = rate; _wallet = wallet; _token = token; } - // ----------------------------------------- - // Crowdsale external interface - // ----------------------------------------- - /** * @dev fallback function ***DO NOT OVERRIDE*** + * Note that other contracts will transfer fund with a base gas stipend + * of 2300, which is not enough to call buyTokens. Consider calling + * buyTokens directly when purchasing tokens from a contract. */ function () external payable { buyTokens(msg.sender); @@ -83,26 +77,26 @@ contract Crowdsale is Initializable { /** * @return the token being sold. */ - function token() public view returns(IERC20) { + function token() public view returns (IERC20) { return _token; } /** * @return the address where funds are collected. */ - function wallet() public view returns(address) { + function wallet() public view returns (address payable) { return _wallet; } /** * @return the number of token units a buyer gets per wei. */ - function rate() public view returns(uint256) { + function rate() public view returns (uint256) { return _rate; } /** - * @return the mount of wei raised. + * @return the amount of wei raised. */ function weiRaised() public view returns (uint256) { return _weiRaised; @@ -110,10 +104,11 @@ contract Crowdsale is Initializable { /** * @dev low level token purchase ***DO NOT OVERRIDE*** - * @param beneficiary Address performing the token purchase + * This function has a non-reentrancy guard, so it shouldn't be called by + * another `nonReentrant` function. + * @param beneficiary Recipient of the token purchase */ - function buyTokens(address beneficiary) public payable { - + function buyTokens(address beneficiary) public nonReentrant payable { uint256 weiAmount = msg.value; _preValidatePurchase(beneficiary, weiAmount); @@ -124,12 +119,7 @@ contract Crowdsale is Initializable { _weiRaised = _weiRaised.add(weiAmount); _processPurchase(beneficiary, tokens); - emit TokensPurchased( - msg.sender, - beneficiary, - weiAmount, - tokens - ); + emit TokensPurchased(msg.sender, beneficiary, weiAmount, tokens); _updatePurchasingState(beneficiary, weiAmount); @@ -137,86 +127,62 @@ contract Crowdsale is Initializable { _postValidatePurchase(beneficiary, weiAmount); } - // ----------------------------------------- - // Internal interface (extensible) - // ----------------------------------------- - function _hasBeenInitialized() internal view returns (bool) { return ((_rate > 0) && (_wallet != address(0)) && (_token != address(0))); } /** - * @dev Validation of an incoming purchase. Use require statements to revert state when conditions are not met. Use `super` in contracts that inherit from Crowdsale to extend their validations. + * @dev Validation of an incoming purchase. Use require statements to revert state when conditions are not met. + * Use `super` in contracts that inherit from Crowdsale to extend their validations. * Example from CappedCrowdsale.sol's _preValidatePurchase method: - * super._preValidatePurchase(beneficiary, weiAmount); - * require(weiRaised().add(weiAmount) <= cap); + * super._preValidatePurchase(beneficiary, weiAmount); + * require(weiRaised().add(weiAmount) <= cap); * @param beneficiary Address performing the token purchase * @param weiAmount Value in wei involved in the purchase */ - function _preValidatePurchase( - address beneficiary, - uint256 weiAmount - ) - internal - { + function _preValidatePurchase(address beneficiary, uint256 weiAmount) internal view { require(beneficiary != address(0)); require(weiAmount != 0); } /** - * @dev Validation of an executed purchase. Observe state and use revert statements to undo rollback when valid conditions are not met. + * @dev Validation of an executed purchase. Observe state and use revert statements to undo rollback when valid + * conditions are not met. * @param beneficiary Address performing the token purchase * @param weiAmount Value in wei involved in the purchase */ - function _postValidatePurchase( - address beneficiary, - uint256 weiAmount - ) - internal - { - // optional override + function _postValidatePurchase(address beneficiary, uint256 weiAmount) internal view { + // solhint-disable-previous-line no-empty-blocks } /** - * @dev Source of tokens. Override this method to modify the way in which the crowdsale ultimately gets and sends its tokens. + * @dev Source of tokens. Override this method to modify the way in which the crowdsale ultimately gets and sends + * its tokens. * @param beneficiary Address performing the token purchase * @param tokenAmount Number of tokens to be emitted */ - function _deliverTokens( - address beneficiary, - uint256 tokenAmount - ) - internal - { + function _deliverTokens(address beneficiary, uint256 tokenAmount) internal { _token.safeTransfer(beneficiary, tokenAmount); } /** - * @dev Executed when a purchase has been validated and is ready to be executed. Not necessarily emits/sends tokens. + * @dev Executed when a purchase has been validated and is ready to be executed. Doesn't necessarily emit/send + * tokens. * @param beneficiary Address receiving the tokens * @param tokenAmount Number of tokens to be purchased */ - function _processPurchase( - address beneficiary, - uint256 tokenAmount - ) - internal - { + function _processPurchase(address beneficiary, uint256 tokenAmount) internal { _deliverTokens(beneficiary, tokenAmount); } /** - * @dev Override for extensions that require an internal state to check for validity (current user contributions, etc.) + * @dev Override for extensions that require an internal state to check for validity (current user contributions, + * etc.) * @param beneficiary Address receiving the tokens * @param weiAmount Value in wei involved in the purchase */ - function _updatePurchasingState( - address beneficiary, - uint256 weiAmount - ) - internal - { - // optional override + function _updatePurchasingState(address beneficiary, uint256 weiAmount) internal { + // solhint-disable-previous-line no-empty-blocks } /** @@ -224,9 +190,7 @@ contract Crowdsale is Initializable { * @param weiAmount Value in wei to be converted into tokens * @return Number of tokens that can be purchased with the specified _weiAmount */ - function _getTokenAmount(uint256 weiAmount) - internal view returns (uint256) - { + function _getTokenAmount(uint256 weiAmount) internal view returns (uint256) { return weiAmount.mul(_rate); } diff --git a/contracts/crowdsale/distribution/FinalizableCrowdsale.sol b/contracts/crowdsale/distribution/FinalizableCrowdsale.sol index 549afe6fe..f84d6dd92 100644 --- a/contracts/crowdsale/distribution/FinalizableCrowdsale.sol +++ b/contracts/crowdsale/distribution/FinalizableCrowdsale.sol @@ -1,10 +1,9 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "../../math/SafeMath.sol"; import "../validation/TimedCrowdsale.sol"; - /** * @title FinalizableCrowdsale * @dev Extension of Crowdsale with a one-off finalization action, where one @@ -13,7 +12,7 @@ import "../validation/TimedCrowdsale.sol"; contract FinalizableCrowdsale is Initializable, TimedCrowdsale { using SafeMath for uint256; - bool private _finalized = false; + bool private _finalized; event CrowdsaleFinalized(); @@ -32,10 +31,10 @@ contract FinalizableCrowdsale is Initializable, TimedCrowdsale { require(!_finalized); require(hasClosed()); + _finalized = true; + _finalization(); emit CrowdsaleFinalized(); - - _finalized = true; } /** @@ -44,8 +43,8 @@ contract FinalizableCrowdsale is Initializable, TimedCrowdsale { * executed entirely. */ function _finalization() internal { + // solhint-disable-previous-line no-empty-blocks } - uint256[50] private ______gap; } diff --git a/contracts/crowdsale/distribution/PostDeliveryCrowdsale.sol b/contracts/crowdsale/distribution/PostDeliveryCrowdsale.sol index 1a8ceb270..ff7ac60ca 100644 --- a/contracts/crowdsale/distribution/PostDeliveryCrowdsale.sol +++ b/contracts/crowdsale/distribution/PostDeliveryCrowdsale.sol @@ -1,11 +1,9 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "../validation/TimedCrowdsale.sol"; -import "../../token/ERC20/IERC20.sol"; import "../../math/SafeMath.sol"; - /** * @title PostDeliveryCrowdsale * @dev Crowdsale that locks tokens from withdrawal until it ends. @@ -30,7 +28,7 @@ contract PostDeliveryCrowdsale is Initializable, TimedCrowdsale { /** * @return the balance of an account. */ - function balanceOf(address account) public view returns(uint256) { + function balanceOf(address account) public view returns (uint256) { return _balances[account]; } @@ -39,12 +37,7 @@ contract PostDeliveryCrowdsale is Initializable, TimedCrowdsale { * @param beneficiary Token purchaser * @param tokenAmount Amount of tokens purchased */ - function _processPurchase( - address beneficiary, - uint256 tokenAmount - ) - internal - { + function _processPurchase(address beneficiary, uint256 tokenAmount) internal { _balances[beneficiary] = _balances[beneficiary].add(tokenAmount); } diff --git a/contracts/crowdsale/distribution/RefundableCrowdsale.sol b/contracts/crowdsale/distribution/RefundableCrowdsale.sol index 680edd79e..071a10e21 100644 --- a/contracts/crowdsale/distribution/RefundableCrowdsale.sol +++ b/contracts/crowdsale/distribution/RefundableCrowdsale.sol @@ -1,16 +1,19 @@ -pragma solidity ^0.4.24; - +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "../../math/SafeMath.sol"; import "./FinalizableCrowdsale.sol"; -import "../../payment/RefundEscrow.sol"; - +import "../../payment/escrow/RefundEscrow.sol"; /** * @title RefundableCrowdsale - * @dev Extension of Crowdsale contract that adds a funding goal, and - * the possibility of users getting a refund if goal is not met. + * @dev Extension of Crowdsale contract that adds a funding goal, and the possibility of users getting a refund if goal + * is not met. + * + * Deprecated, use RefundablePostDeliveryCrowdsale instead. Note that if you allow tokens to be traded before the goal + * is met, then an attack is possible in which the attacker purchases tokens from the crowdsale and when they sees that + * the goal is unlikely to be met, they sell their tokens (possibly at a discount). The attacker will be refunded when + * the crowdsale is finalized, and the users that purchased from them will be left with worthless tokens. */ contract RefundableCrowdsale is Initializable, FinalizableCrowdsale { using SafeMath for uint256; @@ -30,32 +33,30 @@ contract RefundableCrowdsale is Initializable, FinalizableCrowdsale { assert(TimedCrowdsale._hasBeenInitialized()); require(goal > 0); - // conditional added to make initializer idempotent in case of diamond inheritance if (address(_escrow) == address(0)) { _escrow = new RefundEscrow(); _escrow.initialize(wallet(), address(this)); } - _goal = goal; } /** * @return minimum amount of funds to be raised in wei. */ - function goal() public view returns(uint256) { + function goal() public view returns (uint256) { return _goal; } /** * @dev Investors can claim refunds here if crowdsale is unsuccessful - * @param beneficiary Whose refund will be claimed. + * @param refundee Whose refund will be claimed. */ - function claimRefund(address beneficiary) public { + function claimRefund(address payable refundee) public { require(finalized()); require(!goalReached()); - _escrow.withdraw(beneficiary); + _escrow.withdraw(refundee); } /** @@ -87,6 +88,5 @@ contract RefundableCrowdsale is Initializable, FinalizableCrowdsale { _escrow.deposit.value(msg.value)(msg.sender); } - uint256[50] private ______gap; } diff --git a/contracts/crowdsale/distribution/RefundablePostDeliveryCrowdsale.sol b/contracts/crowdsale/distribution/RefundablePostDeliveryCrowdsale.sol new file mode 100644 index 000000000..be4c5b6a0 --- /dev/null +++ b/contracts/crowdsale/distribution/RefundablePostDeliveryCrowdsale.sol @@ -0,0 +1,20 @@ +pragma solidity ^0.5.0; + +import "./RefundableCrowdsale.sol"; +import "./PostDeliveryCrowdsale.sol"; + + +/** + * @title RefundablePostDeliveryCrowdsale + * @dev Extension of RefundableCrowdsale contract that only delivers the tokens + * once the crowdsale has closed and the goal met, preventing refunds to be issued + * to token holders. + */ +contract RefundablePostDeliveryCrowdsale is RefundableCrowdsale, PostDeliveryCrowdsale { + function withdrawTokens(address beneficiary) public { + require(finalized()); + require(goalReached()); + + super.withdrawTokens(beneficiary); + } +} diff --git a/contracts/crowdsale/emission/AllowanceCrowdsale.sol b/contracts/crowdsale/emission/AllowanceCrowdsale.sol index 0e062e49e..067ac7525 100644 --- a/contracts/crowdsale/emission/AllowanceCrowdsale.sol +++ b/contracts/crowdsale/emission/AllowanceCrowdsale.sol @@ -1,11 +1,11 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "../Crowdsale.sol"; import "../../token/ERC20/IERC20.sol"; import "../../token/ERC20/SafeERC20.sol"; import "../../math/SafeMath.sol"; - +import "../../math/Math.sol"; /** * @title AllowanceCrowdsale @@ -31,7 +31,7 @@ contract AllowanceCrowdsale is Initializable, Crowdsale { /** * @return the address of the wallet that will hold the tokens. */ - function tokenWallet() public view returns(address) { + function tokenWallet() public view returns (address) { return _tokenWallet; } @@ -40,7 +40,7 @@ contract AllowanceCrowdsale is Initializable, Crowdsale { * @return Amount of tokens left in the allowance */ function remainingTokens() public view returns (uint256) { - return token().allowance(_tokenWallet, this); + return Math.min(token().balanceOf(_tokenWallet), token().allowance(_tokenWallet, address(this))); } /** @@ -48,12 +48,7 @@ contract AllowanceCrowdsale is Initializable, Crowdsale { * @param beneficiary Token purchaser * @param tokenAmount Amount of tokens purchased */ - function _deliverTokens( - address beneficiary, - uint256 tokenAmount - ) - internal - { + function _deliverTokens(address beneficiary, uint256 tokenAmount) internal { token().safeTransferFrom(_tokenWallet, beneficiary, tokenAmount); } diff --git a/contracts/crowdsale/emission/MintedCrowdsale.sol b/contracts/crowdsale/emission/MintedCrowdsale.sol index 58b01d2f8..f57ddbeec 100644 --- a/contracts/crowdsale/emission/MintedCrowdsale.sol +++ b/contracts/crowdsale/emission/MintedCrowdsale.sol @@ -1,31 +1,23 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "../Crowdsale.sol"; import "../../token/ERC20/ERC20Mintable.sol"; - /** * @title MintedCrowdsale * @dev Extension of Crowdsale contract whose tokens are minted in each purchase. * Token ownership should be transferred to MintedCrowdsale for minting. */ contract MintedCrowdsale is Initializable, Crowdsale { - /** * @dev Overrides delivery by minting tokens upon purchase. * @param beneficiary Token purchaser * @param tokenAmount Number of tokens to be minted */ - function _deliverTokens( - address beneficiary, - uint256 tokenAmount - ) - internal - { + function _deliverTokens(address beneficiary, uint256 tokenAmount) internal { // Potentially dangerous assumption about the type of the token. - require( - ERC20Mintable(address(token())).mint(beneficiary, tokenAmount)); + require(ERC20Mintable(address(token())).mint(beneficiary, tokenAmount)); } uint256[50] private ______gap; diff --git a/contracts/crowdsale/price/IncreasingPriceCrowdsale.sol b/contracts/crowdsale/price/IncreasingPriceCrowdsale.sol index 3a9dddcbc..008d3c388 100644 --- a/contracts/crowdsale/price/IncreasingPriceCrowdsale.sol +++ b/contracts/crowdsale/price/IncreasingPriceCrowdsale.sol @@ -1,10 +1,9 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "../validation/TimedCrowdsale.sol"; import "../../math/SafeMath.sol"; - /** * @title IncreasingPriceCrowdsale * @dev Extension of Crowdsale contract that increases the price of tokens linearly in time. @@ -26,15 +25,23 @@ contract IncreasingPriceCrowdsale is Initializable, TimedCrowdsale { assert(TimedCrowdsale._hasBeenInitialized()); require(finalRate > 0); - require(initialRate >= finalRate); + require(initialRate > finalRate); _initialRate = initialRate; _finalRate = finalRate; } + /** + * The base rate function is overridden to revert, since this crowdsale doens't use it, and + * all calls to it are a mistake. + */ + function rate() public view returns (uint256) { + revert(); + } + /** * @return the initial rate of the crowdsale. */ - function initialRate() public view returns(uint256) { + function initialRate() public view returns (uint256) { return _initialRate; } @@ -51,7 +58,11 @@ contract IncreasingPriceCrowdsale is Initializable, TimedCrowdsale { * @return The number of tokens a buyer gets per wei at a given time */ function getCurrentRate() public view returns (uint256) { - // solium-disable-next-line security/no-block-members + if (!isOpen()) { + return 0; + } + + // solhint-disable-next-line not-rely-on-time uint256 elapsedTime = block.timestamp.sub(openingTime()); uint256 timeRange = closingTime().sub(openingTime()); uint256 rateRange = _initialRate.sub(_finalRate); @@ -63,13 +74,10 @@ contract IncreasingPriceCrowdsale is Initializable, TimedCrowdsale { * @param weiAmount The value in wei to be converted into tokens * @return The number of tokens _weiAmount wei will buy at present time */ - function _getTokenAmount(uint256 weiAmount) - internal view returns (uint256) - { + function _getTokenAmount(uint256 weiAmount) internal view returns (uint256) { uint256 currentRate = getCurrentRate(); return currentRate.mul(weiAmount); } - uint256[50] private ______gap; } diff --git a/contracts/crowdsale/validation/CappedCrowdsale.sol b/contracts/crowdsale/validation/CappedCrowdsale.sol index 09dcaf595..055e459ce 100644 --- a/contracts/crowdsale/validation/CappedCrowdsale.sol +++ b/contracts/crowdsale/validation/CappedCrowdsale.sol @@ -1,10 +1,9 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "../../math/SafeMath.sol"; import "../Crowdsale.sol"; - /** * @title CappedCrowdsale * @dev Crowdsale with a limit for total contributions. @@ -28,7 +27,7 @@ contract CappedCrowdsale is Initializable, Crowdsale { /** * @return the cap of the crowdsale. */ - function cap() public view returns(uint256) { + function cap() public view returns (uint256) { return _cap; } @@ -45,16 +44,10 @@ contract CappedCrowdsale is Initializable, Crowdsale { * @param beneficiary Token purchaser * @param weiAmount Amount of wei contributed */ - function _preValidatePurchase( - address beneficiary, - uint256 weiAmount - ) - internal - { + function _preValidatePurchase(address beneficiary, uint256 weiAmount) internal view { super._preValidatePurchase(beneficiary, weiAmount); require(weiRaised().add(weiAmount) <= _cap); } - uint256[50] private ______gap; } diff --git a/contracts/crowdsale/validation/IndividuallyCappedCrowdsale.sol b/contracts/crowdsale/validation/IndividuallyCappedCrowdsale.sol index 255375eb3..65da37d4f 100644 --- a/contracts/crowdsale/validation/IndividuallyCappedCrowdsale.sol +++ b/contracts/crowdsale/validation/IndividuallyCappedCrowdsale.sol @@ -1,11 +1,10 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "../../math/SafeMath.sol"; import "../Crowdsale.sol"; import "../../access/roles/CapperRole.sol"; - /** * @title IndividuallyCappedCrowdsale * @dev Crowdsale with per-beneficiary caps. @@ -45,9 +44,7 @@ contract IndividuallyCappedCrowdsale is Initializable, Crowdsale, CapperRole { * @param beneficiary Address of contributor * @return Beneficiary contribution so far */ - function getContribution(address beneficiary) - public view returns (uint256) - { + function getContribution(address beneficiary) public view returns (uint256) { return _contributions[beneficiary]; } @@ -56,15 +53,9 @@ contract IndividuallyCappedCrowdsale is Initializable, Crowdsale, CapperRole { * @param beneficiary Token purchaser * @param weiAmount Amount of wei contributed */ - function _preValidatePurchase( - address beneficiary, - uint256 weiAmount - ) - internal - { + function _preValidatePurchase(address beneficiary, uint256 weiAmount) internal view { super._preValidatePurchase(beneficiary, weiAmount); - require( - _contributions[beneficiary].add(weiAmount) <= _caps[beneficiary]); + require(_contributions[beneficiary].add(weiAmount) <= _caps[beneficiary]); } /** @@ -72,17 +63,10 @@ contract IndividuallyCappedCrowdsale is Initializable, Crowdsale, CapperRole { * @param beneficiary Token purchaser * @param weiAmount Amount of wei contributed */ - function _updatePurchasingState( - address beneficiary, - uint256 weiAmount - ) - internal - { + function _updatePurchasingState(address beneficiary, uint256 weiAmount) internal { super._updatePurchasingState(beneficiary, weiAmount); - _contributions[beneficiary] = _contributions[beneficiary].add( - weiAmount); + _contributions[beneficiary] = _contributions[beneficiary].add(weiAmount); } - uint256[50] private ______gap; } diff --git a/contracts/crowdsale/validation/PausableCrowdsale.sol b/contracts/crowdsale/validation/PausableCrowdsale.sol new file mode 100644 index 000000000..cc89aebab --- /dev/null +++ b/contracts/crowdsale/validation/PausableCrowdsale.sol @@ -0,0 +1,21 @@ +pragma solidity ^0.5.0; + +import "../Crowdsale.sol"; +import "../../lifecycle/Pausable.sol"; + +/** + * @title PausableCrowdsale + * @dev Extension of Crowdsale contract where purchases can be paused and unpaused by the pauser role. + */ +contract PausableCrowdsale is Crowdsale, Pausable { + /** + * @dev Validation of an incoming purchase. Use require statements to revert state when conditions are not met. + * Use super to concatenate validations. + * Adds the validation that the crowdsale must not be paused. + * @param _beneficiary Address performing the token purchase + * @param _weiAmount Value in wei involved in the purchase + */ + function _preValidatePurchase(address _beneficiary, uint256 _weiAmount) internal view whenNotPaused { + return super._preValidatePurchase(_beneficiary, _weiAmount); + } +} diff --git a/contracts/crowdsale/validation/TimedCrowdsale.sol b/contracts/crowdsale/validation/TimedCrowdsale.sol index 9356b054c..e12de24f6 100644 --- a/contracts/crowdsale/validation/TimedCrowdsale.sol +++ b/contracts/crowdsale/validation/TimedCrowdsale.sol @@ -1,10 +1,9 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "../../math/SafeMath.sol"; import "../Crowdsale.sol"; - /** * @title TimedCrowdsale * @dev Crowdsale accepting contributions only within a time frame. @@ -31,9 +30,9 @@ contract TimedCrowdsale is Initializable, Crowdsale { function initialize(uint256 openingTime, uint256 closingTime) public initializer { assert(Crowdsale._hasBeenInitialized()); - // solium-disable-next-line security/no-block-members + // solhint-disable-next-line not-rely-on-time require(openingTime >= block.timestamp); - require(closingTime >= openingTime); + require(closingTime > openingTime); _openingTime = openingTime; _closingTime = closingTime; @@ -42,14 +41,14 @@ contract TimedCrowdsale is Initializable, Crowdsale { /** * @return the crowdsale opening time. */ - function openingTime() public view returns(uint256) { + function openingTime() public view returns (uint256) { return _openingTime; } /** * @return the crowdsale closing time. */ - function closingTime() public view returns(uint256) { + function closingTime() public view returns (uint256) { return _closingTime; } @@ -57,7 +56,7 @@ contract TimedCrowdsale is Initializable, Crowdsale { * @return true if the crowdsale is open, false otherwise. */ function isOpen() public view returns (bool) { - // solium-disable-next-line security/no-block-members + // solhint-disable-next-line not-rely-on-time return block.timestamp >= _openingTime && block.timestamp <= _closingTime; } @@ -66,7 +65,7 @@ contract TimedCrowdsale is Initializable, Crowdsale { * @return Whether crowdsale period has elapsed */ function hasClosed() public view returns (bool) { - // solium-disable-next-line security/no-block-members + // solhint-disable-next-line not-rely-on-time return block.timestamp > _closingTime; } @@ -79,16 +78,9 @@ contract TimedCrowdsale is Initializable, Crowdsale { * @param beneficiary Token purchaser * @param weiAmount Amount of wei contributed */ - function _preValidatePurchase( - address beneficiary, - uint256 weiAmount - ) - internal - onlyWhileOpen - { + function _preValidatePurchase(address beneficiary, uint256 weiAmount) internal onlyWhileOpen view { super._preValidatePurchase(beneficiary, weiAmount); } - uint256[50] private ______gap; } diff --git a/contracts/crowdsale/validation/WhitelistCrowdsale.sol b/contracts/crowdsale/validation/WhitelistCrowdsale.sol new file mode 100644 index 000000000..16e28786e --- /dev/null +++ b/contracts/crowdsale/validation/WhitelistCrowdsale.sol @@ -0,0 +1,21 @@ +pragma solidity ^0.5.0; +import "../Crowdsale.sol"; +import "../../access/roles/WhitelistedRole.sol"; + + +/** + * @title WhitelistCrowdsale + * @dev Crowdsale in which only whitelisted users can contribute. + */ +contract WhitelistCrowdsale is WhitelistedRole, Crowdsale { + /** + * @dev Extend parent behavior requiring beneficiary to be whitelisted. Note that no + * restriction is imposed on the account sending the transaction. + * @param _beneficiary Token beneficiary + * @param _weiAmount Amount of wei contributed + */ + function _preValidatePurchase(address _beneficiary, uint256 _weiAmount) internal view { + require(isWhitelisted(_beneficiary)); + super._preValidatePurchase(_beneficiary, _weiAmount); + } +} diff --git a/contracts/cryptography/ECDSA.sol b/contracts/cryptography/ECDSA.sol index b3f6d8de0..432a23c9a 100644 --- a/contracts/cryptography/ECDSA.sol +++ b/contracts/cryptography/ECDSA.sol @@ -1,5 +1,4 @@ -pragma solidity ^0.4.24; - +pragma solidity ^0.5.0; /** * @title Elliptic curve signature operations @@ -9,17 +8,12 @@ pragma solidity ^0.4.24; */ library ECDSA { - /** * @dev Recover signer address from a message by using their signature * @param hash bytes32 message, the hash is the signed message. What is recovered is the signer address. * @param signature bytes signature, the signature is generated using web3.eth.sign() */ - function recover(bytes32 hash, bytes signature) - internal - pure - returns (address) - { + function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { bytes32 r; bytes32 s; uint8 v; @@ -32,11 +26,11 @@ library ECDSA { // Divide the signature in r, s and v variables // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. - // solium-disable-next-line security/no-inline-assembly + // solhint-disable-next-line no-inline-assembly assembly { - r := mload(add(signature, 32)) - s := mload(add(signature, 64)) - v := byte(0, mload(add(signature, 96))) + r := mload(add(signature, 0x20)) + s := mload(add(signature, 0x40)) + v := byte(0, mload(add(signature, 0x60))) } // Version of signature should be 27 or 28, but 0 and 1 are also possible versions @@ -48,7 +42,6 @@ library ECDSA { if (v != 27 && v != 28) { return (address(0)); } else { - // solium-disable-next-line arg-overflow return ecrecover(hash, v, r, s); } } @@ -58,15 +51,9 @@ library ECDSA { * @dev prefix a bytes32 value with "\x19Ethereum Signed Message:" * and hash the result */ - function toEthSignedMessageHash(bytes32 hash) - internal - pure - returns (bytes32) - { + function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, // enforced by the type signature above - return keccak256( - abi.encodePacked("\x19Ethereum Signed Message:\n32", hash) - ); + return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } } diff --git a/contracts/cryptography/MerkleProof.sol b/contracts/cryptography/MerkleProof.sol index 210b78a82..2a964c8ba 100644 --- a/contracts/cryptography/MerkleProof.sol +++ b/contracts/cryptography/MerkleProof.sol @@ -1,5 +1,4 @@ -pragma solidity ^0.4.24; - +pragma solidity ^0.5.0; /** * @title MerkleProof @@ -14,15 +13,7 @@ library MerkleProof { * @param root Merkle root * @param leaf Leaf of Merkle tree */ - function verify( - bytes32[] proof, - bytes32 root, - bytes32 leaf - ) - internal - pure - returns (bool) - { + function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { diff --git a/contracts/drafts/Counter.sol b/contracts/drafts/Counter.sol index e5bfc7e09..af8f1e45d 100644 --- a/contracts/drafts/Counter.sol +++ b/contracts/drafts/Counter.sol @@ -1,5 +1,4 @@ -pragma solidity ^0.4.24; - +pragma solidity ^0.5.0; /** * @title Counter @@ -14,15 +13,11 @@ pragma solidity ^0.4.24; * so it's not something you have to worry about.) */ library Counter { - struct Counter { uint256 current; // default: 0 } - function next(Counter storage index) - internal - returns (uint256) - { + function next(Counter storage index) internal returns (uint256) { index.current += 1; return index.current; } diff --git a/contracts/drafts/ERC1046/TokenMetadata.sol b/contracts/drafts/ERC1046/TokenMetadata.sol index ec0ae3a46..0c148532d 100644 --- a/contracts/drafts/ERC1046/TokenMetadata.sol +++ b/contracts/drafts/ERC1046/TokenMetadata.sol @@ -1,33 +1,27 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "../../token/ERC20/IERC20.sol"; - /** * @title ERC-1047 Token Metadata * @dev See https://eips.ethereum.org/EIPS/eip-1046 * @dev tokenURI must respond with a URI that implements https://eips.ethereum.org/EIPS/eip-1047 - * @dev TODO - update https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/token/ERC721/IERC721.sol#L17 when 1046 is finalized */ contract ERC20TokenMetadata is Initializable, IERC20 { - function tokenURI() external view returns (string); + function tokenURI() external view returns (string memory); uint256[50] private ______gap; } - contract ERC20WithMetadata is Initializable, ERC20TokenMetadata { - string private _tokenURI = ""; + string private _tokenURI; - function initialize(string tokenURI) - public - initializer - { + function initialize(string memory tokenURI) public { _tokenURI = tokenURI; } - function tokenURI() external view returns (string) { + function tokenURI() external view returns (string memory) { return _tokenURI; } diff --git a/contracts/drafts/ERC20Migrator.sol b/contracts/drafts/ERC20Migrator.sol index 03cfcdacd..9c48d00a4 100644 --- a/contracts/drafts/ERC20Migrator.sol +++ b/contracts/drafts/ERC20Migrator.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "../token/ERC20/IERC20.sol"; @@ -6,7 +6,6 @@ import "../token/ERC20/ERC20Mintable.sol"; import "../token/ERC20/SafeERC20.sol"; import "../math/Math.sol"; - /** * @title ERC20Migrator * @dev This contract can be used to migrate an ERC20 token from one @@ -46,7 +45,7 @@ contract ERC20Migrator is Initializable { * @param legacyToken address of the old token contract */ function initialize(IERC20 legacyToken) public initializer { - require(legacyToken != address(0)); + require(address(legacyToken) != address(0)); _legacyToken = legacyToken; } @@ -70,9 +69,9 @@ contract ERC20Migrator is Initializable { * @param newToken the token that will be minted */ function beginMigration(ERC20Mintable newToken) public { - require(_newToken == address(0)); - require(newToken != address(0)); - require(newToken.isMinter(this)); + require(address(_newToken) == address(0)); + require(address(newToken) != address(0)); + require(newToken.isMinter(address(this))); _newToken = newToken; } @@ -84,7 +83,7 @@ contract ERC20Migrator is Initializable { * @param amount amount of tokens to be migrated */ function migrate(address account, uint256 amount) public { - _legacyToken.safeTransferFrom(account, this, amount); + _legacyToken.safeTransferFrom(account, address(this), amount); _newToken.mint(account, amount); } @@ -95,7 +94,7 @@ contract ERC20Migrator is Initializable { */ function migrateAll(address account) public { uint256 balance = _legacyToken.balanceOf(account); - uint256 allowance = _legacyToken.allowance(account, this); + uint256 allowance = _legacyToken.allowance(account, address(this)); uint256 amount = Math.min(balance, allowance); migrate(account, amount); } diff --git a/contracts/drafts/SignatureBouncer.sol b/contracts/drafts/SignatureBouncer.sol index 0e5937bbd..a2467e3de 100644 --- a/contracts/drafts/SignatureBouncer.sol +++ b/contracts/drafts/SignatureBouncer.sol @@ -1,33 +1,39 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "../access/roles/SignerRole.sol"; import "../cryptography/ECDSA.sol"; - /** * @title SignatureBouncer * @author PhABC, Shrugs and aflesher - * @dev SignatureBouncer allows users to submit a signature as a permission to do an action. - * If the signature is from one of the authorized signer addresses, the signature - * is valid. + * @dev SignatureBouncer allows users to submit a signature as a permission to + * do an action. + * If the signature is from one of the authorized signer addresses, the + * signature is valid. + * Note that SignatureBouncer offers no protection against replay attacks, users + * must add this themselves! + * * Signer addresses can be individual servers signing grants or different - * users within a decentralized club that have permission to invite other members. - * This technique is useful for whitelists and airdrops; instead of putting all - * valid addresses on-chain, simply sign a grant of the form - * keccak256(abi.encodePacked(`:contractAddress` + `:granteeAddress`)) using a valid signer address. + * users within a decentralized club that have permission to invite other + * members. This technique is useful for whitelists and airdrops; instead of + * putting all valid addresses on-chain, simply sign a grant of the form + * keccak256(abi.encodePacked(`:contractAddress` + `:granteeAddress`)) using a + * valid signer address. * Then restrict access to your crowdsale/whitelist/airdrop using the * `onlyValidSignature` modifier (or implement your own using _isValidSignature). * In addition to `onlyValidSignature`, `onlyValidSignatureAndMethod` and - * `onlyValidSignatureAndData` can be used to restrict access to only a given method - * or a given method with given parameters respectively. + * `onlyValidSignatureAndData` can be used to restrict access to only a given + * method or a given method with given parameters respectively. * See the tests in SignatureBouncer.test.js for specific usage examples. - * @notice A method that uses the `onlyValidSignatureAndData` modifier must make the _signature - * parameter the "last" parameter. You cannot sign a message that has its own - * signature in it so the last 128 bytes of msg.data (which represents the - * length of the _signature data and the _signaature data itself) is ignored when validating. - * Also non fixed sized parameters make constructing the data in the signature - * much more complex. See https://ethereum.stackexchange.com/a/50616 for more details. + * + * @notice A method that uses the `onlyValidSignatureAndData` modifier must make + * the _signature parameter the "last" parameter. You cannot sign a message that + * has its own signature in it so the last 128 bytes of msg.data (which + * represents the length of the _signature data and the _signaature data itself) + * is ignored when validating. Also non fixed sized parameters make constructing + * the data in the signature much more complex. + * See https://ethereum.stackexchange.com/a/50616 for more details. */ contract SignatureBouncer is Initializable, SignerRole { using ECDSA for bytes32; @@ -38,11 +44,14 @@ contract SignatureBouncer is Initializable, SignerRole { // Signature size is 65 bytes (tightly packed v + r + s), but gets padded to 96 bytes uint256 private constant _SIGNATURE_SIZE = 96; + function initialize(address sender) internal initializer { + SignerRole.initialize(sender); + } + /** * @dev requires that a valid signature of a signer was provided */ - modifier onlyValidSignature(bytes signature) - { + modifier onlyValidSignature(bytes memory signature) { require(_isValidSignature(msg.sender, signature)); _; } @@ -50,8 +59,7 @@ contract SignatureBouncer is Initializable, SignerRole { /** * @dev requires that a valid signature with a specifed method of a signer was provided */ - modifier onlyValidSignatureAndMethod(bytes signature) - { + modifier onlyValidSignatureAndMethod(bytes memory signature) { require(_isValidSignatureAndMethod(msg.sender, signature)); _; } @@ -59,48 +67,29 @@ contract SignatureBouncer is Initializable, SignerRole { /** * @dev requires that a valid signature with a specifed method and params of a signer was provided */ - modifier onlyValidSignatureAndData(bytes signature) - { + modifier onlyValidSignatureAndData(bytes memory signature) { require(_isValidSignatureAndData(msg.sender, signature)); _; } - function initialize(address sender) public initializer { - SignerRole.initialize(sender); - } - /** * @dev is the signature of `this + sender` from a signer? * @return bool */ - function _isValidSignature(address account, bytes signature) - internal - view - returns (bool) - { - return _isValidDataHash( - keccak256(abi.encodePacked(address(this), account)), - signature - ); + function _isValidSignature(address account, bytes memory signature) internal view returns (bool) { + return _isValidDataHash(keccak256(abi.encodePacked(address(this), account)), signature); } /** * @dev is the signature of `this + sender + methodId` from a signer? * @return bool */ - function _isValidSignatureAndMethod(address account, bytes signature) - internal - view - returns (bool) - { + function _isValidSignatureAndMethod(address account, bytes memory signature) internal view returns (bool) { bytes memory data = new bytes(_METHOD_ID_SIZE); for (uint i = 0; i < data.length; i++) { data[i] = msg.data[i]; } - return _isValidDataHash( - keccak256(abi.encodePacked(address(this), account, data)), - signature - ); + return _isValidDataHash(keccak256(abi.encodePacked(address(this), account, data)), signature); } /** @@ -108,20 +97,15 @@ contract SignatureBouncer is Initializable, SignerRole { * @notice the signature parameter of the method being validated must be the "last" parameter * @return bool */ - function _isValidSignatureAndData(address account, bytes signature) - internal - view - returns (bool) - { + function _isValidSignatureAndData(address account, bytes memory signature) internal view returns (bool) { require(msg.data.length > _SIGNATURE_SIZE); + bytes memory data = new bytes(msg.data.length - _SIGNATURE_SIZE); for (uint i = 0; i < data.length; i++) { data[i] = msg.data[i]; } - return _isValidDataHash( - keccak256(abi.encodePacked(address(this), account, data)), - signature - ); + + return _isValidDataHash(keccak256(abi.encodePacked(address(this), account, data)), signature); } /** @@ -129,14 +113,8 @@ contract SignatureBouncer is Initializable, SignerRole { * and then recover the signature and check it against the signer role * @return bool */ - function _isValidDataHash(bytes32 hash, bytes signature) - internal - view - returns (bool) - { - address signer = hash - .toEthSignedMessageHash() - .recover(signature); + function _isValidDataHash(bytes32 hash, bytes memory signature) internal view returns (bool) { + address signer = hash.toEthSignedMessageHash().recover(signature); return signer != address(0) && isSigner(signer); } diff --git a/contracts/drafts/SignedSafeMath.sol b/contracts/drafts/SignedSafeMath.sol new file mode 100644 index 000000000..4e6ab0af7 --- /dev/null +++ b/contracts/drafts/SignedSafeMath.sol @@ -0,0 +1,60 @@ +pragma solidity ^0.5.0; + +/** + * @title SignedSafeMath + * @dev Signed math operations with safety checks that revert on error + */ +library SignedSafeMath { + int256 constant private INT256_MIN = -2**255; + + /** + * @dev Multiplies two signed integers, reverts on overflow. + */ + function mul(int256 a, int256 b) internal pure returns (int256) { + // Gas optimization: this is cheaper than requiring 'a' not being zero, but the + // benefit is lost if 'b' is also tested. + // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 + if (a == 0) { + return 0; + } + + require(!(a == -1 && b == INT256_MIN)); // This is the only case of overflow not detected by the check below + + int256 c = a * b; + require(c / a == b); + + return c; + } + + /** + * @dev Integer division of two signed integers truncating the quotient, reverts on division by zero. + */ + function div(int256 a, int256 b) internal pure returns (int256) { + require(b != 0); // Solidity only automatically asserts when dividing by 0 + require(!(b == -1 && a == INT256_MIN)); // This is the only case of overflow + + int256 c = a / b; + + return c; + } + + /** + * @dev Subtracts two signed integers, reverts on overflow. + */ + function sub(int256 a, int256 b) internal pure returns (int256) { + int256 c = a - b; + require((b >= 0 && c <= a) || (b < 0 && c > a)); + + return c; + } + + /** + * @dev Adds two signed integers, reverts on overflow. + */ + function add(int256 a, int256 b) internal pure returns (int256) { + int256 c = a + b; + require((b >= 0 && c >= a) || (b < 0 && c < a)); + + return c; + } +} diff --git a/contracts/drafts/TokenVesting.sol b/contracts/drafts/TokenVesting.sol index bb86d5917..d4839f7ae 100644 --- a/contracts/drafts/TokenVesting.sol +++ b/contracts/drafts/TokenVesting.sol @@ -1,13 +1,10 @@ -/* solium-disable security/no-block-members */ - -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "../token/ERC20/SafeERC20.sol"; import "../ownership/Ownable.sol"; import "../math/SafeMath.sol"; - /** * @title TokenVesting * @dev A token holder contract that can release its token balance gradually like a @@ -15,15 +12,22 @@ import "../math/SafeMath.sol"; * owner. */ contract TokenVesting is Initializable, Ownable { + // The vesting schedule is time-based (i.e. using block timestamps as opposed to e.g. block numbers), and is + // therefore sensitive to timestamp manipulation (which is something miners can do, to a certain degree). Therefore, + // it is recommended to avoid using short time durations (less than a minute). Typical vesting schemes, with a cliff + // period of a year and a duration of four years, are safe to use. + // solhint-disable not-rely-on-time + using SafeMath for uint256; using SafeERC20 for IERC20; - event Released(uint256 amount); - event Revoked(); + event TokensReleased(address token, uint256 amount); + event TokenVestingRevoked(address token); // beneficiary of tokens after they are released address private _beneficiary; + // Durations and timestamps are expressed in UNIX time, the same units as block.timestamp. uint256 private _cliff; uint256 private _start; uint256 private _duration; @@ -43,21 +47,13 @@ contract TokenVesting is Initializable, Ownable { * @param duration duration in seconds of the period in which the tokens will vest * @param revocable whether the vesting is revocable or not */ - function initialize( - address beneficiary, - uint256 start, - uint256 cliffDuration, - uint256 duration, - bool revocable, - address sender - ) - public - initializer - { + constructor (address beneficiary, uint256 start, uint256 cliffDuration, uint256 duration, bool revocable, address sender) public initializer { Ownable.initialize(sender); require(beneficiary != address(0)); require(cliffDuration <= duration); + require(duration > 0); + require(start.add(duration) > block.timestamp); _beneficiary = beneficiary; _revocable = revocable; @@ -69,49 +65,49 @@ contract TokenVesting is Initializable, Ownable { /** * @return the beneficiary of the tokens. */ - function beneficiary() public view returns(address) { + function beneficiary() public view returns (address) { return _beneficiary; } /** * @return the cliff time of the token vesting. */ - function cliff() public view returns(uint256) { + function cliff() public view returns (uint256) { return _cliff; } /** * @return the start time of the token vesting. */ - function start() public view returns(uint256) { + function start() public view returns (uint256) { return _start; } /** * @return the duration of the token vesting. */ - function duration() public view returns(uint256) { + function duration() public view returns (uint256) { return _duration; } /** * @return true if the vesting is revocable. */ - function revocable() public view returns(bool) { + function revocable() public view returns (bool) { return _revocable; } /** * @return the amount of the token released. */ - function released(address token) public view returns(uint256) { + function released(address token) public view returns (uint256) { return _released[token]; } /** * @return true if the token is revoked. */ - function revoked(address token) public view returns(bool) { + function revoked(address token) public view returns (bool) { return _revoked[token]; } @@ -120,15 +116,15 @@ contract TokenVesting is Initializable, Ownable { * @param token ERC20 token which is being vested */ function release(IERC20 token) public { - uint256 unreleased = releasableAmount(token); + uint256 unreleased = _releasableAmount(token); require(unreleased > 0); - _released[token] = _released[token].add(unreleased); + _released[address(token)] = _released[address(token)].add(unreleased); token.safeTransfer(_beneficiary, unreleased); - emit Released(unreleased); + emit TokensReleased(address(token), unreleased); } /** @@ -138,39 +134,39 @@ contract TokenVesting is Initializable, Ownable { */ function revoke(IERC20 token) public onlyOwner { require(_revocable); - require(!_revoked[token]); + require(!_revoked[address(token)]); uint256 balance = token.balanceOf(address(this)); - uint256 unreleased = releasableAmount(token); + uint256 unreleased = _releasableAmount(token); uint256 refund = balance.sub(unreleased); - _revoked[token] = true; + _revoked[address(token)] = true; token.safeTransfer(owner(), refund); - emit Revoked(); + emit TokenVestingRevoked(address(token)); } /** * @dev Calculates the amount that has already vested but hasn't been released yet. * @param token ERC20 token which is being vested */ - function releasableAmount(IERC20 token) public view returns (uint256) { - return vestedAmount(token).sub(_released[token]); + function _releasableAmount(IERC20 token) private view returns (uint256) { + return _vestedAmount(token).sub(_released[address(token)]); } /** * @dev Calculates the amount that has already vested. * @param token ERC20 token which is being vested */ - function vestedAmount(IERC20 token) public view returns (uint256) { - uint256 currentBalance = token.balanceOf(this); - uint256 totalBalance = currentBalance.add(_released[token]); + function _vestedAmount(IERC20 token) private view returns (uint256) { + uint256 currentBalance = token.balanceOf(address(this)); + uint256 totalBalance = currentBalance.add(_released[address(token)]); if (block.timestamp < _cliff) { return 0; - } else if (block.timestamp >= _start.add(_duration) || _revoked[token]) { + } else if (block.timestamp >= _start.add(_duration) || _revoked[address(token)]) { return totalBalance; } else { return totalBalance.mul(block.timestamp.sub(_start)).div(_duration); diff --git a/contracts/examples/SampleCrowdsale.sol b/contracts/examples/SampleCrowdsale.sol index cb51fcbab..d02649425 100644 --- a/contracts/examples/SampleCrowdsale.sol +++ b/contracts/examples/SampleCrowdsale.sol @@ -1,35 +1,26 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "../crowdsale/validation/CappedCrowdsale.sol"; import "../crowdsale/distribution/RefundableCrowdsale.sol"; import "../crowdsale/emission/MintedCrowdsale.sol"; import "../token/ERC20/ERC20Mintable.sol"; - +import "../token/ERC20/ERC20Detailed.sol"; /** * @title SampleCrowdsaleToken * @dev Very simple ERC20 Token that can be minted. * It is meant to be used in a crowdsale contract. */ -contract SampleCrowdsaleToken is Initializable, ERC20Mintable { - - string public name; - string public symbol; - uint8 public decimals; - +contract SampleCrowdsaleToken is Initializable, ERC20Mintable, ERC20Detailed { function initialize(address sender) public initializer { ERC20Mintable.initialize(sender); - - name = "Sample Crowdsale Token"; - symbol = "SCT"; - decimals = 18; + ERC20Detailed.initialize("Sample Crowdsale Token", "SCT", 18); } uint256[50] private ______gap; } - /** * @title SampleCrowdsale * @dev This is an example of a fully fledged crowdsale. @@ -37,22 +28,19 @@ contract SampleCrowdsaleToken is Initializable, ERC20Mintable { * In this example we are providing following extensions: * CappedCrowdsale - sets a max boundary for raised funds * RefundableCrowdsale - set a min goal to be reached and returns funds if it's not met + * MintedCrowdsale - assumes the token can be minted by the crowdsale, which does so + * when receiving purchases. * * After adding multiple features it's good practice to run integration tests * to ensure that subcontracts works together as intended. */ -// XXX There doesn't seem to be a way to split this line that keeps solium -// happy. See: -// https://github.com/duaraghav8/Solium/issues/205 -// --elopio - 2018-05-10 -// solium-disable-next-line max-len contract SampleCrowdsale is Initializable, Crowdsale, CappedCrowdsale, RefundableCrowdsale, MintedCrowdsale { function initialize( uint256 openingTime, uint256 closingTime, uint256 rate, - address wallet, + address payable wallet, uint256 cap, ERC20Mintable token, uint256 goal diff --git a/contracts/examples/SimpleToken.sol b/contracts/examples/SimpleToken.sol index c67472a4d..845fdd2cc 100644 --- a/contracts/examples/SimpleToken.sol +++ b/contracts/examples/SimpleToken.sol @@ -1,9 +1,8 @@ -pragma solidity ^0.4.24; - +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "../token/ERC20/ERC20.sol"; - +import "../token/ERC20/ERC20Detailed.sol"; /** * @title SimpleToken @@ -11,21 +10,17 @@ import "../token/ERC20/ERC20.sol"; * Note they can later distribute these tokens as they wish using `transfer` and other * `ERC20` functions. */ -contract SimpleToken is Initializable, ERC20 { - - string public constant name = "SimpleToken"; - string public constant symbol = "SIM"; - uint8 public constant decimals = 18; - - uint256 public constant INITIAL_SUPPLY = 10000 * (10 ** uint256(decimals)); +contract SimpleToken is Initializable, ERC20, ERC20Detailed { + uint8 public constant DECIMALS = 18; + uint256 public constant INITIAL_SUPPLY = 10000 * (10 ** uint256(DECIMALS)); /** - * @dev Constructor that gives sender all of existing tokens. + * @dev Constructor that gives msg.sender all of existing tokens. */ function initialize(address sender) public initializer { - _mint(sender, INITIAL_SUPPLY); + ERC20Detailed.initialize("SimpleToken", "SIM", DECIMALS); + _mint(msg.sender, INITIAL_SUPPLY); } - uint256[50] private ______gap; } diff --git a/contracts/introspection/ERC165.sol b/contracts/introspection/ERC165.sol index 427383d80..8666fa2b5 100644 --- a/contracts/introspection/ERC165.sol +++ b/contracts/introspection/ERC165.sol @@ -1,55 +1,44 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "./IERC165.sol"; - /** * @title ERC165 * @author Matt Condon (@shrugs) * @dev Implements ERC165 using a lookup table. */ contract ERC165 is Initializable, IERC165 { - - bytes4 private constant _InterfaceId_ERC165 = 0x01ffc9a7; + bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7; /** * 0x01ffc9a7 === - * bytes4(keccak256('supportsInterface(bytes4)')) + * bytes4(keccak256('supportsInterface(bytes4)')) */ /** * @dev a mapping of interface id to whether or not it's supported */ - mapping(bytes4 => bool) internal _supportedInterfaces; + mapping(bytes4 => bool) private _supportedInterfaces; /** * @dev A contract implementing SupportsInterfaceWithLookup * implement ERC165 itself */ - function initialize() - public - initializer - { + function initialize() public initializer { _registerInterface(_InterfaceId_ERC165); } /** * @dev implement supportsInterface(bytes4) using a lookup table */ - function supportsInterface(bytes4 interfaceId) - public - view - returns (bool) - { + function supportsInterface(bytes4 interfaceId) external view returns (bool) { return _supportedInterfaces[interfaceId]; } /** - * @dev private method for registering an interface + * @dev internal method for registering an interface */ - function _registerInterface(bytes4 interfaceId) - internal - { + function _registerInterface(bytes4 interfaceId) internal { require(interfaceId != 0xffffffff); _supportedInterfaces[interfaceId] = true; } diff --git a/contracts/introspection/ERC165Checker.sol b/contracts/introspection/ERC165Checker.sol index 68d3532a8..f6034d483 100644 --- a/contracts/introspection/ERC165Checker.sol +++ b/contracts/introspection/ERC165Checker.sol @@ -1,5 +1,4 @@ -pragma solidity ^0.4.24; - +pragma solidity ^0.5.0; /** * @title ERC165Checker @@ -8,29 +7,24 @@ pragma solidity ^0.4.24; */ library ERC165Checker { // As per the EIP-165 spec, no interface should ever match 0xffffffff - bytes4 private constant _InterfaceId_Invalid = 0xffffffff; + bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff; - bytes4 private constant _InterfaceId_ERC165 = 0x01ffc9a7; + bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7; /** * 0x01ffc9a7 === - * bytes4(keccak256('supportsInterface(bytes4)')) + * bytes4(keccak256('supportsInterface(bytes4)')) */ - /** * @notice Query if a contract supports ERC165 * @param account The address of the contract to query for support of ERC165 * @return true if the contract at account implements ERC165 */ - function supportsERC165(address account) - internal - view - returns (bool) - { + function _supportsERC165(address account) internal view returns (bool) { // Any contract that implements ERC165 must explicitly indicate support of // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid - return supportsERC165Interface(account, _InterfaceId_ERC165) && - !supportsERC165Interface(account, _InterfaceId_Invalid); + return _supportsERC165Interface(account, _INTERFACE_ID_ERC165) && + !_supportsERC165Interface(account, _INTERFACE_ID_INVALID); } /** @@ -41,14 +35,10 @@ library ERC165Checker { * identifier interfaceId, false otherwise * @dev Interface identification is specified in ERC-165. */ - function supportsInterface(address account, bytes4 interfaceId) - internal - view - returns (bool) - { + function _supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) { // query support of both ERC165 as per the spec and support of _interfaceId - return supportsERC165(account) && - supportsERC165Interface(account, interfaceId); + return _supportsERC165(account) && + _supportsERC165Interface(account, interfaceId); } /** @@ -59,19 +49,15 @@ library ERC165Checker { * interfaceIds list, false otherwise * @dev Interface identification is specified in ERC-165. */ - function supportsInterfaces(address account, bytes4[] interfaceIds) - internal - view - returns (bool) - { + function _supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) { // query support of ERC165 itself - if (!supportsERC165(account)) { + if (!_supportsERC165(account)) { return false; } // query support of each interface in _interfaceIds for (uint256 i = 0; i < interfaceIds.length; i++) { - if (!supportsERC165Interface(account, interfaceIds[i])) { + if (!_supportsERC165Interface(account, interfaceIds[i])) { return false; } } @@ -91,15 +77,10 @@ library ERC165Checker { * with the `supportsERC165` method in this library. * Interface identification is specified in ERC-165. */ - function supportsERC165Interface(address account, bytes4 interfaceId) - private - view - returns (bool) - { + function _supportsERC165Interface(address account, bytes4 interfaceId) private view returns (bool) { // success determines whether the staticcall succeeded and result determines // whether the contract at account indicates support of _interfaceId - (bool success, bool result) = callERC165SupportsInterface( - account, interfaceId); + (bool success, bool result) = _callERC165SupportsInterface(account, interfaceId); return (success && result); } @@ -112,37 +93,31 @@ library ERC165Checker { * @return result true if the STATICCALL succeeded and the contract at account * indicates support of the interface with identifier interfaceId, false otherwise */ - function callERC165SupportsInterface( - address account, - bytes4 interfaceId - ) + function _callERC165SupportsInterface(address account, bytes4 interfaceId) private view returns (bool success, bool result) { - bytes memory encodedParams = abi.encodeWithSelector( - _InterfaceId_ERC165, - interfaceId - ); + bytes memory encodedParams = abi.encodeWithSelector(_INTERFACE_ID_ERC165, interfaceId); - // solium-disable-next-line security/no-inline-assembly + // solhint-disable-next-line no-inline-assembly assembly { let encodedParams_data := add(0x20, encodedParams) let encodedParams_size := mload(encodedParams) - let output := mload(0x40) // Find empty storage location using "free memory pointer" + let output := mload(0x40) // Find empty storage location using "free memory pointer" mstore(output, 0x0) success := staticcall( - 30000, // 30k gas - account, // To addr + 30000, // 30k gas + account, // To addr encodedParams_data, encodedParams_size, output, - 0x20 // Outputs are 32 bytes long + 0x20 // Outputs are 32 bytes long ) - result := mload(output) // Load the result + result := mload(output) // Load the result } } } diff --git a/contracts/introspection/IERC165.sol b/contracts/introspection/IERC165.sol index 41567f241..393e6fb29 100644 --- a/contracts/introspection/IERC165.sol +++ b/contracts/introspection/IERC165.sol @@ -1,20 +1,15 @@ -pragma solidity ^0.4.24; - +pragma solidity ^0.5.0; /** * @title IERC165 * @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md */ interface IERC165 { - /** * @notice Query if a contract implements an interface * @param interfaceId The interface identifier, as specified in ERC-165 * @dev Interface identification is specified in ERC-165. This function * uses less than 30,000 gas. */ - function supportsInterface(bytes4 interfaceId) - external - view - returns (bool); + function supportsInterface(bytes4 interfaceId) external view returns (bool); } diff --git a/contracts/lifecycle/Pausable.sol b/contracts/lifecycle/Pausable.sol index be25872b5..5a36a6074 100644 --- a/contracts/lifecycle/Pausable.sol +++ b/contracts/lifecycle/Pausable.sol @@ -1,27 +1,26 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "../access/roles/PauserRole.sol"; - /** * @title Pausable * @dev Base contract which allows children to implement an emergency stop mechanism. */ contract Pausable is Initializable, PauserRole { - event Paused(); - event Unpaused(); + event Paused(address account); + event Unpaused(address account); - bool private _paused = false; + bool private _paused; function initialize(address sender) public initializer { - PauserRole.initialize(sender); + _paused = false; } /** * @return true if the contract is paused, false otherwise. */ - function paused() public view returns(bool) { + function paused() public view returns (bool) { return _paused; } @@ -46,7 +45,7 @@ contract Pausable is Initializable, PauserRole { */ function pause() public onlyPauser whenNotPaused { _paused = true; - emit Paused(); + emit Paused(msg.sender); } /** @@ -54,7 +53,7 @@ contract Pausable is Initializable, PauserRole { */ function unpause() public onlyPauser whenPaused { _paused = false; - emit Unpaused(); + emit Unpaused(msg.sender); } uint256[50] private ______gap; diff --git a/contracts/math/Math.sol b/contracts/math/Math.sol index 690e0b530..1cdc075f0 100644 --- a/contracts/math/Math.sol +++ b/contracts/math/Math.sol @@ -1,19 +1,29 @@ -pragma solidity ^0.4.24; - +pragma solidity ^0.5.0; /** * @title Math * @dev Assorted math operations */ library Math { + /** + * @dev Returns the largest of two numbers. + */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } + /** + * @dev Returns the smallest of two numbers. + */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } + /** + * @dev Calculates the average of two numbers. Since these are integers, + * averages of an even and odd number cannot be represented, and will be + * rounded down. + */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow, so we distribute return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2); diff --git a/contracts/math/SafeMath.sol b/contracts/math/SafeMath.sol index 06828ea10..54ab43acf 100644 --- a/contracts/math/SafeMath.sol +++ b/contracts/math/SafeMath.sol @@ -1,14 +1,12 @@ -pragma solidity ^0.4.24; - +pragma solidity ^0.5.0; /** * @title SafeMath - * @dev Math operations with safety checks that revert on error + * @dev Unsigned math operations with safety checks that revert on error */ library SafeMath { - /** - * @dev Multiplies two numbers, reverts on overflow. + * @dev Multiplies two unsigned integers, reverts on overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the @@ -25,10 +23,11 @@ library SafeMath { } /** - * @dev Integer division of two numbers truncating the quotient, reverts on division by zero. + * @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { - require(b > 0); // Solidity only automatically asserts when dividing by 0 + // Solidity only automatically asserts when dividing by 0 + require(b > 0); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold @@ -36,7 +35,7 @@ library SafeMath { } /** - * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend). + * @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend). */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a); @@ -46,7 +45,7 @@ library SafeMath { } /** - * @dev Adds two numbers, reverts on overflow. + * @dev Adds two unsigned integers, reverts on overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; @@ -56,7 +55,7 @@ library SafeMath { } /** - * @dev Divides two numbers and returns the remainder (unsigned integer modulo), + * @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo), * reverts when dividing by zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { diff --git a/contracts/mocks/Acknowledger.sol b/contracts/mocks/Acknowledger.sol new file mode 100644 index 000000000..f3f514cb0 --- /dev/null +++ b/contracts/mocks/Acknowledger.sol @@ -0,0 +1,19 @@ +pragma solidity ^0.5.0; + +contract Acknowledger { + event AcknowledgeFoo(uint256 a); + event AcknowledgeBarSingle(uint256 a); + event AcknowledgeBarDouble(uint256 a, uint256 b); + + function foo(uint256 a) public { + emit AcknowledgeFoo(a); + } + + function bar(uint256 a) public { + emit AcknowledgeBarSingle(a); + } + + function bar(uint256 a, uint256 b) public { + emit AcknowledgeBarDouble(a, b); + } +} diff --git a/contracts/mocks/AddressImpl.sol b/contracts/mocks/AddressImpl.sol new file mode 100644 index 000000000..a73591c37 --- /dev/null +++ b/contracts/mocks/AddressImpl.sol @@ -0,0 +1,9 @@ +pragma solidity ^0.5.0; + +import "../utils/Address.sol"; + +contract AddressImpl { + function isContract(address account) external view returns (bool) { + return Address.isContract(account); + } +} diff --git a/contracts/mocks/AllowanceCrowdsaleImpl.sol b/contracts/mocks/AllowanceCrowdsaleImpl.sol index 42de59375..c3663c2dc 100644 --- a/contracts/mocks/AllowanceCrowdsaleImpl.sol +++ b/contracts/mocks/AllowanceCrowdsaleImpl.sol @@ -1,21 +1,13 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "../token/ERC20/IERC20.sol"; import "../crowdsale/emission/AllowanceCrowdsale.sol"; - contract AllowanceCrowdsaleImpl is AllowanceCrowdsale { - - constructor ( - uint256 rate, - address wallet, - IERC20 token, - address tokenWallet - ) + constructor (uint256 rate, address payable wallet, IERC20 token, address tokenWallet) public { Crowdsale.initialize(rate, wallet, token); AllowanceCrowdsale.initialize(tokenWallet); } - } diff --git a/contracts/mocks/ArraysImpl.sol b/contracts/mocks/ArraysImpl.sol new file mode 100644 index 000000000..b2067526d --- /dev/null +++ b/contracts/mocks/ArraysImpl.sol @@ -0,0 +1,17 @@ +pragma solidity ^0.5.0; + +import "../utils/Arrays.sol"; + +contract ArraysImpl { + using Arrays for uint256[]; + + uint256[] private array; + + constructor (uint256[] memory _array) public { + array = _array; + } + + function findUpperBound(uint256 _element) external view returns (uint256) { + return array.findUpperBound(_element); + } +} diff --git a/contracts/mocks/CappedCrowdsaleImpl.sol b/contracts/mocks/CappedCrowdsaleImpl.sol index ff80ffe08..a38abdfd6 100644 --- a/contracts/mocks/CappedCrowdsaleImpl.sol +++ b/contracts/mocks/CappedCrowdsaleImpl.sol @@ -1,21 +1,13 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "../token/ERC20/IERC20.sol"; import "../crowdsale/validation/CappedCrowdsale.sol"; - contract CappedCrowdsaleImpl is CappedCrowdsale { - - constructor ( - uint256 rate, - address wallet, - IERC20 token, - uint256 cap - ) + constructor (uint256 rate, address payable wallet, IERC20 token, uint256 cap) public { Crowdsale.initialize(rate, wallet, token); CappedCrowdsale.initialize(cap); } - } diff --git a/contracts/mocks/CapperRoleMock.sol b/contracts/mocks/CapperRoleMock.sol index e38f23618..7b17d2aca 100644 --- a/contracts/mocks/CapperRoleMock.sol +++ b/contracts/mocks/CapperRoleMock.sol @@ -1,8 +1,7 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "../access/roles/CapperRole.sol"; - contract CapperRoleMock is CapperRole { constructor() public { CapperRole.initialize(msg.sender); @@ -13,6 +12,7 @@ contract CapperRoleMock is CapperRole { } function onlyCapperMock() public view onlyCapper { + // solhint-disable-previous-line no-empty-blocks } // Causes a compilation error if super._removeCapper is not internal diff --git a/contracts/mocks/ConditionalEscrowMock.sol b/contracts/mocks/ConditionalEscrowMock.sol index b1a2055e8..877d8f5a4 100644 --- a/contracts/mocks/ConditionalEscrowMock.sol +++ b/contracts/mocks/ConditionalEscrowMock.sol @@ -1,7 +1,6 @@ -pragma solidity ^0.4.24; - -import "../payment/ConditionalEscrow.sol"; +pragma solidity ^0.5.0; +import "../payment/escrow/ConditionalEscrow.sol"; // mock class using ConditionalEscrow contract ConditionalEscrowMock is ConditionalEscrow { diff --git a/contracts/mocks/CounterImpl.sol b/contracts/mocks/CounterImpl.sol index 3432506e1..4d976f55d 100644 --- a/contracts/mocks/CounterImpl.sol +++ b/contracts/mocks/CounterImpl.sol @@ -1,8 +1,7 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "../drafts/Counter.sol"; - contract CounterImpl { using Counter for Counter.Counter; @@ -11,10 +10,7 @@ contract CounterImpl { // use whatever key you want to track your counters mapping(string => Counter.Counter) private _counters; - function doThing(string key) - public - returns (uint256) - { + function doThing(string memory key) public returns (uint256) { theId = _counters[key].next(); return theId; } diff --git a/contracts/mocks/CrowdsaleMock.sol b/contracts/mocks/CrowdsaleMock.sol index 86fbdd219..d9b3893e5 100644 --- a/contracts/mocks/CrowdsaleMock.sol +++ b/contracts/mocks/CrowdsaleMock.sol @@ -1,10 +1,9 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "../crowdsale/Crowdsale.sol"; - contract CrowdsaleMock is Crowdsale { - constructor(uint256 rate, address wallet, IERC20 token) public { + constructor (uint256 rate, address payable wallet, IERC20 token) public { Crowdsale.initialize(rate, wallet, token); } } diff --git a/contracts/mocks/DetailedERC20Mock.sol b/contracts/mocks/DetailedERC20Mock.sol index 63fc237dd..2d486f470 100644 --- a/contracts/mocks/DetailedERC20Mock.sol +++ b/contracts/mocks/DetailedERC20Mock.sol @@ -1,15 +1,10 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "../token/ERC20/ERC20.sol"; import "../token/ERC20/ERC20Detailed.sol"; - contract ERC20DetailedMock is ERC20, ERC20Detailed { - constructor( - string name, - string symbol, - uint8 decimals - ) + constructor (string memory name, string memory symbol, uint8 decimals) public { ERC20Detailed.initialize(name, symbol, decimals); diff --git a/contracts/mocks/ECDSAMock.sol b/contracts/mocks/ECDSAMock.sol index 4d8e70c82..977f324ac 100644 --- a/contracts/mocks/ECDSAMock.sol +++ b/contracts/mocks/ECDSAMock.sol @@ -1,24 +1,15 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "../cryptography/ECDSA.sol"; - contract ECDSAMock { using ECDSA for bytes32; - function recover(bytes32 hash, bytes signature) - public - pure - returns (address) - { + function recover(bytes32 hash, bytes memory signature) public pure returns (address) { return hash.recover(signature); } - function toEthSignedMessageHash(bytes32 hash) - public - pure - returns (bytes32) - { + function toEthSignedMessageHash(bytes32 hash) public pure returns (bytes32) { return hash.toEthSignedMessageHash(); } } diff --git a/contracts/mocks/ERC165/ERC165InterfacesSupported.sol b/contracts/mocks/ERC165/ERC165InterfacesSupported.sol index 235cfe2f0..fccf84e69 100644 --- a/contracts/mocks/ERC165/ERC165InterfacesSupported.sol +++ b/contracts/mocks/ERC165/ERC165InterfacesSupported.sol @@ -1,67 +1,54 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "../../introspection/IERC165.sol"; - /** * https://github.com/ethereum/EIPs/blob/master/EIPS/eip-214.md#specification - * > Any attempts to make state-changing operations inside an execution instance with STATIC set to true will instead throw an exception. + * > Any attempts to make state-changing operations inside an execution instance with STATIC set to true will instead + * throw an exception. * > These operations include [...], LOG0, LOG1, LOG2, [...] * * therefore, because this contract is staticcall'd we need to not emit events (which is how solidity-coverage works) * solidity-coverage ignores the /mocks folder, so we duplicate its implementation here to avoid instrumenting it */ contract SupportsInterfaceWithLookupMock is IERC165 { - - bytes4 public constant InterfaceId_ERC165 = 0x01ffc9a7; + bytes4 public constant INTERFACE_ID_ERC165 = 0x01ffc9a7; /** * 0x01ffc9a7 === - * bytes4(keccak256('supportsInterface(bytes4)')) + * bytes4(keccak256('supportsInterface(bytes4)')) */ /** * @dev a mapping of interface id to whether or not it's supported */ - mapping(bytes4 => bool) internal supportedInterfaces; + mapping(bytes4 => bool) private _supportedInterfaces; /** * @dev A contract implementing SupportsInterfaceWithLookup * implement ERC165 itself */ - constructor() - public - { - _registerInterface(InterfaceId_ERC165); + constructor () public { + _registerInterface(INTERFACE_ID_ERC165); } /** * @dev implement supportsInterface(bytes4) using a lookup table */ - function supportsInterface(bytes4 interfaceId) - external - view - returns (bool) - { - return supportedInterfaces[interfaceId]; + function supportsInterface(bytes4 interfaceId) external view returns (bool) { + return _supportedInterfaces[interfaceId]; } /** * @dev private method for registering an interface */ - function _registerInterface(bytes4 interfaceId) - internal - { + function _registerInterface(bytes4 interfaceId) internal { require(interfaceId != 0xffffffff); - supportedInterfaces[interfaceId] = true; + _supportedInterfaces[interfaceId] = true; } } - - contract ERC165InterfacesSupported is SupportsInterfaceWithLookupMock { - constructor (bytes4[] interfaceIds) - public - { + constructor (bytes4[] memory interfaceIds) public { for (uint256 i = 0; i < interfaceIds.length; i++) { _registerInterface(interfaceIds[i]); } diff --git a/contracts/mocks/ERC165/ERC165NotSupported.sol b/contracts/mocks/ERC165/ERC165NotSupported.sol index 763f8faba..d154da33e 100644 --- a/contracts/mocks/ERC165/ERC165NotSupported.sol +++ b/contracts/mocks/ERC165/ERC165NotSupported.sol @@ -1,6 +1,5 @@ -pragma solidity ^0.4.24; - +pragma solidity ^0.5.0; contract ERC165NotSupported { - + // solhint-disable-previous-line no-empty-blocks } diff --git a/contracts/mocks/ERC165CheckerMock.sol b/contracts/mocks/ERC165CheckerMock.sol index 35d2255f0..db1853de0 100644 --- a/contracts/mocks/ERC165CheckerMock.sol +++ b/contracts/mocks/ERC165CheckerMock.sol @@ -1,32 +1,19 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "../introspection/ERC165Checker.sol"; - contract ERC165CheckerMock { using ERC165Checker for address; - function supportsERC165(address account) - public - view - returns (bool) - { - return account.supportsERC165(); + function supportsERC165(address account) public view returns (bool) { + return account._supportsERC165(); } - function supportsInterface(address account, bytes4 interfaceId) - public - view - returns (bool) - { - return account.supportsInterface(interfaceId); + function supportsInterface(address account, bytes4 interfaceId) public view returns (bool) { + return account._supportsInterface(interfaceId); } - function supportsInterfaces(address account, bytes4[] interfaceIds) - public - view - returns (bool) - { - return account.supportsInterfaces(interfaceIds); + function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) public view returns (bool) { + return account._supportsAllInterfaces(interfaceIds); } } diff --git a/contracts/mocks/ERC165Mock.sol b/contracts/mocks/ERC165Mock.sol index 3853f8001..3ee1f28ee 100644 --- a/contracts/mocks/ERC165Mock.sol +++ b/contracts/mocks/ERC165Mock.sol @@ -1,16 +1,13 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "../introspection/ERC165.sol"; - contract ERC165Mock is ERC165 { constructor() public { ERC165.initialize(); } - function registerInterface(bytes4 interfaceId) - public - { + function registerInterface(bytes4 interfaceId) public { _registerInterface(interfaceId); } } diff --git a/contracts/mocks/ERC20BurnableMock.sol b/contracts/mocks/ERC20BurnableMock.sol index 5db472294..46bbe07d9 100644 --- a/contracts/mocks/ERC20BurnableMock.sol +++ b/contracts/mocks/ERC20BurnableMock.sol @@ -1,12 +1,9 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "../token/ERC20/ERC20Burnable.sol"; - contract ERC20BurnableMock is ERC20Burnable { - constructor(address initialAccount, uint256 initialBalance) public { _mint(initialAccount, initialBalance); } - } diff --git a/contracts/mocks/ERC20MintableMock.sol b/contracts/mocks/ERC20MintableMock.sol index a0e8d2c60..900556f42 100644 --- a/contracts/mocks/ERC20MintableMock.sol +++ b/contracts/mocks/ERC20MintableMock.sol @@ -1,11 +1,9 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "../token/ERC20/ERC20Mintable.sol"; import "./MinterRoleMock.sol"; - contract ERC20MintableMock is ERC20Mintable, MinterRoleMock { - constructor() public { ERC20Mintable.initialize(msg.sender); } diff --git a/contracts/mocks/ERC20Mock.sol b/contracts/mocks/ERC20Mock.sol index 3180f616d..857cf3ff1 100644 --- a/contracts/mocks/ERC20Mock.sol +++ b/contracts/mocks/ERC20Mock.sol @@ -1,12 +1,10 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "../token/ERC20/ERC20.sol"; - // mock class using ERC20 contract ERC20Mock is ERC20 { - - constructor(address initialAccount, uint256 initialBalance) public { + constructor (address initialAccount, uint256 initialBalance) public { _mint(initialAccount, initialBalance); } @@ -21,5 +19,4 @@ contract ERC20Mock is ERC20 { function burnFrom(address account, uint256 amount) public { _burnFrom(account, amount); } - } diff --git a/contracts/mocks/ERC20PausableMock.sol b/contracts/mocks/ERC20PausableMock.sol index c3c323030..b93592e8f 100644 --- a/contracts/mocks/ERC20PausableMock.sol +++ b/contracts/mocks/ERC20PausableMock.sol @@ -1,16 +1,12 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "../token/ERC20/ERC20Pausable.sol"; import "./PauserRoleMock.sol"; - // mock class using ERC20Pausable contract ERC20PausableMock is ERC20Pausable, PauserRoleMock { - - constructor(address initialAccount, uint initialBalance) public { + constructor (address initialAccount, uint initialBalance) public { ERC20Pausable.initialize(msg.sender); - _mint(initialAccount, initialBalance); } - } diff --git a/contracts/mocks/ERC20WithMetadataMock.sol b/contracts/mocks/ERC20WithMetadataMock.sol index b7fdf1ad1..b5aa88489 100644 --- a/contracts/mocks/ERC20WithMetadataMock.sol +++ b/contracts/mocks/ERC20WithMetadataMock.sol @@ -1,11 +1,10 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "../token/ERC20/ERC20.sol"; import "../drafts/ERC1046/TokenMetadata.sol"; - contract ERC20WithMetadataMock is ERC20, ERC20WithMetadata { - constructor(string tokenURI) public { + constructor (string memory tokenURI) public { ERC20WithMetadata.initialize(tokenURI); } } diff --git a/contracts/mocks/ERC721FullMock.sol b/contracts/mocks/ERC721FullMock.sol index 3e2c1eead..7a8840e95 100644 --- a/contracts/mocks/ERC721FullMock.sol +++ b/contracts/mocks/ERC721FullMock.sol @@ -1,19 +1,17 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "../token/ERC721/ERC721Full.sol"; import "../token/ERC721/ERC721Mintable.sol"; import "../token/ERC721/ERC721MetadataMintable.sol"; import "../token/ERC721/ERC721Burnable.sol"; - /** * @title ERC721FullMock - * This mock just provides a public mint and burn functions for testing purposes, - * and a public setter for metadata URI + * This mock just provides public functions for setting metadata URI, getting all tokens of an owner, + * checking token existence, removal of a token from an address */ contract ERC721FullMock is ERC721Full, ERC721Mintable, ERC721MetadataMintable, ERC721Burnable { - constructor(string name, string symbol) public - { + constructor (string memory name, string memory symbol) public { ERC721.initialize(); ERC721Metadata.initialize(name, symbol); ERC721Enumerable.initialize(); @@ -25,11 +23,11 @@ contract ERC721FullMock is ERC721Full, ERC721Mintable, ERC721MetadataMintable, E return _exists(tokenId); } - function setTokenURI(uint256 tokenId, string uri) public { - _setTokenURI(tokenId, uri); + function tokensOfOwner(address owner) public view returns (uint256[] memory) { + return _tokensOfOwner(owner); } - function removeTokenFrom(address from, uint256 tokenId) public { - _removeTokenFrom(from, tokenId); + function setTokenURI(uint256 tokenId, string memory uri) public { + _setTokenURI(tokenId, uri); } } diff --git a/contracts/mocks/ERC721MintableBurnableImpl.sol b/contracts/mocks/ERC721MintableBurnableImpl.sol index e3aade0f1..d99fd1447 100644 --- a/contracts/mocks/ERC721MintableBurnableImpl.sol +++ b/contracts/mocks/ERC721MintableBurnableImpl.sol @@ -1,20 +1,15 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "../token/ERC721/ERC721Full.sol"; import "../token/ERC721/ERC721Mintable.sol"; import "../token/ERC721/ERC721MetadataMintable.sol"; import "../token/ERC721/ERC721Burnable.sol"; - /** * @title ERC721MintableBurnableImpl */ -contract ERC721MintableBurnableImpl - is ERC721Full, ERC721Mintable, ERC721MetadataMintable, ERC721Burnable { - - constructor() - public - { +contract ERC721MintableBurnableImpl is ERC721Full, ERC721Mintable, ERC721MetadataMintable, ERC721Burnable { + constructor () public { ERC721.initialize(); ERC721Metadata.initialize("Test", "TEST"); ERC721Enumerable.initialize(); diff --git a/contracts/mocks/ERC721Mock.sol b/contracts/mocks/ERC721Mock.sol index 2a7c049f0..69bd5a0d1 100644 --- a/contracts/mocks/ERC721Mock.sol +++ b/contracts/mocks/ERC721Mock.sol @@ -1,8 +1,7 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "../token/ERC721/ERC721.sol"; - /** * @title ERC721Mock * This mock just provides a public mint and burn functions for testing purposes @@ -16,7 +15,11 @@ contract ERC721Mock is ERC721 { _mint(to, tokenId); } + function burn(address owner, uint256 tokenId) public { + _burn(owner, tokenId); + } + function burn(uint256 tokenId) public { - _burn(ownerOf(tokenId), tokenId); + _burn(tokenId); } } diff --git a/contracts/mocks/ERC721PausableMock.sol b/contracts/mocks/ERC721PausableMock.sol index db3870f92..26c1cb4b2 100644 --- a/contracts/mocks/ERC721PausableMock.sol +++ b/contracts/mocks/ERC721PausableMock.sol @@ -1,9 +1,8 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "../token/ERC721/ERC721Pausable.sol"; import "./PauserRoleMock.sol"; - /** * @title ERC721PausableMock * This mock just provides a public mint, burn and exists functions for testing purposes @@ -19,7 +18,7 @@ contract ERC721PausableMock is ERC721Pausable, PauserRoleMock { } function burn(uint256 tokenId) public { - super._burn(ownerOf(tokenId), tokenId); + super._burn(tokenId); } function exists(uint256 tokenId) public view returns (bool) { diff --git a/contracts/mocks/ERC721ReceiverMock.sol b/contracts/mocks/ERC721ReceiverMock.sol index 00a30b439..1b4de6737 100644 --- a/contracts/mocks/ERC721ReceiverMock.sol +++ b/contracts/mocks/ERC721ReceiverMock.sol @@ -1,42 +1,23 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "../token/ERC721/IERC721Receiver.sol"; - contract ERC721ReceiverMock is IERC721Receiver { bytes4 private _retval; bool private _reverts; - event Received( - address operator, - address from, - uint256 tokenId, - bytes data, - uint256 gas - ); + event Received(address operator, address from, uint256 tokenId, bytes data, uint256 gas); - constructor(bytes4 retval, bool reverts) public { + constructor (bytes4 retval, bool reverts) public { _retval = retval; _reverts = reverts; } - function onERC721Received( - address operator, - address from, - uint256 tokenId, - bytes data - ) - public - returns(bytes4) + function onERC721Received(address operator, address from, uint256 tokenId, bytes memory data) + public returns (bytes4) { require(!_reverts); - emit Received( - operator, - from, - tokenId, - data, - gasleft() // msg.gas was deprecated in solidityv0.4.21 - ); + emit Received(operator, from, tokenId, data, gasleft()); return _retval; } } diff --git a/contracts/mocks/EventEmitter.sol b/contracts/mocks/EventEmitter.sol new file mode 100644 index 000000000..4ffc77c4b --- /dev/null +++ b/contracts/mocks/EventEmitter.sol @@ -0,0 +1,73 @@ +pragma solidity ^0.5.0; + +contract EventEmitter { + event Argumentless(); + event ShortUint(uint8 value); + event ShortInt(int8 value); + event LongUint(uint256 value); + event LongInt(int256 value); + event Address(address value); + event Boolean(bool value); + event String(string value); + event LongUintBooleanString(uint256 uintValue, bool booleanValue, string stringValue); + + constructor (uint8 uintValue, bool booleanValue, string memory stringValue) public { + emit ShortUint(uintValue); + emit Boolean(booleanValue); + emit String(stringValue); + } + + function emitArgumentless() public { + emit Argumentless(); + } + + function emitShortUint(uint8 value) public { + emit ShortUint(value); + } + + function emitShortInt(int8 value) public { + emit ShortInt(value); + } + + function emitLongUint(uint256 value) public { + emit LongUint(value); + } + + function emitLongInt(int256 value) public { + emit LongInt(value); + } + + function emitAddress(address value) public { + emit Address(value); + } + + function emitBoolean(bool value) public { + emit Boolean(value); + } + + function emitString(string memory value) public { + emit String(value); + } + + function emitLongUintBooleanString(uint256 uintValue, bool booleanValue, string memory stringValue) public { + emit LongUintBooleanString(uintValue, booleanValue, stringValue); + } + + function emitLongUintAndBoolean(uint256 uintValue, bool boolValue) public { + emit LongUint(uintValue); + emit Boolean(boolValue); + } + + function emitStringAndEmitIndirectly(string memory value, IndirectEventEmitter emitter) public { + emit String(value); + emitter.emitStringIndirectly(value); + } +} + +contract IndirectEventEmitter { + event IndirectString(string value); + + function emitStringIndirectly(string memory value) public { + emit IndirectString(value); + } +} diff --git a/contracts/mocks/Failer.sol b/contracts/mocks/Failer.sol new file mode 100644 index 000000000..088bc498c --- /dev/null +++ b/contracts/mocks/Failer.sol @@ -0,0 +1,23 @@ +pragma solidity ^0.5.0; + +contract Failer { + uint256[] private array; + + function dontFail() public pure { + // solhint-disable-previous-line no-empty-blocks + } + + function failWithRevert() public pure { + revert(); + } + + function failWithThrow() public pure { + assert(false); + } + + function failWithOutOfGas() public { + for (uint256 i = 0; i < 2**200; ++i) { + array.push(i); + } + } +} diff --git a/contracts/mocks/FinalizableCrowdsaleImpl.sol b/contracts/mocks/FinalizableCrowdsaleImpl.sol index 013791504..2bdb4bd5a 100644 --- a/contracts/mocks/FinalizableCrowdsaleImpl.sol +++ b/contracts/mocks/FinalizableCrowdsaleImpl.sol @@ -1,22 +1,13 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "../token/ERC20/IERC20.sol"; import "../crowdsale/distribution/FinalizableCrowdsale.sol"; - contract FinalizableCrowdsaleImpl is FinalizableCrowdsale { - - constructor ( - uint256 openingTime, - uint256 closingTime, - uint256 rate, - address wallet, - IERC20 token - ) + constructor (uint256 openingTime, uint256 closingTime, uint256 rate, address payable wallet, IERC20 token) public { Crowdsale.initialize(rate, wallet, token); TimedCrowdsale.initialize(openingTime, closingTime); } - } diff --git a/contracts/mocks/IncreasingPriceCrowdsaleImpl.sol b/contracts/mocks/IncreasingPriceCrowdsaleImpl.sol index 6b69384ac..e331bdcc5 100644 --- a/contracts/mocks/IncreasingPriceCrowdsaleImpl.sol +++ b/contracts/mocks/IncreasingPriceCrowdsaleImpl.sol @@ -1,15 +1,13 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "../crowdsale/price/IncreasingPriceCrowdsale.sol"; import "../math/SafeMath.sol"; - contract IncreasingPriceCrowdsaleImpl is IncreasingPriceCrowdsale { - constructor ( uint256 openingTime, uint256 closingTime, - address wallet, + address payable wallet, IERC20 token, uint256 initialRate, uint256 finalRate @@ -20,5 +18,4 @@ contract IncreasingPriceCrowdsaleImpl is IncreasingPriceCrowdsale { TimedCrowdsale.initialize(openingTime, closingTime); IncreasingPriceCrowdsale.initialize(initialRate, finalRate); } - } diff --git a/contracts/mocks/IndividuallyCappedCrowdsaleImpl.sol b/contracts/mocks/IndividuallyCappedCrowdsaleImpl.sol index 6a2587bbf..1ec261d19 100644 --- a/contracts/mocks/IndividuallyCappedCrowdsaleImpl.sol +++ b/contracts/mocks/IndividuallyCappedCrowdsaleImpl.sol @@ -1,20 +1,11 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "../token/ERC20/IERC20.sol"; import "../crowdsale/validation/IndividuallyCappedCrowdsale.sol"; import "./CapperRoleMock.sol"; - -contract IndividuallyCappedCrowdsaleImpl - is Crowdsale, IndividuallyCappedCrowdsale, CapperRoleMock { - - constructor( - uint256 rate, - address wallet, - IERC20 token - ) - public - { +contract IndividuallyCappedCrowdsaleImpl is IndividuallyCappedCrowdsale, CapperRoleMock { + constructor (uint256 rate, address payable wallet, IERC20 token) public { Crowdsale.initialize(rate, wallet, token); IndividuallyCappedCrowdsale.initialize(msg.sender); } diff --git a/contracts/mocks/MathMock.sol b/contracts/mocks/MathMock.sol index fb169e6a2..2461fe902 100644 --- a/contracts/mocks/MathMock.sol +++ b/contracts/mocks/MathMock.sol @@ -1,9 +1,7 @@ -pragma solidity ^0.4.24; - +pragma solidity ^0.5.0; import "../math/Math.sol"; - contract MathMock { function max(uint256 a, uint256 b) public pure returns (uint256) { return Math.max(a, b); diff --git a/contracts/mocks/MerkleProofWrapper.sol b/contracts/mocks/MerkleProofWrapper.sol index 0d8e68fc7..23c72b269 100644 --- a/contracts/mocks/MerkleProofWrapper.sol +++ b/contracts/mocks/MerkleProofWrapper.sol @@ -1,19 +1,9 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import { MerkleProof } from "../cryptography/MerkleProof.sol"; - contract MerkleProofWrapper { - - function verify( - bytes32[] proof, - bytes32 root, - bytes32 leaf - ) - public - pure - returns (bool) - { + function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) public pure returns (bool) { return MerkleProof.verify(proof, root, leaf); } } diff --git a/contracts/mocks/MintedCrowdsaleImpl.sol b/contracts/mocks/MintedCrowdsaleImpl.sol index 5b55b5e37..f63240017 100644 --- a/contracts/mocks/MintedCrowdsaleImpl.sol +++ b/contracts/mocks/MintedCrowdsaleImpl.sol @@ -1,19 +1,10 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "../token/ERC20/ERC20Mintable.sol"; import "../crowdsale/emission/MintedCrowdsale.sol"; - contract MintedCrowdsaleImpl is MintedCrowdsale { - - constructor ( - uint256 rate, - address wallet, - ERC20Mintable token - ) - public - { + constructor (uint256 rate, address payable wallet, ERC20Mintable token) public { Crowdsale.initialize(rate, wallet, token); } - } diff --git a/contracts/mocks/MinterRoleMock.sol b/contracts/mocks/MinterRoleMock.sol index 85f779195..8091918e4 100644 --- a/contracts/mocks/MinterRoleMock.sol +++ b/contracts/mocks/MinterRoleMock.sol @@ -1,8 +1,7 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "../access/roles/MinterRole.sol"; - contract MinterRoleMock is MinterRole { constructor() public { MinterRole.initialize(msg.sender); @@ -13,6 +12,7 @@ contract MinterRoleMock is MinterRole { } function onlyMinterMock() public view onlyMinter { + // solhint-disable-previous-line no-empty-blocks } // Causes a compilation error if super._removeMinter is not internal diff --git a/contracts/mocks/OwnableInterfaceId.sol b/contracts/mocks/OwnableInterfaceId.sol new file mode 100644 index 000000000..363d9a2ac --- /dev/null +++ b/contracts/mocks/OwnableInterfaceId.sol @@ -0,0 +1,15 @@ +pragma solidity ^0.5.0; + +import "../ownership/Ownable.sol"; + +/** + * @title Ownable interface id calculator. + * @dev See the EIP165 specification for more information: + * https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md#specification + */ +contract OwnableInterfaceId { + function getInterfaceId() public pure returns (bytes4) { + Ownable i; + return i.owner.selector ^ i.isOwner.selector ^ i.renounceOwnership.selector ^ i.transferOwnership.selector; + } +} diff --git a/contracts/mocks/OwnableMock.sol b/contracts/mocks/OwnableMock.sol index 0523d48e7..54d62f6dd 100644 --- a/contracts/mocks/OwnableMock.sol +++ b/contracts/mocks/OwnableMock.sol @@ -1,6 +1,6 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; -import { Ownable } from "../ownership/Ownable.sol"; +import "../ownership/Ownable.sol"; contract OwnableMock is Ownable { constructor() { diff --git a/contracts/mocks/PausableCrowdsaleImpl.sol b/contracts/mocks/PausableCrowdsaleImpl.sol new file mode 100644 index 000000000..11f44c7b8 --- /dev/null +++ b/contracts/mocks/PausableCrowdsaleImpl.sol @@ -0,0 +1,10 @@ +pragma solidity ^0.5.0; + +import "../token/ERC20/ERC20.sol"; +import "../crowdsale/validation/PausableCrowdsale.sol"; + +contract PausableCrowdsaleImpl is PausableCrowdsale { + constructor (uint256 _rate, address payable _wallet, ERC20 _token) public Crowdsale(_rate, _wallet, _token) { + // solhint-disable-previous-line no-empty-blocks + } +} diff --git a/contracts/mocks/PausableMock.sol b/contracts/mocks/PausableMock.sol index 10b03f8bd..3f30905fc 100644 --- a/contracts/mocks/PausableMock.sol +++ b/contracts/mocks/PausableMock.sol @@ -1,15 +1,14 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "../lifecycle/Pausable.sol"; import "./PauserRoleMock.sol"; - // mock class using Pausable contract PausableMock is Pausable, PauserRoleMock { bool public drasticMeasureTaken; uint256 public count; - constructor() public { + constructor () public { Pausable.initialize(msg.sender); drasticMeasureTaken = false; @@ -23,5 +22,4 @@ contract PausableMock is Pausable, PauserRoleMock { function drasticMeasure() external whenPaused { drasticMeasureTaken = true; } - } diff --git a/contracts/mocks/PauserRoleMock.sol b/contracts/mocks/PauserRoleMock.sol index 4c53ba289..ea01088df 100644 --- a/contracts/mocks/PauserRoleMock.sol +++ b/contracts/mocks/PauserRoleMock.sol @@ -1,10 +1,9 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "../access/roles/PauserRole.sol"; - contract PauserRoleMock is PauserRole { - constructor() public { + constructor () public { PauserRole.initialize(msg.sender); } @@ -13,6 +12,7 @@ contract PauserRoleMock is PauserRole { } function onlyPauserMock() public view onlyPauser { + // solhint-disable-previous-line no-empty-blocks } // Causes a compilation error if super._removePauser is not internal diff --git a/contracts/mocks/PaymentSplitterMock.sol b/contracts/mocks/PaymentSplitterMock.sol new file mode 100644 index 000000000..5a0882ab0 --- /dev/null +++ b/contracts/mocks/PaymentSplitterMock.sol @@ -0,0 +1,9 @@ +pragma solidity ^0.4.24; + +import "../payment/PaymentSplitter.sol"; + +contract PaymentSplitterMock is PaymentSplitter { + constructor(address[] payees, uint256[] shares) public { + PaymentSplitter.initialize(payees, shares); + } +} diff --git a/contracts/mocks/PostDeliveryCrowdsaleImpl.sol b/contracts/mocks/PostDeliveryCrowdsaleImpl.sol index 9352ca3a0..c9c38fc86 100644 --- a/contracts/mocks/PostDeliveryCrowdsaleImpl.sol +++ b/contracts/mocks/PostDeliveryCrowdsaleImpl.sol @@ -1,22 +1,15 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "../token/ERC20/IERC20.sol"; import "../crowdsale/distribution/PostDeliveryCrowdsale.sol"; - contract PostDeliveryCrowdsaleImpl is PostDeliveryCrowdsale { - - constructor ( - uint256 openingTime, - uint256 closingTime, - uint256 rate, - address wallet, - IERC20 token - ) + constructor (uint256 openingTime, uint256 closingTime, uint256 rate, address payable wallet, IERC20 token) public + TimedCrowdsale(openingTime, closingTime) + Crowdsale(rate, wallet, token) { Crowdsale.initialize(rate, wallet, token); TimedCrowdsale.initialize(openingTime, closingTime); } - } diff --git a/contracts/mocks/PullPaymentMock.sol b/contracts/mocks/PullPaymentMock.sol index 8c4f8d2cf..01c883d00 100644 --- a/contracts/mocks/PullPaymentMock.sol +++ b/contracts/mocks/PullPaymentMock.sol @@ -1,13 +1,10 @@ -pragma solidity ^0.4.24; - +pragma solidity ^0.5.0; import "../payment/PullPayment.sol"; - // mock class using PullPayment contract PullPaymentMock is PullPayment { - - constructor() public payable { + constructor () public payable { PullPayment.initialize(); } @@ -15,5 +12,4 @@ contract PullPaymentMock is PullPayment { function callTransfer(address dest, uint256 amount) public { _asyncTransfer(dest, amount); } - } diff --git a/contracts/mocks/ReentrancyAttack.sol b/contracts/mocks/ReentrancyAttack.sol index d84c5fb2a..965a053e0 100644 --- a/contracts/mocks/ReentrancyAttack.sol +++ b/contracts/mocks/ReentrancyAttack.sol @@ -1,11 +1,9 @@ -pragma solidity ^0.4.24; - +pragma solidity ^0.5.0; contract ReentrancyAttack { - function callSender(bytes4 data) public { - // solium-disable-next-line security/no-low-level-calls - require(msg.sender.call(abi.encodeWithSelector(data))); + // solhint-disable-next-line avoid-low-level-calls + (bool success,) = msg.sender.call(abi.encodeWithSelector(data)); + require(success); } - } diff --git a/contracts/mocks/ReentrancyMock.sol b/contracts/mocks/ReentrancyMock.sol index 8f9f086ab..4d5102616 100644 --- a/contracts/mocks/ReentrancyMock.sol +++ b/contracts/mocks/ReentrancyMock.sol @@ -1,14 +1,12 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "../utils/ReentrancyGuard.sol"; import "./ReentrancyAttack.sol"; - contract ReentrancyMock is ReentrancyGuard { - uint256 public counter; - constructor() public { + constructor () public { ReentrancyGuard.initialize(); counter = 0; } @@ -27,9 +25,9 @@ contract ReentrancyMock is ReentrancyGuard { function countThisRecursive(uint256 n) public nonReentrant { if (n > 0) { count(); - // solium-disable-next-line security/no-low-level-calls - bool result = address(this).call(abi.encodeWithSignature("countThisRecursive(uint256)", n - 1)); - require(result == true); + // solhint-disable-next-line avoid-low-level-calls + (bool success,) = address(this).call(abi.encodeWithSignature("countThisRecursive(uint256)", n - 1)); + require(success); } } @@ -42,5 +40,4 @@ contract ReentrancyMock is ReentrancyGuard { function count() private { counter += 1; } - } diff --git a/contracts/mocks/RefundableCrowdsaleImpl.sol b/contracts/mocks/RefundableCrowdsaleImpl.sol index 5ce3550ea..3d9650980 100644 --- a/contracts/mocks/RefundableCrowdsaleImpl.sol +++ b/contracts/mocks/RefundableCrowdsaleImpl.sol @@ -1,17 +1,15 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; -import "../token/ERC20/ERC20Mintable.sol"; +import "../token/ERC20/IERC20.sol"; import "../crowdsale/distribution/RefundableCrowdsale.sol"; - contract RefundableCrowdsaleImpl is Crowdsale, TimedCrowdsale, RefundableCrowdsale { - constructor ( uint256 openingTime, uint256 closingTime, uint256 rate, - address wallet, - ERC20Mintable token, + address payable wallet, + IERC20 token, uint256 goal ) public @@ -20,5 +18,4 @@ contract RefundableCrowdsaleImpl is Crowdsale, TimedCrowdsale, RefundableCrowdsa TimedCrowdsale.initialize(openingTime, closingTime); RefundableCrowdsale.initialize(goal); } - } diff --git a/contracts/mocks/RefundablePostDeliveryCrowdsaleImpl.sol b/contracts/mocks/RefundablePostDeliveryCrowdsaleImpl.sol new file mode 100644 index 000000000..b81f0757c --- /dev/null +++ b/contracts/mocks/RefundablePostDeliveryCrowdsaleImpl.sol @@ -0,0 +1,22 @@ +pragma solidity ^0.5.0; + +import "../token/ERC20/IERC20.sol"; +import "../crowdsale/distribution/RefundablePostDeliveryCrowdsale.sol"; + +contract RefundablePostDeliveryCrowdsaleImpl is RefundablePostDeliveryCrowdsale { + constructor ( + uint256 openingTime, + uint256 closingTime, + uint256 rate, + address payable wallet, + IERC20 token, + uint256 goal + ) + public + Crowdsale(rate, wallet, token) + TimedCrowdsale(openingTime, closingTime) + RefundableCrowdsale(goal) + { + // solhint-disable-previous-line no-empty-blocks + } +} diff --git a/contracts/mocks/RolesMock.sol b/contracts/mocks/RolesMock.sol index 0aca6196e..4b0f0de0a 100644 --- a/contracts/mocks/RolesMock.sol +++ b/contracts/mocks/RolesMock.sol @@ -1,8 +1,7 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "../access/Roles.sol"; - contract RolesMock { using Roles for Roles.Role; diff --git a/contracts/mocks/SafeERC20Helper.sol b/contracts/mocks/SafeERC20Helper.sol index 8354751e4..c9c455e58 100644 --- a/contracts/mocks/SafeERC20Helper.sol +++ b/contracts/mocks/SafeERC20Helper.sol @@ -1,13 +1,10 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "../token/ERC20/IERC20.sol"; import "../token/ERC20/SafeERC20.sol"; - -contract ERC20FailingMock is IERC20 { - function totalSupply() public view returns (uint256) { - return 0; - } +contract ERC20FailingMock { + uint256 private _allowance; function transfer(address, uint256) public returns (bool) { return false; @@ -21,20 +18,13 @@ contract ERC20FailingMock is IERC20 { return false; } - function balanceOf(address) public view returns (uint256) { - return 0; - } - function allowance(address, address) public view returns (uint256) { return 0; } } - -contract ERC20SucceedingMock is IERC20 { - function totalSupply() public view returns (uint256) { - return 0; - } +contract ERC20SucceedingMock { + uint256 private _allowance; function transfer(address, uint256) public returns (bool) { return true; @@ -48,25 +38,24 @@ contract ERC20SucceedingMock is IERC20 { return true; } - function balanceOf(address) public view returns (uint256) { - return 0; + function setAllowance(uint256 allowance_) public { + _allowance = allowance_; } function allowance(address, address) public view returns (uint256) { - return 0; + return _allowance; } } - contract SafeERC20Helper { using SafeERC20 for IERC20; IERC20 private _failing; IERC20 private _succeeding; - constructor() public { - _failing = new ERC20FailingMock(); - _succeeding = new ERC20SucceedingMock(); + constructor () public { + _failing = IERC20(address(new ERC20FailingMock())); + _succeeding = IERC20(address(new ERC20SucceedingMock())); } function doFailingTransfer() public { @@ -81,6 +70,14 @@ contract SafeERC20Helper { _failing.safeApprove(address(0), 0); } + function doFailingIncreaseAllowance() public { + _failing.safeIncreaseAllowance(address(0), 0); + } + + function doFailingDecreaseAllowance() public { + _failing.safeDecreaseAllowance(address(0), 0); + } + function doSucceedingTransfer() public { _succeeding.safeTransfer(address(0), 0); } @@ -89,7 +86,23 @@ contract SafeERC20Helper { _succeeding.safeTransferFrom(address(0), address(0), 0); } - function doSucceedingApprove() public { - _succeeding.safeApprove(address(0), 0); + function doSucceedingApprove(uint256 amount) public { + _succeeding.safeApprove(address(0), amount); + } + + function doSucceedingIncreaseAllowance(uint256 amount) public { + _succeeding.safeIncreaseAllowance(address(0), amount); + } + + function doSucceedingDecreaseAllowance(uint256 amount) public { + _succeeding.safeDecreaseAllowance(address(0), amount); + } + + function setAllowance(uint256 allowance_) public { + ERC20SucceedingMock(address(_succeeding)).setAllowance(allowance_); + } + + function allowance() public view returns (uint256) { + return _succeeding.allowance(address(0), address(0)); } } diff --git a/contracts/mocks/SafeMathMock.sol b/contracts/mocks/SafeMathMock.sol index 909864023..43dac5ec2 100644 --- a/contracts/mocks/SafeMathMock.sol +++ b/contracts/mocks/SafeMathMock.sol @@ -1,11 +1,8 @@ -pragma solidity ^0.4.24; - +pragma solidity ^0.5.0; import "../math/SafeMath.sol"; - contract SafeMathMock { - function mul(uint256 a, uint256 b) public pure returns (uint256) { return SafeMath.mul(a, b); } diff --git a/contracts/mocks/SecondaryMock.sol b/contracts/mocks/SecondaryMock.sol index a3edbe17c..aa2ccd3bf 100644 --- a/contracts/mocks/SecondaryMock.sol +++ b/contracts/mocks/SecondaryMock.sol @@ -1,13 +1,13 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "../ownership/Secondary.sol"; - contract SecondaryMock is Secondary { constructor() public { Secondary.initialize(msg.sender); } function onlyPrimaryMock() public view onlyPrimary { + // solhint-disable-previous-line no-empty-blocks } } diff --git a/contracts/mocks/SignatureBouncerMock.sol b/contracts/mocks/SignatureBouncerMock.sol index c7dc30313..c764a0a4e 100644 --- a/contracts/mocks/SignatureBouncerMock.sol +++ b/contracts/mocks/SignatureBouncerMock.sol @@ -1,78 +1,54 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "../drafts/SignatureBouncer.sol"; import "./SignerRoleMock.sol"; - contract SignatureBouncerMock is SignatureBouncer, SignerRoleMock { constructor() public { SignatureBouncer.initialize(msg.sender); } - function checkValidSignature(address account, bytes signature) - public - view - returns (bool) + function checkValidSignature(address account, bytes memory signature) + public view returns (bool) { return _isValidSignature(account, signature); } - function onlyWithValidSignature(bytes signature) - public - onlyValidSignature(signature) - view + function onlyWithValidSignature(bytes memory signature) + public onlyValidSignature(signature) view { - + // solhint-disable-previous-line no-empty-blocks } - function checkValidSignatureAndMethod(address account, bytes signature) - public - view - returns (bool) + function checkValidSignatureAndMethod(address account, bytes memory signature) + public view returns (bool) { return _isValidSignatureAndMethod(account, signature); } - function onlyWithValidSignatureAndMethod(bytes signature) - public - onlyValidSignatureAndMethod(signature) - view + function onlyWithValidSignatureAndMethod(bytes memory signature) + public onlyValidSignatureAndMethod(signature) view { - + // solhint-disable-previous-line no-empty-blocks } - function checkValidSignatureAndData( - address account, - bytes, - uint, - bytes signature - ) - public - view - returns (bool) + function checkValidSignatureAndData(address account, bytes memory, uint, bytes memory signature) + public view returns (bool) { return _isValidSignatureAndData(account, signature); } - function onlyWithValidSignatureAndData(uint, bytes signature) - public - onlyValidSignatureAndData(signature) - view + function onlyWithValidSignatureAndData(uint, bytes memory signature) + public onlyValidSignatureAndData(signature) view { - + // solhint-disable-previous-line no-empty-blocks } - function theWrongMethod(bytes) - public - pure - { - + function theWrongMethod(bytes memory) public pure { + // solhint-disable-previous-line no-empty-blocks } - function tooShortMsgData() - public - onlyValidSignatureAndData("") - view - { + function tooShortMsgData() public onlyValidSignatureAndData("") view { + // solhint-disable-previous-line no-empty-blocks } } diff --git a/contracts/mocks/SignedSafeMathMock.sol b/contracts/mocks/SignedSafeMathMock.sol new file mode 100644 index 000000000..90a3ee642 --- /dev/null +++ b/contracts/mocks/SignedSafeMathMock.sol @@ -0,0 +1,21 @@ +pragma solidity ^0.5.0; + +import "../drafts/SignedSafeMath.sol"; + +contract SignedSafeMathMock { + function mul(int256 a, int256 b) public pure returns (int256) { + return SignedSafeMath.mul(a, b); + } + + function div(int256 a, int256 b) public pure returns (int256) { + return SignedSafeMath.div(a, b); + } + + function sub(int256 a, int256 b) public pure returns (int256) { + return SignedSafeMath.sub(a, b); + } + + function add(int256 a, int256 b) public pure returns (int256) { + return SignedSafeMath.add(a, b); + } +} diff --git a/contracts/mocks/SignerRoleMock.sol b/contracts/mocks/SignerRoleMock.sol index 0f51f83b7..1efedb7ff 100644 --- a/contracts/mocks/SignerRoleMock.sol +++ b/contracts/mocks/SignerRoleMock.sol @@ -1,8 +1,7 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "../access/roles/SignerRole.sol"; - contract SignerRoleMock is SignerRole { constructor() public { SignerRole.initialize(msg.sender); @@ -13,6 +12,7 @@ contract SignerRoleMock is SignerRole { } function onlySignerMock() public view onlySigner { + // solhint-disable-previous-line no-empty-blocks } // Causes a compilation error if super._removeSigner is not internal diff --git a/contracts/mocks/SplitPaymentMock.sol b/contracts/mocks/SplitPaymentMock.sol deleted file mode 100644 index 60b933f5a..000000000 --- a/contracts/mocks/SplitPaymentMock.sol +++ /dev/null @@ -1,9 +0,0 @@ -pragma solidity ^0.4.24; - -import "../payment/SplitPayment.sol"; - -contract SplitPaymentMock is SplitPayment { - constructor(address[] payees, uint256[] shares) public { - SplitPayment.initialize(payees, shares); - } -} diff --git a/contracts/mocks/TimedCrowdsaleImpl.sol b/contracts/mocks/TimedCrowdsaleImpl.sol index e6bcf8768..7d2a13b84 100644 --- a/contracts/mocks/TimedCrowdsaleImpl.sol +++ b/contracts/mocks/TimedCrowdsaleImpl.sol @@ -1,22 +1,13 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "../token/ERC20/IERC20.sol"; import "../crowdsale/validation/TimedCrowdsale.sol"; - contract TimedCrowdsaleImpl is TimedCrowdsale { - - constructor ( - uint256 openingTime, - uint256 closingTime, - uint256 rate, - address wallet, - IERC20 token - ) + constructor (uint256 openingTime, uint256 closingTime, uint256 rate, address payable wallet, IERC20 token) public { Crowdsale.initialize(rate, wallet, token); TimedCrowdsale.initialize(openingTime, closingTime); } - } diff --git a/contracts/mocks/WhitelistAdminRoleMock.sol b/contracts/mocks/WhitelistAdminRoleMock.sol new file mode 100644 index 000000000..7a267ca21 --- /dev/null +++ b/contracts/mocks/WhitelistAdminRoleMock.sol @@ -0,0 +1,18 @@ +pragma solidity ^0.5.0; + +import "../access/roles/WhitelistAdminRole.sol"; + +contract WhitelistAdminRoleMock is WhitelistAdminRole { + function removeWhitelistAdmin(address account) public { + _removeWhitelistAdmin(account); + } + + function onlyWhitelistAdminMock() public view onlyWhitelistAdmin { + // solhint-disable-previous-line no-empty-blocks + } + + // Causes a compilation error if super._removeWhitelistAdmin is not internal + function _removeWhitelistAdmin(address account) internal { + super._removeWhitelistAdmin(account); + } +} diff --git a/contracts/mocks/WhitelistCrowdsaleImpl.sol b/contracts/mocks/WhitelistCrowdsaleImpl.sol new file mode 100644 index 000000000..0200f7f7f --- /dev/null +++ b/contracts/mocks/WhitelistCrowdsaleImpl.sol @@ -0,0 +1,12 @@ +pragma solidity ^0.5.0; + +import "../token/ERC20/IERC20.sol"; +import "../crowdsale/validation/WhitelistCrowdsale.sol"; +import "../crowdsale/Crowdsale.sol"; + + +contract WhitelistCrowdsaleImpl is Crowdsale, WhitelistCrowdsale { + constructor (uint256 _rate, address payable _wallet, IERC20 _token) public Crowdsale(_rate, _wallet, _token) { + // solhint-disable-previous-line no-empty-blocks + } +} diff --git a/contracts/mocks/WhitelistedRoleMock.sol b/contracts/mocks/WhitelistedRoleMock.sol new file mode 100644 index 000000000..7f7c89412 --- /dev/null +++ b/contracts/mocks/WhitelistedRoleMock.sol @@ -0,0 +1,9 @@ +pragma solidity ^0.5.0; + +import "../access/roles/WhitelistedRole.sol"; + +contract WhitelistedRoleMock is WhitelistedRole { + function onlyWhitelistedMock() public view onlyWhitelisted { + // solhint-disable-previous-line no-empty-blocks + } +} diff --git a/contracts/ownership/Ownable.sol b/contracts/ownership/Ownable.sol index 2f74c0e09..fadedac15 100644 --- a/contracts/ownership/Ownable.sol +++ b/contracts/ownership/Ownable.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; @@ -10,13 +10,7 @@ import "zos-lib/contracts/Initializable.sol"; contract Ownable is Initializable { address private _owner; - - event OwnershipRenounced(address indexed previousOwner); - event OwnershipTransferred( - address indexed previousOwner, - address indexed newOwner - ); - + event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev The Ownable constructor sets the original `owner` of the contract to the sender @@ -24,12 +18,13 @@ contract Ownable is Initializable { */ function initialize(address sender) public initializer { _owner = sender; + emit OwnershipTransferred(address(0), _owner); } /** * @return the address of the owner. */ - function owner() public view returns(address) { + function owner() public view returns (address) { return _owner; } @@ -44,7 +39,7 @@ contract Ownable is Initializable { /** * @return true if `msg.sender` is the owner of the contract. */ - function isOwner() public view returns(bool) { + function isOwner() public view returns (bool) { return msg.sender == _owner; } @@ -55,7 +50,7 @@ contract Ownable is Initializable { * modifier anymore. */ function renounceOwnership() public onlyOwner { - emit OwnershipRenounced(_owner); + emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } diff --git a/contracts/ownership/Secondary.sol b/contracts/ownership/Secondary.sol index 0a620121e..9a74e054c 100644 --- a/contracts/ownership/Secondary.sol +++ b/contracts/ownership/Secondary.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; @@ -9,11 +9,16 @@ import "zos-lib/contracts/Initializable.sol"; contract Secondary is Initializable { address private _primary; + event PrimaryTransferred( + address recipient + ); + /** * @dev Sets the primary account to the one that is creating the Secondary contract. */ function initialize(address sender) public initializer { _primary = sender; + emit PrimaryTransferred(_primary); } /** @@ -24,14 +29,21 @@ contract Secondary is Initializable { _; } + /** + * @return the address of the primary. + */ function primary() public view returns (address) { return _primary; } + /** + * @dev Transfers contract to a new primary. + * @param recipient The address of new primary. + */ function transferPrimary(address recipient) public onlyPrimary { require(recipient != address(0)); - _primary = recipient; + emit PrimaryTransferred(_primary); } uint256[50] private ______gap; diff --git a/contracts/payment/SplitPayment.sol b/contracts/payment/PaymentSplitter.sol similarity index 66% rename from contracts/payment/SplitPayment.sol rename to contracts/payment/PaymentSplitter.sol index 2410ee968..280e4b9ac 100644 --- a/contracts/payment/SplitPayment.sol +++ b/contracts/payment/PaymentSplitter.sol @@ -1,17 +1,19 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; -import "zos-lib/contracts/Initializable.sol"; import "../math/SafeMath.sol"; - /** - * @title SplitPayment + * @title PaymentSplitter * @dev This contract can be used when payments need to be received by a group * of people and split proportionately to some number of shares they own. */ -contract SplitPayment is Initializable { +contract PaymentSplitter { using SafeMath for uint256; + event PayeeAdded(address account, uint256 shares); + event PaymentReleased(address to, uint256 amount); + event PaymentReceived(address from, uint256 amount); + uint256 private _totalShares; uint256 private _totalReleased; @@ -22,7 +24,7 @@ contract SplitPayment is Initializable { /** * @dev Constructor */ - function initialize(address[] payees, uint256[] shares) public payable initializer { + constructor (address[] memory payees, uint256[] memory shares) public payable { require(payees.length == shares.length); require(payees.length > 0); @@ -34,40 +36,42 @@ contract SplitPayment is Initializable { /** * @dev payable fallback */ - function () external payable {} + function () external payable { + emit PaymentReceived(msg.sender, msg.value); + } /** * @return the total shares of the contract. */ - function totalShares() public view returns(uint256) { + function totalShares() public view returns (uint256) { return _totalShares; } /** * @return the total amount already released. */ - function totalReleased() public view returns(uint256) { + function totalReleased() public view returns (uint256) { return _totalReleased; } /** * @return the shares of an account. */ - function shares(address account) public view returns(uint256) { + function shares(address account) public view returns (uint256) { return _shares[account]; } /** * @return the amount already released to an account. */ - function released(address account) public view returns(uint256) { + function released(address account) public view returns (uint256) { return _released[account]; } /** * @return the address of a payee. */ - function payee(uint256 index) public view returns(address) { + function payee(uint256 index) public view returns (address) { return _payees[index]; } @@ -75,15 +79,11 @@ contract SplitPayment is Initializable { * @dev Release one of the payee's proportional payment. * @param account Whose payments will be released. */ - function release(address account) public { + function release(address payable account) public { require(_shares[account] > 0); uint256 totalReceived = address(this).balance.add(_totalReleased); - uint256 payment = totalReceived.mul( - _shares[account]).div( - _totalShares).sub( - _released[account] - ); + uint256 payment = totalReceived.mul(_shares[account]).div(_totalShares).sub(_released[account]); require(payment != 0); @@ -91,6 +91,7 @@ contract SplitPayment is Initializable { _totalReleased = _totalReleased.add(payment); account.transfer(payment); + emit PaymentReleased(account, payment); } /** @@ -98,7 +99,7 @@ contract SplitPayment is Initializable { * @param account The address of the payee to add. * @param shares_ The number of shares owned by the payee. */ - function _addPayee(address account, uint256 shares_) internal { + function _addPayee(address account, uint256 shares_) private { require(account != address(0)); require(shares_ > 0); require(_shares[account] == 0); @@ -106,7 +107,6 @@ contract SplitPayment is Initializable { _payees.push(account); _shares[account] = shares_; _totalShares = _totalShares.add(shares_); + emit PayeeAdded(account, shares_); } - - uint256[50] private ______gap; } diff --git a/contracts/payment/PullPayment.sol b/contracts/payment/PullPayment.sol index a8b57ea24..fef5c0753 100644 --- a/contracts/payment/PullPayment.sol +++ b/contracts/payment/PullPayment.sol @@ -1,8 +1,8 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; -import "./Escrow.sol"; +import "./escrow/Escrow.sol"; /** * @title PullPayment @@ -12,7 +12,7 @@ import "./Escrow.sol"; contract PullPayment is Initializable { Escrow private _escrow; - function initialize() public initializer { + function initialize() internal initializer { // conditional added to make initializer idempotent in case of diamond inheritance if (address(_escrow) == address(0)) { _escrow = new Escrow(); @@ -24,7 +24,7 @@ contract PullPayment is Initializable { * @dev Withdraw accumulated balance. * @param payee Whose balance will be withdrawn. */ - function withdrawPayments(address payee) public { + function withdrawPayments(address payable payee) public { _escrow.withdraw(payee); } diff --git a/contracts/payment/ConditionalEscrow.sol b/contracts/payment/escrow/ConditionalEscrow.sol similarity index 61% rename from contracts/payment/ConditionalEscrow.sol rename to contracts/payment/escrow/ConditionalEscrow.sol index 5ccf686a1..268d731fa 100644 --- a/contracts/payment/ConditionalEscrow.sol +++ b/contracts/payment/escrow/ConditionalEscrow.sol @@ -1,18 +1,13 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; -import "zos-lib/contracts/Initializable.sol"; import "./Escrow.sol"; - /** * @title ConditionalEscrow * @dev Base abstract escrow to only allow withdrawal if a condition is met. + * @dev Intended usage: See Escrow.sol. Same usage guidelines apply here. */ -contract ConditionalEscrow is Initializable, Escrow { - function initialize(address sender) public initializer { - Escrow.initialize(sender); - } - +contract ConditionalEscrow is Escrow { /** * @dev Returns whether an address is allowed to withdraw their funds. To be * implemented by derived contracts. @@ -20,10 +15,8 @@ contract ConditionalEscrow is Initializable, Escrow { */ function withdrawalAllowed(address payee) public view returns (bool); - function withdraw(address payee) public { + function withdraw(address payable payee) public { require(withdrawalAllowed(payee)); super.withdraw(payee); } - - uint256[50] private ______gap; } diff --git a/contracts/payment/Escrow.sol b/contracts/payment/escrow/Escrow.sol similarity index 55% rename from contracts/payment/Escrow.sol rename to contracts/payment/escrow/Escrow.sol index 1931bf984..c010add45 100644 --- a/contracts/payment/Escrow.sol +++ b/contracts/payment/escrow/Escrow.sol @@ -1,18 +1,21 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; -import "zos-lib/contracts/Initializable.sol"; -import "../math/SafeMath.sol"; -import "../ownership/Secondary.sol"; +import "../../math/SafeMath.sol"; +import "../../ownership/Secondary.sol"; - -/** + /** * @title Escrow - * @dev Base escrow contract, holds funds destinated to a payee until they - * withdraw them. The contract that uses the escrow as its payment method - * should be its primary, and provide public methods redirecting to the escrow's - * deposit and withdraw. + * @dev Base escrow contract, holds funds designated for a payee until they + * withdraw them. + * @dev Intended usage: This contract (and derived escrow contracts) should be a + * standalone contract, that only interacts with the contract that instantiated + * it. That way, it is guaranteed that all Ether will be handled according to + * the Escrow rules, and there is no need to check for payable functions or + * transfers in the inheritance tree. The contract that uses the escrow as its + * payment method should be its primary, and provide public methods redirecting + * to the escrow's deposit and withdraw. */ -contract Escrow is Initializable, Secondary { +contract Escrow is Secondary { using SafeMath for uint256; event Deposited(address indexed payee, uint256 weiAmount); @@ -20,10 +23,6 @@ contract Escrow is Initializable, Secondary { mapping(address => uint256) private _deposits; - function initialize(address sender) public initializer { - Secondary.initialize(sender); - } - function depositsOf(address payee) public view returns (uint256) { return _deposits[payee]; } @@ -43,7 +42,7 @@ contract Escrow is Initializable, Secondary { * @dev Withdraw accumulated balance for a payee. * @param payee The address whose funds will be withdrawn and transferred to. */ - function withdraw(address payee) public onlyPrimary { + function withdraw(address payable payee) public onlyPrimary { uint256 payment = _deposits[payee]; _deposits[payee] = 0; @@ -52,6 +51,4 @@ contract Escrow is Initializable, Secondary { emit Withdrawn(payee, payment); } - - uint256[50] private ______gap; } diff --git a/contracts/payment/RefundEscrow.sol b/contracts/payment/escrow/RefundEscrow.sol similarity index 67% rename from contracts/payment/RefundEscrow.sol rename to contracts/payment/escrow/RefundEscrow.sol index 353a873c0..0c9cd99a6 100644 --- a/contracts/payment/RefundEscrow.sol +++ b/contracts/payment/escrow/RefundEscrow.sol @@ -1,31 +1,32 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; -import "zos-lib/contracts/Initializable.sol"; import "./ConditionalEscrow.sol"; - /** * @title RefundEscrow - * @dev Escrow that holds funds for a beneficiary, deposited from multiple parties. - * The primary account may close the deposit period, and allow for either withdrawal - * by the beneficiary, or refunds to the depositors. + * @dev Escrow that holds funds for a beneficiary, deposited from multiple + * parties. + * @dev Intended usage: See Escrow.sol. Same usage guidelines apply here. + * @dev The primary account (that is, the contract that instantiates this + * contract) may deposit, close the deposit period, and allow for either + * withdrawal by the beneficiary, or refunds to the depositors. All interactions + * with RefundEscrow will be made through the primary contract. See the + * RefundableCrowdsale contract for an example of RefundEscrow’s use. */ -contract RefundEscrow is Initializable, ConditionalEscrow { +contract RefundEscrow is ConditionalEscrow { enum State { Active, Refunding, Closed } - event Closed(); + event RefundsClosed(); event RefundsEnabled(); State private _state; - address private _beneficiary; + address payable private _beneficiary; /** * @dev Constructor. * @param beneficiary The beneficiary of the deposits. */ - function initialize(address beneficiary, address sender) public initializer { - ConditionalEscrow.initialize(sender); - + constructor (address payable beneficiary) public { require(beneficiary != address(0)); _beneficiary = beneficiary; _state = State.Active; @@ -61,7 +62,7 @@ contract RefundEscrow is Initializable, ConditionalEscrow { function close() public onlyPrimary { require(_state == State.Active); _state = State.Closed; - emit Closed(); + emit RefundsClosed(); } /** @@ -82,11 +83,10 @@ contract RefundEscrow is Initializable, ConditionalEscrow { } /** - * @dev Returns whether refundees can withdraw their deposits (be refunded). + * @dev Returns whether refundees can withdraw their deposits (be refunded). The overriden function receives a + * 'payee' argument, but we ignore it here since the condition is global, not per-payee. */ - function withdrawalAllowed(address payee) public view returns (bool) { + function withdrawalAllowed(address) public view returns (bool) { return _state == State.Refunding; } - - uint256[50] private ______gap; } diff --git a/contracts/token/ERC20/ERC20.sol b/contracts/token/ERC20/ERC20.sol index d1744c3d0..140ad9559 100644 --- a/contracts/token/ERC20/ERC20.sol +++ b/contracts/token/ERC20/ERC20.sol @@ -1,16 +1,20 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "./IERC20.sol"; import "../../math/SafeMath.sol"; - /** * @title Standard ERC20 token * * @dev Implementation of the basic standard token. * https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md - * Originally based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol + * Originally based on code by FirstBlood: + * https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol + * + * This implementation emits additional Approval events, allowing applications to reconstruct the allowance status for + * all accounts just by listening to said events. Note that this isn't required by the specification, and other + * compliant implementations may not do it. */ contract ERC20 is Initializable, IERC20 { using SafeMath for uint256; @@ -30,7 +34,7 @@ contract ERC20 is Initializable, IERC20 { /** * @dev Gets the balance of the specified address. - * @param owner The address to query the the balance of. + * @param owner The address to query the balance of. * @return An uint256 representing the amount owned by the passed address. */ function balanceOf(address owner) public view returns (uint256) { @@ -43,14 +47,7 @@ contract ERC20 is Initializable, IERC20 { * @param spender address The address which will spend the funds. * @return A uint256 specifying the amount of tokens still available for the spender. */ - function allowance( - address owner, - address spender - ) - public - view - returns (uint256) - { + function allowance(address owner, address spender) public view returns (uint256) { return _allowed[owner][spender]; } @@ -82,23 +79,17 @@ contract ERC20 is Initializable, IERC20 { } /** - * @dev Transfer tokens from one address to another + * @dev Transfer tokens from one address to another. + * Note that while this function emits an Approval event, this is not required as per the specification, + * and other compliant implementations may not emit the event. * @param from address The address which you want to send tokens from * @param to address The address which you want to transfer to * @param value uint256 the amount of tokens to be transferred */ - function transferFrom( - address from, - address to, - uint256 value - ) - public - returns (bool) - { - require(value <= _allowed[from][msg.sender]); - + function transferFrom(address from, address to, uint256 value) public returns (bool) { _allowed[from][msg.sender] = _allowed[from][msg.sender].sub(value); _transfer(from, to, value); + emit Approval(from, msg.sender, _allowed[from][msg.sender]); return true; } @@ -108,20 +99,14 @@ contract ERC20 is Initializable, IERC20 { * allowed value is better to use this function to avoid 2 calls (and wait until * the first transaction is mined) * From MonolithDAO Token.sol + * Emits an Approval event. * @param spender The address which will spend the funds. * @param addedValue The amount of tokens to increase the allowance by. */ - function increaseAllowance( - address spender, - uint256 addedValue - ) - public - returns (bool) - { + function increaseAllowance(address spender, uint256 addedValue) public returns (bool) { require(spender != address(0)); - _allowed[msg.sender][spender] = ( - _allowed[msg.sender][spender].add(addedValue)); + _allowed[msg.sender][spender] = _allowed[msg.sender][spender].add(addedValue); emit Approval(msg.sender, spender, _allowed[msg.sender][spender]); return true; } @@ -132,20 +117,14 @@ contract ERC20 is Initializable, IERC20 { * allowed value is better to use this function to avoid 2 calls (and wait until * the first transaction is mined) * From MonolithDAO Token.sol + * Emits an Approval event. * @param spender The address which will spend the funds. * @param subtractedValue The amount of tokens to decrease the allowance by. */ - function decreaseAllowance( - address spender, - uint256 subtractedValue - ) - public - returns (bool) - { + function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) { require(spender != address(0)); - _allowed[msg.sender][spender] = ( - _allowed[msg.sender][spender].sub(subtractedValue)); + _allowed[msg.sender][spender] = _allowed[msg.sender][spender].sub(subtractedValue); emit Approval(msg.sender, spender, _allowed[msg.sender][spender]); return true; } @@ -157,7 +136,6 @@ contract ERC20 is Initializable, IERC20 { * @param value The amount to be transferred. */ function _transfer(address from, address to, uint256 value) internal { - require(value <= _balances[from]); require(to != address(0)); _balances[from] = _balances[from].sub(value); @@ -170,45 +148,42 @@ contract ERC20 is Initializable, IERC20 { * an account. This encapsulates the modification of balances such that the * proper events are emitted. * @param account The account that will receive the created tokens. - * @param amount The amount that will be created. + * @param value The amount that will be created. */ - function _mint(address account, uint256 amount) internal { - require(account != 0); - _totalSupply = _totalSupply.add(amount); - _balances[account] = _balances[account].add(amount); - emit Transfer(address(0), account, amount); + function _mint(address account, uint256 value) internal { + require(account != address(0)); + + _totalSupply = _totalSupply.add(value); + _balances[account] = _balances[account].add(value); + emit Transfer(address(0), account, value); } /** * @dev Internal function that burns an amount of the token of a given * account. * @param account The account whose tokens will be burnt. - * @param amount The amount that will be burnt. + * @param value The amount that will be burnt. */ - function _burn(address account, uint256 amount) internal { - require(account != 0); - require(amount <= _balances[account]); + function _burn(address account, uint256 value) internal { + require(account != address(0)); - _totalSupply = _totalSupply.sub(amount); - _balances[account] = _balances[account].sub(amount); - emit Transfer(account, address(0), amount); + _totalSupply = _totalSupply.sub(value); + _balances[account] = _balances[account].sub(value); + emit Transfer(account, address(0), value); } /** * @dev Internal function that burns an amount of the token of a given * account, deducting from the sender's allowance for said account. Uses the * internal burn function. + * Emits an Approval event (reflecting the reduced allowance). * @param account The account whose tokens will be burnt. - * @param amount The amount that will be burnt. + * @param value The amount that will be burnt. */ - function _burnFrom(address account, uint256 amount) internal { - require(amount <= _allowed[account][msg.sender]); - - // Should https://github.com/OpenZeppelin/zeppelin-solidity/issues/707 be accepted, - // this function needs to emit an event with the updated approval. - _allowed[account][msg.sender] = _allowed[account][msg.sender].sub( - amount); - _burn(account, amount); + function _burnFrom(address account, uint256 value) internal { + _allowed[account][msg.sender] = _allowed[account][msg.sender].sub(value); + _burn(account, value); + emit Approval(account, msg.sender, _allowed[account][msg.sender]); } uint256[50] private ______gap; diff --git a/contracts/token/ERC20/ERC20Burnable.sol b/contracts/token/ERC20/ERC20Burnable.sol index 84b870c1d..ccd4126a0 100644 --- a/contracts/token/ERC20/ERC20Burnable.sol +++ b/contracts/token/ERC20/ERC20Burnable.sol @@ -1,15 +1,13 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "./ERC20.sol"; - /** * @title Burnable Token * @dev Token that can be irreversibly burned (destroyed). */ contract ERC20Burnable is Initializable, ERC20 { - /** * @dev Burns a specific amount of tokens. * @param value The amount of token to be burned. diff --git a/contracts/token/ERC20/ERC20Capped.sol b/contracts/token/ERC20/ERC20Capped.sol index 264d29667..402b60ab6 100644 --- a/contracts/token/ERC20/ERC20Capped.sol +++ b/contracts/token/ERC20/ERC20Capped.sol @@ -1,21 +1,16 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "./ERC20Mintable.sol"; - /** * @title Capped token * @dev Mintable token with a token cap. */ contract ERC20Capped is Initializable, ERC20Mintable { - uint256 private _cap; - function initialize(uint256 cap, address sender) - public - initializer - { + function initialize(uint256 cap, address sender) public initializer { ERC20Mintable.initialize(sender); require(cap > 0); @@ -25,28 +20,14 @@ contract ERC20Capped is Initializable, ERC20Mintable { /** * @return the cap for the token minting. */ - function cap() public view returns(uint256) { + function cap() public view returns (uint256) { return _cap; } - /** - * @dev Function to mint tokens - * @param to The address that will receive the minted tokens. - * @param amount The amount of tokens to mint. - * @return A boolean that indicates if the operation was successful. - */ - function mint( - address to, - uint256 amount - ) - public - returns (bool) - { - require(totalSupply().add(amount) <= _cap); - - return super.mint(to, amount); + function _mint(address account, uint256 value) internal { + require(totalSupply().add(value) <= _cap); + super._mint(account, value); } - uint256[50] private ______gap; } diff --git a/contracts/token/ERC20/ERC20Detailed.sol b/contracts/token/ERC20/ERC20Detailed.sol index 4a1d8d681..d98d12b9b 100644 --- a/contracts/token/ERC20/ERC20Detailed.sol +++ b/contracts/token/ERC20/ERC20Detailed.sol @@ -1,9 +1,8 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "./IERC20.sol"; - /** * @title ERC20Detailed token * @dev The decimals are only for visualization purposes. @@ -15,7 +14,7 @@ contract ERC20Detailed is Initializable, IERC20 { string private _symbol; uint8 private _decimals; - function initialize(string name, string symbol, uint8 decimals) public initializer { + function initialize(string memory name, string memory symbol, uint8 decimals) public initializer { _name = name; _symbol = symbol; _decimals = decimals; @@ -24,21 +23,21 @@ contract ERC20Detailed is Initializable, IERC20 { /** * @return the name of the token. */ - function name() public view returns(string) { + function name() public view returns (string memory) { return _name; } /** * @return the symbol of the token. */ - function symbol() public view returns(string) { + function symbol() public view returns (string memory) { return _symbol; } /** * @return the number of decimals of the token. */ - function decimals() public view returns(uint8) { + function decimals() public view returns (uint8) { return _decimals; } diff --git a/contracts/token/ERC20/ERC20Mintable.sol b/contracts/token/ERC20/ERC20Mintable.sol index 7b6864099..378d2c02c 100644 --- a/contracts/token/ERC20/ERC20Mintable.sol +++ b/contracts/token/ERC20/ERC20Mintable.sol @@ -1,10 +1,9 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "./ERC20.sol"; import "../../access/roles/MinterRole.sol"; - /** * @title ERC20Mintable * @dev ERC20 minting logic @@ -17,18 +16,11 @@ contract ERC20Mintable is Initializable, ERC20, MinterRole { /** * @dev Function to mint tokens * @param to The address that will receive the minted tokens. - * @param amount The amount of tokens to mint. + * @param value The amount of tokens to mint. * @return A boolean that indicates if the operation was successful. */ - function mint( - address to, - uint256 amount - ) - public - onlyMinter - returns (bool) - { - _mint(to, amount); + function mint(address to, uint256 value) public onlyMinter returns (bool) { + _mint(to, value); return true; } diff --git a/contracts/token/ERC20/ERC20Pausable.sol b/contracts/token/ERC20/ERC20Pausable.sol index 9f38dec39..0c6d8ee1d 100644 --- a/contracts/token/ERC20/ERC20Pausable.sol +++ b/contracts/token/ERC20/ERC20Pausable.sol @@ -1,75 +1,35 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "./ERC20.sol"; import "../../lifecycle/Pausable.sol"; - /** * @title Pausable token * @dev ERC20 modified with pausable transfers. **/ contract ERC20Pausable is Initializable, ERC20, Pausable { - function initialize(address sender) public initializer { Pausable.initialize(sender); } - function transfer( - address to, - uint256 value - ) - public - whenNotPaused - returns (bool) - { + function transfer(address to, uint256 value) public whenNotPaused returns (bool) { return super.transfer(to, value); } - function transferFrom( - address from, - address to, - uint256 value - ) - public - whenNotPaused - returns (bool) - { + function transferFrom(address from, address to, uint256 value) public whenNotPaused returns (bool) { return super.transferFrom(from, to, value); } - function approve( - address spender, - uint256 value - ) - public - whenNotPaused - returns (bool) - { + function approve(address spender, uint256 value) public whenNotPaused returns (bool) { return super.approve(spender, value); } - function increaseAllowance( - address spender, - uint addedValue - ) - public - whenNotPaused - returns (bool success) - { + function increaseAllowance(address spender, uint addedValue) public whenNotPaused returns (bool success) { return super.increaseAllowance(spender, addedValue); } - function decreaseAllowance( - address spender, - uint subtractedValue - ) - public - whenNotPaused - returns (bool success) - { + function decreaseAllowance(address spender, uint subtractedValue) public whenNotPaused returns (bool success) { return super.decreaseAllowance(spender, subtractedValue); } - - uint256[50] private ______gap; } diff --git a/contracts/token/ERC20/IERC20.sol b/contracts/token/ERC20/IERC20.sol index 3c111b412..af4a48558 100644 --- a/contracts/token/ERC20/IERC20.sol +++ b/contracts/token/ERC20/IERC20.sol @@ -1,35 +1,23 @@ -pragma solidity ^0.4.24; - +pragma solidity ^0.5.0; /** * @title ERC20 interface * @dev see https://github.com/ethereum/EIPs/issues/20 */ interface IERC20 { + function transfer(address to, uint256 value) external returns (bool); + + function approve(address spender, uint256 value) external returns (bool); + + function transferFrom(address from, address to, uint256 value) external returns (bool); + function totalSupply() external view returns (uint256); function balanceOf(address who) external view returns (uint256); - function allowance(address owner, address spender) - external view returns (uint256); + function allowance(address owner, address spender) external view returns (uint256); - function transfer(address to, uint256 value) external returns (bool); + event Transfer(address indexed from, address indexed to, uint256 value); - function approve(address spender, uint256 value) - external returns (bool); - - function transferFrom(address from, address to, uint256 value) - external returns (bool); - - event Transfer( - address indexed from, - address indexed to, - uint256 value - ); - - event Approval( - address indexed owner, - address indexed spender, - uint256 value - ); + event Approval(address indexed owner, address indexed spender, uint256 value); } diff --git a/contracts/token/ERC20/SafeERC20.sol b/contracts/token/ERC20/SafeERC20.sol index bbc8914a2..25ac9bae7 100644 --- a/contracts/token/ERC20/SafeERC20.sol +++ b/contracts/token/ERC20/SafeERC20.sol @@ -1,8 +1,7 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; -import "./ERC20.sol"; import "./IERC20.sol"; - +import "../../math/SafeMath.sol"; /** * @title SafeERC20 @@ -11,34 +10,31 @@ import "./IERC20.sol"; * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { - function safeTransfer( - IERC20 token, - address to, - uint256 value - ) - internal - { + using SafeMath for uint256; + + function safeTransfer(IERC20 token, address to, uint256 value) internal { require(token.transfer(to, value)); } - function safeTransferFrom( - IERC20 token, - address from, - address to, - uint256 value - ) - internal - { + function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { require(token.transferFrom(from, to, value)); } - function safeApprove( - IERC20 token, - address spender, - uint256 value - ) - internal - { + function safeApprove(IERC20 token, address spender, uint256 value) internal { + // safeApprove should only be called when setting an initial allowance, + // or when resetting it to zero. To increase and decrease it, use + // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' + require((value == 0) || (token.allowance(msg.sender, spender) == 0)); require(token.approve(spender, value)); } + + function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { + uint256 newAllowance = token.allowance(address(this), spender).add(value); + require(token.approve(spender, newAllowance)); + } + + function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { + uint256 newAllowance = token.allowance(address(this), spender).sub(value); + require(token.approve(spender, newAllowance)); + } } diff --git a/contracts/token/ERC20/TokenTimelock.sol b/contracts/token/ERC20/TokenTimelock.sol index a0c9f2ff5..6399ecf64 100644 --- a/contracts/token/ERC20/TokenTimelock.sol +++ b/contracts/token/ERC20/TokenTimelock.sol @@ -1,9 +1,8 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "./SafeERC20.sol"; - /** * @title TokenTimelock * @dev TokenTimelock is a token holder contract that will allow a @@ -21,15 +20,7 @@ contract TokenTimelock is Initializable { // timestamp when token release is enabled uint256 private _releaseTime; - function initialize( - IERC20 token, - address beneficiary, - uint256 releaseTime - ) - public - initializer - { - // solium-disable-next-line security/no-block-members + function initialize (IERC20 token, address beneficiary, uint256 releaseTime) public initializer { require(releaseTime > block.timestamp); _token = token; _beneficiary = beneficiary; @@ -39,21 +30,21 @@ contract TokenTimelock is Initializable { /** * @return the token being held. */ - function token() public view returns(IERC20) { + function token() public view returns (IERC20) { return _token; } /** * @return the beneficiary of the tokens. */ - function beneficiary() public view returns(address) { + function beneficiary() public view returns (address) { return _beneficiary; } /** * @return the time when the tokens are released. */ - function releaseTime() public view returns(uint256) { + function releaseTime() public view returns (uint256) { return _releaseTime; } @@ -61,7 +52,7 @@ contract TokenTimelock is Initializable { * @notice Transfers tokens held by timelock to beneficiary. */ function release() public { - // solium-disable-next-line security/no-block-members + // solhint-disable-next-line not-rely-on-time require(block.timestamp >= _releaseTime); uint256 amount = _token.balanceOf(address(this)); diff --git a/contracts/token/ERC721/ERC721.sol b/contracts/token/ERC721/ERC721.sol index 05a495d53..806df59fb 100644 --- a/contracts/token/ERC721/ERC721.sol +++ b/contracts/token/ERC721/ERC721.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "./IERC721.sol"; @@ -7,13 +7,11 @@ import "../../math/SafeMath.sol"; import "../../utils/Address.sol"; import "../../introspection/ERC165.sol"; - /** * @title ERC721 Non-Fungible Token Standard basic implementation * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md */ contract ERC721 is Initializable, ERC165, IERC721 { - using SafeMath for uint256; using Address for address; @@ -33,32 +31,29 @@ contract ERC721 is Initializable, ERC165, IERC721 { // Mapping from owner to operator approvals mapping (address => mapping (address => bool)) private _operatorApprovals; - bytes4 private constant _InterfaceId_ERC721 = 0x80ac58cd; + bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd; /* * 0x80ac58cd === - * bytes4(keccak256('balanceOf(address)')) ^ - * bytes4(keccak256('ownerOf(uint256)')) ^ - * bytes4(keccak256('approve(address,uint256)')) ^ - * bytes4(keccak256('getApproved(uint256)')) ^ - * bytes4(keccak256('setApprovalForAll(address,bool)')) ^ - * bytes4(keccak256('isApprovedForAll(address,address)')) ^ - * bytes4(keccak256('transferFrom(address,address,uint256)')) ^ - * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) ^ - * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) + * bytes4(keccak256('balanceOf(address)')) ^ + * bytes4(keccak256('ownerOf(uint256)')) ^ + * bytes4(keccak256('approve(address,uint256)')) ^ + * bytes4(keccak256('getApproved(uint256)')) ^ + * bytes4(keccak256('setApprovalForAll(address,bool)')) ^ + * bytes4(keccak256('isApprovedForAll(address,address)')) ^ + * bytes4(keccak256('transferFrom(address,address,uint256)')) ^ + * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) ^ + * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) */ - function initialize() - public - initializer - { + function initialize() public initializer { ERC165.initialize(); // register the supported interfaces to conform to ERC721 via ERC165 - _registerInterface(_InterfaceId_ERC721); + _registerInterface(_INTERFACE_ID_ERC721); } function _hasBeenInitialized() internal view returns (bool) { - return supportsInterface(_InterfaceId_ERC721); + return supportsInterface(_INTERFACE_ID_ERC721); } /** @@ -128,14 +123,7 @@ contract ERC721 is Initializable, ERC165, IERC721 { * @param operator operator address which you want to query the approval of * @return bool whether the given operator is approved by the given owner */ - function isApprovedForAll( - address owner, - address operator - ) - public - view - returns (bool) - { + function isApprovedForAll(address owner, address operator) public view returns (bool) { return _operatorApprovals[owner][operator]; } @@ -147,21 +135,10 @@ contract ERC721 is Initializable, ERC165, IERC721 { * @param to address to receive the ownership of the given token ID * @param tokenId uint256 ID of the token to be transferred */ - function transferFrom( - address from, - address to, - uint256 tokenId - ) - public - { + function transferFrom(address from, address to, uint256 tokenId) public { require(_isApprovedOrOwner(msg.sender, tokenId)); - require(to != address(0)); - _clearApproval(from, tokenId); - _removeTokenFrom(from, tokenId); - _addTokenTo(to, tokenId); - - emit Transfer(from, to, tokenId); + _transferFrom(from, to, tokenId); } /** @@ -176,14 +153,7 @@ contract ERC721 is Initializable, ERC165, IERC721 { * @param to address to receive the ownership of the given token ID * @param tokenId uint256 ID of the token to be transferred */ - function safeTransferFrom( - address from, - address to, - uint256 tokenId - ) - public - { - // solium-disable-next-line arg-overflow + function safeTransferFrom(address from, address to, uint256 tokenId) public { safeTransferFrom(from, to, tokenId, ""); } @@ -199,17 +169,9 @@ contract ERC721 is Initializable, ERC165, IERC721 { * @param tokenId uint256 ID of the token to be transferred * @param _data bytes data to send along with a safe transfer check */ - function safeTransferFrom( - address from, - address to, - uint256 tokenId, - bytes _data - ) - public - { + function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public { transferFrom(from, to, tokenId); - // solium-disable-next-line arg-overflow - require(_checkAndCallSafeTransfer(from, to, tokenId, _data)); + require(_checkOnERC721Received(from, to, tokenId, _data)); } /** @@ -227,83 +189,75 @@ contract ERC721 is Initializable, ERC165, IERC721 { * @param spender address of the spender to query * @param tokenId uint256 ID of the token to be transferred * @return bool whether the msg.sender is approved for the given token ID, - * is an operator of the owner, or is the owner of the token + * is an operator of the owner, or is the owner of the token */ - function _isApprovedOrOwner( - address spender, - uint256 tokenId - ) - internal - view - returns (bool) - { + function _isApprovedOrOwner(address spender, uint256 tokenId) internal view returns (bool) { address owner = ownerOf(tokenId); - // Disable solium check because of - // https://github.com/duaraghav8/Solium/issues/175 - // solium-disable-next-line operator-whitespace - return ( - spender == owner || - getApproved(tokenId) == spender || - isApprovedForAll(owner, spender) - ); + return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender)); } /** * @dev Internal function to mint a new token * Reverts if the given token ID already exists * @param to The address that will own the minted token - * @param tokenId uint256 ID of the token to be minted by the msg.sender + * @param tokenId uint256 ID of the token to be minted */ function _mint(address to, uint256 tokenId) internal { require(to != address(0)); - _addTokenTo(to, tokenId); + require(!_exists(tokenId)); + + _tokenOwner[tokenId] = to; + _ownedTokensCount[to] = _ownedTokensCount[to].add(1); + emit Transfer(address(0), to, tokenId); } /** * @dev Internal function to burn a specific token * Reverts if the token does not exist - * @param tokenId uint256 ID of the token being burned by the msg.sender + * Deprecated, use _burn(uint256) instead. + * @param owner owner of the token to burn + * @param tokenId uint256 ID of the token being burned */ function _burn(address owner, uint256 tokenId) internal { - _clearApproval(owner, tokenId); - _removeTokenFrom(owner, tokenId); + require(ownerOf(tokenId) == owner); + + _clearApproval(tokenId); + + _ownedTokensCount[owner] = _ownedTokensCount[owner].sub(1); + _tokenOwner[tokenId] = address(0); + emit Transfer(owner, address(0), tokenId); } /** - * @dev Internal function to clear current approval of a given token ID - * Reverts if the given address is not indeed the owner of the token - * @param owner owner of the token + * @dev Internal function to burn a specific token + * Reverts if the token does not exist + * @param tokenId uint256 ID of the token being burned + */ + function _burn(uint256 tokenId) internal { + _burn(ownerOf(tokenId), tokenId); + } + + /** + * @dev Internal function to transfer ownership of a given token ID to another address. + * As opposed to transferFrom, this imposes no restrictions on msg.sender. + * @param from current owner of the token + * @param to address to receive the ownership of the given token ID * @param tokenId uint256 ID of the token to be transferred - */ - function _clearApproval(address owner, uint256 tokenId) internal { - require(ownerOf(tokenId) == owner); - if (_tokenApprovals[tokenId] != address(0)) { - _tokenApprovals[tokenId] = address(0); - } - } - - /** - * @dev Internal function to add a token ID to the list of a given address - * @param to address representing the new owner of the given token ID - * @param tokenId uint256 ID of the token to be added to the tokens list of the given address - */ - function _addTokenTo(address to, uint256 tokenId) internal { - require(_tokenOwner[tokenId] == address(0)); - _tokenOwner[tokenId] = to; - _ownedTokensCount[to] = _ownedTokensCount[to].add(1); - } - - /** - * @dev Internal function to remove a token ID from the list of a given address - * @param from address representing the previous owner of the given token ID - * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address - */ - function _removeTokenFrom(address from, uint256 tokenId) internal { + */ + function _transferFrom(address from, address to, uint256 tokenId) internal { require(ownerOf(tokenId) == from); + require(to != address(0)); + + _clearApproval(tokenId); + _ownedTokensCount[from] = _ownedTokensCount[from].sub(1); - _tokenOwner[tokenId] = address(0); + _ownedTokensCount[to] = _ownedTokensCount[to].add(1); + + _tokenOwner[tokenId] = to; + + emit Transfer(from, to, tokenId); } /** @@ -315,22 +269,26 @@ contract ERC721 is Initializable, ERC165, IERC721 { * @param _data bytes optional data to send along with the call * @return whether the call correctly returned the expected magic value */ - function _checkAndCallSafeTransfer( - address from, - address to, - uint256 tokenId, - bytes _data - ) - internal - returns (bool) + function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data) + internal returns (bool) { if (!to.isContract()) { return true; } - bytes4 retval = IERC721Receiver(to).onERC721Received( - msg.sender, from, tokenId, _data); + + bytes4 retval = IERC721Receiver(to).onERC721Received(msg.sender, from, tokenId, _data); return (retval == _ERC721_RECEIVED); } + /** + * @dev Private function to clear current approval of a given token ID + * @param tokenId uint256 ID of the token to be transferred + */ + function _clearApproval(uint256 tokenId) private { + if (_tokenApprovals[tokenId] != address(0)) { + _tokenApprovals[tokenId] = address(0); + } + } + uint256[50] private ______gap; } diff --git a/contracts/token/ERC721/ERC721Burnable.sol b/contracts/token/ERC721/ERC721Burnable.sol index 32749b6a3..9efd1cf23 100644 --- a/contracts/token/ERC721/ERC721Burnable.sol +++ b/contracts/token/ERC721/ERC721Burnable.sol @@ -1,15 +1,20 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "./ERC721.sol"; - +/** + * @title ERC721 Burnable Token + * @dev ERC721 Token that can be irreversibly burned (destroyed). + */ contract ERC721Burnable is Initializable, ERC721 { - function burn(uint256 tokenId) - public - { + /** + * @dev Burns a specific ERC721 token. + * @param tokenId uint256 id of the ERC721 token to be burned. + */ + function burn(uint256 tokenId) public { require(_isApprovedOrOwner(msg.sender, tokenId)); - _burn(ownerOf(tokenId), tokenId); + _burn(tokenId); } uint256[50] private ______gap; diff --git a/contracts/token/ERC721/ERC721Enumerable.sol b/contracts/token/ERC721/ERC721Enumerable.sol index 39584ae04..5c61280ed 100644 --- a/contracts/token/ERC721/ERC721Enumerable.sol +++ b/contracts/token/ERC721/ERC721Enumerable.sol @@ -1,11 +1,14 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "./IERC721Enumerable.sol"; import "./ERC721.sol"; import "../../introspection/ERC165.sol"; - +/** + * @title ERC-721 Non-Fungible Token with optional enumeration extension logic + * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md + */ contract ERC721Enumerable is Initializable, ERC165, ERC721, IERC721Enumerable { // Mapping from owner to list of owned token IDs mapping(address => uint256[]) private _ownedTokens; @@ -19,12 +22,12 @@ contract ERC721Enumerable is Initializable, ERC165, ERC721, IERC721Enumerable { // Mapping from token id to position in the allTokens array mapping(uint256 => uint256) private _allTokensIndex; - bytes4 private constant _InterfaceId_ERC721Enumerable = 0x780e9d63; + bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63; /** * 0x780e9d63 === - * bytes4(keccak256('totalSupply()')) ^ - * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) ^ - * bytes4(keccak256('tokenByIndex(uint256)')) + * bytes4(keccak256('totalSupply()')) ^ + * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) ^ + * bytes4(keccak256('tokenByIndex(uint256)')) */ /** @@ -47,14 +50,7 @@ contract ERC721Enumerable is Initializable, ERC165, ERC721, IERC721Enumerable { * @param index uint256 representing the index to be accessed of the requested tokens list * @return uint256 token ID at the given index of the tokens list owned by the requested address */ - function tokenOfOwnerByIndex( - address owner, - uint256 index - ) - public - view - returns (uint256) - { + function tokenOfOwnerByIndex(address owner, uint256 index) public view returns (uint256) { require(index < balanceOf(owner)); return _ownedTokens[owner][index]; } @@ -79,76 +75,132 @@ contract ERC721Enumerable is Initializable, ERC165, ERC721, IERC721Enumerable { } /** - * @dev Internal function to add a token ID to the list of a given address - * @param to address representing the new owner of the given token ID - * @param tokenId uint256 ID of the token to be added to the tokens list of the given address - */ - function _addTokenTo(address to, uint256 tokenId) internal { - super._addTokenTo(to, tokenId); - uint256 length = _ownedTokens[to].length; - _ownedTokens[to].push(tokenId); - _ownedTokensIndex[tokenId] = length; - } + * @dev Internal function to transfer ownership of a given token ID to another address. + * As opposed to transferFrom, this imposes no restrictions on msg.sender. + * @param from current owner of the token + * @param to address to receive the ownership of the given token ID + * @param tokenId uint256 ID of the token to be transferred + */ + function _transferFrom(address from, address to, uint256 tokenId) internal { + super._transferFrom(from, to, tokenId); - /** - * @dev Internal function to remove a token ID from the list of a given address - * @param from address representing the previous owner of the given token ID - * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address - */ - function _removeTokenFrom(address from, uint256 tokenId) internal { - super._removeTokenFrom(from, tokenId); + _removeTokenFromOwnerEnumeration(from, tokenId); - // To prevent a gap in the array, we store the last token in the index of the token to delete, and - // then delete the last slot. - uint256 tokenIndex = _ownedTokensIndex[tokenId]; - uint256 lastTokenIndex = _ownedTokens[from].length.sub(1); - uint256 lastToken = _ownedTokens[from][lastTokenIndex]; - - _ownedTokens[from][tokenIndex] = lastToken; - // This also deletes the contents at the last position of the array - _ownedTokens[from].length--; - - // Note that this will handle single-element arrays. In that case, both tokenIndex and lastTokenIndex are going to - // be zero. Then we can make sure that we will remove tokenId from the ownedTokens list since we are first swapping - // the lastToken to the first position, and then dropping the element placed in the last position of the list - - _ownedTokensIndex[tokenId] = 0; - _ownedTokensIndex[lastToken] = tokenIndex; + _addTokenToOwnerEnumeration(to, tokenId); } /** * @dev Internal function to mint a new token * Reverts if the given token ID already exists * @param to address the beneficiary that will own the minted token - * @param tokenId uint256 ID of the token to be minted by the msg.sender + * @param tokenId uint256 ID of the token to be minted */ function _mint(address to, uint256 tokenId) internal { super._mint(to, tokenId); - _allTokensIndex[tokenId] = _allTokens.length; - _allTokens.push(tokenId); + _addTokenToOwnerEnumeration(to, tokenId); + + _addTokenToAllTokensEnumeration(tokenId); } /** * @dev Internal function to burn a specific token * Reverts if the token does not exist + * Deprecated, use _burn(uint256) instead * @param owner owner of the token to burn - * @param tokenId uint256 ID of the token being burned by the msg.sender + * @param tokenId uint256 ID of the token being burned */ function _burn(address owner, uint256 tokenId) internal { super._burn(owner, tokenId); - // Reorg all tokens array - uint256 tokenIndex = _allTokensIndex[tokenId]; + _removeTokenFromOwnerEnumeration(owner, tokenId); + // Since tokenId will be deleted, we can clear its slot in _ownedTokensIndex to trigger a gas refund + _ownedTokensIndex[tokenId] = 0; + + _removeTokenFromAllTokensEnumeration(tokenId); + } + + /** + * @dev Gets the list of token IDs of the requested owner + * @param owner address owning the tokens + * @return uint256[] List of token IDs owned by the requested address + */ + function _tokensOfOwner(address owner) internal view returns (uint256[] storage) { + return _ownedTokens[owner]; + } + + /** + * @dev Private function to add a token to this extension's ownership-tracking data structures. + * @param to address representing the new owner of the given token ID + * @param tokenId uint256 ID of the token to be added to the tokens list of the given address + */ + function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private { + _ownedTokensIndex[tokenId] = _ownedTokens[to].length; + _ownedTokens[to].push(tokenId); + } + + /** + * @dev Private function to add a token to this extension's token tracking data structures. + * @param tokenId uint256 ID of the token to be added to the tokens list + */ + function _addTokenToAllTokensEnumeration(uint256 tokenId) private { + _allTokensIndex[tokenId] = _allTokens.length; + _allTokens.push(tokenId); + } + + /** + * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that + * while the token is not assigned a new owner, the _ownedTokensIndex mapping is _not_ updated: this allows for + * gas optimizations e.g. when performing a transfer operation (avoiding double writes). + * This has O(1) time complexity, but alters the order of the _ownedTokens array. + * @param from address representing the previous owner of the given token ID + * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address + */ + function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private { + // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and + // then delete the last slot (swap and pop). + + uint256 lastTokenIndex = _ownedTokens[from].length.sub(1); + uint256 tokenIndex = _ownedTokensIndex[tokenId]; + + // When the token to delete is the last token, the swap operation is unnecessary + if (tokenIndex != lastTokenIndex) { + uint256 lastTokenId = _ownedTokens[from][lastTokenIndex]; + + _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token + _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index + } + + // This also deletes the contents at the last position of the array + _ownedTokens[from].length--; + + // Note that _ownedTokensIndex[tokenId] hasn't been cleared: it still points to the old slot (now occcupied by + // lasTokenId, or just over the end of the array if the token was the last one). + } + + /** + * @dev Private function to remove a token from this extension's token tracking data structures. + * This has O(1) time complexity, but alters the order of the _allTokens array. + * @param tokenId uint256 ID of the token to be removed from the tokens list + */ + function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private { + // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and + // then delete the last slot (swap and pop). + uint256 lastTokenIndex = _allTokens.length.sub(1); - uint256 lastToken = _allTokens[lastTokenIndex]; + uint256 tokenIndex = _allTokensIndex[tokenId]; - _allTokens[tokenIndex] = lastToken; - _allTokens[lastTokenIndex] = 0; + // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so + // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding + // an 'if' statement (like in _removeTokenFromOwnerEnumeration) + uint256 lastTokenId = _allTokens[lastTokenIndex]; + _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token + _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index + + // This also deletes the contents at the last position of the array _allTokens.length--; _allTokensIndex[tokenId] = 0; - _allTokensIndex[lastToken] = tokenIndex; } uint256[50] private ______gap; diff --git a/contracts/token/ERC721/ERC721Full.sol b/contracts/token/ERC721/ERC721Full.sol index a44c5abfe..d86ef9e93 100644 --- a/contracts/token/ERC721/ERC721Full.sol +++ b/contracts/token/ERC721/ERC721Full.sol @@ -1,11 +1,10 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "./ERC721.sol"; import "./ERC721Enumerable.sol"; import "./ERC721Metadata.sol"; - /** * @title Full ERC721 Token * This implementation includes all the required and some optional functionality of the ERC721 standard @@ -13,5 +12,9 @@ import "./ERC721Metadata.sol"; * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md */ contract ERC721Full is Initializable, ERC721, ERC721Enumerable, ERC721Metadata { + function initialize(string memory name, string memory symbol) public initializer { + ERC721Metadata.initialize(name, symbol); + } + uint256[50] private ______gap; } diff --git a/contracts/token/ERC721/ERC721Holder.sol b/contracts/token/ERC721/ERC721Holder.sol index aa1413b6a..dd4653229 100644 --- a/contracts/token/ERC721/ERC721Holder.sol +++ b/contracts/token/ERC721/ERC721Holder.sol @@ -1,19 +1,10 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "./IERC721Receiver.sol"; - contract ERC721Holder is Initializable, IERC721Receiver { - function onERC721Received( - address, - address, - uint256, - bytes - ) - public - returns(bytes4) - { + function onERC721Received(address, address, uint256, bytes memory) public returns (bytes4) { return this.onERC721Received.selector; } diff --git a/contracts/token/ERC721/ERC721Metadata.sol b/contracts/token/ERC721/ERC721Metadata.sol index 038d78656..8ca6d0e2e 100644 --- a/contracts/token/ERC721/ERC721Metadata.sol +++ b/contracts/token/ERC721/ERC721Metadata.sol @@ -1,51 +1,46 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "./ERC721.sol"; import "./IERC721Metadata.sol"; import "../../introspection/ERC165.sol"; - contract ERC721Metadata is Initializable, ERC165, ERC721, IERC721Metadata { // Token name - string internal _name; + string private _name; // Token symbol - string internal _symbol; + string private _symbol; // Optional mapping for token URIs mapping(uint256 => string) private _tokenURIs; - bytes4 private constant InterfaceId_ERC721Metadata = 0x5b5e139f; + bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f; /** * 0x5b5e139f === - * bytes4(keccak256('name()')) ^ - * bytes4(keccak256('symbol()')) ^ - * bytes4(keccak256('tokenURI(uint256)')) + * bytes4(keccak256('name()')) ^ + * bytes4(keccak256('symbol()')) ^ + * bytes4(keccak256('tokenURI(uint256)')) */ /** * @dev Constructor function */ - function initialize(string name, string symbol) public initializer { + function initialize(string memory name, string memory symbol) public initializer { require(ERC721._hasBeenInitialized()); _name = name; _symbol = symbol; // register the supported interfaces to conform to ERC721 via ERC165 - _registerInterface(InterfaceId_ERC721Metadata); - } - - function _hasBeenInitialized() internal view returns (bool) { - return supportsInterface(InterfaceId_ERC721Metadata); + _registerInterface(_INTERFACE_ID_ERC721_METADATA); } /** * @dev Gets the token name * @return string representing the token name */ - function name() external view returns (string) { + function name() external view returns (string memory) { return _name; } @@ -53,7 +48,7 @@ contract ERC721Metadata is Initializable, ERC165, ERC721, IERC721Metadata { * @dev Gets the token symbol * @return string representing the token symbol */ - function symbol() external view returns (string) { + function symbol() external view returns (string memory) { return _symbol; } @@ -62,7 +57,7 @@ contract ERC721Metadata is Initializable, ERC165, ERC721, IERC721Metadata { * Throws if the token ID does not exist. May return an empty string. * @param tokenId uint256 ID of the token to query */ - function tokenURI(uint256 tokenId) public view returns (string) { + function tokenURI(uint256 tokenId) external view returns (string memory) { require(_exists(tokenId)); return _tokenURIs[tokenId]; } @@ -73,7 +68,7 @@ contract ERC721Metadata is Initializable, ERC165, ERC721, IERC721Metadata { * @param tokenId uint256 ID of the token to set its URI * @param uri string URI to assign */ - function _setTokenURI(uint256 tokenId, string uri) internal { + function _setTokenURI(uint256 tokenId, string memory uri) internal { require(_exists(tokenId)); _tokenURIs[tokenId] = uri; } @@ -81,6 +76,7 @@ contract ERC721Metadata is Initializable, ERC165, ERC721, IERC721Metadata { /** * @dev Internal function to burn a specific token * Reverts if the token does not exist + * Deprecated, use _burn(uint256) instead * @param owner owner of the token to burn * @param tokenId uint256 ID of the token being burned by the msg.sender */ diff --git a/contracts/token/ERC721/ERC721MetadataMintable.sol b/contracts/token/ERC721/ERC721MetadataMintable.sol index a7b55c9f1..00c534d4a 100644 --- a/contracts/token/ERC721/ERC721MetadataMintable.sol +++ b/contracts/token/ERC721/ERC721MetadataMintable.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "./ERC721Metadata.sol"; @@ -23,15 +23,7 @@ contract ERC721MetadataMintable is Initializable, ERC721, ERC721Metadata, Minter * @param tokenURI The token URI of the minted token. * @return A boolean that indicates if the operation was successful. */ - function mintWithTokenURI( - address to, - uint256 tokenId, - string tokenURI - ) - public - onlyMinter - returns (bool) - { + function mintWithTokenURI(address to, uint256 tokenId, string memory tokenURI) public onlyMinter returns (bool) { _mint(to, tokenId); _setTokenURI(tokenId, tokenURI); return true; diff --git a/contracts/token/ERC721/ERC721Mintable.sol b/contracts/token/ERC721/ERC721Mintable.sol index bf452b0f1..18933ef52 100644 --- a/contracts/token/ERC721/ERC721Mintable.sol +++ b/contracts/token/ERC721/ERC721Mintable.sol @@ -1,10 +1,9 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "./ERC721.sol"; import "../../access/roles/MinterRole.sol"; - /** * @title ERC721Mintable * @dev ERC721 minting logic @@ -21,14 +20,7 @@ contract ERC721Mintable is Initializable, ERC721, MinterRole { * @param tokenId The token id to mint. * @return A boolean that indicates if the operation was successful. */ - function mint( - address to, - uint256 tokenId - ) - public - onlyMinter - returns (bool) - { + function mint(address to, uint256 tokenId) public onlyMinter returns (bool) { _mint(to, tokenId); return true; } diff --git a/contracts/token/ERC721/ERC721Pausable.sol b/contracts/token/ERC721/ERC721Pausable.sol index e7dbd0054..aa777fa14 100644 --- a/contracts/token/ERC721/ERC721Pausable.sol +++ b/contracts/token/ERC721/ERC721Pausable.sol @@ -1,10 +1,9 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "./ERC721.sol"; import "../../lifecycle/Pausable.sol"; - /** * @title ERC721 Non-Fungible Pausable token * @dev ERC721 modified with pausable transfers. @@ -15,34 +14,15 @@ contract ERC721Pausable is Initializable, ERC721, Pausable { Pausable.initialize(sender); } - function approve( - address to, - uint256 tokenId - ) - public - whenNotPaused - { + function approve(address to, uint256 tokenId) public whenNotPaused { super.approve(to, tokenId); } - function setApprovalForAll( - address to, - bool approved - ) - public - whenNotPaused - { + function setApprovalForAll(address to, bool approved) public whenNotPaused { super.setApprovalForAll(to, approved); } - function transferFrom( - address from, - address to, - uint256 tokenId - ) - public - whenNotPaused - { + function transferFrom(address from, address to, uint256 tokenId) public whenNotPaused { super.transferFrom(from, to, tokenId); } diff --git a/contracts/token/ERC721/IERC721.sol b/contracts/token/ERC721/IERC721.sol index 200e43fa8..250433881 100644 --- a/contracts/token/ERC721/IERC721.sol +++ b/contracts/token/ERC721/IERC721.sol @@ -1,51 +1,28 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "../../introspection/IERC165.sol"; - /** * @title ERC721 Non-Fungible Token Standard basic interface * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md */ contract IERC721 is Initializable, IERC165 { - - event Transfer( - address indexed from, - address indexed to, - uint256 indexed tokenId - ); - event Approval( - address indexed owner, - address indexed approved, - uint256 indexed tokenId - ); - event ApprovalForAll( - address indexed owner, - address indexed operator, - bool approved - ); + event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); + event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); + event ApprovalForAll(address indexed owner, address indexed operator, bool approved); function balanceOf(address owner) public view returns (uint256 balance); function ownerOf(uint256 tokenId) public view returns (address owner); function approve(address to, uint256 tokenId) public; - function getApproved(uint256 tokenId) - public view returns (address operator); + function getApproved(uint256 tokenId) public view returns (address operator); function setApprovalForAll(address operator, bool _approved) public; - function isApprovedForAll(address owner, address operator) - public view returns (bool); + function isApprovedForAll(address owner, address operator) public view returns (bool); function transferFrom(address from, address to, uint256 tokenId) public; - function safeTransferFrom(address from, address to, uint256 tokenId) - public; + function safeTransferFrom(address from, address to, uint256 tokenId) public; - function safeTransferFrom( - address from, - address to, - uint256 tokenId, - bytes data - ) - public; + function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public; } diff --git a/contracts/token/ERC721/IERC721Enumerable.sol b/contracts/token/ERC721/IERC721Enumerable.sol index d09479781..d71cf9815 100644 --- a/contracts/token/ERC721/IERC721Enumerable.sol +++ b/contracts/token/ERC721/IERC721Enumerable.sol @@ -1,22 +1,15 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "./IERC721.sol"; - /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md */ contract IERC721Enumerable is Initializable, IERC721 { function totalSupply() public view returns (uint256); - function tokenOfOwnerByIndex( - address owner, - uint256 index - ) - public - view - returns (uint256 tokenId); + function tokenOfOwnerByIndex(address owner, uint256 index) public view returns (uint256 tokenId); function tokenByIndex(uint256 index) public view returns (uint256); } diff --git a/contracts/token/ERC721/IERC721Full.sol b/contracts/token/ERC721/IERC721Full.sol index fc1c29bc1..589924afa 100644 --- a/contracts/token/ERC721/IERC721Full.sol +++ b/contracts/token/ERC721/IERC721Full.sol @@ -1,14 +1,14 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "./IERC721.sol"; import "./IERC721Enumerable.sol"; import "./IERC721Metadata.sol"; - /** * @title ERC-721 Non-Fungible Token Standard, full implementation interface * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md */ contract IERC721Full is Initializable, IERC721, IERC721Enumerable, IERC721Metadata { + // solhint-disable-previous-line no-empty-blocks } diff --git a/contracts/token/ERC721/IERC721Metadata.sol b/contracts/token/ERC721/IERC721Metadata.sol index 495780efe..560a6e13a 100644 --- a/contracts/token/ERC721/IERC721Metadata.sol +++ b/contracts/token/ERC721/IERC721Metadata.sol @@ -1,15 +1,14 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; import "./IERC721.sol"; - /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md */ contract IERC721Metadata is Initializable, IERC721 { - function name() external view returns (string); - function symbol() external view returns (string); - function tokenURI(uint256 tokenId) public view returns (string); + function name() external view returns (string memory); + function symbol() external view returns (string memory); + function tokenURI(uint256 tokenId) external view returns (string memory); } diff --git a/contracts/token/ERC721/IERC721Receiver.sol b/contracts/token/ERC721/IERC721Receiver.sol index 42ca6f91d..e2d019759 100644 --- a/contracts/token/ERC721/IERC721Receiver.sol +++ b/contracts/token/ERC721/IERC721Receiver.sol @@ -1,5 +1,4 @@ -pragma solidity ^0.4.24; - +pragma solidity ^0.5.0; /** * @title ERC721 token receiver interface @@ -21,12 +20,6 @@ contract IERC721Receiver { * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` */ - function onERC721Received( - address operator, - address from, - uint256 tokenId, - bytes data - ) - public - returns(bytes4); + function onERC721Received(address operator, address from, uint256 tokenId, bytes memory data) + public returns (bytes4); } diff --git a/contracts/utils/Address.sol b/contracts/utils/Address.sol index feb31eeba..500467212 100644 --- a/contracts/utils/Address.sol +++ b/contracts/utils/Address.sol @@ -1,11 +1,9 @@ -pragma solidity ^0.4.24; - +pragma solidity ^0.5.0; /** * Utility library of inline functions on addresses */ library Address { - /** * Returns whether the target address is a contract * @dev This function will return false if invoked during the constructor of a contract, @@ -21,7 +19,7 @@ library Address { // for more details about how this works. // TODO Check this again before the Serenity release, because all addresses will be // contracts then. - // solium-disable-next-line security/no-inline-assembly + // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } diff --git a/contracts/utils/Arrays.sol b/contracts/utils/Arrays.sol new file mode 100644 index 000000000..c34154c52 --- /dev/null +++ b/contracts/utils/Arrays.sol @@ -0,0 +1,48 @@ +pragma solidity ^0.5.0; + +import "../math/Math.sol"; + + +/** + * @title Arrays + * @dev Utility library of inline array functions + */ +library Arrays { + /** + * @dev Upper bound search function which is kind of binary search algoritm. It searches sorted + * array to find index of the element value. If element is found then returns it's index otherwise + * it returns index of first element which is grater than searched value. If searched element is + * bigger than any array element function then returns first index after last element (i.e. all + * values inside the array are smaller than the target). Complexity O(log n). + * @param array The array sorted in ascending order. + * @param element The element's value to be find. + * @return The calculated index value. Returns 0 for empty array. + */ + function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) { + if (array.length == 0) { + return 0; + } + + uint256 low = 0; + uint256 high = array.length; + + while (low < high) { + uint256 mid = Math.average(low, high); + + // Note that mid will always be strictly less than high (i.e. it will be a valid array index) + // because Math.average rounds down (it does integer division with truncation). + if (array[mid] > element) { + high = mid; + } else { + low = mid + 1; + } + } + + // At this point `low` is the exclusive upper bound. We will return the inclusive upper bound. + if (low > 0 && array[low - 1] == element) { + return low - 1; + } else { + return low; + } + } +} diff --git a/contracts/utils/ReentrancyGuard.sol b/contracts/utils/ReentrancyGuard.sol index 1e8196b26..9045a2571 100644 --- a/contracts/utils/ReentrancyGuard.sol +++ b/contracts/utils/ReentrancyGuard.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.24; +pragma solidity ^0.5.0; import "zos-lib/contracts/Initializable.sol"; @@ -9,21 +9,21 @@ import "zos-lib/contracts/Initializable.sol"; * mark it `external`. */ contract ReentrancyGuard is Initializable { - /// @dev counter to allow mutex lock with only one SSTORE operation uint256 private _guardCounter; function initialize() public initializer { + // The counter starts at one to prevent changing it from zero to a non-zero + // value, which is a more expensive operation. _guardCounter = 1; } /** * @dev Prevents a contract from calling itself, directly or indirectly. - * If you mark a function `nonReentrant`, you should also - * mark it `external`. Calling one `nonReentrant` function from - * another is not supported. Instead, you can implement a - * `private` function doing the actual work, and an `external` - * wrapper marked as `nonReentrant`. + * Calling a `nonReentrant` function from another `nonReentrant` + * function is not supported. It is possible to prevent this from happening + * by making the `nonReentrant` function external, and make it call a + * `private` function that does the actual work. */ modifier nonReentrant() { _guardCounter += 1; diff --git a/ethpm.json b/ethpm.json index ced48af3d..03149be3d 100644 --- a/ethpm.json +++ b/ethpm.json @@ -1,6 +1,6 @@ { "package_name": "zeppelin", - "version": "2.0.0-rc.3", + "version": "2.1.1", "description": "Secure Smart Contract library for Solidity", "authors": [ "OpenZeppelin Community " diff --git a/package-lock.json b/package-lock.json index a1bd45763..05aa559c4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,14 +1,70 @@ { "name": "openzeppelin-eth", - "version": "2.0.2", + "version": "2.1.1", "lockfileVersion": 1, "requires": true, "dependencies": { + "@babel/code-frame": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", + "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/highlight": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", + "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "@mrmlnc/readdir-enhanced": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", - "dev": true, "requires": { "call-me-maybe": "^1.0.1", "glob-to-regexp": "^0.3.0" @@ -17,8 +73,7 @@ "@nodelib/fs.stat": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.0.tgz", - "integrity": "sha512-LAQ1d4OPfSJ/BMbI2DuizmYrrkD9JMaTdi2hQTlI53lQ4kRQPyZQRS4CYQ7O66bnBBnP/oYdRxbk++X0xuFU6A==", - "dev": true + "integrity": "sha512-LAQ1d4OPfSJ/BMbI2DuizmYrrkD9JMaTdi2hQTlI53lQ4kRQPyZQRS4CYQ7O66bnBBnP/oYdRxbk++X0xuFU6A==" }, "@samverschueren/stream-to-observable": { "version": "0.3.0", @@ -110,7 +165,6 @@ "version": "1.3.5", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", - "dev": true, "requires": { "mime-types": "~2.1.18", "negotiator": "0.6.1" @@ -119,14 +173,12 @@ "mime-db": { "version": "1.33.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", - "dev": true + "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==" }, "mime-types": { "version": "2.1.18", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", - "dev": true, "requires": { "mime-db": "~1.33.0" } @@ -176,22 +228,21 @@ } }, "adm-zip": { - "version": "0.4.11", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.11.tgz", - "integrity": "sha512-L8vcjDTCOIJk7wFvmlEUN7AsSb8T+2JrdP7KINBjzr24TJ5Mwj590sLu3BC7zNZowvJWa/JtPmD8eJCzdtDWjA==", + "version": "0.4.13", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.13.tgz", + "integrity": "sha512-fERNJX8sOXfel6qCBCMPvZLzENBEhZTzKqg6vrOW5pvoEaQuJhRU4ndTAh6lHOxn1I6jnz2NHra56ZODM751uw==", "dev": true }, "aes-js": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-0.2.4.tgz", - "integrity": "sha1-lLiBq3FyhtAV+iGeCPtmcJ3aWj0=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", + "integrity": "sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0=", "dev": true }, "ajv": { "version": "5.5.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", - "dev": true, "requires": { "co": "^4.6.0", "fast-deep-equal": "^1.0.0", @@ -240,6 +291,18 @@ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", "dev": true }, + "antlr4": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/antlr4/-/antlr4-4.7.1.tgz", + "integrity": "sha512-haHyTW7Y9joE5MVs37P2lNYfU2RWBLfcRDD8OWldcdZm5TiCE91B5Xl1oWSwiDUSd4rlExpt2pu1fksYQjRBYQ==", + "dev": true + }, + "any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=", + "dev": true + }, "anymatch": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", @@ -251,16 +314,18 @@ } }, "aproba": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.1.2.tgz", - "integrity": "sha512-ZpYajIfO0j2cOFTO955KUMIKNmj6zhX8kVztMAxFsDaMwz+9Z9SV0uou2pC9HJqcfpffOsjnbrDMvkNy+9RXPw==", - "dev": true + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true, + "optional": true }, "are-we-there-yet": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz", - "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", "dev": true, + "optional": true, "requires": { "delegates": "^1.0.0", "readable-stream": "^2.0.6" @@ -287,26 +352,22 @@ "arr-flatten": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" }, "arr-union": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" }, "array-differ": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", - "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=", - "dev": true + "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=" }, "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", - "dev": true + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, "array-from": { "version": "2.1.1", @@ -318,7 +379,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, "requires": { "array-uniq": "^1.0.1" } @@ -326,8 +386,7 @@ "array-uniq": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" }, "array-unique": { "version": "0.2.1", @@ -338,20 +397,28 @@ "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" }, "asn1": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", - "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", - "dev": true + "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=" + }, + "asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } }, "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" }, "assertion-error": { "version": "1.1.0", @@ -362,7 +429,12 @@ "assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", "dev": true }, "async": { @@ -400,32 +472,27 @@ "async-limiter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", - "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", - "dev": true + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, "atob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.1.tgz", - "integrity": "sha1-ri1acpR38onWDdf5amMUoi3Wwio=", - "dev": true + "integrity": "sha1-ri1acpR38onWDdf5amMUoi3Wwio=" }, "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" }, "aws4": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz", - "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==", - "dev": true + "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==" }, "axios": { "version": "0.18.0", @@ -1709,14 +1776,12 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, "base": { "version": "0.11.2", "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, "requires": { "cache-base": "^1.0.1", "class-utils": "^0.3.5", @@ -1731,7 +1796,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, "requires": { "is-descriptor": "^1.0.0" } @@ -1740,7 +1804,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -1749,7 +1812,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -1758,7 +1820,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", @@ -1768,14 +1829,12 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" }, "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" } } }, @@ -1785,18 +1844,16 @@ "integrity": "sha1-eAqZyE59YAJgNhURxId2E78k9rs=", "dev": true }, - "base-x": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-1.1.0.tgz", - "integrity": "sha1-QtPXF0dPnqAiB/bRqh9CaRPut6w=", + "base64-js": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", + "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", "dev": true }, "bcrypt-pbkdf": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", - "dev": true, - "optional": true, "requires": { "tweetnacl": "^0.14.3" } @@ -1813,36 +1870,22 @@ "dev": true }, "binary-extensions": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", - "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=", + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.12.0.tgz", + "integrity": "sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg==", "dev": true }, "binaryextensions": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/binaryextensions/-/binaryextensions-2.1.1.tgz", - "integrity": "sha512-XBaoWE9RW8pPdPQNibZsW2zh8TW6gcarXp1FZPwT8Uop8ScSNldJEWf2k9l3HeTqdrEwsOsFcq74RiJECW34yA==", - "dev": true + "integrity": "sha512-XBaoWE9RW8pPdPQNibZsW2zh8TW6gcarXp1FZPwT8Uop8ScSNldJEWf2k9l3HeTqdrEwsOsFcq74RiJECW34yA==" }, "bindings": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.0.tgz", - "integrity": "sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.1.tgz", + "integrity": "sha512-i47mqjF9UbjxJhxGf+pZ6kSxrnI3wBLlnGI2ArWJ4r0VrvDS7ZYXkprq/pLaBWYq4GM0r4zdHY+NNRqEMU7uew==", "dev": true }, - "bip39": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/bip39/-/bip39-2.5.0.tgz", - "integrity": "sha512-xwIx/8JKoT2+IPJpFEfXoWdYwP7UVAoUxxLNfGCfVowaJE7yg1Y5B1BVPqlUNsBq5/nGwmFkwRJ8xDW4sX8OdA==", - "dev": true, - "requires": { - "create-hash": "^1.1.0", - "pbkdf2": "^3.0.9", - "randombytes": "^2.0.1", - "safe-buffer": "^5.0.1", - "unorm": "^1.3.3" - } - }, "bip66": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", @@ -1853,31 +1896,71 @@ } }, "bl": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.1.tgz", - "integrity": "sha1-ysMo977kVzDUBLaSID/LWQ4XLV4=", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", + "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", "dev": true, "requires": { - "readable-stream": "^2.0.5" + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + }, + "dependencies": { + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "block-stream": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", + "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", + "dev": true, + "requires": { + "inherits": "~2.0.0" } }, "bluebird": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.2.tgz", - "integrity": "sha512-dhHTWMI7kMx5whMQntl7Vr9C6BvV10lFXDAasnqnrMYhXVCzzk6IO9Fo2L75jXHT07WrOngL1WDXOp+yYS91Yg==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz", + "integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==", "dev": true }, "bn.js": { "version": "4.11.8", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" }, "body-parser": { "version": "1.18.3", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", - "dev": true, "requires": { "bytes": "3.0.0", "content-type": "~1.0.4", @@ -1895,7 +1978,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "requires": { "ms": "2.0.0" } @@ -1904,7 +1986,6 @@ "version": "0.4.23", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", - "dev": true, "requires": { "safer-buffer": ">= 2.1.2 < 3" } @@ -1912,8 +1993,7 @@ "qs": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" } } }, @@ -1927,7 +2007,6 @@ "version": "1.1.8", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", - "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1947,8 +2026,7 @@ "brorand": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" }, "browser-stdout": { "version": "1.3.0", @@ -1957,27 +2035,83 @@ "dev": true }, "browserify-aes": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.0.6.tgz", - "integrity": "sha1-Xncl297x/Vkw1OurSFZ85FHEigo=", + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", "dev": true, "requires": { - "buffer-xor": "^1.0.2", + "buffer-xor": "^1.0.3", "cipher-base": "^1.0.0", "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.0", - "inherits": "^2.0.1" + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "randombytes": "^2.0.1" } }, "browserify-sha3": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/browserify-sha3/-/browserify-sha3-0.0.1.tgz", "integrity": "sha1-P/NKMAbvFcD7NWflQbkaI0ASPRE=", - "dev": true, "requires": { "js-sha3": "^0.3.1" } }, + "browserify-sign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", + "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "dev": true, + "requires": { + "bn.js": "^4.1.1", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.2", + "elliptic": "^6.0.0", + "inherits": "^2.0.1", + "parse-asn1": "^5.0.0" + } + }, "browserslist": { "version": "3.2.8", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz", @@ -1988,25 +2122,44 @@ "electron-to-chromium": "^1.3.47" } }, - "bs58": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-3.1.0.tgz", - "integrity": "sha1-1MJjiL9IBMrHFBQbGUWqR+XrJI4=", + "buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", + "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", "dev": true, "requires": { - "base-x": "^1.1.0" + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" } }, - "bs58check": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-1.3.4.tgz", - "integrity": "sha1-xSVABzdJEXcU+gQsMEfrj5FRy/g=", + "buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", "dev": true, "requires": { - "bs58": "^3.1.0", - "create-hash": "^1.1.0" + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" } }, + "buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", + "dev": true + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true + }, + "buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", + "dev": true + }, "buffer-from": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz", @@ -2016,8 +2169,7 @@ "buffer-to-arraybuffer": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz", - "integrity": "sha1-YGSkD6dutDxyOrqe+PbhIW0QURo=", - "dev": true + "integrity": "sha1-YGSkD6dutDxyOrqe+PbhIW0QURo=" }, "buffer-xor": { "version": "1.0.3", @@ -2034,14 +2186,12 @@ "bytes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", - "dev": true + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" }, "cache-base": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, "requires": { "collection-visit": "^1.0.0", "component-emitter": "^1.2.1", @@ -2057,8 +2207,7 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" } } }, @@ -2088,8 +2237,7 @@ "call-me-maybe": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", - "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=", - "dev": true + "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=" }, "caller-path": { "version": "0.1.0", @@ -2113,16 +2261,15 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30000860", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000860.tgz", - "integrity": "sha512-6HCqcu+cCwWCY+WLL+rtAsAFt1ufvqMhA8dTfhMQhCJHYhJDhRRrh105DfjqRlTrDK3vvbEq8K0drNsJbymDtQ==", + "version": "1.0.30000929", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000929.tgz", + "integrity": "sha512-n2w1gPQSsYyorSVYqPMqbSaz1w7o9ZC8VhOEGI9T5MfGDzp7sbopQxG6GaQmYsaq13Xfx/mkxJUWC1Dz3oZfzw==", "dev": true }, "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, "center-align": { "version": "0.1.3", @@ -2221,10 +2368,11 @@ } }, "chownr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz", - "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=", - "dev": true + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", + "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==", + "dev": true, + "optional": true }, "cipher-base": { "version": "1.0.4", @@ -2246,7 +2394,6 @@ "version": "0.3.6", "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, "requires": { "arr-union": "^3.1.0", "define-property": "^0.2.5", @@ -2258,7 +2405,6 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, "requires": { "is-descriptor": "^0.1.0" } @@ -2266,8 +2412,7 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" } } }, @@ -2290,7 +2435,6 @@ "version": "0.3.1", "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.1.tgz", "integrity": "sha1-9TsFJmqLGguTSz0IIebi3FkUriM=", - "dev": true, "requires": { "colors": "1.0.3" }, @@ -2298,8 +2442,7 @@ "colors": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", - "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", - "dev": true + "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=" } } }, @@ -2318,6 +2461,17 @@ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", "dev": true + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } } } }, @@ -2336,19 +2490,30 @@ "string-width": "^1.0.1", "strip-ansi": "^3.0.1", "wrap-ansi": "^2.0.0" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } } }, "clone": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz", - "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=", - "dev": true + "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=" }, "clone-buffer": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", - "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=", - "dev": true + "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=" }, "clone-response": { "version": "1.0.2", @@ -2362,14 +2527,12 @@ "clone-stats": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", - "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", - "dev": true + "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=" }, "cloneable-readable": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.2.tgz", "integrity": "sha512-Bq6+4t+lbM8vhTs/Bef5c5AdEMtapp/iFb6+s4/Hh9MVTt8OLKH7ZOOZSCT+Ys7hsHvqv0GuMPJ1lnQJVHvxpg==", - "dev": true, "requires": { "inherits": "^2.0.1", "process-nextick-args": "^2.0.0", @@ -2379,14 +2542,12 @@ "process-nextick-args": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", - "dev": true + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" }, "readable-stream": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -2401,7 +2562,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, "requires": { "safe-buffer": "~5.1.0" } @@ -2411,8 +2571,7 @@ "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" }, "code-point-at": { "version": "1.1.0", @@ -2420,29 +2579,10 @@ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "dev": true }, - "coinstring": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/coinstring/-/coinstring-2.3.0.tgz", - "integrity": "sha1-zbYzY6lhUCQEolr7gsLibV/2J6Q=", - "dev": true, - "requires": { - "bs58": "^2.0.1", - "create-hash": "^1.1.1" - }, - "dependencies": { - "bs58": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-2.0.1.tgz", - "integrity": "sha1-VZCNWPGYKrogCPob7Y+RmYopv40=", - "dev": true - } - } - }, "collection-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, "requires": { "map-visit": "^1.0.0", "object-visit": "^1.0.0" @@ -2452,7 +2592,6 @@ "version": "1.9.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", - "dev": true, "requires": { "color-name": "^1.1.1" } @@ -2466,8 +2605,7 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "colors": { "version": "1.1.2", @@ -2479,7 +2617,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", - "dev": true, "requires": { "delayed-stream": "~1.0.0" } @@ -2493,20 +2630,17 @@ "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" }, "component-emitter": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", - "dev": true + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "concat-stream": { "version": "1.6.2", @@ -2520,6 +2654,33 @@ "typedarray": "^0.0.6" } }, + "configstore": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-4.0.0.tgz", + "integrity": "sha512-CmquAXFBocrzaSM8mtGPMM/HiWmyIpr4CcJl/rgY2uCObZ/S7cKU0silxslqJejl+t/T9HS8E0PUNQD81JGUEQ==", + "dev": true, + "requires": { + "dot-prop": "^4.1.0", + "graceful-fs": "^4.1.2", + "make-dir": "^1.0.0", + "unique-string": "^1.0.0", + "write-file-atomic": "^2.0.0", + "xdg-basedir": "^3.0.0" + }, + "dependencies": { + "write-file-atomic": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz", + "integrity": "sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + } + } + }, "console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", @@ -2535,14 +2696,12 @@ "content-disposition": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=", - "dev": true + "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" }, "content-type": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "dev": true + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" }, "convert-source-map": { "version": "1.5.1", @@ -2553,14 +2712,12 @@ "cookie": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", - "dev": true + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" }, "cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", - "dev": true + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" }, "cookiejar": { "version": "2.1.2", @@ -2571,8 +2728,7 @@ "copy-descriptor": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" }, "core-js": { "version": "2.5.0", @@ -2583,14 +2739,12 @@ "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, "cors": { "version": "2.8.4", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.4.tgz", "integrity": "sha1-K9OB8usgECAQXNUOpZ2mMJBpRoY=", - "dev": true, "requires": { "object-assign": "^4", "vary": "^1" @@ -2652,22 +2806,33 @@ } } }, + "create-ecdh": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", + "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.0.0" + } + }, "create-hash": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz", - "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=", + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", "dev": true, "requires": { "cipher-base": "^1.0.1", "inherits": "^2.0.1", - "ripemd160": "^2.0.0", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", "sha.js": "^2.4.0" } }, "create-hmac": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz", - "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=", + "version": "1.1.7", + "resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "dev": true, "requires": { "cipher-base": "^1.0.3", @@ -2679,9 +2844,9 @@ } }, "cross-fetch": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-2.2.1.tgz", - "integrity": "sha1-lshZEE113vyWf7XbYkdOdUJrArA=", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-2.2.3.tgz", + "integrity": "sha512-PrWWNH3yL2NYIb/7WF/5vFG3DCQiXDOVf8k3ijatbrtnwNuhMWLC7YF7uqf53tbTFDzHIUD8oITw4Bxt8ST3Nw==", "dev": true, "requires": { "node-fetch": "2.1.2", @@ -2711,12 +2876,37 @@ } } }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, "crypto-js": { "version": "3.1.8", "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.1.8.tgz", "integrity": "sha1-cV8HC/YBTyrpkqmLOSkli3E/CNU=", "dev": true }, + "crypto-random-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", + "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", + "dev": true + }, "css-select": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", @@ -2754,14 +2944,12 @@ "dargs": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/dargs/-/dargs-5.1.0.tgz", - "integrity": "sha1-7H6lDHhWTNNsnV7Bj2Yyn63ieCk=", - "dev": true + "integrity": "sha1-7H6lDHhWTNNsnV7Bj2Yyn63ieCk=" }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, "requires": { "assert-plus": "^1.0.0" } @@ -2775,8 +2963,7 @@ "dateformat": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", - "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", - "dev": true + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==" }, "death": { "version": "1.1.0", @@ -2788,7 +2975,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "requires": { "ms": "2.0.0" } @@ -2796,24 +2982,124 @@ "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" }, "decode-uri-component": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" + }, + "decompress": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.0.tgz", + "integrity": "sha1-eu3YVCflqS2s/lVnSnxQXpbQH50=", + "dev": true, + "requires": { + "decompress-tar": "^4.0.0", + "decompress-tarbz2": "^4.0.0", + "decompress-targz": "^4.0.0", + "decompress-unzip": "^4.0.1", + "graceful-fs": "^4.1.10", + "make-dir": "^1.0.0", + "pify": "^2.3.0", + "strip-dirs": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } }, "decompress-response": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "dev": true, "requires": { "mimic-response": "^1.0.0" } }, + "decompress-tar": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", + "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", + "dev": true, + "requires": { + "file-type": "^5.2.0", + "is-stream": "^1.1.0", + "tar-stream": "^1.5.2" + } + }, + "decompress-tarbz2": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", + "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", + "dev": true, + "requires": { + "decompress-tar": "^4.1.0", + "file-type": "^6.1.0", + "is-stream": "^1.1.0", + "seek-bzip": "^1.0.5", + "unbzip2-stream": "^1.0.9" + }, + "dependencies": { + "file-type": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz", + "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==", + "dev": true + } + } + }, + "decompress-targz": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", + "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", + "dev": true, + "requires": { + "decompress-tar": "^4.1.1", + "file-type": "^5.2.0", + "is-stream": "^1.1.0" + } + }, + "decompress-unzip": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", + "integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=", + "dev": true, + "requires": { + "file-type": "^3.8.0", + "get-stream": "^2.2.0", + "pify": "^2.3.0", + "yauzl": "^2.4.2" + }, + "dependencies": { + "file-type": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", + "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=", + "dev": true + }, + "get-stream": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", + "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", + "dev": true, + "requires": { + "object-assign": "^4.0.1", + "pinkie-promise": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, "deep-eql": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", @@ -2829,12 +3115,34 @@ "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", "dev": true }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, + "defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "dev": true, + "requires": { + "clone": "^1.0.2" + }, + "dependencies": { + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true + } + } + }, "deferred-leveldown": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz", @@ -2845,20 +3153,18 @@ } }, "define-properties": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", - "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", "dev": true, "requires": { - "foreach": "^2.0.5", - "object-keys": "^1.0.8" + "object-keys": "^1.0.12" } }, "define-property": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, "requires": { "is-descriptor": "^1.0.2", "isobject": "^3.0.1" @@ -2868,7 +3174,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -2877,7 +3182,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -2886,7 +3190,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", @@ -2896,14 +3199,12 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" }, "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" } } }, @@ -2926,37 +3227,52 @@ "pify": "^2.0.0", "pinkie-promise": "^2.0.0", "rimraf": "^2.2.8" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } } }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, "delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true + "dev": true, + "optional": true }, "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "dev": true + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "des.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", + "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } }, "destroy": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", - "dev": true + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, "detect-conflict": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/detect-conflict/-/detect-conflict-1.0.1.tgz", - "integrity": "sha1-CIZXpmqWHAUBnbfEIwiDsca0F24=", - "dev": true + "integrity": "sha1-CIZXpmqWHAUBnbfEIwiDsca0F24=" }, "detect-indent": { "version": "4.0.0", @@ -2967,17 +3283,33 @@ "repeating": "^2.0.0" } }, + "detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", + "dev": true, + "optional": true + }, "diff": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", - "dev": true + "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==" + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } }, "dir-glob": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.0.0.tgz", "integrity": "sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag==", - "dev": true, "requires": { "arrify": "^1.0.1", "path-type": "^3.0.0" @@ -2987,7 +3319,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, "requires": { "pify": "^3.0.0" } @@ -2995,8 +3326,7 @@ "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" } } }, @@ -3030,13 +3360,12 @@ "dom-walk": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz", - "integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg=", - "dev": true + "integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg=" }, "domelementtype": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz", - "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", "dev": true }, "domhandler": { @@ -3058,11 +3387,14 @@ "domelementtype": "1" } }, - "dotenv": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-4.0.0.tgz", - "integrity": "sha1-hk7xN5rO1Vzm+V3r7NzhefegzR0=", - "dev": true + "dot-prop": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", + "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", + "dev": true, + "requires": { + "is-obj": "^1.0.0" + } }, "drbg.js": { "version": "1.0.1", @@ -3078,8 +3410,7 @@ "duplexer3": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", - "dev": true + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" }, "easy-stack": { "version": "1.0.0", @@ -3091,8 +3422,6 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", - "dev": true, - "optional": true, "requires": { "jsbn": "~0.1.0" } @@ -3100,19 +3429,22 @@ "editions": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/editions/-/editions-1.3.4.tgz", - "integrity": "sha512-gzao+mxnYDzIysXKMQi/+M1mjy/rjestjg6OPoYTtI+3Izp23oiGZitsl9lPDPiTGXbcSIk1iJWhliSaglxnUg==", - "dev": true + "integrity": "sha512-gzao+mxnYDzIysXKMQi/+M1mjy/rjestjg6OPoYTtI+3Izp23oiGZitsl9lPDPiTGXbcSIk1iJWhliSaglxnUg==" }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "ejs": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.6.1.tgz", + "integrity": "sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ==" }, "electron-to-chromium": { - "version": "1.3.50", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.50.tgz", - "integrity": "sha1-dDi3b5K0G5GfP73TUPvQdX2s3fc=", + "version": "1.3.103", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.103.tgz", + "integrity": "sha512-tObPqGmY9X8MUM8i3MEimYmbnLLf05/QV5gPlkR8MQ3Uj8G8B2govE1U4cQcBYtv3ymck9Y8cIOu4waoiykMZQ==", "dev": true }, "elegant-spinner": { @@ -3125,7 +3457,6 @@ "version": "6.4.0", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", - "dev": true, "requires": { "bn.js": "^4.4.0", "brorand": "^1.0.1", @@ -3136,6 +3467,13 @@ "minimalistic-crypto-utils": "^1.0.0" } }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true, + "optional": true + }, "emojis-list": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", @@ -3145,8 +3483,7 @@ "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "dev": true + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" }, "encoding": { "version": "0.1.12", @@ -3158,9 +3495,9 @@ } }, "end-of-stream": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.0.tgz", - "integrity": "sha1-epDYM+/abPpurA9JSduw+tOmMgY=", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", "dev": true, "requires": { "once": "^1.4.0" @@ -3178,15 +3515,9 @@ } }, "entities": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", - "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=", - "dev": true - }, - "eol": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/eol/-/eol-0.9.1.tgz", - "integrity": "sha512-Ds/TEoZjwggRoz/Q2O7SE3i4Jm66mqTDfmdHdq/7DKVk3bro9Q8h6WdXKdPqFLMoqxrDK5SVRzHVPOS6uuGtrg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", "dev": true }, "errno": { @@ -3210,7 +3541,6 @@ "version": "7.0.2", "resolved": "https://registry.npmjs.org/error/-/error-7.0.2.tgz", "integrity": "sha1-pfdf/02ZJhJt2sDqXcOOaJFTywI=", - "dev": true, "requires": { "string-template": "~0.2.1", "xtend": "~4.0.0" @@ -3220,22 +3550,22 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", - "dev": true, "requires": { "is-arrayish": "^0.2.1" } }, "es-abstract": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", - "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", + "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", "dev": true, "requires": { - "es-to-primitive": "^1.1.1", + "es-to-primitive": "^1.2.0", "function-bind": "^1.1.1", - "has": "^1.0.1", - "is-callable": "^1.1.3", - "is-regex": "^1.0.4" + "has": "^1.0.3", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-keys": "^1.0.12" }, "dependencies": { "function-bind": { @@ -3243,31 +3573,38 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } } } }, "es-to-primitive": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", - "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", + "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", "dev": true, "requires": { - "is-callable": "^1.1.1", + "is-callable": "^1.1.4", "is-date-object": "^1.0.1", - "is-symbol": "^1.0.1" + "is-symbol": "^1.0.2" } }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "escodegen": { "version": "1.8.1", @@ -3569,6 +3906,14 @@ "parse-json": "^2.2.0", "pify": "^2.0.0", "strip-bom": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } } }, "path-type": { @@ -3578,6 +3923,14 @@ "dev": true, "requires": { "pify": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } } }, "read-pkg": { @@ -3618,6 +3971,15 @@ } } }, + "eslint-plugin-mocha-no-only": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-mocha-no-only/-/eslint-plugin-mocha-no-only-1.1.0.tgz", + "integrity": "sha512-YdeWE2KpZxsRs72SFfQobvf9G5Cv25sTbely9AEdn7trstDlhcgCyWl6wH/wYf2a0tJ6At5/BOJO/+9C6QYbVQ==", + "dev": true, + "requires": { + "requireindex": "~1.1.0" + } + }, "eslint-plugin-node": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-5.2.1.tgz", @@ -3660,6 +4022,12 @@ "estraverse": "^4.1.1" } }, + "eslint-utils": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz", + "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==", + "dev": true + }, "eslint-visitor-keys": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", @@ -3682,6 +4050,25 @@ "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", "dev": true }, + "esprima-extract-comments": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/esprima-extract-comments/-/esprima-extract-comments-1.1.0.tgz", + "integrity": "sha512-sBQUnvJwpeE9QnPrxh7dpI/dp67erYG4WXEAreAMoelPRpMR7NWb4YtwRPn9b+H1uLQKl/qS8WYmyaljTpjIsw==", + "dev": true, + "optional": true, + "requires": { + "esprima": "^4.0.0" + }, + "dependencies": { + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "optional": true + } + } + }, "esquery": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", @@ -3715,8 +4102,7 @@ "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "dev": true + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" }, "eth-block-tracker": { "version": "3.0.1", @@ -3731,6 +4117,47 @@ "json-rpc-engine": "^3.6.0", "pify": "^2.3.0", "tape": "^4.6.3" + }, + "dependencies": { + "ethereumjs-util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz", + "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", + "dev": true, + "requires": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "ethjs-util": "^0.1.3", + "keccak": "^1.0.2", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1", + "secp256k1": "^3.0.1" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "eth-ens-namehash": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz", + "integrity": "sha1-IprEbsqG1S4MmR58sq74P/D2i88=", + "dev": true, + "requires": { + "idna-uts46-hx": "^2.3.1", + "js-sha3": "^0.5.7" + }, + "dependencies": { + "js-sha3": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", + "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=", + "dev": true + } } }, "eth-json-rpc-infura": { @@ -3775,6 +4202,21 @@ "requires": { "lodash": "^4.17.10" } + }, + "ethereumjs-util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz", + "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", + "dev": true, + "requires": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "ethjs-util": "^0.1.3", + "keccak": "^1.0.2", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1", + "secp256k1": "^3.0.1" + } } } }, @@ -3782,7 +4224,6 @@ "version": "0.1.27", "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.27.tgz", "integrity": "sha512-B8czsfkJYzn2UIEMwjc7Mbj+Cy72V+/OXH/tb44LV8jhrjizQJJ325xMOMyk3+ETa6r6oi0jsUY14+om8mQMWA==", - "dev": true, "requires": { "bn.js": "^4.11.6", "elliptic": "^6.4.0", @@ -3809,17 +4250,23 @@ "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", "dev": true, "requires": { - "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#00ba8463a7f7a67fcad737ff9c2ebd95643427f7", + "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", "ethereumjs-util": "^5.1.1" }, "dependencies": { - "ethereumjs-abi": { - "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#00ba8463a7f7a67fcad737ff9c2ebd95643427f7", - "from": "ethereumjs-abi@git+https://github.com/ethereumjs/ethereumjs-abi.git#00ba8463a7f7a67fcad737ff9c2ebd95643427f7", + "ethereumjs-util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz", + "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", "dev": true, "requires": { - "bn.js": "^4.10.0", - "ethereumjs-util": "^5.0.0" + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "ethjs-util": "^0.1.3", + "keccak": "^1.0.2", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1", + "secp256k1": "^3.0.1" } } } @@ -3872,7 +4319,7 @@ "dependencies": { "async-eventemitter": { "version": "github:ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c", - "from": "async-eventemitter@github:ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c", + "from": "github:ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c", "dev": true, "requires": { "async": "^2.4.0" @@ -3886,6 +4333,21 @@ "integrity": "sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA==", "dev": true }, + "ethereumjs-util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz", + "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", + "dev": true, + "requires": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "ethjs-util": "^0.1.3", + "keccak": "^1.0.2", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1", + "secp256k1": "^3.0.1" + } + }, "ethereumjs-vm": { "version": "2.3.4", "resolved": "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-2.3.4.tgz", @@ -3905,6 +4367,12 @@ "safe-buffer": "^5.1.1" } }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, "web3-provider-engine": { "version": "13.8.0", "resolved": "https://registry.npmjs.org/web3-provider-engine/-/web3-provider-engine-13.8.0.tgz", @@ -3941,25 +4409,26 @@ "dev": true }, "ethereumjs-abi": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.5.tgz", - "integrity": "sha1-WmN+8Wq0NHP6cqKa2QhxQFs/UkE=", + "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", + "from": "ethereumjs-abi@git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", "dev": true, "requires": { "bn.js": "^4.10.0", - "ethereumjs-util": "^4.3.0" + "ethereumjs-util": "^5.0.0" }, "dependencies": { "ethereumjs-util": { - "version": "4.5.0", - "resolved": "http://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-4.5.0.tgz", - "integrity": "sha1-PpQosxfuvaPXJg2FT93alUsfG8Y=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz", + "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", "dev": true, "requires": { - "bn.js": "^4.8.0", + "bn.js": "^4.11.0", "create-hash": "^1.1.2", - "keccakjs": "^0.2.0", + "ethjs-util": "^0.1.3", + "keccak": "^1.0.2", "rlp": "^2.0.0", + "safe-buffer": "^5.1.1", "secp256k1": "^3.0.1" } } @@ -3974,6 +4443,23 @@ "ethereumjs-util": "^5.0.0", "rlp": "^2.0.0", "safe-buffer": "^5.1.1" + }, + "dependencies": { + "ethereumjs-util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz", + "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", + "dev": true, + "requires": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "ethjs-util": "^0.1.3", + "keccak": "^1.0.2", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1", + "secp256k1": "^3.0.1" + } + } } }, "ethereumjs-block": { @@ -4003,9 +4489,30 @@ "resolved": "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.2.0.tgz", "integrity": "sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA==", "dev": true + }, + "ethereumjs-util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz", + "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", + "dev": true, + "requires": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "ethjs-util": "^0.1.3", + "keccak": "^1.0.2", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1", + "secp256k1": "^3.0.1" + } } } }, + "ethereumjs-common": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/ethereumjs-common/-/ethereumjs-common-0.6.1.tgz", + "integrity": "sha512-4jOrfDu9qOBTTGGb3zrfT1tE1Hyc6a8LJpEk0Vk9AYlLkBY7crjVICyJpRvjNI+KLDMpMITMw3eWVZOLMtZdhw==", + "dev": true + }, "ethereumjs-testrpc-sc": { "version": "6.1.2", "resolved": "https://registry.npmjs.org/ethereumjs-testrpc-sc/-/ethereumjs-testrpc-sc-6.1.2.tgz", @@ -4035,24 +4542,41 @@ } }, "ethereumjs-tx": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.3.5.tgz", - "integrity": "sha512-cPr0BxitCaffq0qQwZRHJgiNCM/3IIJqkYbweeUCyPwV77S+GlQHou2L3afKEFtfiAjfaa82T9LnSmY/pM8iYQ==", + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz", + "integrity": "sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA==", "dev": true, "requires": { "ethereum-common": "^0.0.18", "ethereumjs-util": "^5.0.0" + }, + "dependencies": { + "ethereumjs-util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz", + "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", + "dev": true, + "requires": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "ethjs-util": "^0.1.3", + "keccak": "^1.0.2", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1", + "secp256k1": "^3.0.1" + } + } } }, "ethereumjs-util": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz", - "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.0.0.tgz", + "integrity": "sha512-E3yKUyl0Fs95nvTFQZe/ZSNcofhDzUsDlA5y2uoRmf1+Ec7gpGhNCsgKkZBRh7Br5op8mJcYF/jFbmjj909+nQ==", "dev": true, "requires": { "bn.js": "^4.11.0", "create-hash": "^1.1.2", - "ethjs-util": "^0.1.3", + "ethjs-util": "^0.1.6", "keccak": "^1.0.2", "rlp": "^2.0.0", "safe-buffer": "^5.1.1", @@ -4060,21 +4584,21 @@ } }, "ethereumjs-vm": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-2.3.5.tgz", - "integrity": "sha512-AJ7x44+xqyE5+UO3Nns19WkTdZfyqFZ+sEjIEpvme7Ipbe3iBU1uwCcHEdiu/yY9bdhr3IfSa/NfIKNeXPaRVQ==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-2.5.1.tgz", + "integrity": "sha512-YLxPfJLHIS6caKJb2WEY+atN8N9DsXzixZfZORCKQBx6nEe1ar6rQBHBNQBBhM7Vbk/bFCOYZpU5gHShvXN1Vw==", "dev": true, "requires": { "async": "^2.1.2", "async-eventemitter": "^0.2.2", - "ethereum-common": "0.2.0", "ethereumjs-account": "^2.0.3", - "ethereumjs-block": "~1.7.0", - "ethereumjs-util": "^5.1.3", + "ethereumjs-block": "~2.1.0", + "ethereumjs-common": "^0.6.0", + "ethereumjs-util": "^6.0.0", "fake-merkle-patricia-tree": "^1.0.1", "functional-red-black-tree": "^1.0.1", - "merkle-patricia-tree": "^2.1.2", - "rustbn.js": "~0.1.1", + "merkle-patricia-tree": "^2.3.2", + "rustbn.js": "~0.2.0", "safe-buffer": "^5.1.1" }, "dependencies": { @@ -4087,46 +4611,40 @@ "lodash": "^4.17.10" } }, - "ethereum-common": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.2.0.tgz", - "integrity": "sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA==", - "dev": true - } - } - }, - "ethereumjs-wallet": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/ethereumjs-wallet/-/ethereumjs-wallet-0.6.0.tgz", - "integrity": "sha1-gnY7Fpfuenlr5xVdqd+0my+Yz9s=", - "dev": true, - "requires": { - "aes-js": "^0.2.3", - "bs58check": "^1.0.8", - "ethereumjs-util": "^4.4.0", - "hdkey": "^0.7.0", - "scrypt.js": "^0.2.0", - "utf8": "^2.1.1", - "uuid": "^2.0.1" - }, - "dependencies": { - "ethereumjs-util": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-4.5.0.tgz", - "integrity": "sha1-PpQosxfuvaPXJg2FT93alUsfG8Y=", + "ethereumjs-block": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-2.1.0.tgz", + "integrity": "sha512-ip+x4/7hUInX+TQfhEKsQh9MJK1Dbjp4AuPjf1UdX3udAV4beYD4EMCNIPzBLCsGS8WQZYXLpo83tVTISYNpow==", "dev": true, "requires": { - "bn.js": "^4.8.0", - "create-hash": "^1.1.2", - "keccakjs": "^0.2.0", - "rlp": "^2.0.0", - "secp256k1": "^3.0.1" + "async": "^2.0.1", + "ethereumjs-common": "^0.6.0", + "ethereumjs-tx": "^1.2.2", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" + }, + "dependencies": { + "ethereumjs-util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz", + "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", + "dev": true, + "requires": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "ethjs-util": "^0.1.3", + "keccak": "^1.0.2", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1", + "secp256k1": "^3.0.1" + } + } } }, - "uuid": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", - "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=", + "rustbn.js": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz", + "integrity": "sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==", "dev": true } } @@ -4149,12 +4667,6 @@ "xmlhttprequest": "1.8.0" }, "dependencies": { - "aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0=", - "dev": true - }, "elliptic": { "version": "6.3.3", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.3.3.tgz", @@ -4175,7 +4687,7 @@ }, "uuid": { "version": "2.0.1", - "resolved": "http://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=", "dev": true } @@ -4210,7 +4722,6 @@ "version": "0.1.6", "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", "integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=", - "dev": true, "requires": { "bn.js": "4.11.6", "number-to-bn": "1.7.0" @@ -4219,15 +4730,14 @@ "bn.js": { "version": "4.11.6", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", - "dev": true + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" } } }, "ethjs-util": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.4.tgz", - "integrity": "sha1-HItoeSV0RO9NPz+7rC3tEs2ZfZM=", + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", + "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", "dev": true, "requires": { "is-hex-prefixed": "1.0.0", @@ -4309,8 +4819,7 @@ "dependencies": { "bignumber.js": { "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", - "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git", - "dev": true + "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git" }, "bn.js": { "version": "4.11.6", @@ -4358,6 +4867,10 @@ "truffle-contract-schema": "^0.0.5" }, "dependencies": { + "bignumber.js": { + "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", + "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934" + }, "fs-extra": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", @@ -4387,7 +4900,6 @@ "integrity": "sha512-VU6/DSUX93d1fCzBz7WP/SGCQizO1rKZi4Px9j/3yRyfssHyFcZamMw2/sj4E8TlfMXONvZLoforR8B4bRoyTQ==", "dev": true, "requires": { - "bignumber.js": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", "crypto-js": "^3.1.4", "utf8": "^2.1.1", "xhr2-cookies": "^1.1.0", @@ -4439,11 +4951,10 @@ }, "web3": { "version": "0.16.0", - "resolved": "http://registry.npmjs.org/web3/-/web3-0.16.0.tgz", + "resolved": "https://registry.npmjs.org/web3/-/web3-0.16.0.tgz", "integrity": "sha1-pFVBdc1GKUMDWx8dOUMvdBxrYBk=", "dev": true, "requires": { - "bignumber.js": "git+https://github.com/debris/bignumber.js.git#c7a38de919ed75e6fb6ba38051986e294b328df9", "crypto-js": "^3.1.4", "utf8": "^2.1.1", "xmlhttprequest": "*" @@ -4451,8 +4962,7 @@ "dependencies": { "bignumber.js": { "version": "git+https://github.com/debris/bignumber.js.git#c7a38de919ed75e6fb6ba38051986e294b328df9", - "from": "git+https://github.com/debris/bignumber.js.git#master", - "dev": true + "from": "git+https://github.com/debris/bignumber.js.git#c7a38de919ed75e6fb6ba38051986e294b328df9" } } } @@ -4475,13 +4985,26 @@ "integrity": "sha512-z7IyloorXvKbFx9Bpie2+vMJKKx1fH1EN5yiTfp8CiLOTptSYy1g8H4yDpGlEdshL1PBiFtBHepF2cNsqeEeFQ==", "dev": true }, + "eventemitter3": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.1.1.tgz", + "integrity": "sha1-R3hr2qCHyvext15zq8XH1UAVjNA=", + "dev": true + }, + "events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz", + "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==", + "dev": true + }, "evp_bytestokey": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.0.tgz", - "integrity": "sha1-SXtmrZ/vZc18CKYYCCS6FHa2blM=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", "dev": true, "requires": { - "create-hash": "^1.1.1" + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" } }, "execa": { @@ -4523,12 +5046,6 @@ "fill-range": "^2.1.0" } }, - "expand-template": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-1.0.3.tgz", - "integrity": "sha1-bDAzIxd6YrGyLAcCefeGEoe2mxo=", - "dev": true - }, "expand-tilde": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", @@ -4542,7 +5059,6 @@ "version": "4.16.3", "resolved": "https://registry.npmjs.org/express/-/express-4.16.3.tgz", "integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=", - "dev": true, "requires": { "accepts": "~1.3.5", "array-flatten": "1.1.1", @@ -4580,7 +5096,6 @@ "version": "1.18.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", - "dev": true, "requires": { "bytes": "3.0.0", "content-type": "~1.0.4", @@ -4598,7 +5113,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "requires": { "ms": "2.0.0" } @@ -4606,20 +5120,17 @@ "iconv-lite": { "version": "0.4.19", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", - "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", - "dev": true + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" }, "qs": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", - "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", - "dev": true + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" }, "raw-body": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", - "dev": true, "requires": { "bytes": "3.0.0", "http-errors": "1.6.2", @@ -4630,14 +5141,12 @@ "depd": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", - "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=", - "dev": true + "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=" }, "http-errors": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", - "dev": true, "requires": { "depd": "1.1.1", "inherits": "2.0.3", @@ -4648,30 +5157,26 @@ "setprototypeof": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", - "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=", - "dev": true + "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" } } }, "statuses": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", - "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", - "dev": true + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" } } }, "extend": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", - "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", - "dev": true + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=" }, "extend-shallow": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, "requires": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" @@ -4681,7 +5186,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, "requires": { "is-plain-object": "^2.0.4" } @@ -4708,11 +5212,21 @@ "is-extglob": "^1.0.0" } }, + "extract-comments": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/extract-comments/-/extract-comments-1.1.0.tgz", + "integrity": "sha512-dzbZV2AdSSVW/4E7Ti5hZdHWbA+Z80RJsJhr5uiL10oyjl/gy7/o+HI1HwK4/WSZhlq4SNKU3oUzXlM13Qx02Q==", + "dev": true, + "optional": true, + "requires": { + "esprima-extract-comments": "^1.1.0", + "parse-code-context": "^1.0.0" + } + }, "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" }, "fake-merkle-patricia-tree": { "version": "1.0.1", @@ -4726,14 +5240,18 @@ "fast-deep-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", - "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=", + "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=" + }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", "dev": true }, "fast-glob": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.2.tgz", "integrity": "sha512-TR6zxCKftDQnUAPvkrCWdBgDq/gbqx8A3ApnBrR5rMvpp6+KMJI0Igw7fkWPgeVK0uhRXTXdvO3O+YP0CaUX2g==", - "dev": true, "requires": { "@mrmlnc/readdir-enhanced": "^2.2.1", "@nodelib/fs.stat": "^1.0.1", @@ -4746,20 +5264,17 @@ "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" }, "array-unique": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" }, "braces": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, "requires": { "arr-flatten": "^1.1.0", "array-unique": "^0.3.2", @@ -4777,7 +5292,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, "requires": { "is-extendable": "^0.1.0" } @@ -4788,7 +5302,6 @@ "version": "2.1.4", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, "requires": { "debug": "^2.3.3", "define-property": "^0.2.5", @@ -4803,7 +5316,6 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, "requires": { "is-descriptor": "^0.1.0" } @@ -4812,7 +5324,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, "requires": { "is-extendable": "^0.1.0" } @@ -4821,7 +5332,6 @@ "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, "requires": { "kind-of": "^3.0.2" }, @@ -4830,7 +5340,6 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, "requires": { "is-buffer": "^1.1.5" } @@ -4841,7 +5350,6 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, "requires": { "kind-of": "^3.0.2" }, @@ -4850,7 +5358,6 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, "requires": { "is-buffer": "^1.1.5" } @@ -4861,7 +5368,6 @@ "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, "requires": { "is-accessor-descriptor": "^0.1.6", "is-data-descriptor": "^0.1.4", @@ -4871,8 +5377,7 @@ "kind-of": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" } } }, @@ -4880,7 +5385,6 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, "requires": { "array-unique": "^0.3.2", "define-property": "^1.0.0", @@ -4896,7 +5400,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, "requires": { "is-descriptor": "^1.0.0" } @@ -4905,7 +5408,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, "requires": { "is-extendable": "^0.1.0" } @@ -4916,7 +5418,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, "requires": { "extend-shallow": "^2.0.1", "is-number": "^3.0.0", @@ -4928,7 +5429,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, "requires": { "is-extendable": "^0.1.0" } @@ -4939,7 +5439,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, "requires": { "is-glob": "^3.1.0", "path-dirname": "^1.0.0" @@ -4949,7 +5448,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, "requires": { "is-extglob": "^2.1.0" } @@ -4960,7 +5458,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -4969,7 +5466,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -4978,7 +5474,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", @@ -4988,14 +5483,12 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" }, "is-glob": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", - "dev": true, "requires": { "is-extglob": "^2.1.1" } @@ -5004,7 +5497,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, "requires": { "kind-of": "^3.0.2" }, @@ -5013,7 +5505,6 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, "requires": { "is-buffer": "^1.1.5" } @@ -5023,20 +5514,17 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" }, "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" }, "micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, "requires": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", @@ -5058,8 +5546,7 @@ "fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", - "dev": true + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" }, "fast-levenshtein": { "version": "2.0.6", @@ -5067,6 +5554,15 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, "fetch-ponyfill": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/fetch-ponyfill/-/fetch-ponyfill-4.1.0.tgz", @@ -5107,6 +5603,12 @@ "object-assign": "^4.0.1" } }, + "file-type": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", + "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=", + "dev": true + }, "filename-regex": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", @@ -5157,7 +5659,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", - "dev": true, "requires": { "debug": "2.6.9", "encodeurl": "~1.0.2", @@ -5172,7 +5673,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "requires": { "ms": "2.0.0" } @@ -5180,8 +5680,7 @@ "statuses": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", - "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", - "dev": true + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" } } }, @@ -5199,7 +5698,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-2.0.0.tgz", "integrity": "sha1-G97NuOCDwGZLkZRVgVd6Q6nzHXA=", - "dev": true, "requires": { "readable-stream": "^2.0.2" } @@ -5246,7 +5744,6 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.2.tgz", "integrity": "sha1-LEBFC5NI6X8oEyJZO6lnBLmr1NQ=", - "dev": true, "requires": { "is-function": "~1.0.0" } @@ -5254,8 +5751,7 @@ "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" }, "for-own": { "version": "0.1.5", @@ -5275,14 +5771,12 @@ "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" }, "form-data": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", - "dev": true, "requires": { "asynckit": "^0.4.0", "combined-stream": "1.0.6", @@ -5292,14 +5786,12 @@ "forwarded": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", - "dev": true + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" }, "fragment-cache": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, "requires": { "map-cache": "^0.2.2" } @@ -5307,8 +5799,7 @@ "fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "dev": true + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" }, "from2": { "version": "2.3.0", @@ -5320,6 +5811,12 @@ "readable-stream": "^2.0.0" } }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, "fs-extra": { "version": "0.30.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", @@ -5333,6 +5830,40 @@ "rimraf": "^2.2.8" } }, + "fs-minipass": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz", + "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs-promise": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/fs-promise/-/fs-promise-2.0.3.tgz", + "integrity": "sha1-9k5PhUvPaJqovdy6JokW2z20aFQ=", + "dev": true, + "requires": { + "any-promise": "^1.3.0", + "fs-extra": "^2.0.0", + "mz": "^2.6.0", + "thenify-all": "^1.6.0" + }, + "dependencies": { + "fs-extra": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-2.1.2.tgz", + "integrity": "sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0" + } + } + } + }, "fs-readdir-recursive": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", @@ -5342,536 +5873,29 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "fsevents": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", - "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.6.tgz", + "integrity": "sha512-BalK54tfK0pMC0jQFb2oHn1nz7JNQD/2ex5pBnCHgBi2xG7VV0cAOGy2RS2VbCqUXx5/6obMrMcQTJ8yjcGzbg==", "dev": true, "optional": true, "requires": { "nan": "^2.9.2", "node-pre-gyp": "^0.10.0" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "debug": { - "version": "2.6.9", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "deep-extend": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.21", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safer-buffer": "^2.1.0" - } - }, - "ignore-walk": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "dev": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true - }, - "minipass": { - "version": "2.2.4", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "^5.1.1", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "needle": { - "version": "2.2.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "debug": "^2.1.2", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.10.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.0", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.1.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.1.10", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.7", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "deep-extend": "^0.5.1", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.6.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "glob": "^7.0.5" - } - }, - "safe-buffer": { - "version": "5.1.1", - "bundled": true, - "dev": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "dev": true, - "optional": true - }, - "semver": { - "version": "5.5.0", - "bundled": true, - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "tar": { - "version": "4.4.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.0.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.2.4", - "minizlib": "^1.1.0", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.1", - "yallist": "^3.0.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "wide-align": { - "version": "1.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "string-width": "^1.0.2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "yallist": { - "version": "3.0.2", - "bundled": true, - "dev": true - } + } + }, + "fstream": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", + "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" } }, "function-bind": { @@ -5887,13 +5911,12 @@ "dev": true }, "ganache-cli": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ganache-cli/-/ganache-cli-6.1.0.tgz", - "integrity": "sha512-FdTeyk4uLRHGeFiMe+Qnh4Hc5KiTVqvRVVvLDFJEVVKC1P1yHhEgZeh9sp1KhuvxSrxToxgJS25UapYQwH4zHw==", + "version": "6.1.8", + "resolved": "https://registry.npmjs.org/ganache-cli/-/ganache-cli-6.1.8.tgz", + "integrity": "sha512-yXzteu4SIgUL31mnpm9j+x6dpHUw0p/nsRVkcySKq0w+1vDxH9jMErP1QhZAJuTVE6ni4nfvGSNkaQx5cD3jfg==", "dev": true, "requires": { - "source-map-support": "^0.5.3", - "webpack-cli": "^2.0.9" + "source-map-support": "^0.5.3" }, "dependencies": { "source-map": { @@ -5903,11 +5926,12 @@ "dev": true }, "source-map-support": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.4.tgz", - "integrity": "sha512-PETSPG6BjY1AHs2t64vS2aqAgu6dMIMXJULWFBGbh2Gr8nVLbCFDo6i/RMMvviIQ2h1Z8+5gQhVKSn2je9nmdg==", + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.9.tgz", + "integrity": "sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA==", "dev": true, "requires": { + "buffer-from": "^1.0.0", "source-map": "^0.6.0" } } @@ -5918,6 +5942,7 @@ "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", "dev": true, + "optional": true, "requires": { "aproba": "^1.0.3", "console-control-strings": "^1.0.0", @@ -5927,13 +5952,26 @@ "string-width": "^1.0.1", "strip-ansi": "^3.0.1", "wide-align": "^1.1.0" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } } }, "get-caller-file": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", - "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", - "dev": true + "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=" }, "get-func-name": { "version": "2.0.0", @@ -5950,20 +5988,17 @@ "get-stream": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" }, "get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, "requires": { "assert-plus": "^1.0.0" } @@ -5972,7 +6007,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/gh-got/-/gh-got-6.0.0.tgz", "integrity": "sha512-F/mS+fsWQMo1zfgG9MD8KWvTWPPzzhuVwY++fhQ5Ggd+0P+CAMHtzMZhNxG+TqGfHDChJKsbh6otfMGqO2AKBw==", - "dev": true, "requires": { "got": "^7.0.0", "is-plain-obj": "^1.1.0" @@ -5982,7 +6016,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", - "dev": true, "requires": { "decompress-response": "^3.2.0", "duplexer3": "^0.1.4", @@ -6003,14 +6036,12 @@ "p-cancelable": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", - "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==", - "dev": true + "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==" }, "p-timeout": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=", - "dev": true, "requires": { "p-finally": "^1.0.0" } @@ -6018,14 +6049,12 @@ "prepend-http": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", - "dev": true + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" }, "url-parse-lax": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", - "dev": true, "requires": { "prepend-http": "^1.0.1" } @@ -6058,17 +6087,10 @@ } } }, - "github-from-package": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=", - "dev": true - }, "github-username": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/github-username/-/github-username-4.1.0.tgz", "integrity": "sha1-y+KABBiDIG2kISrp5LXxacML9Bc=", - "dev": true, "requires": { "gh-got": "^6.0.0" } @@ -6077,7 +6099,6 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -6136,14 +6157,12 @@ "glob-to-regexp": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", - "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=", - "dev": true + "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=" }, "global": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz", "integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=", - "dev": true, "requires": { "min-document": "^2.19.0", "process": "~0.5.1" @@ -6191,12 +6210,79 @@ "object-assign": "^4.0.1", "pify": "^2.0.0", "pinkie-promise": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "got": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", + "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", + "dev": true, + "requires": { + "decompress-response": "^3.2.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-plain-obj": "^1.1.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "isurl": "^1.0.0-alpha5", + "lowercase-keys": "^1.0.0", + "p-cancelable": "^0.3.0", + "p-timeout": "^1.1.1", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "url-parse-lax": "^1.0.0", + "url-to-options": "^1.0.1" + }, + "dependencies": { + "p-cancelable": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", + "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==", + "dev": true + }, + "p-timeout": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", + "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=", + "dev": true, + "requires": { + "p-finally": "^1.0.0" + } + }, + "prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", + "dev": true + }, + "url-parse-lax": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", + "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", + "dev": true, + "requires": { + "prepend-http": "^1.0.1" + } + } } }, "graceful-fs": { "version": "4.1.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + }, + "graceful-readlink": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", "dev": true }, "graphlib": { @@ -6212,7 +6298,6 @@ "version": "0.3.3", "resolved": "https://registry.npmjs.org/grouped-queue/-/grouped-queue-0.3.3.tgz", "integrity": "sha1-wWfSpTGcWg4JZO9qJbfC34mWyFw=", - "dev": true, "requires": { "lodash": "^4.17.2" } @@ -6249,14 +6334,12 @@ "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" }, "har-validator": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", - "dev": true, "requires": { "ajv": "^5.1.0", "har-schema": "^2.0.0" @@ -6289,20 +6372,23 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, "has-symbol-support-x": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", - "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==", + "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==" + }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", "dev": true }, "has-to-string-tag-x": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", - "dev": true, "requires": { "has-symbol-support-x": "^1.4.1" } @@ -6311,13 +6397,13 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true + "dev": true, + "optional": true }, "has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, "requires": { "get-value": "^2.0.6", "has-values": "^1.0.0", @@ -6327,8 +6413,7 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" } } }, @@ -6336,7 +6421,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, "requires": { "is-number": "^3.0.0", "kind-of": "^4.0.0" @@ -6346,7 +6430,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, "requires": { "kind-of": "^3.0.2" }, @@ -6355,7 +6438,6 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, "requires": { "is-buffer": "^1.1.5" } @@ -6366,7 +6448,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, "requires": { "is-buffer": "^1.1.5" } @@ -6374,34 +6455,24 @@ } }, "hash-base": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", - "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", "dev": true, "requires": { - "inherits": "^2.0.1" + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, "hash.js": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", - "dev": true, "requires": { "inherits": "^2.0.3", "minimalistic-assert": "^1.0.0" } }, - "hdkey": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/hdkey/-/hdkey-0.7.1.tgz", - "integrity": "sha1-yu5L6BqneSHpCbjSKN0PKayu5jI=", - "dev": true, - "requires": { - "coinstring": "^2.0.0", - "secp256k1": "^3.0.1" - } - }, "he": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", @@ -6412,7 +6483,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, "requires": { "hash.js": "^1.0.3", "minimalistic-assert": "^1.0.0", @@ -6468,7 +6538,6 @@ "version": "1.6.3", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", - "dev": true, "requires": { "depd": "~1.1.2", "inherits": "2.0.3", @@ -6476,11 +6545,16 @@ "statuses": ">= 1.4.0 < 2" } }, + "http-https": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz", + "integrity": "sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs=", + "dev": true + }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, "requires": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", @@ -6579,11 +6653,43 @@ "integrity": "sha512-sr1ZQph3UwHTR0XftSbK85OvBbxe/abLGzEnPENCQwmHf7sck8Oyu4ob3LgBxWWxRoM+QszeUyl7jbqapu2TqA==", "dev": true }, + "idna-uts46-hx": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz", + "integrity": "sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA==", + "dev": true, + "requires": { + "punycode": "2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", + "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=", + "dev": true + } + } + }, + "ieee754": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", + "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==", + "dev": true + }, "ignore": { "version": "3.3.7", "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz", - "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==", - "dev": true + "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==" + }, + "ignore-walk": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz", + "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } }, "immediate": { "version": "3.2.3", @@ -6640,7 +6746,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -6649,8 +6754,7 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, "ini": { "version": "1.3.4", @@ -6751,8 +6855,7 @@ "interpret": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.0.3.tgz", - "integrity": "sha1-y8NcYu7uc/Gat7EKgBURQBr8D5A=", - "dev": true + "integrity": "sha1-y8NcYu7uc/Gat7EKgBURQBr8D5A=" }, "into-stream": { "version": "3.1.0", @@ -6782,8 +6885,7 @@ "ipaddr.js": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.6.0.tgz", - "integrity": "sha1-4/o1e3c9phnybpXwSdBVxyeW+Gs=", - "dev": true + "integrity": "sha1-4/o1e3c9phnybpXwSdBVxyeW+Gs=" }, "ipfs-mini": { "version": "1.1.2", @@ -6798,7 +6900,6 @@ "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, "requires": { "kind-of": "^3.0.2" } @@ -6806,8 +6907,7 @@ "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" }, "is-binary-path": { "version": "1.0.1", @@ -6821,8 +6921,7 @@ "is-buffer": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", - "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=", - "dev": true + "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=" }, "is-builtin-module": { "version": "1.0.0", @@ -6834,16 +6933,15 @@ } }, "is-callable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz", - "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", "dev": true }, "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, "requires": { "kind-of": "^3.0.2" } @@ -6858,7 +6956,6 @@ "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, "requires": { "is-accessor-descriptor": "^0.1.6", "is-data-descriptor": "^0.1.4", @@ -6868,8 +6965,7 @@ "kind-of": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" } } }, @@ -6891,8 +6987,7 @@ "is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" }, "is-extglob": { "version": "1.0.0", @@ -6927,8 +7022,7 @@ "is-function": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.1.tgz", - "integrity": "sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU=", - "dev": true + "integrity": "sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU=" }, "is-glob": { "version": "2.0.1", @@ -6942,7 +7036,12 @@ "is-hex-prefixed": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", - "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=", + "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=" + }, + "is-natural-number": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", + "integrity": "sha1-q5124dtM7VHjXeDHLr7PCfc0zeg=", "dev": true }, "is-number": { @@ -6954,11 +7053,16 @@ "kind-of": "^3.0.2" } }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true + }, "is-object": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz", - "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=", - "dev": true + "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=" }, "is-path-cwd": { "version": "1.0.0", @@ -6987,14 +7091,12 @@ "is-plain-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", - "dev": true + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" }, "is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, "requires": { "isobject": "^3.0.1" }, @@ -7002,8 +7104,7 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" } } }, @@ -7022,8 +7123,7 @@ "is-promise": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", - "dev": true + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" }, "is-regex": { "version": "1.0.4", @@ -7043,14 +7143,12 @@ "is-retry-allowed": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", - "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=", - "dev": true + "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=" }, "is-scoped": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-scoped/-/is-scoped-1.0.0.tgz", "integrity": "sha1-RJypgpnnEwOCViieyytUDcQ3yzA=", - "dev": true, "requires": { "scoped-regex": "^1.0.0" } @@ -7058,44 +7156,41 @@ "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" }, "is-symbol": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", - "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", - "dev": true + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.0" + } }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, "is-utf8": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", - "dev": true + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" }, "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, "isbinaryfile": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.2.tgz", - "integrity": "sha1-Sj6XTsDLqQBNP8bN5yCeppNopiE=", - "dev": true + "integrity": "sha1-Sj6XTsDLqQBNP8bN5yCeppNopiE=" }, "isexe": { "version": "2.0.0", @@ -7115,8 +7210,7 @@ "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, "istanbul": { "version": "0.4.5", @@ -7180,7 +7274,6 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/istextorbinary/-/istextorbinary-2.2.1.tgz", "integrity": "sha512-TS+hoFl8Z5FAFMK38nhBkdLt44CclNRgDHWeMgsV8ko3nDlr/9UI2Sf839sW7enijf8oKsZYXRvM8g0it9Zmcw==", - "dev": true, "requires": { "binaryextensions": "2", "editions": "^1.3.3", @@ -7191,7 +7284,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", - "dev": true, "requires": { "has-to-string-tag-x": "^1.2.0", "is-object": "^1.0.1" @@ -7215,14 +7307,7 @@ "js-sha3": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.3.1.tgz", - "integrity": "sha1-hhIoAhQvCChQKg0d7h2V4lO7AkM=", - "dev": true - }, - "js-string-escape": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", - "integrity": "sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8=", - "dev": true + "integrity": "sha1-hhIoAhQvCChQKg0d7h2V4lO7AkM=" }, "js-tokens": { "version": "3.0.2", @@ -7249,9 +7334,7 @@ "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true, - "optional": true + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" }, "jscodeshift": { "version": "0.5.1", @@ -7369,8 +7452,7 @@ "json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" }, "json-pointer": { "version": "0.6.0", @@ -7382,17 +7464,17 @@ } }, "json-rpc-engine": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/json-rpc-engine/-/json-rpc-engine-3.7.3.tgz", - "integrity": "sha512-+FO3UWu/wafh/+MZ6BXy0HZU+f5plwUn82FgxpC0scJkEh5snOjFrAAtqCITPDfvfLHRUFOG5pQDUx2pspfERQ==", + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/json-rpc-engine/-/json-rpc-engine-3.8.0.tgz", + "integrity": "sha512-6QNcvm2gFuuK4TKU1uwfH0Qd/cOSb9c1lls0gbnIhciktIUQJwz6NQNAW4B1KiGPenv7IKu97V222Yo1bNhGuA==", "dev": true, "requires": { "async": "^2.0.1", - "babel-preset-env": "^1.3.2", + "babel-preset-env": "^1.7.0", "babelify": "^7.3.0", - "clone": "^2.1.1", "json-rpc-error": "^2.0.0", - "promise-to-callback": "^1.0.0" + "promise-to-callback": "^1.0.0", + "safe-event-emitter": "^1.0.1" }, "dependencies": { "async": { @@ -7424,8 +7506,7 @@ "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" }, "json-schema-to-markdown": { "version": "1.0.3", @@ -7436,8 +7517,7 @@ "json-schema-traverse": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", - "dev": true + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" }, "json-stable-stringify": { "version": "1.0.1", @@ -7457,8 +7537,7 @@ "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, "json5": { "version": "0.5.1", @@ -7491,7 +7570,6 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "dev": true, "requires": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", @@ -7499,22 +7577,15 @@ "verror": "1.10.0" } }, - "just-extend": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-3.0.0.tgz", - "integrity": "sha512-Fu3T6pKBuxjWT/p4DkqGHFRsysc8OauWr4ZRTY9dIx07Y9O0RkoR5jcv28aeD1vuAwhm3nLkDurwLXoALp4DpQ==", - "dev": true - }, "keccak": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-1.3.0.tgz", - "integrity": "sha512-JgsKPxYhcJxKrV+TrCyg/GwZbOjhpRPrz2kG8xbAsUaIDelUlKjm08YcwBO9Fm8sqf/Kg8ZWkk6nWujhLykfvw==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-1.4.0.tgz", + "integrity": "sha512-eZVaCpblK5formjPjeTBik7TAg+pqnDrMHIffSvi9Lh7PQgM1+hSzakUeZFCk9DVVG0dacZJuaz2ntwlzZUIBw==", "dev": true, "requires": { "bindings": "^1.2.1", "inherits": "^2.0.3", "nan": "^2.2.1", - "prebuild-install": "^2.0.0", "safe-buffer": "^5.1.0" } }, @@ -7522,7 +7593,6 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/keccakjs/-/keccakjs-0.2.1.tgz", "integrity": "sha1-HWM6+QfvMFu/ny+mFtVsRFYd+k0=", - "dev": true, "requires": { "browserify-sha3": "^0.0.1", "sha3": "^1.1.0" @@ -7541,7 +7611,6 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, "requires": { "is-buffer": "^1.1.5" } @@ -7827,6 +7896,14 @@ "pify": "^2.0.0", "pinkie-promise": "^2.0.0", "strip-bom": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } } }, "loader-utils": { @@ -7868,10 +7945,9 @@ } }, "lodash": { - "version": "4.17.10", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", - "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", - "dev": true + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" }, "lodash-es": { "version": "4.17.11", @@ -7907,7 +7983,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", - "dev": true, "requires": { "chalk": "^2.0.1" }, @@ -7916,7 +7991,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -7925,7 +7999,6 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz", "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", - "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -7935,14 +8008,12 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, "supports-color": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", - "dev": true, "requires": { "has-flag": "^3.0.0" } @@ -8016,8 +8087,7 @@ "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" }, "ltgt": { "version": "2.2.1", @@ -8029,7 +8099,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.2.0.tgz", "integrity": "sha512-aNUAa4UMg/UougV25bbrU4ZaaKNjJ/3/xnvg/twpmKROPdKZPZ9wGgI0opdZzO8q/zUFawoUuixuOv33eZ61Iw==", - "dev": true, "requires": { "pify": "^3.0.0" }, @@ -8037,22 +8106,19 @@ "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" } } }, "map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" }, "map-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, "requires": { "object-visit": "^1.0.0" } @@ -8069,11 +8135,29 @@ "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=", "dev": true }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "dev": true + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" }, "mem": { "version": "1.1.0", @@ -8088,13 +8172,73 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/mem-fs/-/mem-fs-1.1.3.tgz", "integrity": "sha1-uK6NLj/Lb10/kWXBLUVRoGXZicw=", - "dev": true, "requires": { "through2": "^2.0.0", "vinyl": "^1.1.0", "vinyl-file": "^2.0.0" } }, + "mem-fs-editor": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/mem-fs-editor/-/mem-fs-editor-4.0.3.tgz", + "integrity": "sha512-tgWmwI/+6vwu6POan82dTjxEpwAoaj0NAFnghtVo/FcLK2/7IhPUtFUUYlwou4MOY6OtjTUJtwpfH1h+eSUziw==", + "requires": { + "commondir": "^1.0.1", + "deep-extend": "^0.6.0", + "ejs": "^2.5.9", + "glob": "^7.0.3", + "globby": "^7.1.1", + "isbinaryfile": "^3.0.2", + "mkdirp": "^0.5.0", + "multimatch": "^2.0.0", + "rimraf": "^2.2.8", + "through2": "^2.0.0", + "vinyl": "^2.0.1" + }, + "dependencies": { + "clone-stats": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", + "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=" + }, + "globby": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-7.1.1.tgz", + "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=", + "requires": { + "array-union": "^1.0.1", + "dir-glob": "^2.0.0", + "glob": "^7.1.2", + "ignore": "^3.3.5", + "pify": "^3.0.0", + "slash": "^1.0.0" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + }, + "replace-ext": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", + "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=" + }, + "vinyl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz", + "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==", + "requires": { + "clone": "^2.1.1", + "clone-buffer": "^1.0.0", + "clone-stats": "^1.0.0", + "cloneable-readable": "^1.0.0", + "remove-trailing-separator": "^1.0.1", + "replace-ext": "^1.0.0" + } + } + } + }, "memdown": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz", @@ -8139,19 +8283,17 @@ "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", - "dev": true + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" }, "merge2": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.2.2.tgz", - "integrity": "sha512-bgM8twH86rWni21thii6WCMQMRMmwqqdW3sGWi9IipnVAszdLXRjwDwAnyrVXo6DuP3AjRMMttZKUB48QWIFGg==", - "dev": true + "integrity": "sha512-bgM8twH86rWni21thii6WCMQMRMmwqqdW3sGWi9IipnVAszdLXRjwDwAnyrVXo6DuP3AjRMMttZKUB48QWIFGg==" }, "merkle-patricia-tree": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.1.tgz", - "integrity": "sha512-Qp9Mpb3xazznXzzGQBqHbqCpT2AR9joUOHYYPiQjYCarrdCPCnLWXo4BFv77y4xN26KR224xoU1n/qYY7RYYgw==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz", + "integrity": "sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g==", "dev": true, "requires": { "async": "^1.4.2", @@ -8162,13 +8304,29 @@ "readable-stream": "^2.0.0", "rlp": "^2.0.0", "semaphore": ">=1.0.1" + }, + "dependencies": { + "ethereumjs-util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz", + "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", + "dev": true, + "requires": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "ethjs-util": "^0.1.3", + "keccak": "^1.0.2", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1", + "secp256k1": "^3.0.1" + } + } } }, "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", - "dev": true + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" }, "micromatch": { "version": "2.3.11", @@ -8191,23 +8349,30 @@ "regex-cache": "^0.4.2" } }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + } + }, "mime": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", - "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", - "dev": true + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" }, "mime-db": { "version": "1.33.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", - "dev": true + "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==" }, "mime-types": { "version": "2.1.18", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", - "dev": true, "requires": { "mime-db": "~1.33.0" } @@ -8221,14 +8386,12 @@ "mimic-response": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.0.tgz", - "integrity": "sha1-3z02Uqc/3ta5sLJBRub9BSNTRY4=", - "dev": true + "integrity": "sha1-3z02Uqc/3ta5sLJBRub9BSNTRY4=" }, "min-document": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", - "dev": true, "requires": { "dom-walk": "^0.1.0" } @@ -8236,20 +8399,17 @@ "minimalistic-assert": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz", - "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=", - "dev": true + "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=" }, "minimalistic-crypto-utils": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -8257,14 +8417,46 @@ "minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "minipass": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz", + "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "yallist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "dev": true + } + } + }, + "minizlib": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.2.1.tgz", + "integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==", + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } }, "mixin-deep": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", - "dev": true, "requires": { "for-in": "^1.0.2", "is-extendable": "^1.0.1" @@ -8274,7 +8466,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, "requires": { "is-plain-object": "^2.0.4" } @@ -8285,11 +8476,19 @@ "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, "requires": { "minimist": "0.0.8" } }, + "mkdirp-promise": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz", + "integrity": "sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE=", + "dev": true, + "requires": { + "mkdirp": "*" + } + }, "mocha": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", @@ -8334,17 +8533,27 @@ } } }, + "mock-fs": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.7.0.tgz", + "integrity": "sha512-WlQNtUlzMRpvLHf8dqeUmNqfdPjGY29KrJF50Ldb4AcL+vQeR8QH3wQcFMgrhTwb1gHjZn9xggho+84tBskLgA==", + "dev": true + }, + "mout": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/mout/-/mout-0.11.1.tgz", + "integrity": "sha1-ujYR318OWx/7/QEWa48C0fX6K5k=", + "dev": true + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "multimatch": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", "integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=", - "dev": true, "requires": { "array-differ": "^1.0.0", "array-union": "^1.0.1", @@ -8358,17 +8567,26 @@ "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", "dev": true }, + "mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "requires": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, "nan": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", - "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", - "dev": true + "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==" }, "nano-json-stream-parser": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz", - "integrity": "sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18=", - "dev": true + "integrity": "sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18=" }, "nanoid": { "version": "1.3.0", @@ -8380,7 +8598,6 @@ "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, "requires": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", @@ -8398,20 +8615,17 @@ "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" }, "array-unique": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" }, "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" } } }, @@ -8421,11 +8635,22 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, + "needle": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.2.4.tgz", + "integrity": "sha512-HyoqEb4wr/rsoaIDfTH2aVL9nWtQqba2/HvMv+++m8u0dz808MaagKILxtfeSN7QU7nvbQ79zk3vYOJp9zsNEA==", + "dev": true, + "optional": true, + "requires": { + "debug": "^2.1.2", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, "negotiator": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", - "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", - "dev": true + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" }, "neo-async": { "version": "2.5.0", @@ -8440,24 +8665,39 @@ "dev": true }, "nise": { - "version": "1.4.6", - "resolved": "https://registry.npmjs.org/nise/-/nise-1.4.6.tgz", - "integrity": "sha512-1GedetLKzmqmgwabuMSqPsT7oumdR77SBpDfNNJhADRIeA3LN/2RVqR4fFqwvzhAqcTef6PPCzQwITE/YQ8S8A==", + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/nise/-/nise-1.4.8.tgz", + "integrity": "sha512-kGASVhuL4tlAV0tvA34yJYZIVihrUt/5bDwpp4tTluigxUr2bBlJeDXmivb6NuEdFkqvdv/Ybb9dm16PSKUhtw==", "dev": true, "requires": { - "@sinonjs/formatio": "3.0.0", - "just-extend": "^3.0.0", + "@sinonjs/formatio": "^3.1.0", + "just-extend": "^4.0.2", "lolex": "^2.3.2", "path-to-regexp": "^1.7.0", "text-encoding": "^0.6.4" }, "dependencies": { + "@sinonjs/formatio": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.1.0.tgz", + "integrity": "sha512-ZAR2bPHOl4Xg6eklUGpsdiIJ4+J1SNag1DHHrG/73Uz/nVwXqjgUtRPLoS+aVyieN9cSbc0E4LsU984tWcDyNg==", + "dev": true, + "requires": { + "@sinonjs/samsam": "^2 || ^3" + } + }, "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, + "just-extend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.0.2.tgz", + "integrity": "sha512-FrLwOgm+iXrPV+5zDU6Jqu4gCRXbWEQg2O3SKONsWE4w7AXFRkryS53bpWdaL9cNol+AmR3AEYz6kn+o0fCPnw==", + "dev": true + }, "path-to-regexp": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", @@ -8469,12 +8709,6 @@ } } }, - "node-abi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.1.0.tgz", - "integrity": "sha512-AbW35CPRE4vdieOse46V+16dKispLNv3PQwgqlcfg7GQeQHcLu3gvp3fbU2gTh7d8NfGjp5CJh+j4Hpyb0XzaA==", - "dev": true - }, "node-dir": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.8.tgz", @@ -8507,6 +8741,38 @@ "js-queue": "2.0.0" } }, + "node-pre-gyp": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz", + "integrity": "sha512-d1xFs+C/IPS8Id0qPTZ4bUT8wWryfR/OzzAFxweG+uLN85oPzyo2Iw6bVlLQ/JOdgNonXLCoRyqDzDWq4iw72A==", + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + }, + "dependencies": { + "nopt": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", + "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + } + } + }, "nomnom": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/nomnom/-/nomnom-1.8.1.tgz", @@ -8542,12 +8808,6 @@ } } }, - "noop-logger": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", - "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=", - "dev": true - }, "nopt": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", @@ -8590,9 +8850,9 @@ } }, "npm": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/npm/-/npm-6.4.1.tgz", - "integrity": "sha512-mXJL1NTVU136PtuopXCUQaNWuHlXCTp4McwlSW8S9/Aj8OEPAlSBgo8og7kJ01MjCDrkmqFQTvN5tTEhBMhXQg==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/npm/-/npm-6.5.0.tgz", + "integrity": "sha512-SPq8zG2Kto+Xrq55E97O14Jla13PmQT5kSnvwBj88BmJZ5Nvw++OmlWfhjkB67pcgP5UEXljEtnGFKZtOgt6MQ==", "dev": true, "requires": { "JSONStream": "^1.3.4", @@ -8602,29 +8862,29 @@ "aproba": "~1.2.0", "archy": "~1.0.0", "bin-links": "^1.1.2", - "bluebird": "~3.5.1", + "bluebird": "^3.5.3", "byte-size": "^4.0.3", "cacache": "^11.2.0", "call-limit": "~1.1.0", "chownr": "~1.0.1", - "ci-info": "^1.4.0", + "ci-info": "^1.6.0", "cli-columns": "^3.1.2", "cli-table3": "^0.5.0", "cmd-shim": "~2.0.2", "columnify": "~1.5.4", - "config-chain": "~1.1.11", + "config-chain": "^1.1.12", "debuglog": "*", "detect-indent": "~5.0.0", "detect-newline": "^2.1.0", "dezalgo": "~1.0.3", "editor": "~1.0.0", - "figgy-pudding": "^3.4.1", + "figgy-pudding": "^3.5.1", "find-npm-prefix": "^1.0.2", "fs-vacuum": "~1.2.10", "fs-write-stream-atomic": "~1.0.10", "gentle-fs": "^2.0.1", - "glob": "~7.1.2", - "graceful-fs": "~4.1.11", + "glob": "^7.1.3", + "graceful-fs": "^4.1.15", "has-unicode": "~2.0.1", "hosted-git-info": "^2.7.1", "iferr": "^1.0.2", @@ -8665,7 +8925,7 @@ "npm-install-checks": "~3.0.0", "npm-lifecycle": "^2.1.0", "npm-package-arg": "^6.1.0", - "npm-packlist": "^1.1.11", + "npm-packlist": "^1.1.12", "npm-pick-manifest": "^2.1.0", "npm-profile": "^3.0.2", "npm-registry-client": "^8.6.0", @@ -8673,7 +8933,7 @@ "npm-user-validate": "~1.0.0", "npmlog": "~4.1.2", "once": "~1.4.0", - "opener": "^1.5.0", + "opener": "^1.5.1", "osenv": "^0.1.5", "pacote": "^8.1.6", "path-is-inside": "~1.0.2", @@ -8692,14 +8952,14 @@ "retry": "^0.12.0", "rimraf": "~2.6.2", "safe-buffer": "^5.1.2", - "semver": "^5.5.0", + "semver": "^5.5.1", "sha": "~2.0.1", "slide": "~1.1.6", "sorted-object": "~2.0.1", "sorted-union-stream": "~2.1.3", - "ssri": "^6.0.0", + "ssri": "^6.0.1", "stringify-package": "^1.0.0", - "tar": "^4.4.6", + "tar": "^4.4.8", "text-table": "~0.2.0", "tiny-relative-date": "^1.3.0", "uid-number": "0.0.6", @@ -8874,7 +9134,7 @@ } }, "bluebird": { - "version": "3.5.1", + "version": "3.5.3", "bundled": true, "dev": true }, @@ -8983,7 +9243,7 @@ "dev": true }, "ci-info": { - "version": "1.4.0", + "version": "1.6.0", "bundled": true, "dev": true }, @@ -9121,7 +9381,7 @@ } }, "config-chain": { - "version": "1.1.11", + "version": "1.1.12", "bundled": true, "dev": true, "requires": { @@ -9406,7 +9666,7 @@ "dev": true }, "figgy-pudding": { - "version": "3.4.1", + "version": "3.5.1", "bundled": true, "dev": true }, @@ -9581,7 +9841,7 @@ } }, "glob": { - "version": "7.1.2", + "version": "7.1.3", "bundled": true, "dev": true, "requires": { @@ -9620,7 +9880,7 @@ } }, "graceful-fs": { - "version": "4.1.11", + "version": "4.1.15", "bundled": true, "dev": true }, @@ -10189,7 +10449,7 @@ } }, "minizlib": { - "version": "1.1.0", + "version": "1.1.1", "bundled": true, "dev": true, "requires": { @@ -10377,7 +10637,7 @@ } }, "npm-packlist": { - "version": "1.1.11", + "version": "1.1.12", "bundled": true, "dev": true, "requires": { @@ -10602,7 +10862,7 @@ } }, "opener": { - "version": "1.5.0", + "version": "1.5.1", "bundled": true, "dev": true }, @@ -11058,7 +11318,7 @@ "dev": true }, "semver": { - "version": "5.5.0", + "version": "5.5.1", "bundled": true, "dev": true }, @@ -11226,9 +11486,12 @@ } }, "ssri": { - "version": "6.0.0", + "version": "6.0.1", "bundled": true, - "dev": true + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1" + } }, "stream-each": { "version": "1.2.2", @@ -11327,21 +11590,35 @@ } }, "tar": { - "version": "4.4.6", + "version": "4.4.8", "bundled": true, "dev": true, "requires": { - "chownr": "^1.0.1", + "chownr": "^1.1.1", "fs-minipass": "^1.2.5", - "minipass": "^2.3.3", - "minizlib": "^1.1.0", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", "mkdirp": "^0.5.0", "safe-buffer": "^5.1.2", "yallist": "^3.0.2" }, "dependencies": { + "chownr": { + "version": "1.1.1", + "bundled": true, + "dev": true + }, + "minipass": { + "version": "2.3.5", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, "yallist": { - "version": "3.0.2", + "version": "3.0.3", "bundled": true, "dev": true } @@ -11672,6 +11949,13 @@ } } }, + "npm-bundled": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.5.tgz", + "integrity": "sha512-m/e6jgWu8/v5niCUKQi9qQl8QdeEduFA96xHDDzFGqly0OOjI7c+60KM/2sppfnUU9JJagf+zs+yGhqSOFj71g==", + "dev": true, + "optional": true + }, "npm-install-peers": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/npm-install-peers/-/npm-install-peers-1.2.1.tgz", @@ -11682,6 +11966,17 @@ "npm": "*" } }, + "npm-packlist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.2.0.tgz", + "integrity": "sha512-7Mni4Z8Xkx0/oegoqlcao/JpPCPEMtUvsmB0q7mgvlMinykJLSRTYuFqoQLYgGY8biuxIeiHO+QNJKbCfljewQ==", + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, "npm-programmatic": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/npm-programmatic/-/npm-programmatic-0.0.10.tgz", @@ -11705,6 +12000,7 @@ "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", "dev": true, + "optional": true, "requires": { "are-we-there-yet": "~1.1.2", "console-control-strings": "~1.1.0", @@ -11731,7 +12027,6 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", "integrity": "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=", - "dev": true, "requires": { "bn.js": "4.11.6", "strip-hex-prefix": "1.0.0" @@ -11740,8 +12035,7 @@ "bn.js": { "version": "4.11.6", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", - "dev": true + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" } } }, @@ -11755,20 +12049,17 @@ "oauth-sign": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", - "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", - "dev": true + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, "object-copy": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, "requires": { "copy-descriptor": "^0.1.0", "define-property": "^0.2.5", @@ -11779,7 +12070,6 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, "requires": { "is-descriptor": "^0.1.0" } @@ -11802,7 +12092,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, "requires": { "isobject": "^3.0.0" }, @@ -11810,8 +12099,7 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" } } }, @@ -11829,7 +12117,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, "requires": { "isobject": "^3.0.1" }, @@ -11837,16 +12124,23 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" } } }, + "oboe": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.3.tgz", + "integrity": "sha1-K0hl29Rr6BIlcT9Om/5Lz09oCk8=", + "dev": true, + "requires": { + "http-https": "^1.0.0" + } + }, "on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dev": true, "requires": { "ee-first": "1.1.1" } @@ -11855,7 +12149,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, "requires": { "wrappy": "1" } @@ -11973,6 +12266,17 @@ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, "output-file-sync": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/output-file-sync/-/output-file-sync-1.1.2.tgz", @@ -12002,8 +12306,7 @@ "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" }, "p-is-promise": { "version": "1.1.0", @@ -12053,6 +12356,27 @@ "p-finally": "^1.0.0" } }, + "parse-asn1": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.3.tgz", + "integrity": "sha512-VrPoetlz7B/FqjBLD2f5wBVZvsZVLnRUrxVLfRYhGXCODa/NWE4p3Wp+6+aV3ZPL3KM7/OZmxDIwwijD7yuucg==", + "dev": true, + "requires": { + "asn1.js": "^4.0.0", + "browserify-aes": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "parse-code-context": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-code-context/-/parse-code-context-1.0.0.tgz", + "integrity": "sha512-OZQaqKaQnR21iqhlnPfVisFjBWjhnMl5J9MgbP8xC+EwoVqbXrq78lp+9Zb3ahmLzrIX5Us/qbvBnaS3hkH6OA==", + "dev": true, + "optional": true + }, "parse-glob": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", @@ -12063,13 +12387,27 @@ "is-dotfile": "^1.0.0", "is-extglob": "^1.0.0", "is-glob": "^2.0.0" + }, + "dependencies": { + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } } }, "parse-headers": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.1.tgz", "integrity": "sha1-aug6eqJanZtwCswoaYzR8e1+lTY=", - "dev": true, "requires": { "for-each": "^0.3.2", "trim": "0.0.1" @@ -12102,20 +12440,17 @@ "parseurl": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", - "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=", - "dev": true + "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" }, "pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" }, "path-dirname": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" }, "path-exists": { "version": "2.1.0", @@ -12129,8 +12464,7 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "path-is-inside": { "version": "1.0.2", @@ -12147,14 +12481,12 @@ "path-parse": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", - "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", - "dev": true + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=" }, "path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", - "dev": true + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" }, "path-type": { "version": "1.1.0", @@ -12165,6 +12497,14 @@ "graceful-fs": "^4.1.2", "pify": "^2.0.0", "pinkie-promise": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } } }, "pathval": { @@ -12192,29 +12532,32 @@ "integrity": "sha1-z4uvrm7d/0tafvsYUmnqr0YQ3b0=", "dev": true }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true }, "pinkie": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" }, "pinkie-promise": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, "requires": { "pinkie": "^2.0.0" } @@ -12237,47 +12580,7 @@ "posix-character-classes": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "prebuild-install": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-2.2.2.tgz", - "integrity": "sha512-F46pcvDxtQhbV3B+dm+exHuKxIyJK26fVNiJRmbTW/5D7o0Z2yzc8CKeu7UWbo9XxQZoVOC88aKgySAsza+cWw==", - "dev": true, - "requires": { - "expand-template": "^1.0.2", - "github-from-package": "0.0.0", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "node-abi": "^2.0.0", - "noop-logger": "^0.1.1", - "npmlog": "^4.0.1", - "os-homedir": "^1.0.1", - "pump": "^1.0.1", - "rc": "^1.1.6", - "simple-get": "^1.4.2", - "tar-fs": "^1.13.0", - "tunnel-agent": "^0.6.0", - "xtend": "4.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - } - } + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" }, "precond": { "version": "0.2.3", @@ -12303,11 +12606,77 @@ "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", "dev": true }, + "prettier": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.15.3.tgz", + "integrity": "sha512-gAU9AGAPMaKb3NNSUUuhhFAS7SCO4ALTN4nRIn6PJ075Qd28Yn2Ig2ahEJWdJwJmlEBTUfC7mMUSFy8MwsOCfg==", + "dev": true + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "requires": { + "fast-diff": "^1.1.2" + } + }, + "prettier-plugin-solidity": { + "version": "1.0.0-alpha.12", + "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.0.0-alpha.12.tgz", + "integrity": "sha512-H5SqMHv1jttrm8h8JwVIm+f3BAXLGvqgxfXioUfPl7x0Rw+3KZaQ53bW2DBpJG7NefJxnUKq5dZrWZkclqp9AA==", + "dev": true, + "optional": true, + "requires": { + "emoji-regex": "^7.0.1", + "escape-string-regexp": "^1.0.5", + "extract-comments": "^1.1.0", + "prettier": "^1.15.2", + "solidity-parser-antlr": "^0.3.1", + "string-width": "^2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "optional": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "optional": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "optional": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, "pretty-bytes": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-4.0.2.tgz", - "integrity": "sha1-sr+C5zUNZcbDOqlaqlpPYyf2HNk=", - "dev": true + "integrity": "sha1-sr+C5zUNZcbDOqlaqlpPYyf2HNk=" }, "private": { "version": "0.1.7", @@ -12318,14 +12687,12 @@ "process": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz", - "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=", - "dev": true + "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=" }, "process-nextick-args": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", - "dev": true + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" }, "progress": { "version": "2.0.0", @@ -12347,7 +12714,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.3.tgz", "integrity": "sha512-jQTChiCJteusULxjBp8+jftSQE5Obdl3k4cnmLA6WXtK6XFuWRnvVL7aCiBqaLPM8c4ph0S4tKna8XvmIwEnXQ==", - "dev": true, "requires": { "forwarded": "~0.1.2", "ipaddr.js": "1.6.0" @@ -12365,33 +12731,42 @@ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", "dev": true }, - "pump": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.2.tgz", - "integrity": "sha1-Oz7mUS+U8OV1U4wXmV+fFpkKXVE=", + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", "dev": true, "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } } }, "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" }, "qs": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" }, "query-string": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", - "dev": true, "requires": { "decode-uri-component": "^0.2.0", "object-assign": "^4.1.0", @@ -12413,23 +12788,30 @@ "safe-buffer": "^5.1.0" } }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, "randomhex": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/randomhex/-/randomhex-0.1.5.tgz", - "integrity": "sha1-us7vmCMpCRQA8qKRLGzQLxCU9YU=", - "dev": true + "integrity": "sha1-us7vmCMpCRQA8qKRLGzQLxCU9YU=" }, "range-parser": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", - "dev": true + "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" }, "raw-body": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", - "dev": true, "requires": { "bytes": "3.0.0", "http-errors": "1.6.3", @@ -12437,11 +12819,18 @@ "unpipe": "1.0.0" }, "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, "iconv-lite": { "version": "0.4.23", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", - "dev": true, "requires": { "safer-buffer": ">= 2.1.2 < 3" } @@ -12453,6 +12842,7 @@ "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "dev": true, + "optional": true, "requires": { "deep-extend": "^0.6.0", "ini": "~1.3.0", @@ -12464,13 +12854,15 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true + "dev": true, + "optional": true }, "minimist": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true + "dev": true, + "optional": true } } }, @@ -12478,7 +12870,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/read-chunk/-/read-chunk-2.1.0.tgz", "integrity": "sha1-agTAkoAF7Z1C4aasVgDhnLx/9lU=", - "dev": true, "requires": { "pify": "^3.0.0", "safe-buffer": "^5.1.1" @@ -12487,8 +12878,7 @@ "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" } } }, @@ -12517,7 +12907,6 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -12544,7 +12933,6 @@ "version": "0.6.2", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "dev": true, "requires": { "resolve": "^1.1.6" } @@ -12639,7 +13027,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, "requires": { "extend-shallow": "^3.0.2", "safe-regex": "^1.1.0" @@ -12716,20 +13103,17 @@ "remove-trailing-separator": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.0.2.tgz", - "integrity": "sha1-abBi2XhyetFNxrVrpKt3L9jXBRE=", - "dev": true + "integrity": "sha1-abBi2XhyetFNxrVrpKt3L9jXBRE=" }, "repeat-element": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", - "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", - "dev": true + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=" }, "repeat-string": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" }, "repeating": { "version": "2.0.1", @@ -12743,8 +13127,7 @@ "replace-ext": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", - "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", - "dev": true + "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=" }, "req-cwd": { "version": "1.0.1", @@ -12776,7 +13159,6 @@ "version": "2.87.0", "resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz", "integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==", - "dev": true, "requires": { "aws-sign2": "~0.7.0", "aws4": "^1.6.0", @@ -12803,8 +13185,7 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" }, "require-from-string": { "version": "1.2.1", @@ -12815,8 +13196,7 @@ "require-main-filename": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" }, "require-uncached": { "version": "1.0.3", @@ -12828,6 +13208,12 @@ "resolve-from": "^1.0.0" } }, + "requireindex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.1.0.tgz", + "integrity": "sha1-5UBLgVV+91225JxacgBIk/4D4WI=", + "dev": true + }, "reselect": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/reselect/-/reselect-3.0.1.tgz", @@ -12884,7 +13270,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz", "integrity": "sha512-aW7sVKPufyHqOmyyLzg/J+8606v5nevBgaliIlV7nUpVMsDnoBGV/cbSLNjZAg9q0Cfd/+easKVKQ8vOu8fn1Q==", - "dev": true, "requires": { "path-parse": "^1.0.5" } @@ -12925,8 +13310,7 @@ "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" }, "responselike": { "version": "1.0.2", @@ -12959,8 +13343,7 @@ "ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" }, "right-align": { "version": "0.1.3", @@ -12976,26 +13359,28 @@ "version": "2.6.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", - "dev": true, "requires": { "glob": "^7.0.5" } }, "ripemd160": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz", - "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", "dev": true, "requires": { - "hash-base": "^2.0.0", + "hash-base": "^3.0.0", "inherits": "^2.0.1" } }, "rlp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.0.0.tgz", - "integrity": "sha1-nbOE/0uJqPYVY9kjldhiWxjzr7A=", - "dev": true + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.1.0.tgz", + "integrity": "sha512-93U7IKH5j7nmXFVg19MeNBGzQW5uXW1pmCuKY8veeKIhYTE32C2d0mOegfiIAfXcHOKJjjPlJisn8iHDF5AezA==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.1" + } }, "rn-host-detect": { "version": "1.1.5", @@ -13007,7 +13392,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", - "dev": true, "requires": { "is-promise": "^2.1.0" } @@ -13031,6 +13415,16 @@ "dev": true, "requires": { "rx-lite": "*" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + } + } } }, "rxjs": { @@ -13045,8 +13439,7 @@ "safe-buffer": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", - "dev": true + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" }, "safe-eval": { "version": "0.3.0", @@ -13054,11 +13447,19 @@ "integrity": "sha1-Bs4RHuvZwYWrr/AI7A/P/Fxb4Aw=", "dev": true }, + "safe-event-emitter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/safe-event-emitter/-/safe-event-emitter-1.0.1.tgz", + "integrity": "sha512-e1wFe99A91XYYxoQbcq2ZJUWurxEyP8vfz7A7vuUe1s95q8r5ebraVaA1BukYJcpM6V16ugWoD9vngi8Ccu5fg==", + "dev": true, + "requires": { + "events": "^3.0.0" + } + }, "safe-regex": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, "requires": { "ret": "~0.1.10" } @@ -13066,8 +13467,7 @@ "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "sax": { "version": "1.2.4", @@ -13100,8 +13500,7 @@ "scoped-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/scoped-regex/-/scoped-regex-1.0.0.tgz", - "integrity": "sha1-o0a7Gs1CB65wvXwMfKnlZra63bg=", - "dev": true + "integrity": "sha1-o0a7Gs1CB65wvXwMfKnlZra63bg=" }, "scrypt": { "version": "6.0.3", @@ -13138,9 +13537,9 @@ } }, "secp256k1": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.3.0.tgz", - "integrity": "sha512-CbrQoeGG5V0kQ1ohEMGI+J7oKerapLTpivLICBaXR0R4HyQcN3kM9itLsV5fdpV1UR1bD14tOkJ1xughmlDIiQ==", + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.5.2.tgz", + "integrity": "sha512-iin3kojdybY6NArd+UFsoTuapOF7bnJNf2UbcWXaY3z+E1sJDipl60vtzB5hbO/uquBu7z0fd4VC4Irp+xoFVQ==", "dev": true, "requires": { "bindings": "^1.2.1", @@ -13150,10 +13549,29 @@ "drbg.js": "^1.0.1", "elliptic": "^6.2.3", "nan": "^2.2.1", - "prebuild-install": "^2.0.0", "safe-buffer": "^5.1.0" } }, + "seek-bzip": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.5.tgz", + "integrity": "sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w=", + "dev": true, + "requires": { + "commander": "~2.8.1" + }, + "dependencies": { + "commander": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz", + "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", + "dev": true, + "requires": { + "graceful-readlink": ">= 1.0.0" + } + } + } + }, "semaphore": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/semaphore/-/semaphore-1.1.0.tgz", @@ -13170,7 +13588,6 @@ "version": "0.16.2", "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", - "dev": true, "requires": { "debug": "2.6.9", "depd": "~1.1.2", @@ -13191,7 +13608,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "requires": { "ms": "2.0.0" } @@ -13199,8 +13615,7 @@ "statuses": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", - "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", - "dev": true + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" } } }, @@ -13208,7 +13623,6 @@ "version": "1.13.2", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", - "dev": true, "requires": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", @@ -13220,7 +13634,6 @@ "version": "0.1.12", "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz", "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==", - "dev": true, "requires": { "body-parser": "^1.16.0", "cors": "^2.8.1", @@ -13232,8 +13645,7 @@ "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, "set-immediate-shim": { "version": "1.0.1", @@ -13245,7 +13657,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", - "dev": true, "requires": { "extend-shallow": "^2.0.1", "is-extendable": "^0.1.1", @@ -13257,10 +13668,17 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, "requires": { "is-extendable": "^0.1.0" } + }, + "node-dir": { + "version": "0.1.17", + "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", + "integrity": "sha1-X1Zl2TNRM1yqvvjxxVRRbPXx5OU=", + "requires": { + "minimatch": "^3.0.2" + } } } }, @@ -13273,25 +13691,55 @@ "setprototypeof": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" }, "sha.js": { - "version": "2.4.8", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.8.tgz", - "integrity": "sha1-NwaMLEdra69ALRSknGf1l5IfY08=", + "version": "2.4.11", + "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", "dev": true, "requires": { - "inherits": "^2.0.1" + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, "sha3": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/sha3/-/sha3-1.2.2.tgz", "integrity": "sha1-pmxQmN5MJbyIM27ItIF9AFvKe6k=", - "dev": true, "requires": { "nan": "2.10.0" + }, + "dependencies": { + "async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", + "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "requires": { + "lodash": "^4.17.10" + } + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + }, + "node-dir": { + "version": "0.1.17", + "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", + "integrity": "sha1-X1Zl2TNRM1yqvvjxxVRRbPXx5OU=", + "requires": { + "minimatch": "^3.0.2" + } + } } }, "shebang-command": { @@ -13338,19 +13786,7 @@ "simple-concat": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", - "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=", - "dev": true - }, - "simple-get": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-1.4.3.tgz", - "integrity": "sha1-6XVe2kB+ltpAxeUVjJ6jezO+y+s=", - "dev": true, - "requires": { - "once": "^1.3.1", - "unzip-response": "^1.0.0", - "xtend": "^4.0.0" - } + "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=" }, "sinon": { "version": "6.3.5", @@ -13389,8 +13825,7 @@ "slash": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", - "dev": true + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=" }, "slice-ansi": { "version": "1.0.0", @@ -13419,7 +13854,6 @@ "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, "requires": { "base": "^0.11.1", "debug": "^2.2.0", @@ -13435,7 +13869,6 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, "requires": { "is-descriptor": "^0.1.0" } @@ -13444,7 +13877,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, "requires": { "is-extendable": "^0.1.0" } @@ -13455,7 +13887,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, "requires": { "define-property": "^1.0.0", "isobject": "^3.0.0", @@ -13466,7 +13897,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, "requires": { "is-descriptor": "^1.0.0" } @@ -13475,7 +13905,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -13484,7 +13913,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -13493,7 +13921,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", @@ -13503,14 +13930,12 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" }, "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" } } }, @@ -13518,7 +13943,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, "requires": { "kind-of": "^3.2.0" } @@ -13558,12 +13982,6 @@ } } }, - "sol-digger": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/sol-digger/-/sol-digger-0.0.2.tgz", - "integrity": "sha1-QGxKnTHiaef4jrHC6hATGOXgkCU=", - "dev": true - }, "sol-explore": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/sol-explore/-/sol-explore-1.6.2.tgz", @@ -13583,6 +14001,22 @@ "yargs": "^4.7.1" }, "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, "yargs": { "version": "4.8.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", @@ -13607,6 +14041,372 @@ } } }, + "solhint": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/solhint/-/solhint-1.5.0.tgz", + "integrity": "sha512-D4vmV9hlBRcBEdCap6kHUKtBOjKJbC6JhvsoGrcTKW6+WHRDkbpif35R1Enzd0+OvvIC2UReMwK85dSqrqUSoQ==", + "dev": true, + "requires": { + "antlr4": "4.7.1", + "commander": "2.18.0", + "eslint": "^5.6.0", + "fast-diff": "^1.1.2", + "glob": "7.1.3", + "ignore": "^4.0.6", + "lodash": "^4.17.11", + "prettier": "^1.14.3", + "prettier-linter-helpers": "^1.0.0", + "prettier-plugin-solidity": "^1.0.0-alpha.4" + }, + "dependencies": { + "acorn": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.4.tgz", + "integrity": "sha512-VY4i5EKSKkofY2I+6QLTbTTN/UvEQPCo6eiwzzSaSWfpaDhOmStMCMod6wmuPciNq+XS0faCglFu2lHZpdHUtg==", + "dev": true + }, + "acorn-jsx": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.1.tgz", + "integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==", + "dev": true + }, + "ajv": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.6.2.tgz", + "integrity": "sha512-FBHEW6Jf5TB9MGBgUUA9XHkTbjXYfAUjY43ACMfmdMRHniyoMHjHjzD50OK8LGDWQwp4rWEsIq5kEqq7rvIM1g==", + "dev": true, + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "commander": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.18.0.tgz", + "integrity": "sha512-6CYPa+JP2ftfRU2qkDK+UTVeQYosOg/2GbcjIcKPHfinyOLPVGXu/ovN86RP49Re5ndJK1N0kuiidFFuepc4ZQ==", + "dev": true + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "eslint": { + "version": "5.11.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.11.0.tgz", + "integrity": "sha512-gbEg0ttToZPkZUv2yYjpipxuYrv/9aSSmgM4V6GkiO3u04QosHYBtduUCqLEulEg3YvNDAkk3OWzyQJ/heZ3Nw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.5.3", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^2.1.0", + "eslint-scope": "^4.0.0", + "eslint-utils": "^1.3.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^5.0.0", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^2.0.0", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "imurmurhash": "^0.1.4", + "inquirer": "^6.1.0", + "js-yaml": "^3.12.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.5", + "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", + "text-table": "^0.2.0" + } + }, + "eslint-scope": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz", + "integrity": "sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "espree": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.0.tgz", + "integrity": "sha512-1MpUfwsdS9MMoN7ZXqAr9e9UKdVHDcvrJpyx7mm1WuQlx/ygErEQBzgi5Nh5qBHIoYweprhtMkTCb9GhcAIcsA==", + "dev": true, + "requires": { + "acorn": "^6.0.2", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.0.0" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "external-editor": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz", + "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "globals": { + "version": "11.9.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.9.0.tgz", + "integrity": "sha512-5cJVtyXWH8PiJPVLZzzoIizXx944O4OmRro5MWKx5fT4MgcN7OfaMutPeaTdJCCURwbWdhhcCWcKIffPnmTzBg==", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "inquirer": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.2.1.tgz", + "integrity": "sha512-088kl3DRT2dLU5riVMKKr1DlImd6X7smDhpXUCkJDCKvTEJeRiXh0G132HG9u5a+6Ylw9plFRY7RuTnwohYSpg==", + "dev": true, + "requires": { + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.0", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.0", + "figures": "^2.0.0", + "lodash": "^4.17.10", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^6.1.0", + "string-width": "^2.1.0", + "strip-ansi": "^5.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.0.0.tgz", + "integrity": "sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w==", + "dev": true + }, + "strip-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.0.0.tgz", + "integrity": "sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow==", + "dev": true, + "requires": { + "ansi-regex": "^4.0.0" + } + } + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "js-yaml": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", + "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true + }, + "rxjs": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", + "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", + "dev": true + }, + "slice-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.0.0.tgz", + "integrity": "sha512-4j2WTWjp3GsZ+AOagyzVbzp4vWGtZ0hEZ/gDY/uTvm6MTxUfTUIsnMIFb1bn8o0RuXiqUw15H1bue8f22Vw2oQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "table": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/table/-/table-5.1.1.tgz", + "integrity": "sha512-NUjapYb/qd4PeFW03HnAuOJ7OMcBkJlqeClWxeNlQ0lXGSb52oZXGzkO0/I0ARegQ2eUT1g2VDJH0eUxDRcHmw==", + "dev": true, + "requires": { + "ajv": "^6.6.1", + "lodash": "^4.17.11", + "slice-ansi": "2.0.0", + "string-width": "^2.1.1" + } + } + } + }, "solidity-coverage": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.5.4.tgz", @@ -13626,9 +14426,9 @@ } }, "solidity-parser-antlr": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/solidity-parser-antlr/-/solidity-parser-antlr-0.3.2.tgz", - "integrity": "sha512-aO/lbnc14A81cQigN5sKNuwbxohPyJOq7kpLirYT/6emCw5Gjb0TJoZ3TzL1tYdIX6gjTAMlQ1UZwOcrzOAp4w==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/solidity-parser-antlr/-/solidity-parser-antlr-0.3.3.tgz", + "integrity": "sha512-RNUc18pjf7DLWs//WF+V+VnvrbetEbNFUYxm2JFbXU62G9WSu+nVyDxV5r+FG4wu8jom17vLdM/3I7bMBGfZ9g==", "dev": true }, "solidity-parser-sc": { @@ -13642,6 +14442,17 @@ "yargs": "^4.6.0" }, "dependencies": { + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, "yargs": { "version": "4.8.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", @@ -13681,8 +14492,7 @@ "dependencies": { "bignumber.js": { "version": "git+https://github.com/debris/bignumber.js.git#c7a38de919ed75e6fb6ba38051986e294b328df9", - "from": "git+https://github.com/debris/bignumber.js.git#master", - "dev": true + "from": "git+https://github.com/debris/bignumber.js.git#master" }, "web3": { "version": "0.16.0", @@ -13694,158 +14504,17 @@ "crypto-js": "^3.1.4", "utf8": "^2.1.1", "xmlhttprequest": "*" + }, + "dependencies": { + "bignumber.js": { + "version": "git+https://github.com/debris/bignumber.js.git#c7a38de919ed75e6fb6ba38051986e294b328df9", + "from": "git+https://github.com/debris/bignumber.js.git#c7a38de919ed75e6fb6ba38051986e294b328df9", + "dev": true + } } } } }, - "solium": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/solium/-/solium-1.1.8.tgz", - "integrity": "sha512-fn0lusM6of14CytIDDHK73SGjn6NsVTaCVJjaKCKJyqKhT00rH/hDtvnIeZ2ZTD9z/xaXd4Js2brW3az6AV9RA==", - "dev": true, - "requires": { - "ajv": "^5.2.2", - "chokidar": "^1.6.0", - "colors": "^1.1.2", - "commander": "^2.9.0", - "eol": "^0.9.1", - "js-string-escape": "^1.0.1", - "lodash": "^4.14.2", - "sol-digger": "0.0.2", - "sol-explore": "1.6.1", - "solium-plugin-security": "0.1.1", - "solparse": "2.2.5", - "text-table": "^0.2.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - }, - "cliui": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", - "dev": true, - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "os-locale": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", - "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", - "dev": true, - "requires": { - "execa": "^0.7.0", - "lcid": "^1.0.0", - "mem": "^1.1.0" - } - }, - "sol-explore": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/sol-explore/-/sol-explore-1.6.1.tgz", - "integrity": "sha1-tZ8HPGn+MyVg1aEMMrqMp/KYbPs=", - "dev": true - }, - "solparse": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/solparse/-/solparse-2.2.5.tgz", - "integrity": "sha512-t7tvtR6KU6QfPYLMv1nlCh9DA8HYIu5tbjHpKu0fhGFZ1NuSp0KKDHfFHv07g6v1xgcuUY3rVqNFjZt5b9+5qA==", - "dev": true, - "requires": { - "mocha": "^4.0.1", - "pegjs": "^0.10.0", - "yargs": "^10.0.3" - } - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "yargs": { - "version": "10.1.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-10.1.2.tgz", - "integrity": "sha512-ivSoxqBGYOqQVruxD35+EyCFDYNEFL/Uo6FcOnz+9xZdZzK0Zzw4r4KhbrME1Oo2gOggwJod2MnsdamSG7H9ig==", - "dev": true, - "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.1.1", - "find-up": "^2.1.0", - "get-caller-file": "^1.0.1", - "os-locale": "^2.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^8.1.0" - } - }, - "yargs-parser": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-8.1.0.tgz", - "integrity": "sha512-yP+6QqN8BmrgW2ggLtTbdrOyBNSI7zBa4IykmiV5R1wl1JWNxQvWhMfMdmzIYtKU7oP3OOInY/tl2ov3BDjnJQ==", - "dev": true, - "requires": { - "camelcase": "^4.1.0" - } - } - } - }, - "solium-plugin-security": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/solium-plugin-security/-/solium-plugin-security-0.1.1.tgz", - "integrity": "sha512-kpLirBwIq4mhxk0Y/nn5cQ6qdJTI+U1LO3gpoNIcqNaW+sI058moXBe2UiHs+9wvF9IzYD49jcKhFTxcR9u9SQ==", - "dev": true - }, "sort-keys": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", @@ -13858,14 +14527,12 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" }, "source-map-resolve": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", - "dev": true, "requires": { "atob": "^2.1.1", "decode-uri-component": "^0.2.0", @@ -13886,8 +14553,7 @@ "source-map-url": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" }, "spawn-args": { "version": "0.1.0", @@ -13920,7 +14586,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, "requires": { "extend-shallow": "^3.0.0" } @@ -13932,10 +14597,9 @@ "dev": true }, "sshpk": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz", - "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=", - "dev": true, + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.0.tgz", + "integrity": "sha512-Zhev35/y7hRMcID/upReIvRse+I9SVhyVre/KTJSJQWMz3C3+G+HpO7m1wK/yckEtujKZ7dS4hkVxAnmHaIGVQ==", "requires": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", @@ -13952,7 +14616,6 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, "requires": { "define-property": "^0.2.5", "object-copy": "^0.1.0" @@ -13962,7 +14625,6 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, "requires": { "is-descriptor": "^0.1.0" } @@ -13972,30 +14634,45 @@ "statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "dev": true + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" }, "strict-uri-encode": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", - "dev": true + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" }, "string-template": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz", - "integrity": "sha1-QpMuWYo1LQH8IuwzZ9nYTuxsmt0=", - "dev": true + "integrity": "sha1-QpMuWYo1LQH8IuwzZ9nYTuxsmt0=" }, "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + } } }, "string.prototype.trim": { @@ -14013,9 +14690,39 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, "requires": { "safe-buffer": "~5.1.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" + }, + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" + }, + "utf8": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.1.tgz", + "integrity": "sha1-LgHbAvfY0JRPdxBPFgnrDDBM92g=" + }, + "web3-utils": { + "version": "1.0.0-beta.36", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.0.0-beta.36.tgz", + "integrity": "sha512-7ri74lG5fS2Th0fhYvTtiEHMB1Pmf2p7dQx1COQ3OHNI/CHNEMjzoNMEbBU6FAENrywfoFur40K4m0AOmEUq5A==", + "requires": { + "bn.js": "4.11.6", + "eth-lib": "0.1.27", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randomhex": "0.1.5", + "underscore": "1.8.3", + "utf8": "2.1.1" + } + } } }, "strip-ansi": { @@ -14031,7 +14738,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, "requires": { "is-utf8": "^0.2.0" } @@ -14040,12 +14746,20 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-bom-stream/-/strip-bom-stream-2.0.0.tgz", "integrity": "sha1-+H217yYT9paKpUWr/h7HKLaoKco=", - "dev": true, "requires": { "first-chunk-stream": "^2.0.0", "strip-bom": "^2.0.0" } }, + "strip-dirs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", + "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==", + "dev": true, + "requires": { + "is-natural-number": "^4.0.1" + } + }, "strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", @@ -14056,7 +14770,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=", - "dev": true, "requires": { "is-hex-prefixed": "1.0.0" } @@ -14073,6 +14786,45 @@ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true }, + "swarm-js": { + "version": "0.1.37", + "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.37.tgz", + "integrity": "sha512-G8gi5fcXP/2upwiuOShJ258sIufBVztekgobr3cVgYXObZwJ5AXLqZn52AI+/ffft29pJexF9WNdUxjlkVehoQ==", + "dev": true, + "requires": { + "bluebird": "^3.5.0", + "buffer": "^5.0.5", + "decompress": "^4.0.0", + "eth-lib": "^0.1.26", + "fs-extra": "^2.1.2", + "fs-promise": "^2.0.0", + "got": "^7.1.0", + "mime-types": "^2.1.16", + "mkdirp-promise": "^5.0.1", + "mock-fs": "^4.1.0", + "setimmediate": "^1.0.5", + "tar.gz": "^1.0.5", + "xhr-request-promise": "^0.1.2" + }, + "dependencies": { + "fs-extra": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-2.1.2.tgz", + "integrity": "sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0" + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + } + } + }, "symbol-observable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz", @@ -14236,30 +14988,85 @@ } } }, - "tar-fs": { - "version": "1.15.3", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.15.3.tgz", - "integrity": "sha1-7M+TXpQUk9gVECjmNuUc5MPKfyA=", + "tar": { + "version": "4.4.8", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.8.tgz", + "integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==", "dev": true, + "optional": true, "requires": { - "chownr": "^1.0.1", - "mkdirp": "^0.5.1", - "pump": "^1.0.0", - "tar-stream": "^1.1.2" + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "optional": true + }, + "yallist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "dev": true, + "optional": true + } } }, "tar-stream": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.4.tgz", - "integrity": "sha1-NlSc8E7RrumyowwBQyUiONr5QBY=", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", + "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", "dev": true, "requires": { "bl": "^1.0.0", + "buffer-alloc": "^1.2.0", "end-of-stream": "^1.0.0", - "readable-stream": "^2.0.0", + "fs-constants": "^1.0.0", + "readable-stream": "^2.3.0", + "to-buffer": "^1.1.1", "xtend": "^4.0.0" } }, + "tar.gz": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/tar.gz/-/tar.gz-1.0.7.tgz", + "integrity": "sha512-uhGatJvds/3diZrETqMj4RxBR779LKlIE74SsMcn5JProZsfs9j0QBwWO1RW+IWNJxS2x8Zzra1+AW6OQHWphg==", + "dev": true, + "requires": { + "bluebird": "^2.9.34", + "commander": "^2.8.1", + "fstream": "^1.0.8", + "mout": "^0.11.0", + "tar": "^2.1.1" + }, + "dependencies": { + "bluebird": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz", + "integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=", + "dev": true + }, + "tar": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", + "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "dev": true, + "requires": { + "block-stream": "*", + "fstream": "^1.0.2", + "inherits": "2" + } + } + } + }, "temp": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.3.tgz", @@ -14275,6 +15082,42 @@ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=", "dev": true + }, + "shelljs": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.2.tgz", + "integrity": "sha512-pRXeNrCA2Wd9itwhvLp5LZQvPJ0wU6bcjaTMywHHGX5XWhVN2nzSu7WV0q+oUY7mGK3mgSkDDzP3MgjqdyIgbQ==", + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "requires": { + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=" + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "requires": { + "has-flag": "^3.0.0" + } } } }, @@ -14287,14 +15130,30 @@ "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" }, "textextensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/textextensions/-/textextensions-2.2.0.tgz", - "integrity": "sha512-j5EMxnryTvKxwH2Cq+Pb43tsf6sdEgw6Pdwxk83mPaq0ToeFJt6WE4J3s5BqY7vmjlLgkgXvhtXUxo80FyBhCA==", - "dev": true + "integrity": "sha512-j5EMxnryTvKxwH2Cq+Pb43tsf6sdEgw6Pdwxk83mPaq0ToeFJt6WE4J3s5BqY7vmjlLgkgXvhtXUxo80FyBhCA==" + }, + "thenify": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz", + "integrity": "sha1-5p44obq+lpsBCCB5eLn2K4hgSDk=", + "dev": true, + "requires": { + "any-promise": "^1.0.0" + } + }, + "thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=", + "dev": true, + "requires": { + "thenify": ">= 3.1.0 < 4" + } }, "through": { "version": "2.3.8", @@ -14303,20 +15162,47 @@ "dev": true }, "through2": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", - "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", - "dev": true, + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", "requires": { - "readable-stream": "^2.1.5", + "readable-stream": "~2.3.6", "xtend": "~4.0.1" + }, + "dependencies": { + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } } }, "timed-out": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", - "dev": true + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=" }, "tmp": { "version": "0.0.33", @@ -14327,6 +15213,12 @@ "os-tmpdir": "~1.0.2" } }, + "to-buffer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", + "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", + "dev": true + }, "to-fast-properties": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", @@ -14337,7 +15229,6 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, "requires": { "kind-of": "^3.0.2" } @@ -14346,7 +15237,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, "requires": { "define-property": "^2.0.2", "extend-shallow": "^3.0.2", @@ -14358,7 +15248,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, "requires": { "is-number": "^3.0.0", "repeat-string": "^1.6.1" @@ -14368,7 +15257,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, "requires": { "kind-of": "^3.0.2" } @@ -14379,7 +15267,6 @@ "version": "2.3.4", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", - "dev": true, "requires": { "punycode": "^1.4.1" } @@ -14406,8 +15293,7 @@ "trim": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", - "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=", - "dev": true + "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=" }, "trim-right": { "version": "1.0.1", @@ -14427,17 +15313,17 @@ } }, "truffle-artifactor": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/truffle-artifactor/-/truffle-artifactor-3.0.7.tgz", - "integrity": "sha1-xdwLNdD6dutRkNsgj+++0c4k0D0=", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/truffle-artifactor/-/truffle-artifactor-3.0.8.tgz", + "integrity": "sha512-FlJp5qIyqrBkmuNOxhe/m4Bnj/QPMdkL6idSsY4qQhsKK94CcF1YVyd1odcxjUNo60gCHSKdbGiW4umCdfwD9g==", "dev": true, "requires": { "async": "2.6.1", "debug": "^3.1.0", "fs-extra": "6.0.1", "lodash": "4.17.10", - "truffle-contract": "^3.0.6", - "truffle-contract-schema": "^2.0.1", + "truffle-contract": "^3.0.7", + "truffle-contract-schema": "^2.0.2", "truffle-expect": "^0.0.4" }, "dependencies": { @@ -14450,6 +15336,16 @@ "lodash": "^4.17.10" } }, + "bignumber.js": { + "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", + "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git" + }, + "bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", + "dev": true + }, "crypto-js": { "version": "3.1.9-1", "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.1.9-1.tgz", @@ -14465,6 +15361,17 @@ "ms": "^2.1.1" } }, + "ethjs-abi": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/ethjs-abi/-/ethjs-abi-0.1.8.tgz", + "integrity": "sha1-zSiFg+1ijN+tr4re+juh28vKbBg=", + "dev": true, + "requires": { + "bn.js": "4.11.6", + "js-sha3": "0.5.5", + "number-to-bn": "1.7.0" + } + }, "fs-extra": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-6.0.1.tgz", @@ -14476,6 +15383,12 @@ "universalify": "^0.1.0" } }, + "js-sha3": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.5.tgz", + "integrity": "sha1-uvDA6MVK1ZA0R9+Wreekobynmko=", + "dev": true + }, "jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", @@ -14485,22 +15398,71 @@ "graceful-fs": "^4.1.6" } }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + }, "ms": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", "dev": true }, + "truffle-blockchain-utils": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/truffle-blockchain-utils/-/truffle-blockchain-utils-0.0.5.tgz", + "integrity": "sha1-pOXAZNrdafeCoTfz0nbSEJXaekc=", + "dev": true + }, + "truffle-contract": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/truffle-contract/-/truffle-contract-3.0.7.tgz", + "integrity": "sha512-av4MTJDP29PI3oVh8TrvRzRHt+nZJH8ODSiil/TfcXrKMSes52DTA5LHj00siLvcadkxUgoEZfEZ04qqhNGoiA==", + "dev": true, + "requires": { + "ethjs-abi": "0.1.8", + "truffle-blockchain-utils": "^0.0.5", + "truffle-contract-schema": "^2.0.2", + "truffle-error": "^0.0.3", + "web3": "0.20.6" + } + }, "truffle-contract-schema": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/truffle-contract-schema/-/truffle-contract-schema-2.0.1.tgz", - "integrity": "sha1-m/gh0y4m5nS6FetdQPlrELHJ1Wg=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/truffle-contract-schema/-/truffle-contract-schema-2.0.2.tgz", + "integrity": "sha512-8mYAu0Y7wgMqcIa612dxiN9pzr6rq2YxZCzPizvqyDq+/rGWy8s0irl/T7i92a/4ME1V5ddNFf3+86uIlYbPUg==", "dev": true, "requires": { "ajv": "^5.1.1", "crypto-js": "^3.1.9-1", "debug": "^3.1.0" } + }, + "web3": { + "version": "0.20.6", + "resolved": "https://registry.npmjs.org/web3/-/web3-0.20.6.tgz", + "integrity": "sha1-PpcwauAk+yThCj11yIQwJWIhUSA=", + "dev": true, + "requires": { + "crypto-js": "^3.1.4", + "utf8": "^2.1.1", + "xhr2": "*", + "xmlhttprequest": "*" + }, + "dependencies": { + "bignumber.js": { + "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", + "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934" + }, + "crypto-js": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.1.8.tgz", + "integrity": "sha1-cV8HC/YBTyrpkqmLOSkli3E/CNU=", + "dev": true + } + } } } }, @@ -14515,8 +15477,7 @@ "dependencies": { "bignumber.js": { "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", - "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git", - "dev": true + "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git" }, "web3": { "version": "0.20.7", @@ -14524,28 +15485,66 @@ "integrity": "sha512-VU6/DSUX93d1fCzBz7WP/SGCQizO1rKZi4Px9j/3yRyfssHyFcZamMw2/sj4E8TlfMXONvZLoforR8B4bRoyTQ==", "dev": true, "requires": { - "bignumber.js": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", "crypto-js": "^3.1.4", "utf8": "^2.1.1", "xhr2-cookies": "^1.1.0", "xmlhttprequest": "*" + }, + "dependencies": { + "bignumber.js": { + "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", + "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934" + } } } } }, "truffle-box": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/truffle-box/-/truffle-box-1.0.7.tgz", - "integrity": "sha1-2PkNq6wC8DmkOQgPXVbuovXd7/4=", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/truffle-box/-/truffle-box-1.0.10.tgz", + "integrity": "sha512-y+GsmCI5s5s/Wqu/mqbJYnfCYIuTX8QX5zmA0on+p24JdrXV8yQCnOw9ub7lwGpiAattVuEksE91etJCa9/DeQ==", "dev": true, "requires": { "fs-extra": "6.0.1", "github-download": "^0.5.0", - "request": "^2.83.0", + "ora": "^3.0.0", + "request": "^2.85.0", "tmp": "0.0.33", "vcsurl": "^0.1.1" }, "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "cli-spinners": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-1.3.1.tgz", + "integrity": "sha512-1QL4544moEsDVH9T/l6Cemov/37iv1RtoKf7NJ04A60+4MREXNfx/QvavbH6QoGdsD4N4Mwy49cmaINR/o2mdg==", + "dev": true + }, "fs-extra": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-6.0.1.tgz", @@ -14565,27 +15564,59 @@ "requires": { "graceful-fs": "^4.1.6" } + }, + "ora": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-3.0.0.tgz", + "integrity": "sha512-LBS97LFe2RV6GJmXBi6OKcETKyklHNMV0xw7BtsVn2MlsgsydyZetSCbCANr+PFLmDyv4KV88nn0eCKza665Mg==", + "dev": true, + "requires": { + "chalk": "^2.3.1", + "cli-cursor": "^2.1.0", + "cli-spinners": "^1.1.0", + "log-symbols": "^2.2.0", + "strip-ansi": "^4.0.0", + "wcwidth": "^1.0.1" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } } } }, "truffle-code-utils": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/truffle-code-utils/-/truffle-code-utils-1.1.1.tgz", - "integrity": "sha1-AGG+BvoBSijxtDq0ZNNDPKfUW8M=", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/truffle-code-utils/-/truffle-code-utils-1.1.3.tgz", + "integrity": "sha512-3m8lSZF1Ek0lW/+1by3+099Jm/EqQ2yvAR9ykWRLStMx6S3hPiw/9SIkLip2IlPbV6gjv+JDLpRSNnjcPuRTDg==", "dev": true }, "truffle-compile": { - "version": "3.0.13", - "resolved": "https://registry.npmjs.org/truffle-compile/-/truffle-compile-3.0.13.tgz", - "integrity": "sha1-rOcluhipXN5fm/H/CXJL0pH2lU4=", + "version": "3.0.14", + "resolved": "https://registry.npmjs.org/truffle-compile/-/truffle-compile-3.0.14.tgz", + "integrity": "sha512-eU6DOVsgdz6EhoHCbqqcm0MnVghCERyBgfhJJM/PA7tjvWSbhQLKcYtVZqxOJ2qs40A13svpt2Ks3ufQqOvh5A==", "dev": true, "requires": { "async": "2.6.1", "colors": "^1.1.2", "debug": "^3.1.0", "graphlib": "^2.1.1", - "solc": "0.4.24", - "truffle-config": "^1.0.6", + "solc": "0.4.25", + "truffle-config": "^1.0.7", "truffle-contract-sources": "^0.0.2", "truffle-error": "^0.0.3", "truffle-expect": "^0.0.4" @@ -14600,6 +15631,12 @@ "lodash": "^4.17.10" } }, + "bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", + "dev": true + }, "debug": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", @@ -14609,11 +15646,140 @@ "ms": "^2.1.1" } }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, "ms": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", "dev": true + }, + "solc": { + "version": "0.4.25", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.25.tgz", + "integrity": "sha512-jU1YygRVy6zatgXrLY2rRm7HW1d7a8CkkEgNJwvH2VLpWhMFsMdWcJn6kUqZwcSz/Vm+w89dy7Z/aB5p6AFTrg==", + "dev": true, + "requires": { + "fs-extra": "^0.30.0", + "memorystream": "^0.3.1", + "require-from-string": "^1.1.0", + "semver": "^5.3.0", + "yargs": "^4.7.1" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "truffle-config": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/truffle-config/-/truffle-config-1.1.2.tgz", + "integrity": "sha512-TfvE5KCTZSXPfEZ8xgs25sOY7uR1xnE52dYPj+arLlaMw1UmMWcIts97HqqK+jVGeKlMPQu2/PwN5m18c+91Fg==", + "dev": true, + "requires": { + "configstore": "^4.0.0", + "find-up": "^2.1.0", + "lodash": "4.17.10", + "original-require": "1.0.1", + "truffle-error": "^0.0.3", + "truffle-provider": "^0.1.2" + }, + "dependencies": { + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + } + } + }, + "truffle-provider": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/truffle-provider/-/truffle-provider-0.1.2.tgz", + "integrity": "sha512-UcHfKydFzZsVyX7uedbNduEU3Po0BlFUI4Sg4jpuLUQUkPZiY8UZkRLAdhBgwjP0W0AEDFtK8VCoffwUxNicQw==", + "dev": true, + "requires": { + "truffle-error": "^0.0.3", + "web3": "^1.0.0-beta.37" + } + }, + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", + "dev": true + }, + "utf8": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.1.tgz", + "integrity": "sha1-LgHbAvfY0JRPdxBPFgnrDDBM92g=", + "dev": true + }, + "web3": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3/-/web3-1.0.0-beta.37.tgz", + "integrity": "sha512-8XLgUspdzicC/xHG82TLrcF/Fxzj2XYNJ1KTYnepOI77bj5rvpsxxwHYBWQ6/JOjk0HkZqoBfnXWgcIHCDhZhQ==", + "dev": true, + "requires": { + "web3-bzz": "1.0.0-beta.37", + "web3-core": "1.0.0-beta.37", + "web3-eth": "1.0.0-beta.37", + "web3-eth-personal": "1.0.0-beta.37", + "web3-net": "1.0.0-beta.37", + "web3-shh": "1.0.0-beta.37", + "web3-utils": "1.0.0-beta.37" + } + }, + "web3-utils": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.0.0-beta.37.tgz", + "integrity": "sha512-kA1fyhO8nKgU21wi30oJQ/ssvu+9srMdjOTKbHYbQe4ATPcr5YNwwrxG3Bcpbu1bEwRUVKHCkqi+wTvcAWBdlQ==", + "dev": true, + "requires": { + "bn.js": "4.11.6", + "eth-lib": "0.1.27", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randomhex": "0.1.5", + "underscore": "1.8.3", + "utf8": "2.1.1" + } + }, + "yargs": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", + "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=", + "dev": true, + "requires": { + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "lodash.assign": "^4.0.3", + "os-locale": "^1.4.0", + "read-pkg-up": "^1.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^1.0.1", + "which-module": "^1.0.0", + "window-size": "^0.2.0", + "y18n": "^3.2.1", + "yargs-parser": "^2.4.1" + } } } }, @@ -14638,6 +15804,12 @@ "requires": { "locate-path": "^2.0.0" } + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true } } }, @@ -14656,8 +15828,7 @@ "dependencies": { "bignumber.js": { "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", - "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git", - "dev": true + "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git" }, "bn.js": { "version": "4.11.6", @@ -14733,6 +15904,11 @@ "xmlhttprequest": "*" }, "dependencies": { + "bignumber.js": { + "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", + "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", + "dev": true + }, "crypto-js": { "version": "3.1.8", "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.1.8.tgz", @@ -14781,13 +15957,13 @@ } }, "truffle-debug-utils": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/truffle-debug-utils/-/truffle-debug-utils-1.0.6.tgz", - "integrity": "sha1-jNrxt6SZSWZGeLKQdP2JGJ0Z4TU=", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/truffle-debug-utils/-/truffle-debug-utils-1.0.8.tgz", + "integrity": "sha512-EbmDb9BluFSPV8G9ZoVfPry7xfaVLtnv0Y0yHZq7NlSERLyEuTNSjNdKJMTOeJ6SoZAS8+Tl1Q844YqbTRDrwg==", "dev": true, "requires": { "async": "2.6.1", - "debug": "^3.1.0", + "debug": "^4.1.0", "node-dir": "0.1.17" }, "dependencies": { @@ -14801,9 +15977,9 @@ } }, "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, "requires": { "ms": "^2.1.1" @@ -14883,7 +16059,7 @@ "dependencies": { "bignumber.js": { "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", - "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git", + "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", "dev": true } } @@ -14968,18 +16144,6 @@ } } }, - "truffle-hdwallet-provider": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/truffle-hdwallet-provider/-/truffle-hdwallet-provider-0.0.5.tgz", - "integrity": "sha512-dVVcHIOy7DRwVs+BeDt39pvHnHak1zb1BQ30pHaux7fmxk/T/TJVKp18D584qCWnCbnSt8bMdB3XxALPLXIbVw==", - "dev": true, - "requires": { - "bip39": "^2.2.0", - "ethereumjs-wallet": "^0.6.0", - "web3": "^0.18.2", - "web3-provider-engine": "^14.0.5" - } - }, "truffle-init": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/truffle-init/-/truffle-init-1.0.7.tgz", @@ -15040,8 +16204,7 @@ }, "bignumber.js": { "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", - "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git", - "dev": true + "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git" }, "node-dir": { "version": "0.1.17", @@ -15063,6 +16226,13 @@ "utf8": "^2.1.1", "xhr2": "*", "xmlhttprequest": "*" + }, + "dependencies": { + "bignumber.js": { + "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", + "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", + "dev": true + } } } } @@ -15079,8 +16249,7 @@ "dependencies": { "bignumber.js": { "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", - "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git", - "dev": true + "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git" }, "web3": { "version": "0.20.6", @@ -15093,6 +16262,13 @@ "utf8": "^2.1.1", "xhr2": "*", "xmlhttprequest": "*" + }, + "dependencies": { + "bignumber.js": { + "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", + "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", + "dev": true + } } } } @@ -15117,8 +16293,7 @@ "dependencies": { "bignumber.js": { "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", - "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git", - "dev": true + "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git" }, "web3": { "version": "0.20.6", @@ -15131,6 +16306,13 @@ "utf8": "^2.1.1", "xhr2": "*", "xmlhttprequest": "*" + }, + "dependencies": { + "bignumber.js": { + "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", + "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", + "dev": true + } } } } @@ -15159,25 +16341,25 @@ } }, "truffle-solidity-utils": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/truffle-solidity-utils/-/truffle-solidity-utils-1.1.2.tgz", - "integrity": "sha1-giZyC+nP2uAiGTROPx7Tmu+atfQ=", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/truffle-solidity-utils/-/truffle-solidity-utils-1.2.1.tgz", + "integrity": "sha512-ROITGiAgWjSLgq/2L+I8eOEaLB5YKyaOPvKdq0yhga9S20tEScbgeWx5CjtNWHjkBLUkxBKJ12xH3WIqg1AV5Q==", "dev": true }, "truffle-workflow-compile": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/truffle-workflow-compile/-/truffle-workflow-compile-1.0.6.tgz", - "integrity": "sha1-XFwY1J0hjULxwycESDLZnx2L9S0=", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/truffle-workflow-compile/-/truffle-workflow-compile-1.0.7.tgz", + "integrity": "sha512-3RSqHs/XYNH5O2PySUARAfB6uvYwUgvSt/eF6yjPMkdIwQ84Sd3pcM/qg56bR2aeeoBVFrDAHaCQRxtltiItSA==", "dev": true, "requires": { "async": "2.6.1", "lodash": "4.17.10", "mkdirp": "^0.5.1", - "truffle-artifactor": "^3.0.7", - "truffle-compile": "^3.0.13", - "truffle-config": "^1.0.6", + "truffle-artifactor": "^3.0.8", + "truffle-compile": "^3.0.14", + "truffle-config": "^1.0.7", "truffle-expect": "^0.0.4", - "truffle-resolver": "^4.0.4" + "truffle-resolver": "^4.0.5" }, "dependencies": { "async": { @@ -15188,6 +16370,201 @@ "requires": { "lodash": "^4.17.10" } + }, + "bignumber.js": { + "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", + "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git" + }, + "bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", + "dev": true + }, + "crypto-js": { + "version": "3.1.9-1", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.1.9-1.tgz", + "integrity": "sha1-/aGedh/Ad+Af+/3G6f38WeiAbNg=", + "dev": true + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ethjs-abi": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/ethjs-abi/-/ethjs-abi-0.1.8.tgz", + "integrity": "sha1-zSiFg+1ijN+tr4re+juh28vKbBg=", + "dev": true, + "requires": { + "bn.js": "4.11.6", + "js-sha3": "0.5.5", + "number-to-bn": "1.7.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "js-sha3": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.5.tgz", + "integrity": "sha1-uvDA6MVK1ZA0R9+Wreekobynmko=", + "dev": true + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "truffle-blockchain-utils": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/truffle-blockchain-utils/-/truffle-blockchain-utils-0.0.5.tgz", + "integrity": "sha1-pOXAZNrdafeCoTfz0nbSEJXaekc=", + "dev": true + }, + "truffle-config": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/truffle-config/-/truffle-config-1.1.2.tgz", + "integrity": "sha512-TfvE5KCTZSXPfEZ8xgs25sOY7uR1xnE52dYPj+arLlaMw1UmMWcIts97HqqK+jVGeKlMPQu2/PwN5m18c+91Fg==", + "dev": true, + "requires": { + "configstore": "^4.0.0", + "find-up": "^2.1.0", + "lodash": "4.17.10", + "original-require": "1.0.1", + "truffle-error": "^0.0.3", + "truffle-provider": "^0.1.2" + } + }, + "truffle-contract": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/truffle-contract/-/truffle-contract-3.0.7.tgz", + "integrity": "sha512-av4MTJDP29PI3oVh8TrvRzRHt+nZJH8ODSiil/TfcXrKMSes52DTA5LHj00siLvcadkxUgoEZfEZ04qqhNGoiA==", + "dev": true, + "requires": { + "ethjs-abi": "0.1.8", + "truffle-blockchain-utils": "^0.0.5", + "truffle-contract-schema": "^2.0.2", + "truffle-error": "^0.0.3", + "web3": "0.20.6" + }, + "dependencies": { + "bignumber.js": { + "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", + "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934" + }, + "crypto-js": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.1.8.tgz", + "integrity": "sha1-cV8HC/YBTyrpkqmLOSkli3E/CNU=", + "dev": true + }, + "web3": { + "version": "0.20.6", + "resolved": "https://registry.npmjs.org/web3/-/web3-0.20.6.tgz", + "integrity": "sha1-PpcwauAk+yThCj11yIQwJWIhUSA=", + "dev": true, + "requires": { + "crypto-js": "^3.1.4", + "utf8": "^2.1.1", + "xhr2": "*", + "xmlhttprequest": "*" + } + } + } + }, + "truffle-contract-schema": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/truffle-contract-schema/-/truffle-contract-schema-2.0.2.tgz", + "integrity": "sha512-8mYAu0Y7wgMqcIa612dxiN9pzr6rq2YxZCzPizvqyDq+/rGWy8s0irl/T7i92a/4ME1V5ddNFf3+86uIlYbPUg==", + "dev": true, + "requires": { + "ajv": "^5.1.1", + "crypto-js": "^3.1.9-1", + "debug": "^3.1.0" + } + }, + "truffle-provider": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/truffle-provider/-/truffle-provider-0.1.2.tgz", + "integrity": "sha512-UcHfKydFzZsVyX7uedbNduEU3Po0BlFUI4Sg4jpuLUQUkPZiY8UZkRLAdhBgwjP0W0AEDFtK8VCoffwUxNicQw==", + "dev": true, + "requires": { + "truffle-error": "^0.0.3", + "web3": "^1.0.0-beta.37" + } + }, + "truffle-resolver": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/truffle-resolver/-/truffle-resolver-4.0.5.tgz", + "integrity": "sha512-aqPxo+bpL9yjfpSptvkV35WmkceBY4HbQGiUT2Rhx9cttNi0dQnPWL89inpQnBEqr1aLP9LxbZ+sai0PHKAD0w==", + "dev": true, + "requires": { + "async": "2.6.1", + "truffle-contract": "^3.0.7", + "truffle-expect": "^0.0.4", + "truffle-provisioner": "^0.1.1" + } + }, + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", + "dev": true + }, + "utf8": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.1.tgz", + "integrity": "sha1-LgHbAvfY0JRPdxBPFgnrDDBM92g=", + "dev": true + }, + "web3": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3/-/web3-1.0.0-beta.37.tgz", + "integrity": "sha512-8XLgUspdzicC/xHG82TLrcF/Fxzj2XYNJ1KTYnepOI77bj5rvpsxxwHYBWQ6/JOjk0HkZqoBfnXWgcIHCDhZhQ==", + "dev": true, + "requires": { + "web3-bzz": "1.0.0-beta.37", + "web3-core": "1.0.0-beta.37", + "web3-eth": "1.0.0-beta.37", + "web3-eth-personal": "1.0.0-beta.37", + "web3-net": "1.0.0-beta.37", + "web3-shh": "1.0.0-beta.37", + "web3-utils": "1.0.0-beta.37" + } + }, + "web3-utils": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.0.0-beta.37.tgz", + "integrity": "sha512-kA1fyhO8nKgU21wi30oJQ/ssvu+9srMdjOTKbHYbQe4ATPcr5YNwwrxG3Bcpbu1bEwRUVKHCkqi+wTvcAWBdlQ==", + "dev": true, + "requires": { + "bn.js": "4.11.6", + "eth-lib": "0.1.27", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randomhex": "0.1.5", + "underscore": "1.8.3", + "utf8": "2.1.1" + } } } }, @@ -15205,7 +16582,7 @@ }, "tunnel": { "version": "0.0.2", - "resolved": "http://registry.npmjs.org/tunnel/-/tunnel-0.0.2.tgz", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.2.tgz", "integrity": "sha1-8jvNi3p7ioZCYbIIT2b5MZM5YzQ=", "dev": true }, @@ -15213,7 +16590,6 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, "requires": { "safe-buffer": "^5.0.1" } @@ -15221,9 +16597,7 @@ "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true, - "optional": true + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, "type-check": { "version": "0.3.2", @@ -15244,7 +16618,6 @@ "version": "1.6.16", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", - "dev": true, "requires": { "media-typer": "0.3.0", "mime-types": "~2.1.18" @@ -15253,16 +16626,86 @@ "mime-db": { "version": "1.33.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", - "dev": true + "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==" }, - "mime-types": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", - "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", - "dev": true, + "v8-compile-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.0.tgz", + "integrity": "sha512-qNdTUMaCjPs4eEnM3W9H94R3sU70YCuT+/ST7nUf+id1bVOrdjrpUaeZLqPBPRph3hsgn4a4BvwpxhHZx+oSDg==" + }, + "vinyl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz", + "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==", "requires": { - "mime-db": "~1.33.0" + "clone": "^2.1.1", + "clone-buffer": "^1.0.0", + "cloneable-readable": "^1.0.0", + "remove-trailing-separator": "^1.0.1" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + }, + "yargs": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", + "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==", + "requires": { + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^9.0.2" + } + }, + "yargs-parser": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz", + "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=" + }, + "yeoman-environment": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/yeoman-environment/-/yeoman-environment-2.3.0.tgz", + "integrity": "sha512-PHSAkVOqYdcR+C+Uht1SGC4eVD/9OhygYFkYaI66xF8vKIeS1RNYay+umj2ZrQeJ50tF5Q/RSO6qGDz9y3Ifug==", + "requires": { + "diff": "^3.3.1", + "escape-string-regexp": "^1.0.2", + "grouped-queue": "^0.3.3", + "is-scoped": "^1.0.0", + "lodash": "^4.17.10", + "log-symbols": "^2.1.0", + "mem-fs": "^1.1.0", + "text-table": "^0.2.0" + } + }, + "yeoman-generator": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/yeoman-generator/-/yeoman-generator-2.0.5.tgz", + "integrity": "sha512-rV6tJ8oYzm4mmdF2T3wjY+Q42jKF2YiiD0VKfJ8/0ZYwmhCKC9Xs2346HVLPj/xE13i68psnFJv7iS6gWRkeAg==", + "requires": { + "cli-table": "^0.3.1", + "dargs": "^5.1.0", + "dateformat": "^3.0.3", + "detect-conflict": "^1.0.0", + "error": "^7.0.2", + "github-username": "^4.0.0", + "istextorbinary": "^2.2.1", + "lodash": "^4.17.10", + "make-dir": "^1.1.0", + "mem-fs-editor": "^4.0.0", + "pretty-bytes": "^4.0.2", + "read-chunk": "^2.1.0", + "run-async": "^2.0.0", + "text-table": "^0.2.0", + "through2": "^2.0.0", + "yeoman-environment": "^2.0.5" } } } @@ -15295,8 +16738,36 @@ "ultron": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", - "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", - "dev": true + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==" + }, + "unbzip2-stream": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.3.1.tgz", + "integrity": "sha512-fIZnvdjblYs7Cru/xC6tCPVhz7JkYcVQQkePwMLyQELzYTds2Xn8QefPVnvdVhhZqubxNA1cASXEH5wcK0Bucw==", + "dev": true, + "requires": { + "buffer": "^3.0.1", + "through": "^2.3.6" + }, + "dependencies": { + "base64-js": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz", + "integrity": "sha1-EQHpVE9KdrG8OybUUsqW16NeeXg=", + "dev": true + }, + "buffer": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-3.6.0.tgz", + "integrity": "sha1-pyyTb3e5a/UvX357RnGAYoVR3vs=", + "dev": true, + "requires": { + "base64-js": "0.0.8", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + } + } }, "underscore": { "version": "1.6.0", @@ -15308,7 +16779,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", - "dev": true, "requires": { "arr-union": "^3.1.0", "get-value": "^2.0.6", @@ -15320,7 +16790,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, "requires": { "is-extendable": "^0.1.0" } @@ -15329,7 +16798,6 @@ "version": "0.4.3", "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", - "dev": true, "requires": { "extend-shallow": "^2.0.1", "is-extendable": "^0.1.1", @@ -15339,29 +16807,30 @@ } } }, + "unique-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", + "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", + "dev": true, + "requires": { + "crypto-random-string": "^1.0.0" + } + }, "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true }, - "unorm": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.4.1.tgz", - "integrity": "sha1-NkIA1fE2RsqLzURJAnEzVhR5IwA=", - "dev": true - }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "dev": true + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" }, "unset-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, "requires": { "has-value": "^0.3.1", "isobject": "^3.0.0" @@ -15371,7 +16840,6 @@ "version": "0.3.1", "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, "requires": { "get-value": "^2.0.3", "has-values": "^0.1.4", @@ -15382,7 +16850,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, "requires": { "isarray": "1.0.0" } @@ -15392,34 +16859,41 @@ "has-values": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" }, "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "minimist": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + } + } + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true } } }, - "untildify": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/untildify/-/untildify-3.0.2.tgz", - "integrity": "sha1-fx8wIFWz/qDz6B3HjrNnZstl4/E=", - "dev": true - }, - "unzip-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-1.0.2.tgz", - "integrity": "sha1-uYTwh3/AqJwsdzzB73tbIytbBv4=", - "dev": true - }, "urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" }, "url-parse-lax": { "version": "3.0.0", @@ -15433,20 +16907,17 @@ "url-set-query": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz", - "integrity": "sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk=", - "dev": true + "integrity": "sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk=" }, "url-to-options": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", - "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=", - "dev": true + "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=" }, "use": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/use/-/use-3.1.0.tgz", "integrity": "sha512-6UJEQM/L+mzC3ZJNM56Q4DFGLX/evKGRg15UJHGB9X5j5Z3AFbgZvjUh2yq/UJUY4U5dh7Fal++XbNg1uzpRAw==", - "dev": true, "requires": { "kind-of": "^6.0.2" }, @@ -15454,8 +16925,7 @@ "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" } } }, @@ -15474,19 +16944,22 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "dev": true + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" }, "uuid": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.0.tgz", - "integrity": "sha512-ijO9N2xY/YaOqQ5yz5c4sy2ZjWmA6AR6zASb/gdpeKZ8+948CxwfMW9RrKVk5may6ev8c0/Xguu32e2Llelpqw==", + "integrity": "sha512-ijO9N2xY/YaOqQ5yz5c4sy2ZjWmA6AR6zASb/gdpeKZ8+948CxwfMW9RrKVk5may6ev8c0/Xguu32e2Llelpqw==" + }, + "v8-compile-cache": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.2.tgz", + "integrity": "sha512-1wFuMUIM16MDJRCrpbpuEPTUGmM5QMUg0cr3KFwra2XgOgFcPGDQHDh3CszSCD2Zewc/dh/pamNEW8CbfDebUw==", "dev": true }, "v8flags": { @@ -15511,8 +16984,7 @@ "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "dev": true + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" }, "vcsurl": { "version": "0.1.1", @@ -15524,7 +16996,6 @@ "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, "requires": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", @@ -15535,7 +17006,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", - "dev": true, "requires": { "clone": "^1.0.0", "clone-stats": "^0.0.1", @@ -15545,8 +17015,7 @@ "clone": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", - "dev": true + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=" } } }, @@ -15554,7 +17023,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/vinyl-file/-/vinyl-file-2.0.0.tgz", "integrity": "sha1-p+v1/779obfRjRQPyweyI++2dRo=", - "dev": true, "requires": { "graceful-fs": "^4.1.2", "pify": "^2.3.0", @@ -15562,6 +17030,22 @@ "strip-bom": "^2.0.0", "strip-bom-stream": "^2.0.0", "vinyl": "^1.1.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + } + } + }, + "wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "dev": true, + "requires": { + "defaults": "^1.0.3" } }, "web3": { @@ -15577,15 +17061,35 @@ "xmlhttprequest": "*" } }, - "web3-eth-abi": { - "version": "1.0.0-beta.36", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.0.0-beta.36.tgz", - "integrity": "sha512-fBfW+7hvA0rxEMV45fO7JU+0R32ayT7aRwG9Cl6NW2/QvhFeME2qVbMIWw0q5MryPZGIN8A6366hKNuWvVidDg==", + "web3-bzz": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.0.0-beta.37.tgz", + "integrity": "sha512-E+dho49Nsm/QpQvYWOF35YDsQrMvLB19AApENxhlQsu6HpWQt534DQul0t3Y/aAh8rlKD6Kanxt8LhHDG3vejQ==", "dev": true, "requires": { - "ethers": "4.0.0-beta.1", - "underscore": "1.8.3", - "web3-utils": "1.0.0-beta.36" + "got": "7.1.0", + "swarm-js": "0.1.37", + "underscore": "1.8.3" + }, + "dependencies": { + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", + "dev": true + } + } + }, + "web3-core": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.0.0-beta.37.tgz", + "integrity": "sha512-cIwEqCj7OJyefQNauI0HOgW4sSaOQ98V99H2/HEIlnCZylsDzfw7gtQUdwnRFiIyIxjbWy3iWsjwDPoXNPZBYg==", + "dev": true, + "requires": { + "web3-core-helpers": "1.0.0-beta.37", + "web3-core-method": "1.0.0-beta.37", + "web3-core-requestmanager": "1.0.0-beta.37", + "web3-utils": "1.0.0-beta.37" }, "dependencies": { "bn.js": { @@ -15607,9 +17111,583 @@ "dev": true }, "web3-utils": { - "version": "1.0.0-beta.36", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.0.0-beta.36.tgz", - "integrity": "sha512-7ri74lG5fS2Th0fhYvTtiEHMB1Pmf2p7dQx1COQ3OHNI/CHNEMjzoNMEbBU6FAENrywfoFur40K4m0AOmEUq5A==", + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.0.0-beta.37.tgz", + "integrity": "sha512-kA1fyhO8nKgU21wi30oJQ/ssvu+9srMdjOTKbHYbQe4ATPcr5YNwwrxG3Bcpbu1bEwRUVKHCkqi+wTvcAWBdlQ==", + "dev": true, + "requires": { + "bn.js": "4.11.6", + "eth-lib": "0.1.27", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randomhex": "0.1.5", + "underscore": "1.8.3", + "utf8": "2.1.1" + } + } + } + }, + "web3-core-helpers": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.0.0-beta.37.tgz", + "integrity": "sha512-efaLOzN28RMnbugnyelgLwPWWaSwElQzcAJ/x3PZu+uPloM/lE5x0YuBKvIh7/PoSMlHqtRWj1B8CpuQOUQ5Ew==", + "dev": true, + "requires": { + "underscore": "1.8.3", + "web3-eth-iban": "1.0.0-beta.37", + "web3-utils": "1.0.0-beta.37" + }, + "dependencies": { + "bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", + "dev": true + }, + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", + "dev": true + }, + "utf8": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.1.tgz", + "integrity": "sha1-LgHbAvfY0JRPdxBPFgnrDDBM92g=", + "dev": true + }, + "web3-utils": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.0.0-beta.37.tgz", + "integrity": "sha512-kA1fyhO8nKgU21wi30oJQ/ssvu+9srMdjOTKbHYbQe4ATPcr5YNwwrxG3Bcpbu1bEwRUVKHCkqi+wTvcAWBdlQ==", + "dev": true, + "requires": { + "bn.js": "4.11.6", + "eth-lib": "0.1.27", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randomhex": "0.1.5", + "underscore": "1.8.3", + "utf8": "2.1.1" + } + } + } + }, + "web3-core-method": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.0.0-beta.37.tgz", + "integrity": "sha512-pKWFUeqnVmzx3VrZg+CseSdrl/Yrk2ioid/HzolNXZE6zdoITZL0uRjnsbqXGEzgRRd1Oe/pFndpTlRsnxXloA==", + "dev": true, + "requires": { + "underscore": "1.8.3", + "web3-core-helpers": "1.0.0-beta.37", + "web3-core-promievent": "1.0.0-beta.37", + "web3-core-subscriptions": "1.0.0-beta.37", + "web3-utils": "1.0.0-beta.37" + }, + "dependencies": { + "bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", + "dev": true + }, + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", + "dev": true + }, + "utf8": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.1.tgz", + "integrity": "sha1-LgHbAvfY0JRPdxBPFgnrDDBM92g=", + "dev": true + }, + "web3-utils": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.0.0-beta.37.tgz", + "integrity": "sha512-kA1fyhO8nKgU21wi30oJQ/ssvu+9srMdjOTKbHYbQe4ATPcr5YNwwrxG3Bcpbu1bEwRUVKHCkqi+wTvcAWBdlQ==", + "dev": true, + "requires": { + "bn.js": "4.11.6", + "eth-lib": "0.1.27", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randomhex": "0.1.5", + "underscore": "1.8.3", + "utf8": "2.1.1" + } + } + } + }, + "web3-core-promievent": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.0.0-beta.37.tgz", + "integrity": "sha512-GTF2r1lP8nJBeA5Gxq5yZpJy9l8Fb9CXGZPfF8jHvaRdQHtm2Z+NDhqYmF833lcdkokRSyfPcXlz1mlWeClFpg==", + "dev": true, + "requires": { + "any-promise": "1.3.0", + "eventemitter3": "1.1.1" + } + }, + "web3-core-requestmanager": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.0.0-beta.37.tgz", + "integrity": "sha512-66VUqye5BGp1Zz1r8psCxdNH+GtTjaFwroum2Osx+wbC5oRjAiXkkadiitf6wRb+edodjEMPn49u7B6WGNuewQ==", + "dev": true, + "requires": { + "underscore": "1.8.3", + "web3-core-helpers": "1.0.0-beta.37", + "web3-providers-http": "1.0.0-beta.37", + "web3-providers-ipc": "1.0.0-beta.37", + "web3-providers-ws": "1.0.0-beta.37" + }, + "dependencies": { + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", + "dev": true + } + } + }, + "web3-core-subscriptions": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.0.0-beta.37.tgz", + "integrity": "sha512-FdXl8so9kwkRRWziuCSpFsAuAdg9KvpXa1fQlT16uoGcYYfxwFO/nkwyBGQzkZt7emShI2IRugcazyPCZDwkOA==", + "dev": true, + "requires": { + "eventemitter3": "1.1.1", + "underscore": "1.8.3", + "web3-core-helpers": "1.0.0-beta.37" + }, + "dependencies": { + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", + "dev": true + } + } + }, + "web3-eth": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.0.0-beta.37.tgz", + "integrity": "sha512-Eb3aGtkz3G9q+Z9DKgSQNbn/u8RtcZQQ0R4sW9hy5KK47GoT6vab5c6DiD3QWzI0BzitHzR5Ji+3VHf/hPUGgw==", + "dev": true, + "requires": { + "underscore": "1.8.3", + "web3-core": "1.0.0-beta.37", + "web3-core-helpers": "1.0.0-beta.37", + "web3-core-method": "1.0.0-beta.37", + "web3-core-subscriptions": "1.0.0-beta.37", + "web3-eth-abi": "1.0.0-beta.37", + "web3-eth-accounts": "1.0.0-beta.37", + "web3-eth-contract": "1.0.0-beta.37", + "web3-eth-ens": "1.0.0-beta.37", + "web3-eth-iban": "1.0.0-beta.37", + "web3-eth-personal": "1.0.0-beta.37", + "web3-net": "1.0.0-beta.37", + "web3-utils": "1.0.0-beta.37" + }, + "dependencies": { + "bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", + "dev": true + }, + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", + "dev": true + }, + "utf8": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.1.tgz", + "integrity": "sha1-LgHbAvfY0JRPdxBPFgnrDDBM92g=", + "dev": true + }, + "web3-utils": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.0.0-beta.37.tgz", + "integrity": "sha512-kA1fyhO8nKgU21wi30oJQ/ssvu+9srMdjOTKbHYbQe4ATPcr5YNwwrxG3Bcpbu1bEwRUVKHCkqi+wTvcAWBdlQ==", + "dev": true, + "requires": { + "bn.js": "4.11.6", + "eth-lib": "0.1.27", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randomhex": "0.1.5", + "underscore": "1.8.3", + "utf8": "2.1.1" + } + } + } + }, + "web3-eth-abi": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.0.0-beta.37.tgz", + "integrity": "sha512-g9DKZGM2OqwKp/tX3W/yihcj7mQCtJ6CXyZXEIZfuDyRBED/iSEIFfieDOd+yo16sokLMig6FG7ADhhu+19hdA==", + "dev": true, + "requires": { + "ethers": "4.0.0-beta.1", + "underscore": "1.8.3", + "web3-utils": "1.0.0-beta.37" + }, + "dependencies": { + "bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", + "dev": true + }, + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", + "dev": true + }, + "utf8": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.1.tgz", + "integrity": "sha1-LgHbAvfY0JRPdxBPFgnrDDBM92g=", + "dev": true + }, + "web3-utils": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.0.0-beta.37.tgz", + "integrity": "sha512-kA1fyhO8nKgU21wi30oJQ/ssvu+9srMdjOTKbHYbQe4ATPcr5YNwwrxG3Bcpbu1bEwRUVKHCkqi+wTvcAWBdlQ==", + "dev": true, + "requires": { + "bn.js": "4.11.6", + "eth-lib": "0.1.27", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randomhex": "0.1.5", + "underscore": "1.8.3", + "utf8": "2.1.1" + } + } + } + }, + "web3-eth-accounts": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.0.0-beta.37.tgz", + "integrity": "sha512-uvbHL62/zwo4GDmwKdqH9c/EgYd8QVnAfpVw8D3epSISpgbONNY7Hr4MRMSd/CqAP12l2Ls9JVQGLhhC83bW6g==", + "dev": true, + "requires": { + "any-promise": "1.3.0", + "crypto-browserify": "3.12.0", + "eth-lib": "0.2.7", + "scrypt.js": "0.2.0", + "underscore": "1.8.3", + "uuid": "2.0.1", + "web3-core": "1.0.0-beta.37", + "web3-core-helpers": "1.0.0-beta.37", + "web3-core-method": "1.0.0-beta.37", + "web3-utils": "1.0.0-beta.37" + }, + "dependencies": { + "eth-lib": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz", + "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=", + "dev": true, + "requires": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", + "dev": true + }, + "utf8": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.1.tgz", + "integrity": "sha1-LgHbAvfY0JRPdxBPFgnrDDBM92g=", + "dev": true + }, + "uuid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", + "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=", + "dev": true + }, + "web3-utils": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.0.0-beta.37.tgz", + "integrity": "sha512-kA1fyhO8nKgU21wi30oJQ/ssvu+9srMdjOTKbHYbQe4ATPcr5YNwwrxG3Bcpbu1bEwRUVKHCkqi+wTvcAWBdlQ==", + "dev": true, + "requires": { + "bn.js": "4.11.6", + "eth-lib": "0.1.27", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randomhex": "0.1.5", + "underscore": "1.8.3", + "utf8": "2.1.1" + }, + "dependencies": { + "bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", + "dev": true + }, + "eth-lib": { + "version": "0.1.27", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.27.tgz", + "integrity": "sha512-B8czsfkJYzn2UIEMwjc7Mbj+Cy72V+/OXH/tb44LV8jhrjizQJJ325xMOMyk3+ETa6r6oi0jsUY14+om8mQMWA==", + "dev": true, + "requires": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "keccakjs": "^0.2.1", + "nano-json-stream-parser": "^0.1.2", + "servify": "^0.1.12", + "ws": "^3.0.0", + "xhr-request-promise": "^0.1.2" + } + } + } + } + } + }, + "web3-eth-contract": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.0.0-beta.37.tgz", + "integrity": "sha512-h1B3A8Z/C7BlnTCHkrWbXZQTViDxfR12lKMeTkT8Sqj5phFmxrBlPE4ORy4lf1Dk5b23mZYE0r/IRACx4ThCrQ==", + "dev": true, + "requires": { + "underscore": "1.8.3", + "web3-core": "1.0.0-beta.37", + "web3-core-helpers": "1.0.0-beta.37", + "web3-core-method": "1.0.0-beta.37", + "web3-core-promievent": "1.0.0-beta.37", + "web3-core-subscriptions": "1.0.0-beta.37", + "web3-eth-abi": "1.0.0-beta.37", + "web3-utils": "1.0.0-beta.37" + }, + "dependencies": { + "bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", + "dev": true + }, + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", + "dev": true + }, + "utf8": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.1.tgz", + "integrity": "sha1-LgHbAvfY0JRPdxBPFgnrDDBM92g=", + "dev": true + }, + "web3-utils": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.0.0-beta.37.tgz", + "integrity": "sha512-kA1fyhO8nKgU21wi30oJQ/ssvu+9srMdjOTKbHYbQe4ATPcr5YNwwrxG3Bcpbu1bEwRUVKHCkqi+wTvcAWBdlQ==", + "dev": true, + "requires": { + "bn.js": "4.11.6", + "eth-lib": "0.1.27", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randomhex": "0.1.5", + "underscore": "1.8.3", + "utf8": "2.1.1" + } + } + } + }, + "web3-eth-ens": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.0.0-beta.37.tgz", + "integrity": "sha512-dR3UkrVzdRrJhfP57xBPx0CMiVnCcYFvh+u2XMkGydrhHgupSUkjqGr89xry/j1T0BkuN9mikpbyhdCVMXqMbg==", + "dev": true, + "requires": { + "eth-ens-namehash": "2.0.8", + "underscore": "1.8.3", + "web3-core": "1.0.0-beta.37", + "web3-core-helpers": "1.0.0-beta.37", + "web3-core-promievent": "1.0.0-beta.37", + "web3-eth-abi": "1.0.0-beta.37", + "web3-eth-contract": "1.0.0-beta.37", + "web3-utils": "1.0.0-beta.37" + }, + "dependencies": { + "bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", + "dev": true + }, + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", + "dev": true + }, + "utf8": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.1.tgz", + "integrity": "sha1-LgHbAvfY0JRPdxBPFgnrDDBM92g=", + "dev": true + }, + "web3-utils": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.0.0-beta.37.tgz", + "integrity": "sha512-kA1fyhO8nKgU21wi30oJQ/ssvu+9srMdjOTKbHYbQe4ATPcr5YNwwrxG3Bcpbu1bEwRUVKHCkqi+wTvcAWBdlQ==", + "dev": true, + "requires": { + "bn.js": "4.11.6", + "eth-lib": "0.1.27", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randomhex": "0.1.5", + "underscore": "1.8.3", + "utf8": "2.1.1" + } + } + } + }, + "web3-eth-iban": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.0.0-beta.37.tgz", + "integrity": "sha512-WQRniGJFxH/XCbd7miO6+jnUG+6bvuzfeufPIiOtCbeIC1ypp1kSqER8YVBDrTyinU1xnf1U5v0KBZ2yiWBJxQ==", + "dev": true, + "requires": { + "bn.js": "4.11.6", + "web3-utils": "1.0.0-beta.37" + }, + "dependencies": { + "bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", + "dev": true + }, + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", + "dev": true + }, + "utf8": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.1.tgz", + "integrity": "sha1-LgHbAvfY0JRPdxBPFgnrDDBM92g=", + "dev": true + }, + "web3-utils": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.0.0-beta.37.tgz", + "integrity": "sha512-kA1fyhO8nKgU21wi30oJQ/ssvu+9srMdjOTKbHYbQe4ATPcr5YNwwrxG3Bcpbu1bEwRUVKHCkqi+wTvcAWBdlQ==", + "dev": true, + "requires": { + "bn.js": "4.11.6", + "eth-lib": "0.1.27", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randomhex": "0.1.5", + "underscore": "1.8.3", + "utf8": "2.1.1" + } + } + } + }, + "web3-eth-personal": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.0.0-beta.37.tgz", + "integrity": "sha512-B4dZpGbD+nGnn48i6nJBqrQ+HB7oDmd+Q3wGRKOsHSK5HRWO/KwYeA7wgwamMAElkut50lIsT9EJl4Apfk3G5Q==", + "dev": true, + "requires": { + "web3-core": "1.0.0-beta.37", + "web3-core-helpers": "1.0.0-beta.37", + "web3-core-method": "1.0.0-beta.37", + "web3-net": "1.0.0-beta.37", + "web3-utils": "1.0.0-beta.37" + }, + "dependencies": { + "bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", + "dev": true + }, + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", + "dev": true + }, + "utf8": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.1.tgz", + "integrity": "sha1-LgHbAvfY0JRPdxBPFgnrDDBM92g=", + "dev": true + }, + "web3-utils": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.0.0-beta.37.tgz", + "integrity": "sha512-kA1fyhO8nKgU21wi30oJQ/ssvu+9srMdjOTKbHYbQe4ATPcr5YNwwrxG3Bcpbu1bEwRUVKHCkqi+wTvcAWBdlQ==", + "dev": true, + "requires": { + "bn.js": "4.11.6", + "eth-lib": "0.1.27", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randomhex": "0.1.5", + "underscore": "1.8.3", + "utf8": "2.1.1" + } + } + } + }, + "web3-net": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.0.0-beta.37.tgz", + "integrity": "sha512-xG/uBtMdDa1UMXw9KjDUgf3fXA/fDEJUYUS0TDn+U9PMgngA+UVECHNNvQTrVVDxEky38V3sahwIDiopNsQdsw==", + "dev": true, + "requires": { + "web3-core": "1.0.0-beta.37", + "web3-core-method": "1.0.0-beta.37", + "web3-utils": "1.0.0-beta.37" + }, + "dependencies": { + "bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", + "dev": true + }, + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", + "dev": true + }, + "utf8": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.1.tgz", + "integrity": "sha1-LgHbAvfY0JRPdxBPFgnrDDBM92g=", + "dev": true + }, + "web3-utils": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.0.0-beta.37.tgz", + "integrity": "sha512-kA1fyhO8nKgU21wi30oJQ/ssvu+9srMdjOTKbHYbQe4ATPcr5YNwwrxG3Bcpbu1bEwRUVKHCkqi+wTvcAWBdlQ==", "dev": true, "requires": { "bn.js": "4.11.6", @@ -15661,6 +17739,21 @@ "lodash": "^4.17.10" } }, + "ethereumjs-util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz", + "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", + "dev": true, + "requires": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "ethjs-util": "^0.1.3", + "keccak": "^1.0.2", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1", + "secp256k1": "^3.0.1" + } + }, "ws": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.1.tgz", @@ -15672,6 +17765,75 @@ } } }, + "web3-providers-http": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.0.0-beta.37.tgz", + "integrity": "sha512-FM/1YDB1jtZuTo78habFj7S9tNHoqt0UipdyoQV29b8LkGKZV9Vs3is8L24hzuj1j/tbwkcAH+ewIseHwu0DTg==", + "dev": true, + "requires": { + "web3-core-helpers": "1.0.0-beta.37", + "xhr2-cookies": "1.1.0" + } + }, + "web3-providers-ipc": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.0.0-beta.37.tgz", + "integrity": "sha512-NdRPRxYMIU0C3u18NI8u4bwbhI9pCg5nRgDGYcmSAx5uOBxiYcQy+hb0WkJRRhBoyIXJmy+s26FoH8904+UnPg==", + "dev": true, + "requires": { + "oboe": "2.1.3", + "underscore": "1.8.3", + "web3-core-helpers": "1.0.0-beta.37" + }, + "dependencies": { + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", + "dev": true + } + } + }, + "web3-providers-ws": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.0.0-beta.37.tgz", + "integrity": "sha512-8p6ZLv+1JYa5Vs8oBn33Nn3VGFBbF+wVfO+b78RJS1Qf1uIOzjFVDk3XwYDD7rlz9G5BKpxhaQw+6EGQ7L02aw==", + "dev": true, + "requires": { + "underscore": "1.8.3", + "web3-core-helpers": "1.0.0-beta.37" + }, + "dependencies": { + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", + "dev": true + }, + "websocket": { + "version": "git://github.com/frozeman/WebSocket-Node.git#6c72925e3f8aaaea8dc8450f97627e85263999f2", + "from": "git://github.com/frozeman/WebSocket-Node.git#6c72925e3f8aaaea8dc8450f97627e85263999f2", + "requires": { + "debug": "^2.2.0", + "nan": "^2.3.3", + "typedarray-to-buffer": "^3.1.2", + "yaeti": "^0.0.6" + } + } + } + }, + "web3-shh": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.0.0-beta.37.tgz", + "integrity": "sha512-h5STG/xqZNQWtCLYOu7NiMqwqPea8SfkKQUPUFxXKIPVCFVKpHuQEwW1qcPQRJMLhlQIv17xuoUe1A+RzDNbrw==", + "dev": true, + "requires": { + "web3-core": "1.0.0-beta.37", + "web3-core-method": "1.0.0-beta.37", + "web3-core-subscriptions": "1.0.0-beta.37", + "web3-net": "1.0.0-beta.37" + } + }, "web3-utils": { "version": "1.0.0-beta.34", "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.0.0-beta.34.tgz", @@ -15832,7 +17994,6 @@ "version": "2.6.1", "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", - "dev": true, "requires": { "lodash": "^4.17.10" } @@ -15868,8 +18029,7 @@ "clone-stats": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", - "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", - "dev": true + "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=" }, "cross-spawn": { "version": "6.0.5", @@ -15888,7 +18048,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, "requires": { "ms": "2.0.0" } @@ -15896,8 +18055,7 @@ "deep-extend": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.5.1.tgz", - "integrity": "sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w==", - "dev": true + "integrity": "sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w==" }, "diff": { "version": "3.5.0", @@ -15908,8 +18066,7 @@ "ejs": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.6.1.tgz", - "integrity": "sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ==", - "dev": true + "integrity": "sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ==" }, "envinfo": { "version": "5.10.0", @@ -15930,7 +18087,6 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/globby/-/globby-8.0.1.tgz", "integrity": "sha512-oMrYrJERnKBLXNLVTqhm3vPEdJ/b2ZE28xN4YARiix1NOIOBPEpOUnm844K1iu/BkphCaf2WNFwMszv8Soi1pw==", - "dev": true, "requires": { "array-union": "^1.0.1", "dir-glob": "^2.0.0", @@ -15996,8 +18152,7 @@ "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" }, "is-observable": { "version": "1.1.0", @@ -16106,19 +18261,16 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", - "dev": true, "requires": { "graceful-fs": "^4.1.2", "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" + "pify": "^3.0.0" } }, "mem-fs-editor": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/mem-fs-editor/-/mem-fs-editor-4.0.2.tgz", "integrity": "sha512-QHvdXLLNmwJXxKdf7x27aNUren6IoPxwcM8Sfd+S6/ddQQMcYdEtVKsh6ilpqMrU18VQuKZEaH0aCGt3JDbA0g==", - "dev": true, "requires": { "commondir": "^1.0.1", "deep-extend": "^0.5.1", @@ -16129,15 +18281,13 @@ "mkdirp": "^0.5.0", "multimatch": "^2.0.0", "rimraf": "^2.2.8", - "through2": "^2.0.0", - "vinyl": "^2.0.1" + "through2": "^2.0.0" } }, "minimist": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" }, "os-locale": { "version": "2.1.0", @@ -16154,7 +18304,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, "requires": { "error-ex": "^1.3.1", "json-parse-better-errors": "^1.0.1" @@ -16164,7 +18313,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, "requires": { "pify": "^3.0.0" } @@ -16172,78 +18320,14 @@ "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - }, - "prettier": { - "version": "1.13.6", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.13.6.tgz", - "integrity": "sha512-p5eqCNiohWZN++7aJXUVj0JgLqHCPLf9GLIcLBHGNWs4Y9FJOPs6+KNO2WT0udJIQJTbeZFrJkjzjcb8fkAYYQ==", - "dev": true - }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", - "dev": true, - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - } - }, - "read-pkg-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" - } - }, - "replace-ext": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", - "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", - "dev": true - }, - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "dev": true, - "requires": { - "glob": "^7.0.5" - } + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" }, "semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", "dev": true }, - "shelljs": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.2.tgz", - "integrity": "sha512-pRXeNrCA2Wd9itwhvLp5LZQvPJ0wU6bcjaTMywHHGX5XWhVN2nzSu7WV0q+oUY7mGK3mgSkDDzP3MgjqdyIgbQ==", - "dev": true, - "requires": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - } - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", @@ -16253,16 +18337,10 @@ "ansi-regex": "^3.0.0" } }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { "has-flag": "^3.0.0" @@ -16274,26 +18352,6 @@ "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", "dev": true }, - "v8-compile-cache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.0.tgz", - "integrity": "sha512-qNdTUMaCjPs4eEnM3W9H94R3sU70YCuT+/ST7nUf+id1bVOrdjrpUaeZLqPBPRph3hsgn4a4BvwpxhHZx+oSDg==", - "dev": true - }, - "vinyl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz", - "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==", - "dev": true, - "requires": { - "clone": "^2.1.1", - "clone-buffer": "^1.0.0", - "clone-stats": "^1.0.0", - "cloneable-readable": "^1.0.0", - "remove-trailing-separator": "^1.0.1", - "replace-ext": "^1.0.0" - } - }, "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", @@ -16328,62 +18386,6 @@ "requires": { "camelcase": "^4.1.0" } - }, - "yeoman-environment": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/yeoman-environment/-/yeoman-environment-2.3.0.tgz", - "integrity": "sha512-PHSAkVOqYdcR+C+Uht1SGC4eVD/9OhygYFkYaI66xF8vKIeS1RNYay+umj2ZrQeJ50tF5Q/RSO6qGDz9y3Ifug==", - "dev": true, - "requires": { - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^3.1.0", - "diff": "^3.3.1", - "escape-string-regexp": "^1.0.2", - "globby": "^8.0.1", - "grouped-queue": "^0.3.3", - "inquirer": "^5.2.0", - "is-scoped": "^1.0.0", - "lodash": "^4.17.10", - "log-symbols": "^2.1.0", - "mem-fs": "^1.1.0", - "strip-ansi": "^4.0.0", - "text-table": "^0.2.0", - "untildify": "^3.0.2" - } - }, - "yeoman-generator": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/yeoman-generator/-/yeoman-generator-2.0.5.tgz", - "integrity": "sha512-rV6tJ8oYzm4mmdF2T3wjY+Q42jKF2YiiD0VKfJ8/0ZYwmhCKC9Xs2346HVLPj/xE13i68psnFJv7iS6gWRkeAg==", - "dev": true, - "requires": { - "async": "^2.6.0", - "chalk": "^2.3.0", - "cli-table": "^0.3.1", - "cross-spawn": "^6.0.5", - "dargs": "^5.1.0", - "dateformat": "^3.0.3", - "debug": "^3.1.0", - "detect-conflict": "^1.0.0", - "error": "^7.0.2", - "find-up": "^2.1.0", - "github-username": "^4.0.0", - "istextorbinary": "^2.2.1", - "lodash": "^4.17.10", - "make-dir": "^1.1.0", - "mem-fs-editor": "^4.0.0", - "minimist": "^1.2.0", - "pretty-bytes": "^4.0.2", - "read-chunk": "^2.1.0", - "read-pkg-up": "^3.0.0", - "rimraf": "^2.6.2", - "run-async": "^2.0.0", - "shelljs": "^0.8.0", - "text-table": "^0.2.0", - "through2": "^2.0.0", - "yeoman-environment": "^2.0.5" - } } } }, @@ -16399,7 +18401,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true } @@ -16441,8 +18443,23 @@ "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz", "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==", "dev": true, + "optional": true, "requires": { "string-width": "^1.0.2" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } } }, "window-size": { @@ -16465,13 +18482,25 @@ "requires": { "string-width": "^1.0.1", "strip-ansi": "^3.0.1" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } } }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "write": { "version": "0.2.1", @@ -16497,18 +18526,22 @@ "version": "3.3.3", "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", - "dev": true, "requires": { "async-limiter": "~1.0.0", "safe-buffer": "~5.1.0", "ultron": "~1.1.0" } }, + "xdg-basedir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", + "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", + "dev": true + }, "xhr": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.4.0.tgz", "integrity": "sha1-4W5mpF+GmGHu76tBbV7/ci3ECZM=", - "dev": true, "requires": { "global": "~4.3.0", "is-function": "^1.0.1", @@ -16520,7 +18553,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz", "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==", - "dev": true, "requires": { "buffer-to-arraybuffer": "^0.0.5", "object-assign": "^4.1.1", @@ -16535,7 +18567,6 @@ "version": "2.8.1", "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.1.tgz", "integrity": "sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==", - "dev": true, "requires": { "decompress-response": "^3.3.0", "once": "^1.3.1", @@ -16548,7 +18579,6 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.2.tgz", "integrity": "sha1-NDxE0e53JrhkgGloLQ+EDIO0Jh0=", - "dev": true, "requires": { "xhr-request": "^1.0.1" } @@ -16584,14 +18614,12 @@ "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", - "dev": true + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" }, "y18n": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", - "dev": true + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" }, "yallist": { "version": "2.1.2", @@ -16657,6 +18685,447 @@ "lodash.assign": "^4.0.6" } }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "yeoman-environment": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/yeoman-environment/-/yeoman-environment-2.3.4.tgz", + "integrity": "sha512-KLxE5ft/74Qj7h3AsQZv8G6MEEHYJwmD5F99nfOVaep3rBzCtbrJKkdqWc7bDV141Nr8UZZsIXmzc3IcCm6E2w==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "cross-spawn": "^6.0.5", + "debug": "^3.1.0", + "diff": "^3.5.0", + "escape-string-regexp": "^1.0.2", + "globby": "^8.0.1", + "grouped-queue": "^0.3.3", + "inquirer": "^6.0.0", + "is-scoped": "^1.0.0", + "lodash": "^4.17.10", + "log-symbols": "^2.2.0", + "mem-fs": "^1.1.0", + "strip-ansi": "^4.0.0", + "text-table": "^0.2.0", + "untildify": "^3.0.3" + }, + "dependencies": { + "ansi-regex": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.0.0.tgz", + "integrity": "sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "external-editor": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz", + "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, + "globby": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-8.0.2.tgz", + "integrity": "sha512-yTzMmKygLp8RUpG1Ymu2VXPSJQZjNAZPD4ywgYEaG7e4tBJeUQBO8OpXrf1RCNcEs5alsoJYPAMiIHP0cmeC7w==", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "dir-glob": "2.0.0", + "fast-glob": "^2.0.2", + "glob": "^7.1.2", + "ignore": "^3.3.5", + "pify": "^3.0.0", + "slash": "^1.0.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "inquirer": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.2.1.tgz", + "integrity": "sha512-088kl3DRT2dLU5riVMKKr1DlImd6X7smDhpXUCkJDCKvTEJeRiXh0G132HG9u5a+6Ylw9plFRY7RuTnwohYSpg==", + "dev": true, + "requires": { + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.0", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.0", + "figures": "^2.0.0", + "lodash": "^4.17.10", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^6.1.0", + "string-width": "^2.1.0", + "strip-ansi": "^5.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "strip-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.0.0.tgz", + "integrity": "sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow==", + "dev": true, + "requires": { + "ansi-regex": "^4.0.0" + } + } + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "rxjs": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", + "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + } + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "untildify": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-3.0.3.tgz", + "integrity": "sha512-iSk/J8efr8uPT/Z4eSUywnqyrQU7DSdMfdqK4iWEaUVVmcP5JcnpRqmVMwcwcnmI1ATFNgC5V90u09tBynNFKA==", + "dev": true + } + } + }, + "yeoman-generator": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/yeoman-generator/-/yeoman-generator-2.0.5.tgz", + "integrity": "sha512-rV6tJ8oYzm4mmdF2T3wjY+Q42jKF2YiiD0VKfJ8/0ZYwmhCKC9Xs2346HVLPj/xE13i68psnFJv7iS6gWRkeAg==", + "dev": true, + "requires": { + "async": "^2.6.0", + "chalk": "^2.3.0", + "cli-table": "^0.3.1", + "cross-spawn": "^6.0.5", + "dargs": "^5.1.0", + "dateformat": "^3.0.3", + "debug": "^3.1.0", + "detect-conflict": "^1.0.0", + "error": "^7.0.2", + "find-up": "^2.1.0", + "github-username": "^4.0.0", + "istextorbinary": "^2.2.1", + "lodash": "^4.17.10", + "make-dir": "^1.1.0", + "mem-fs-editor": "^4.0.0", + "minimist": "^1.2.0", + "pretty-bytes": "^4.0.2", + "read-chunk": "^2.1.0", + "read-pkg-up": "^3.0.0", + "rimraf": "^2.6.2", + "run-async": "^2.0.0", + "shelljs": "^0.8.0", + "text-table": "^0.2.0", + "through2": "^2.0.0", + "yeoman-environment": "^2.0.5" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", + "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "dev": true, + "requires": { + "lodash": "^4.17.10" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "read-pkg-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + } + }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", + "dev": true + }, + "shelljs": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.3.tgz", + "integrity": "sha512-fc0BKlAWiLpwZljmOvAOTE/gXawtCoNrP5oaY7KIaQbbyHeQVg01pSEuEGvGh3HEdBU4baCD7wQBwADmM/7f7A==", + "dev": true, + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "zos": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/zos/-/zos-2.0.0.tgz", @@ -16706,8 +19175,7 @@ }, "bignumber.js": { "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", - "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git", - "dev": true + "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git" }, "browser-stdout": { "version": "1.3.1", @@ -16937,6 +19405,12 @@ "pify": "^2.0.0" } }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, "read-pkg": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", @@ -17066,6 +19540,14 @@ "truffle-workflow-compile": "^1.0.6", "web3": "0.20.6", "yargs": "^8.0.2" + }, + "dependencies": { + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + } } }, "web3": { @@ -17079,6 +19561,13 @@ "utf8": "^2.1.1", "xhr2": "*", "xmlhttprequest": "*" + }, + "dependencies": { + "bignumber.js": { + "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", + "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", + "dev": true + } } }, "which-module": { diff --git a/package.json b/package.json index 137b18e68..471895827 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "openzeppelin-eth", - "version": "2.0.2", + "version": "2.1.1", "description": "Secure Smart Contract library for Solidity", "files": [ "build", @@ -10,17 +10,18 @@ "zos.*.json" ], "scripts": { - "test": "scripts/test.sh", - "prepare": "rm -rf build/contracts && truffle compile", - "lint:js": "eslint .", - "lint:js:fix": "eslint . --fix", - "lint:sol": "solium -d .", - "lint:sol:fix": "solium -d . --fix", - "lint": "npm run lint:js && npm run lint:sol", - "lint:fix": "npm run lint:js:fix && npm run lint:sol:fix", + "build": "scripts/build.sh", + "compile": "scripts/compile.sh", "console": "truffle console", "coverage": "scripts/coverage.sh", - "version": "scripts/version.js" + "lint": "npm run lint:js && npm run lint:sol", + "lint:fix": "npm run lint:js:fix", + "lint:js": "eslint .", + "lint:js:fix": "eslint . --fix", + "lint:sol": "solhint --max-warnings 0 \"contracts/**/*.sol\"", + "prepack": "npm run build", + "version": "scripts/version.js", + "test": "npm run compile && scripts/test.sh" }, "repository": { "type": "git", @@ -44,24 +45,26 @@ "chai": "^4.1.2", "chai-bignumber": "^2.0.2", "coveralls": "^3.0.1", - "dotenv": "^4.0.0", "eslint": "^4.19.1", "eslint-config-standard": "^10.2.1", "eslint-plugin-import": "^2.13.0", + "eslint-plugin-mocha-no-only": "^1.1.0", "eslint-plugin-node": "^5.2.1", "eslint-plugin-promise": "^3.8.0", "eslint-plugin-standard": "^3.1.0", + "ethereumjs-util": "^6.0.0", "ethjs-abi": "^0.2.1", - "ganache-cli": "6.1.0", + "ganache-cli": "6.1.8", "npm-install-peers": "^1.2.1", + "pify": "^4.0.1", + "solhint": "^1.5.0", "solidity-coverage": "^0.5.4", - "solium": "^1.1.8", "truffle": "^4.1.13", - "truffle-hdwallet-provider": "0.0.5", "web3-utils": "^1.0.0-beta.34", "zos": "^2.0.0" }, "peerDependencies": { "zos-lib": "^2.0.0" - } + }, + "dependencies": {} } diff --git a/scripts/build.sh b/scripts/build.sh new file mode 100755 index 000000000..ec4607756 --- /dev/null +++ b/scripts/build.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +# Configure to exit script as soon as a command fails. +set -o errexit + +# Clean the existing build directory. +rm -rf build + +# Create a temporary directory to place ignored files (e.g. examples). +tmp_dir="ignored_contracts" +mkdir "$tmp_dir" + +# Move the ignored files to the temporary directory. +while IFS="" read -r ignored +do + mv "contracts/$ignored" "$tmp_dir" +done < contracts/.npmignore + +# Compile everything else. +npm run compile + +# Return ignored files to their place. +mv "$tmp_dir/"* contracts/ + +# Delete the temporary directory. +rmdir "$tmp_dir" diff --git a/scripts/compile.sh b/scripts/compile.sh new file mode 100755 index 000000000..d037daac5 --- /dev/null +++ b/scripts/compile.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash + +# Configure to exit script as soon as a command fails. +set -o errexit + +SOLC_05_DIR=solc-0.5 + +# Delete any previous build artifacts +rm -rf build/ + +# Create a subproject where 0.5.x compilation will take place +mkdir -p "$SOLC_05_DIR" + +cd "$SOLC_05_DIR" +echo '{ "private": true }' > package.json +npm install --save-dev truffle@5.0.0 + +rm -rf contracts +ln --symbolic ../contracts contracts + +# Delete any previous build artifacts +rm -rf build/ + +# Compile +echo " +module.exports = { + compilers: { + solc: { + version: \"0.5.0\", + }, + }, +}; +" > truffle-config.js + +npx truffle compile + +# Modify the paths in the artifacts to make it look as if they were built in the root +sed --in-place --expression "s/\/$SOLC_05_DIR//g" build/contracts/*.json + +# Copy them back into the root +cd .. +cp --recursive "$SOLC_05_DIR"/build build diff --git a/test/access/Roles.test.js b/test/access/Roles.test.js index 7d5573cec..15fffec34 100644 --- a/test/access/Roles.test.js +++ b/test/access/Roles.test.js @@ -1,19 +1,17 @@ -const { assertRevert } = require('../helpers/assertRevert'); +const shouldFail = require('../helpers/shouldFail'); +const { ZERO_ADDRESS } = require('../helpers/constants'); const RolesMock = artifacts.require('RolesMock'); -require('chai') - .should(); +require('./../helpers/setup'); contract('Roles', function ([_, authorized, otherAuthorized, anyone]) { - const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; - beforeEach(async function () { this.roles = await RolesMock.new(); }); it('reverts when querying roles for the null account', async function () { - await assertRevert(this.roles.has(ZERO_ADDRESS)); + await shouldFail.reverting(this.roles.has(ZERO_ADDRESS)); }); context('initially', function () { @@ -30,14 +28,13 @@ contract('Roles', function ([_, authorized, otherAuthorized, anyone]) { (await this.roles.has(anyone)).should.equal(false); }); - it('adds roles to an already-assigned account', async function () { + it('reverts when adding roles to an already assigned account', async function () { await this.roles.add(authorized); - await this.roles.add(authorized); - (await this.roles.has(authorized)).should.equal(true); + await shouldFail.reverting(this.roles.add(authorized)); }); it('reverts when adding roles to the null account', async function () { - await assertRevert(this.roles.add(ZERO_ADDRESS)); + await shouldFail.reverting(this.roles.add(ZERO_ADDRESS)); }); }); }); @@ -55,12 +52,12 @@ contract('Roles', function ([_, authorized, otherAuthorized, anyone]) { (await this.roles.has(otherAuthorized)).should.equal(true); }); - it('doesn\'t revert when removing unassigned roles', async function () { - await this.roles.remove(anyone); + it('reverts when removing unassigned roles', async function () { + await shouldFail.reverting(this.roles.remove(anyone)); }); it('reverts when removing roles from the null account', async function () { - await assertRevert(this.roles.remove(ZERO_ADDRESS)); + await shouldFail.reverting(this.roles.remove(ZERO_ADDRESS)); }); }); }); diff --git a/test/access/roles/PublicRole.behavior.js b/test/access/roles/PublicRole.behavior.js index f1c723b78..d558c1300 100644 --- a/test/access/roles/PublicRole.behavior.js +++ b/test/access/roles/PublicRole.behavior.js @@ -1,16 +1,15 @@ -const { assertRevert } = require('../../helpers/assertRevert'); +const shouldFail = require('../../helpers/shouldFail'); +const { ZERO_ADDRESS } = require('../../helpers/constants'); const expectEvent = require('../../helpers/expectEvent'); -require('chai') - .should(); +require('../../helpers/setup'); function capitalize (str) { return str.replace(/\b\w/g, l => l.toUpperCase()); } -function shouldBehaveLikePublicRole (authorized, otherAuthorized, [anyone], rolename) { +function shouldBehaveLikePublicRole (authorized, otherAuthorized, [anyone], rolename, manager) { rolename = capitalize(rolename); - const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; describe('should behave like public role', function () { beforeEach('check preconditions', async function () { @@ -19,8 +18,16 @@ function shouldBehaveLikePublicRole (authorized, otherAuthorized, [anyone], role (await this.contract[`is${rolename}`](anyone)).should.equal(false); }); + if (manager === undefined) { // Managed roles are only assigned by the manager, and none are set at construction + it('emits events during construction', async function () { + await expectEvent.inConstruction(this.contract, `${rolename}Added`, { + account: authorized, + }); + }); + } + it('reverts when querying roles for the null account', async function () { - await assertRevert(this.contract[`is${rolename}`](ZERO_ADDRESS)); + await shouldFail.reverting(this.contract[`is${rolename}`](ZERO_ADDRESS)); }); describe('access control', function () { @@ -36,50 +43,58 @@ function shouldBehaveLikePublicRole (authorized, otherAuthorized, [anyone], role const from = anyone; it('reverts', async function () { - await assertRevert(this.contract[`only${rolename}Mock`]({ from })); + await shouldFail.reverting(this.contract[`only${rolename}Mock`]({ from })); }); }); }); describe('add', function () { - it('adds role to a new account', async function () { - await this.contract[`add${rolename}`](anyone, { from: authorized }); - (await this.contract[`is${rolename}`](anyone)).should.equal(true); - }); + const from = manager === undefined ? authorized : manager; - it(`emits a ${rolename}Added event`, async function () { - const { logs } = await this.contract[`add${rolename}`](anyone, { from: authorized }); - expectEvent.inLogs(logs, `${rolename}Added`, { account: anyone }); - }); + context(`from ${manager ? 'the manager' : 'a role-haver'} account`, function () { + it('adds role to a new account', async function () { + await this.contract[`add${rolename}`](anyone, { from }); + (await this.contract[`is${rolename}`](anyone)).should.equal(true); + }); - it('adds role to an already-assigned account', async function () { - await this.contract[`add${rolename}`](authorized, { from: authorized }); - (await this.contract[`is${rolename}`](authorized)).should.equal(true); - }); + it(`emits a ${rolename}Added event`, async function () { + const { logs } = await this.contract[`add${rolename}`](anyone, { from }); + expectEvent.inLogs(logs, `${rolename}Added`, { account: anyone }); + }); - it('reverts when adding role to the null account', async function () { - await assertRevert(this.contract[`add${rolename}`](ZERO_ADDRESS, { from: authorized })); + it('reverts when adding role to an already assigned account', async function () { + await shouldFail.reverting(this.contract[`add${rolename}`](authorized, { from })); + }); + + it('reverts when adding role to the null account', async function () { + await shouldFail.reverting(this.contract[`add${rolename}`](ZERO_ADDRESS, { from })); + }); }); }); describe('remove', function () { - it('removes role from an already assigned account', async function () { - await this.contract[`remove${rolename}`](authorized); - (await this.contract[`is${rolename}`](authorized)).should.equal(false); - (await this.contract[`is${rolename}`](otherAuthorized)).should.equal(true); - }); + // Non-managed roles have no restrictions on the mocked '_remove' function (exposed via 'remove'). + const from = manager || anyone; - it(`emits a ${rolename}Removed event`, async function () { - const { logs } = await this.contract[`remove${rolename}`](authorized); - expectEvent.inLogs(logs, `${rolename}Removed`, { account: authorized }); - }); + context(`from ${manager ? 'the manager' : 'any'} account`, function () { + it('removes role from an already assigned account', async function () { + await this.contract[`remove${rolename}`](authorized, { from }); + (await this.contract[`is${rolename}`](authorized)).should.equal(false); + (await this.contract[`is${rolename}`](otherAuthorized)).should.equal(true); + }); - it('doesn\'t revert when removing from an unassigned account', async function () { - await this.contract[`remove${rolename}`](anyone); - }); + it(`emits a ${rolename}Removed event`, async function () { + const { logs } = await this.contract[`remove${rolename}`](authorized, { from }); + expectEvent.inLogs(logs, `${rolename}Removed`, { account: authorized }); + }); - it('reverts when removing role from the null account', async function () { - await assertRevert(this.contract[`remove${rolename}`](ZERO_ADDRESS)); + it('reverts when removing from an unassigned account', async function () { + await shouldFail.reverting(this.contract[`remove${rolename}`](anyone), { from }); + }); + + it('reverts when removing role from the null account', async function () { + await shouldFail.reverting(this.contract[`remove${rolename}`](ZERO_ADDRESS), { from }); + }); }); }); @@ -94,8 +109,8 @@ function shouldBehaveLikePublicRole (authorized, otherAuthorized, [anyone], role expectEvent.inLogs(logs, `${rolename}Removed`, { account: authorized }); }); - it('doesn\'t revert when renouncing unassigned role', async function () { - await this.contract[`renounce${rolename}`]({ from: anyone }); + it('reverts when renouncing unassigned role', async function () { + await shouldFail.reverting(this.contract[`renounce${rolename}`]({ from: anyone })); }); }); }); diff --git a/test/access/roles/WhitelistAdminRole.test.js b/test/access/roles/WhitelistAdminRole.test.js new file mode 100644 index 000000000..e59dcd895 --- /dev/null +++ b/test/access/roles/WhitelistAdminRole.test.js @@ -0,0 +1,11 @@ +const { shouldBehaveLikePublicRole } = require('../../access/roles/PublicRole.behavior'); +const WhitelistAdminRoleMock = artifacts.require('WhitelistAdminRoleMock'); + +contract('WhitelistAdminRole', function ([_, whitelistAdmin, otherWhitelistAdmin, ...otherAccounts]) { + beforeEach(async function () { + this.contract = await WhitelistAdminRoleMock.new({ from: whitelistAdmin }); + await this.contract.addWhitelistAdmin(otherWhitelistAdmin, { from: whitelistAdmin }); + }); + + shouldBehaveLikePublicRole(whitelistAdmin, otherWhitelistAdmin, otherAccounts, 'whitelistAdmin'); +}); diff --git a/test/access/roles/WhitelistedRole.test.js b/test/access/roles/WhitelistedRole.test.js new file mode 100644 index 000000000..e578f6fa2 --- /dev/null +++ b/test/access/roles/WhitelistedRole.test.js @@ -0,0 +1,12 @@ +const { shouldBehaveLikePublicRole } = require('../../access/roles/PublicRole.behavior'); +const WhitelistedRoleMock = artifacts.require('WhitelistedRoleMock'); + +contract('WhitelistedRole', function ([_, whitelisted, otherWhitelisted, whitelistAdmin, ...otherAccounts]) { + beforeEach(async function () { + this.contract = await WhitelistedRoleMock.new({ from: whitelistAdmin }); + await this.contract.addWhitelisted(whitelisted, { from: whitelistAdmin }); + await this.contract.addWhitelisted(otherWhitelisted, { from: whitelistAdmin }); + }); + + shouldBehaveLikePublicRole(whitelisted, otherWhitelisted, otherAccounts, 'whitelisted', whitelistAdmin); +}); diff --git a/test/crowdsale/AllowanceCrowdsale.test.js b/test/crowdsale/AllowanceCrowdsale.test.js index b7ea1dea8..70276fe7a 100644 --- a/test/crowdsale/AllowanceCrowdsale.test.js +++ b/test/crowdsale/AllowanceCrowdsale.test.js @@ -1,14 +1,12 @@ +const expectEvent = require('../helpers/expectEvent'); const { ether } = require('../helpers/ether'); -const { assertRevert } = require('../helpers/assertRevert'); -const { ethGetBalance } = require('../helpers/web3'); +const shouldFail = require('../helpers/shouldFail'); +const { balanceDifference } = require('../helpers/balanceDifference'); +const { ZERO_ADDRESS } = require('../helpers/constants'); -const BigNumber = web3.BigNumber; +const { BigNumber } = require('../helpers/setup'); -const should = require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); - -const AllowanceCrowdsale = artifacts.require('AllowanceCrowdsaleImpl'); +const AllowanceCrowdsaleImpl = artifacts.require('AllowanceCrowdsaleImpl'); const SimpleToken = artifacts.require('SimpleTokenMock'); contract('AllowanceCrowdsale', function ([_, investor, wallet, purchaser, tokenWallet]) { @@ -16,11 +14,10 @@ contract('AllowanceCrowdsale', function ([_, investor, wallet, purchaser, tokenW const value = ether(0.42); const expectedTokenAmount = rate.mul(value); const tokenAllowance = new BigNumber('1e22'); - const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; beforeEach(async function () { this.token = await SimpleToken.new({ from: tokenWallet }); - this.crowdsale = await AllowanceCrowdsale.new(rate, wallet, this.token.address, tokenWallet); + this.crowdsale = await AllowanceCrowdsaleImpl.new(rate, wallet, this.token.address, tokenWallet); await this.token.approve(this.crowdsale.address, tokenAllowance, { from: tokenWallet }); }); @@ -41,12 +38,12 @@ contract('AllowanceCrowdsale', function ([_, investor, wallet, purchaser, tokenW describe('high-level purchase', function () { it('should log purchase', async function () { const { logs } = await this.crowdsale.sendTransaction({ value: value, from: investor }); - const event = logs.find(e => e.event === 'TokensPurchased'); - should.exist(event); - event.args.purchaser.should.equal(investor); - event.args.beneficiary.should.equal(investor); - event.args.value.should.be.bignumber.equal(value); - event.args.amount.should.be.bignumber.equal(expectedTokenAmount); + expectEvent.inLogs(logs, 'TokensPurchased', { + purchaser: investor, + beneficiary: investor, + value: value, + amount: expectedTokenAmount, + }); }); it('should assign tokens to sender', async function () { @@ -55,10 +52,9 @@ contract('AllowanceCrowdsale', function ([_, investor, wallet, purchaser, tokenW }); it('should forward funds to wallet', async function () { - const pre = await ethGetBalance(wallet); - await this.crowdsale.sendTransaction({ value, from: investor }); - const post = await ethGetBalance(wallet); - post.minus(pre).should.be.bignumber.equal(value); + (await balanceDifference(wallet, () => + this.crowdsale.sendTransaction({ value, from: investor })) + ).should.be.bignumber.equal(value); }); }); @@ -68,12 +64,23 @@ contract('AllowanceCrowdsale', function ([_, investor, wallet, purchaser, tokenW await this.crowdsale.buyTokens(investor, { value: value, from: purchaser }); (await this.crowdsale.remainingTokens()).should.be.bignumber.equal(remainingAllowance); }); + + context('when the allowance is larger than the token amount', function () { + beforeEach(async function () { + const amount = await this.token.balanceOf(tokenWallet); + await this.token.approve(this.crowdsale.address, amount.plus(1), { from: tokenWallet }); + }); + + it('should report the amount instead of the allowance', async function () { + (await this.crowdsale.remainingTokens()).should.be.bignumber.equal(await this.token.balanceOf(tokenWallet)); + }); + }); }); describe('when token wallet is different from token address', function () { it('creation reverts', async function () { this.token = await SimpleToken.new({ from: tokenWallet }); - await assertRevert(AllowanceCrowdsale.new(rate, wallet, this.token.address, ZERO_ADDRESS)); + await shouldFail.reverting(AllowanceCrowdsaleImpl.new(rate, wallet, this.token.address, ZERO_ADDRESS)); }); }); }); diff --git a/test/crowdsale/CappedCrowdsale.test.js b/test/crowdsale/CappedCrowdsale.test.js index 5eb8ebce8..92480b513 100644 --- a/test/crowdsale/CappedCrowdsale.test.js +++ b/test/crowdsale/CappedCrowdsale.test.js @@ -1,14 +1,9 @@ const { ether } = require('../helpers/ether'); -const { expectThrow } = require('../helpers/expectThrow'); -const { EVMRevert } = require('../helpers/EVMRevert'); +const shouldFail = require('../helpers/shouldFail'); -const BigNumber = web3.BigNumber; +const { BigNumber } = require('../helpers/setup'); -require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); - -const CappedCrowdsale = artifacts.require('CappedCrowdsaleImpl'); +const CappedCrowdsaleImpl = artifacts.require('CappedCrowdsaleImpl'); const SimpleToken = artifacts.require('SimpleTokenMock'); contract('CappedCrowdsale', function ([_, wallet]) { @@ -22,15 +17,12 @@ contract('CappedCrowdsale', function ([_, wallet]) { }); it('rejects a cap of zero', async function () { - await expectThrow( - CappedCrowdsale.new(rate, wallet, this.token.address, 0), - EVMRevert, - ); + await shouldFail.reverting(CappedCrowdsaleImpl.new(rate, wallet, this.token.address, 0)); }); context('with crowdsale', function () { beforeEach(async function () { - this.crowdsale = await CappedCrowdsale.new(rate, wallet, this.token.address, cap); + this.crowdsale = await CappedCrowdsaleImpl.new(rate, wallet, this.token.address, cap); await this.token.transfer(this.crowdsale.address, tokenSupply); }); @@ -42,17 +34,11 @@ contract('CappedCrowdsale', function ([_, wallet]) { it('should reject payments outside cap', async function () { await this.crowdsale.send(cap); - await expectThrow( - this.crowdsale.send(1), - EVMRevert, - ); + await shouldFail.reverting(this.crowdsale.send(1)); }); it('should reject payments that exceed cap', async function () { - await expectThrow( - this.crowdsale.send(cap.plus(1)), - EVMRevert, - ); + await shouldFail.reverting(this.crowdsale.send(cap.plus(1))); }); }); diff --git a/test/crowdsale/Crowdsale.test.js b/test/crowdsale/Crowdsale.test.js index 140bd10a6..307939071 100644 --- a/test/crowdsale/Crowdsale.test.js +++ b/test/crowdsale/Crowdsale.test.js @@ -1,12 +1,10 @@ -const { assertRevert } = require('../helpers/assertRevert'); +const expectEvent = require('../helpers/expectEvent'); +const shouldFail = require('../helpers/shouldFail'); +const { balanceDifference } = require('../helpers/balanceDifference'); const { ether } = require('../helpers/ether'); -const { ethGetBalance } = require('../helpers/web3'); +const { ZERO_ADDRESS } = require('../helpers/constants'); -const BigNumber = web3.BigNumber; - -const should = require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); +const { BigNumber } = require('../helpers/setup'); const Crowdsale = artifacts.require('CrowdsaleMock'); const SimpleToken = artifacts.require('SimpleTokenMock'); @@ -16,10 +14,9 @@ contract('Crowdsale', function ([_, investor, wallet, purchaser]) { const value = ether(42); const tokenSupply = new BigNumber('1e22'); const expectedTokenAmount = rate.mul(value); - const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; it('requires a non-null token', async function () { - await assertRevert( + await shouldFail.reverting( Crowdsale.new(rate, wallet, ZERO_ADDRESS) ); }); @@ -30,13 +27,13 @@ contract('Crowdsale', function ([_, investor, wallet, purchaser]) { }); it('requires a non-zero rate', async function () { - await assertRevert( + await shouldFail.reverting( Crowdsale.new(0, wallet, this.token.address) ); }); it('requires a non-null wallet', async function () { - await assertRevert( + await shouldFail.reverting( Crowdsale.new(rate, ZERO_ADDRESS, this.token.address) ); }); @@ -54,7 +51,7 @@ contract('Crowdsale', function ([_, investor, wallet, purchaser]) { }); it('reverts on zero-valued payments', async function () { - await assertRevert( + await shouldFail.reverting( this.crowdsale.send(0, { from: purchaser }) ); }); @@ -66,13 +63,13 @@ contract('Crowdsale', function ([_, investor, wallet, purchaser]) { }); it('reverts on zero-valued payments', async function () { - await assertRevert( + await shouldFail.reverting( this.crowdsale.buyTokens(investor, { value: 0, from: purchaser }) ); }); it('requires a non-null beneficiary', async function () { - await assertRevert( + await shouldFail.reverting( this.crowdsale.buyTokens(ZERO_ADDRESS, { value: value, from: purchaser }) ); }); @@ -82,12 +79,12 @@ contract('Crowdsale', function ([_, investor, wallet, purchaser]) { describe('high-level purchase', function () { it('should log purchase', async function () { const { logs } = await this.crowdsale.sendTransaction({ value: value, from: investor }); - const event = logs.find(e => e.event === 'TokensPurchased'); - should.exist(event); - event.args.purchaser.should.equal(investor); - event.args.beneficiary.should.equal(investor); - event.args.value.should.be.bignumber.equal(value); - event.args.amount.should.be.bignumber.equal(expectedTokenAmount); + expectEvent.inLogs(logs, 'TokensPurchased', { + purchaser: investor, + beneficiary: investor, + value: value, + amount: expectedTokenAmount, + }); }); it('should assign tokens to sender', async function () { @@ -96,22 +93,21 @@ contract('Crowdsale', function ([_, investor, wallet, purchaser]) { }); it('should forward funds to wallet', async function () { - const pre = await ethGetBalance(wallet); - await this.crowdsale.sendTransaction({ value, from: investor }); - const post = await ethGetBalance(wallet); - post.minus(pre).should.be.bignumber.equal(value); + (await balanceDifference(wallet, () => + this.crowdsale.sendTransaction({ value, from: investor })) + ).should.be.bignumber.equal(value); }); }); describe('low-level purchase', function () { it('should log purchase', async function () { const { logs } = await this.crowdsale.buyTokens(investor, { value: value, from: purchaser }); - const event = logs.find(e => e.event === 'TokensPurchased'); - should.exist(event); - event.args.purchaser.should.equal(purchaser); - event.args.beneficiary.should.equal(investor); - event.args.value.should.be.bignumber.equal(value); - event.args.amount.should.be.bignumber.equal(expectedTokenAmount); + expectEvent.inLogs(logs, 'TokensPurchased', { + purchaser: purchaser, + beneficiary: investor, + value: value, + amount: expectedTokenAmount, + }); }); it('should assign tokens to beneficiary', async function () { @@ -120,10 +116,9 @@ contract('Crowdsale', function ([_, investor, wallet, purchaser]) { }); it('should forward funds to wallet', async function () { - const pre = await ethGetBalance(wallet); - await this.crowdsale.buyTokens(investor, { value, from: purchaser }); - const post = await ethGetBalance(wallet); - post.minus(pre).should.be.bignumber.equal(value); + (await balanceDifference(wallet, () => + this.crowdsale.buyTokens(investor, { value, from: purchaser })) + ).should.be.bignumber.equal(value); }); }); }); diff --git a/test/crowdsale/FinalizableCrowdsale.test.js b/test/crowdsale/FinalizableCrowdsale.test.js index df7a743dd..778dbcb98 100644 --- a/test/crowdsale/FinalizableCrowdsale.test.js +++ b/test/crowdsale/FinalizableCrowdsale.test.js @@ -1,16 +1,10 @@ -const { advanceBlock } = require('../helpers/advanceToBlock'); -const { increaseTimeTo, duration } = require('../helpers/increaseTime'); -const { latestTime } = require('../helpers/latestTime'); -const { expectThrow } = require('../helpers/expectThrow'); -const { EVMRevert } = require('../helpers/EVMRevert'); +const expectEvent = require('../helpers/expectEvent'); +const time = require('../helpers/time'); +const shouldFail = require('../helpers/shouldFail'); -const BigNumber = web3.BigNumber; +const { BigNumber } = require('../helpers/setup'); -const should = require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); - -const FinalizableCrowdsale = artifacts.require('FinalizableCrowdsaleImpl'); +const FinalizableCrowdsaleImpl = artifacts.require('FinalizableCrowdsaleImpl'); const ERC20 = artifacts.require('ERC20'); contract('FinalizableCrowdsale', function ([_, wallet, anyone]) { @@ -18,39 +12,38 @@ contract('FinalizableCrowdsale', function ([_, wallet, anyone]) { before(async function () { // Advance to the next block to correctly read time in the solidity "now" function interpreted by ganache - await advanceBlock(); + await time.advanceBlock(); }); beforeEach(async function () { - this.openingTime = (await latestTime()) + duration.weeks(1); - this.closingTime = this.openingTime + duration.weeks(1); - this.afterClosingTime = this.closingTime + duration.seconds(1); + this.openingTime = (await time.latest()) + time.duration.weeks(1); + this.closingTime = this.openingTime + time.duration.weeks(1); + this.afterClosingTime = this.closingTime + time.duration.seconds(1); this.token = await ERC20.new(); - this.crowdsale = await FinalizableCrowdsale.new( + this.crowdsale = await FinalizableCrowdsaleImpl.new( this.openingTime, this.closingTime, rate, wallet, this.token.address ); }); it('cannot be finalized before ending', async function () { - await expectThrow(this.crowdsale.finalize({ from: anyone }), EVMRevert); + await shouldFail.reverting(this.crowdsale.finalize({ from: anyone })); }); it('can be finalized by anyone after ending', async function () { - await increaseTimeTo(this.afterClosingTime); + await time.increaseTo(this.afterClosingTime); await this.crowdsale.finalize({ from: anyone }); }); it('cannot be finalized twice', async function () { - await increaseTimeTo(this.afterClosingTime); + await time.increaseTo(this.afterClosingTime); await this.crowdsale.finalize({ from: anyone }); - await expectThrow(this.crowdsale.finalize({ from: anyone }), EVMRevert); + await shouldFail.reverting(this.crowdsale.finalize({ from: anyone })); }); it('logs finalized', async function () { - await increaseTimeTo(this.afterClosingTime); + await time.increaseTo(this.afterClosingTime); const { logs } = await this.crowdsale.finalize({ from: anyone }); - const event = logs.find(e => e.event === 'CrowdsaleFinalized'); - should.exist(event); + expectEvent.inLogs(logs, 'CrowdsaleFinalized'); }); }); diff --git a/test/crowdsale/IncreasingPriceCrowdsale.test.js b/test/crowdsale/IncreasingPriceCrowdsale.test.js index 18c6f06e8..1c70465c5 100644 --- a/test/crowdsale/IncreasingPriceCrowdsale.test.js +++ b/test/crowdsale/IncreasingPriceCrowdsale.test.js @@ -1,16 +1,10 @@ const { ether } = require('../helpers/ether'); -const { advanceBlock } = require('../helpers/advanceToBlock'); -const { increaseTimeTo, duration } = require('../helpers/increaseTime'); -const { latestTime } = require('../helpers/latestTime'); -const { assertRevert } = require('../helpers/assertRevert'); +const time = require('../helpers/time'); +const shouldFail = require('../helpers/shouldFail'); -const BigNumber = web3.BigNumber; +const { BigNumber } = require('../helpers/setup'); -require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); - -const IncreasingPriceCrowdsale = artifacts.require('IncreasingPriceCrowdsaleImpl'); +const IncreasingPriceCrowdsaleImpl = artifacts.require('IncreasingPriceCrowdsaleImpl'); const SimpleToken = artifacts.require('SimpleTokenMock'); contract('IncreasingPriceCrowdsale', function ([_, investor, wallet, purchaser]) { @@ -28,28 +22,34 @@ contract('IncreasingPriceCrowdsale', function ([_, investor, wallet, purchaser]) const rateAtTime450000 = new BigNumber(6439); beforeEach(async function () { - await advanceBlock(); - this.startTime = (await latestTime()) + duration.weeks(1); - this.closingTime = this.startTime + duration.weeks(1); - this.afterClosingTime = this.closingTime + duration.seconds(1); + await time.advanceBlock(); + this.startTime = (await time.latest()) + time.duration.weeks(1); + this.closingTime = this.startTime + time.duration.weeks(1); + this.afterClosingTime = this.closingTime + time.duration.seconds(1); this.token = await SimpleToken.new(); }); - it('rejects a final rate larger than the initial rate', async function () { - await assertRevert(IncreasingPriceCrowdsale.new( + it('reverts with a final rate larger than the initial rate', async function () { + await shouldFail.reverting(IncreasingPriceCrowdsaleImpl.new( this.startTime, this.closingTime, wallet, this.token.address, initialRate, initialRate.plus(1) )); }); - it('rejects a final rate of zero', async function () { - await assertRevert(IncreasingPriceCrowdsale.new( + it('reverts with a final equal to the initial rate', async function () { + await shouldFail.reverting(IncreasingPriceCrowdsaleImpl.new( + this.startTime, this.closingTime, wallet, this.token.address, initialRate, initialRate + )); + }); + + it('reverts with a final rate of zero', async function () { + await shouldFail.reverting(IncreasingPriceCrowdsaleImpl.new( this.startTime, this.closingTime, wallet, this.token.address, initialRate, 0 )); }); context('with crowdsale', function () { beforeEach(async function () { - this.crowdsale = await IncreasingPriceCrowdsale.new( + this.crowdsale = await IncreasingPriceCrowdsaleImpl.new( this.startTime, this.closingTime, wallet, this.token.address, initialRate, finalRate ); await this.token.transfer(this.crowdsale.address, tokenSupply); @@ -60,44 +60,57 @@ contract('IncreasingPriceCrowdsale', function ([_, investor, wallet, purchaser]) (await this.crowdsale.finalRate()).should.be.bignumber.equal(finalRate); }); + it('reverts when the base Crowdsale\'s rate function is called', async function () { + await shouldFail.reverting(this.crowdsale.rate()); + }); + + it('returns a rate of 0 before the crowdsale starts', async function () { + (await this.crowdsale.getCurrentRate()).should.be.bignumber.equal(0); + }); + + it('returns a rate of 0 after the crowdsale ends', async function () { + await time.increaseTo(this.afterClosingTime); + (await this.crowdsale.getCurrentRate()).should.be.bignumber.equal(0); + }); + it('at start', async function () { - await increaseTimeTo(this.startTime); + await time.increaseTo(this.startTime); await this.crowdsale.buyTokens(investor, { value, from: purchaser }); (await this.token.balanceOf(investor)).should.be.bignumber.equal(value.mul(initialRate)); }); it('at time 150', async function () { - await increaseTimeTo(this.startTime + 150); + await time.increaseTo(this.startTime + 150); await this.crowdsale.buyTokens(investor, { value, from: purchaser }); (await this.token.balanceOf(investor)).should.be.bignumber.equal(value.mul(rateAtTime150)); }); it('at time 300', async function () { - await increaseTimeTo(this.startTime + 300); + await time.increaseTo(this.startTime + 300); await this.crowdsale.buyTokens(investor, { value, from: purchaser }); (await this.token.balanceOf(investor)).should.be.bignumber.equal(value.mul(rateAtTime300)); }); it('at time 1500', async function () { - await increaseTimeTo(this.startTime + 1500); + await time.increaseTo(this.startTime + 1500); await this.crowdsale.buyTokens(investor, { value, from: purchaser }); (await this.token.balanceOf(investor)).should.be.bignumber.equal(value.mul(rateAtTime1500)); }); it('at time 30', async function () { - await increaseTimeTo(this.startTime + 30); + await time.increaseTo(this.startTime + 30); await this.crowdsale.buyTokens(investor, { value, from: purchaser }); (await this.token.balanceOf(investor)).should.be.bignumber.equal(value.mul(rateAtTime30)); }); it('at time 150000', async function () { - await increaseTimeTo(this.startTime + 150000); + await time.increaseTo(this.startTime + 150000); await this.crowdsale.buyTokens(investor, { value, from: purchaser }); (await this.token.balanceOf(investor)).should.be.bignumber.equal(value.mul(rateAtTime150000)); }); it('at time 450000', async function () { - await increaseTimeTo(this.startTime + 450000); + await time.increaseTo(this.startTime + 450000); await this.crowdsale.buyTokens(investor, { value, from: purchaser }); (await this.token.balanceOf(investor)).should.be.bignumber.equal(value.mul(rateAtTime450000)); }); diff --git a/test/crowdsale/IndividuallyCappedCrowdsale.test.js b/test/crowdsale/IndividuallyCappedCrowdsale.test.js index a416f2a5e..c3e772cc3 100644 --- a/test/crowdsale/IndividuallyCappedCrowdsale.test.js +++ b/test/crowdsale/IndividuallyCappedCrowdsale.test.js @@ -1,12 +1,7 @@ const { ether } = require('../helpers/ether'); -const { expectThrow } = require('../helpers/expectThrow'); -const { EVMRevert } = require('../helpers/EVMRevert'); +const shouldFail = require('../helpers/shouldFail'); -const BigNumber = web3.BigNumber; - -require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); +const { BigNumber } = require('../helpers/setup'); const IndividuallyCappedCrowdsaleImpl = artifacts.require('IndividuallyCappedCrowdsaleImpl'); const SimpleToken = artifacts.require('SimpleTokenMock'); @@ -42,7 +37,7 @@ contract('IndividuallyCappedCrowdsale', function ( }); it('reverts when a non-capper sets a cap', async function () { - await expectThrow(this.crowdsale.setCap(alice, capAlice, { from: anyone }), EVMRevert); + await shouldFail.reverting(this.crowdsale.setCap(alice, capAlice, { from: anyone })); }); context('with individual caps', function () { @@ -60,21 +55,21 @@ contract('IndividuallyCappedCrowdsale', function ( it('should reject payments outside cap', async function () { await this.crowdsale.buyTokens(alice, { value: capAlice }); - await expectThrow(this.crowdsale.buyTokens(alice, { value: 1 }), EVMRevert); + await shouldFail.reverting(this.crowdsale.buyTokens(alice, { value: 1 })); }); it('should reject payments that exceed cap', async function () { - await expectThrow(this.crowdsale.buyTokens(alice, { value: capAlice.plus(1) }), EVMRevert); - await expectThrow(this.crowdsale.buyTokens(bob, { value: capBob.plus(1) }), EVMRevert); + await shouldFail.reverting(this.crowdsale.buyTokens(alice, { value: capAlice.plus(1) })); + await shouldFail.reverting(this.crowdsale.buyTokens(bob, { value: capBob.plus(1) })); }); it('should manage independent caps', async function () { await this.crowdsale.buyTokens(alice, { value: lessThanCapAlice }); - await expectThrow(this.crowdsale.buyTokens(bob, { value: lessThanCapAlice }), EVMRevert); + await shouldFail.reverting(this.crowdsale.buyTokens(bob, { value: lessThanCapAlice })); }); it('should default to a cap of zero', async function () { - await expectThrow(this.crowdsale.buyTokens(charlie, { value: lessThanCapBoth }), EVMRevert); + await shouldFail.reverting(this.crowdsale.buyTokens(charlie, { value: lessThanCapBoth })); }); }); diff --git a/test/crowdsale/MintedCrowdsale.behavior.js b/test/crowdsale/MintedCrowdsale.behavior.js index f5d61328c..ec41e4948 100644 --- a/test/crowdsale/MintedCrowdsale.behavior.js +++ b/test/crowdsale/MintedCrowdsale.behavior.js @@ -1,10 +1,7 @@ -const { ethGetBalance } = require('../helpers/web3'); +const expectEvent = require('../helpers/expectEvent'); +const { balanceDifference } = require('../helpers/balanceDifference'); -const BigNumber = web3.BigNumber; - -const should = require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); +require('../helpers/setup'); function shouldBehaveLikeMintedCrowdsale ([_, investor, wallet, purchaser], rate, value) { const expectedTokenAmount = rate.mul(value); @@ -20,12 +17,12 @@ function shouldBehaveLikeMintedCrowdsale ([_, investor, wallet, purchaser], rate describe('high-level purchase', function () { it('should log purchase', async function () { const { logs } = await this.crowdsale.sendTransaction({ value: value, from: investor }); - const event = logs.find(e => e.event === 'TokensPurchased'); - should.exist(event); - event.args.purchaser.should.equal(investor); - event.args.beneficiary.should.equal(investor); - event.args.value.should.be.bignumber.equal(value); - event.args.amount.should.be.bignumber.equal(expectedTokenAmount); + expectEvent.inLogs(logs, 'TokensPurchased', { + purchaser: investor, + beneficiary: investor, + value: value, + amount: expectedTokenAmount, + }); }); it('should assign tokens to sender', async function () { @@ -34,10 +31,9 @@ function shouldBehaveLikeMintedCrowdsale ([_, investor, wallet, purchaser], rate }); it('should forward funds to wallet', async function () { - const pre = await ethGetBalance(wallet); - await this.crowdsale.sendTransaction({ value, from: investor }); - const post = await ethGetBalance(wallet); - post.minus(pre).should.be.bignumber.equal(value); + (await balanceDifference(wallet, () => + this.crowdsale.sendTransaction({ value, from: investor })) + ).should.be.bignumber.equal(value); }); }); }); diff --git a/test/crowdsale/MintedCrowdsale.test.js b/test/crowdsale/MintedCrowdsale.test.js index 0aeb653dd..9676f6dea 100644 --- a/test/crowdsale/MintedCrowdsale.test.js +++ b/test/crowdsale/MintedCrowdsale.test.js @@ -1,10 +1,10 @@ const { shouldBehaveLikeMintedCrowdsale } = require('./MintedCrowdsale.behavior'); const { ether } = require('../helpers/ether'); -const { assertRevert } = require('../helpers/assertRevert'); +const shouldFail = require('../helpers/shouldFail'); -const BigNumber = web3.BigNumber; +const { BigNumber } = require('../helpers/setup'); -const MintedCrowdsale = artifacts.require('MintedCrowdsaleImpl'); +const MintedCrowdsaleImpl = artifacts.require('MintedCrowdsaleImpl'); const ERC20Mintable = artifacts.require('ERC20MintableMock'); const ERC20 = artifacts.require('ERC20'); @@ -15,7 +15,7 @@ contract('MintedCrowdsale', function ([_, deployer, investor, wallet, purchaser] describe('using ERC20Mintable', function () { beforeEach(async function () { this.token = await ERC20Mintable.new({ from: deployer }); - this.crowdsale = await MintedCrowdsale.new(rate, wallet, this.token.address); + this.crowdsale = await MintedCrowdsaleImpl.new(rate, wallet, this.token.address); await this.token.addMinter(this.crowdsale.address, { from: deployer }); await this.token.renounceMinter({ from: deployer }); @@ -31,15 +31,15 @@ contract('MintedCrowdsale', function ([_, deployer, investor, wallet, purchaser] describe('using non-mintable token', function () { beforeEach(async function () { this.token = await ERC20.new(); - this.crowdsale = await MintedCrowdsale.new(rate, wallet, this.token.address); + this.crowdsale = await MintedCrowdsaleImpl.new(rate, wallet, this.token.address); }); it('rejects bare payments', async function () { - await assertRevert(this.crowdsale.send(value)); + await shouldFail.reverting(this.crowdsale.send(value)); }); it('rejects token purchases', async function () { - await assertRevert(this.crowdsale.buyTokens(investor, { value: value, from: purchaser })); + await shouldFail.reverting(this.crowdsale.buyTokens(investor, { value: value, from: purchaser })); }); }); }); diff --git a/test/crowdsale/PausableCrowdsale.test.js b/test/crowdsale/PausableCrowdsale.test.js new file mode 100644 index 000000000..f99a14a4c --- /dev/null +++ b/test/crowdsale/PausableCrowdsale.test.js @@ -0,0 +1,46 @@ +const shouldFail = require('../helpers/shouldFail'); + +const PausableCrowdsale = artifacts.require('PausableCrowdsaleImpl'); +const SimpleToken = artifacts.require('SimpleTokenMock'); + +require('../helpers/setup'); + +contract('PausableCrowdsale', function ([_, pauser, wallet, anyone]) { + const rate = 1; + const value = 1; + + beforeEach(async function () { + const from = pauser; + + this.token = await SimpleToken.new({ from }); + this.crowdsale = await PausableCrowdsale.new(rate, wallet, this.token.address, { from }); + await this.token.transfer(this.crowdsale.address, 2 * value, { from }); + }); + + it('purchases work', async function () { + await this.crowdsale.sendTransaction({ from: anyone, value }); + await this.crowdsale.buyTokens(anyone, { from: anyone, value }); + }); + + context('after pause', function () { + beforeEach(async function () { + await this.crowdsale.pause({ from: pauser }); + }); + + it('purchases do not work', async function () { + await shouldFail.reverting(this.crowdsale.sendTransaction({ from: anyone, value })); + await shouldFail.reverting(this.crowdsale.buyTokens(anyone, { from: anyone, value })); + }); + + context('after unpause', function () { + beforeEach(async function () { + await this.crowdsale.unpause({ from: pauser }); + }); + + it('purchases work', async function () { + await this.crowdsale.sendTransaction({ from: anyone, value }); + await this.crowdsale.buyTokens(anyone, { from: anyone, value }); + }); + }); + }); +}); diff --git a/test/crowdsale/PostDeliveryCrowdsale.test.js b/test/crowdsale/PostDeliveryCrowdsale.test.js index 714fb563c..9eaaf12af 100644 --- a/test/crowdsale/PostDeliveryCrowdsale.test.js +++ b/test/crowdsale/PostDeliveryCrowdsale.test.js @@ -1,17 +1,10 @@ -const { advanceBlock } = require('../helpers/advanceToBlock'); -const { increaseTimeTo, duration } = require('../helpers/increaseTime'); -const { latestTime } = require('../helpers/latestTime'); -const { expectThrow } = require('../helpers/expectThrow'); -const { EVMRevert } = require('../helpers/EVMRevert'); +const time = require('../helpers/time'); +const shouldFail = require('../helpers/shouldFail'); const { ether } = require('../helpers/ether'); -const BigNumber = web3.BigNumber; +const { BigNumber } = require('../helpers/setup'); -require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); - -const PostDeliveryCrowdsale = artifacts.require('PostDeliveryCrowdsaleImpl'); +const PostDeliveryCrowdsaleImpl = artifacts.require('PostDeliveryCrowdsaleImpl'); const SimpleToken = artifacts.require('SimpleTokenMock'); contract('PostDeliveryCrowdsale', function ([_, investor, wallet, purchaser]) { @@ -20,15 +13,15 @@ contract('PostDeliveryCrowdsale', function ([_, investor, wallet, purchaser]) { before(async function () { // Advance to the next block to correctly read time in the solidity "now" function interpreted by ganache - await advanceBlock(); + await time.advanceBlock(); }); beforeEach(async function () { - this.openingTime = (await latestTime()) + duration.weeks(1); - this.closingTime = this.openingTime + duration.weeks(1); - this.afterClosingTime = this.closingTime + duration.seconds(1); + this.openingTime = (await time.latest()) + time.duration.weeks(1); + this.closingTime = this.openingTime + time.duration.weeks(1); + this.afterClosingTime = this.closingTime + time.duration.seconds(1); this.token = await SimpleToken.new(); - this.crowdsale = await PostDeliveryCrowdsale.new( + this.crowdsale = await PostDeliveryCrowdsaleImpl.new( this.openingTime, this.closingTime, rate, wallet, this.token.address ); await this.token.transfer(this.crowdsale.address, tokenSupply); @@ -36,7 +29,7 @@ contract('PostDeliveryCrowdsale', function ([_, investor, wallet, purchaser]) { context('after opening time', function () { beforeEach(async function () { - await increaseTimeTo(this.openingTime); + await time.increaseTo(this.openingTime); }); context('with bought tokens', function () { @@ -52,12 +45,12 @@ contract('PostDeliveryCrowdsale', function ([_, investor, wallet, purchaser]) { }); it('does not allow beneficiaries to withdraw tokens before crowdsale ends', async function () { - await expectThrow(this.crowdsale.withdrawTokens(investor), EVMRevert); + await shouldFail.reverting(this.crowdsale.withdrawTokens(investor)); }); context('after closing time', function () { beforeEach(async function () { - await increaseTimeTo(this.afterClosingTime); + await time.increaseTo(this.afterClosingTime); }); it('allows beneficiaries to withdraw tokens', async function () { @@ -68,7 +61,7 @@ contract('PostDeliveryCrowdsale', function ([_, investor, wallet, purchaser]) { it('rejects multiple withdrawals', async function () { await this.crowdsale.withdrawTokens(investor); - await expectThrow(this.crowdsale.withdrawTokens(investor), EVMRevert); + await shouldFail.reverting(this.crowdsale.withdrawTokens(investor)); }); }); }); diff --git a/test/crowdsale/RefundableCrowdsale.test.js b/test/crowdsale/RefundableCrowdsale.test.js index af2d02b96..5fb4e4f5d 100644 --- a/test/crowdsale/RefundableCrowdsale.test.js +++ b/test/crowdsale/RefundableCrowdsale.test.js @@ -1,18 +1,12 @@ const { ether } = require('../helpers/ether'); -const { advanceBlock } = require('../helpers/advanceToBlock'); -const { increaseTimeTo, duration } = require('../helpers/increaseTime'); -const { latestTime } = require('../helpers/latestTime'); -const { expectThrow } = require('../helpers/expectThrow'); -const { EVMRevert } = require('../helpers/EVMRevert'); +const { balanceDifference } = require('../helpers/balanceDifference'); +const shouldFail = require('../helpers/shouldFail'); +const time = require('../helpers/time'); const { ethGetBalance } = require('../helpers/web3'); -const BigNumber = web3.BigNumber; +const { BigNumber } = require('../helpers/setup'); -require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); - -const RefundableCrowdsale = artifacts.require('RefundableCrowdsaleImpl'); +const RefundableCrowdsaleImpl = artifacts.require('RefundableCrowdsaleImpl'); const SimpleToken = artifacts.require('SimpleTokenMock'); contract('RefundableCrowdsale', function ([_, wallet, investor, purchaser, anyone]) { @@ -23,30 +17,27 @@ contract('RefundableCrowdsale', function ([_, wallet, investor, purchaser, anyon before(async function () { // Advance to the next block to correctly read time in the solidity "now" function interpreted by ganache - await advanceBlock(); + await time.advanceBlock(); }); beforeEach(async function () { - this.openingTime = (await latestTime()) + duration.weeks(1); - this.closingTime = this.openingTime + duration.weeks(1); - this.afterClosingTime = this.closingTime + duration.seconds(1); + this.openingTime = (await time.latest()) + time.duration.weeks(1); + this.closingTime = this.openingTime + time.duration.weeks(1); + this.afterClosingTime = this.closingTime + time.duration.seconds(1); this.preWalletBalance = await ethGetBalance(wallet); this.token = await SimpleToken.new(); }); it('rejects a goal of zero', async function () { - await expectThrow( - RefundableCrowdsale.new( - this.openingTime, this.closingTime, rate, wallet, this.token.address, 0, - ), - EVMRevert, + await shouldFail.reverting( + RefundableCrowdsaleImpl.new(this.openingTime, this.closingTime, rate, wallet, this.token.address, 0) ); }); context('with crowdsale', function () { beforeEach(async function () { - this.crowdsale = await RefundableCrowdsale.new( + this.crowdsale = await RefundableCrowdsaleImpl.new( this.openingTime, this.closingTime, rate, wallet, this.token.address, goal ); @@ -55,17 +46,17 @@ contract('RefundableCrowdsale', function ([_, wallet, investor, purchaser, anyon context('before opening time', function () { it('denies refunds', async function () { - await expectThrow(this.crowdsale.claimRefund(investor), EVMRevert); + await shouldFail.reverting(this.crowdsale.claimRefund(investor)); }); }); context('after opening time', function () { beforeEach(async function () { - await increaseTimeTo(this.openingTime); + await time.increaseTo(this.openingTime); }); it('denies refunds', async function () { - await expectThrow(this.crowdsale.claimRefund(investor), EVMRevert); + await shouldFail.reverting(this.crowdsale.claimRefund(investor)); }); context('with unreached goal', function () { @@ -75,15 +66,14 @@ contract('RefundableCrowdsale', function ([_, wallet, investor, purchaser, anyon context('after closing time and finalization', function () { beforeEach(async function () { - await increaseTimeTo(this.afterClosingTime); + await time.increaseTo(this.afterClosingTime); await this.crowdsale.finalize({ from: anyone }); }); it('refunds', async function () { - const pre = await ethGetBalance(investor); - await this.crowdsale.claimRefund(investor, { gasPrice: 0 }); - const post = await ethGetBalance(investor); - post.minus(pre).should.be.bignumber.equal(lessThanGoal); + (await balanceDifference(investor, () => + this.crowdsale.claimRefund(investor, { gasPrice: 0 })) + ).should.be.bignumber.equal(lessThanGoal); }); }); }); @@ -95,12 +85,12 @@ contract('RefundableCrowdsale', function ([_, wallet, investor, purchaser, anyon context('after closing time and finalization', function () { beforeEach(async function () { - await increaseTimeTo(this.afterClosingTime); + await time.increaseTo(this.afterClosingTime); await this.crowdsale.finalize({ from: anyone }); }); it('denies refunds', async function () { - await expectThrow(this.crowdsale.claimRefund(investor), EVMRevert); + await shouldFail.reverting(this.crowdsale.claimRefund(investor)); }); it('forwards funds to wallet', async function () { diff --git a/test/crowdsale/RefundablePostDeliveryCrowdsale.test.js b/test/crowdsale/RefundablePostDeliveryCrowdsale.test.js new file mode 100644 index 000000000..293d78674 --- /dev/null +++ b/test/crowdsale/RefundablePostDeliveryCrowdsale.test.js @@ -0,0 +1,103 @@ +const time = require('../helpers/time'); +const shouldFail = require('../helpers/shouldFail'); +const { ether } = require('../helpers/ether'); + +const BigNumber = web3.BigNumber; + +require('chai') + .use(require('chai-bignumber')(BigNumber)) + .should(); + +const RefundablePostDeliveryCrowdsaleImpl = artifacts.require('RefundablePostDeliveryCrowdsaleImpl'); +const SimpleToken = artifacts.require('SimpleTokenMock'); + +contract('RefundablePostDeliveryCrowdsale', function ([_, investor, wallet, purchaser]) { + const rate = new BigNumber(1); + const tokenSupply = new BigNumber('1e22'); + const goal = ether(100); + + before(async function () { + // Advance to the next block to correctly read time in the solidity "now" function interpreted by ganache + await time.advanceBlock(); + }); + + beforeEach(async function () { + this.openingTime = (await time.latest()) + time.duration.weeks(1); + this.closingTime = this.openingTime + time.duration.weeks(1); + this.afterClosingTime = this.closingTime + time.duration.seconds(1); + this.token = await SimpleToken.new(); + this.crowdsale = await RefundablePostDeliveryCrowdsaleImpl.new( + this.openingTime, this.closingTime, rate, wallet, this.token.address, goal + ); + await this.token.transfer(this.crowdsale.address, tokenSupply); + }); + + context('after opening time', function () { + beforeEach(async function () { + await time.increaseTo(this.openingTime); + }); + + context('with bought tokens below the goal', function () { + const value = goal.sub(1); + + beforeEach(async function () { + await this.crowdsale.buyTokens(investor, { value: value, from: purchaser }); + }); + + it('does not immediately deliver tokens to beneficiaries', async function () { + (await this.crowdsale.balanceOf(investor)).should.be.bignumber.equal(value); + (await this.token.balanceOf(investor)).should.be.bignumber.equal(0); + }); + + it('does not allow beneficiaries to withdraw tokens before crowdsale ends', async function () { + await shouldFail.reverting(this.crowdsale.withdrawTokens(investor)); + }); + + context('after closing time and finalization', function () { + beforeEach(async function () { + await time.increaseTo(this.afterClosingTime); + await this.crowdsale.finalize(); + }); + + it('rejects token withdrawals', async function () { + await shouldFail.reverting(this.crowdsale.withdrawTokens(investor)); + }); + }); + }); + + context('with bought tokens matching the goal', function () { + const value = goal; + + beforeEach(async function () { + await this.crowdsale.buyTokens(investor, { value: value, from: purchaser }); + }); + + it('does not immediately deliver tokens to beneficiaries', async function () { + (await this.crowdsale.balanceOf(investor)).should.be.bignumber.equal(value); + (await this.token.balanceOf(investor)).should.be.bignumber.equal(0); + }); + + it('does not allow beneficiaries to withdraw tokens before crowdsale ends', async function () { + await shouldFail.reverting(this.crowdsale.withdrawTokens(investor)); + }); + + context('after closing time and finalization', function () { + beforeEach(async function () { + await time.increaseTo(this.afterClosingTime); + await this.crowdsale.finalize(); + }); + + it('allows beneficiaries to withdraw tokens', async function () { + await this.crowdsale.withdrawTokens(investor); + (await this.crowdsale.balanceOf(investor)).should.be.bignumber.equal(0); + (await this.token.balanceOf(investor)).should.be.bignumber.equal(value); + }); + + it('rejects multiple withdrawals', async function () { + await this.crowdsale.withdrawTokens(investor); + await shouldFail.reverting(this.crowdsale.withdrawTokens(investor)); + }); + }); + }); + }); +}); diff --git a/test/crowdsale/TimedCrowdsale.test.js b/test/crowdsale/TimedCrowdsale.test.js index d61a1e885..f118c2085 100644 --- a/test/crowdsale/TimedCrowdsale.test.js +++ b/test/crowdsale/TimedCrowdsale.test.js @@ -1,17 +1,10 @@ const { ether } = require('../helpers/ether'); -const { advanceBlock } = require('../helpers/advanceToBlock'); -const { increaseTimeTo, duration } = require('../helpers/increaseTime'); -const { latestTime } = require('../helpers/latestTime'); -const { expectThrow } = require('../helpers/expectThrow'); -const { EVMRevert } = require('../helpers/EVMRevert'); +const shouldFail = require('../helpers/shouldFail'); +const time = require('../helpers/time'); -const BigNumber = web3.BigNumber; +const { BigNumber } = require('../helpers/setup'); -require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); - -const TimedCrowdsale = artifacts.require('TimedCrowdsaleImpl'); +const TimedCrowdsaleImpl = artifacts.require('TimedCrowdsaleImpl'); const SimpleToken = artifacts.require('SimpleTokenMock'); contract('TimedCrowdsale', function ([_, investor, wallet, purchaser]) { @@ -21,37 +14,45 @@ contract('TimedCrowdsale', function ([_, investor, wallet, purchaser]) { before(async function () { // Advance to the next block to correctly read time in the solidity "now" function interpreted by ganache - await advanceBlock(); + await time.advanceBlock(); }); beforeEach(async function () { - this.openingTime = (await latestTime()) + duration.weeks(1); - this.closingTime = this.openingTime + duration.weeks(1); - this.afterClosingTime = this.closingTime + duration.seconds(1); + this.openingTime = (await time.latest()) + time.duration.weeks(1); + this.closingTime = this.openingTime + time.duration.weeks(1); + this.afterClosingTime = this.closingTime + time.duration.seconds(1); this.token = await SimpleToken.new(); }); - it('rejects an opening time in the past', async function () { - await expectThrow(TimedCrowdsale.new( - (await latestTime()) - duration.days(1), this.closingTime, rate, wallet, this.token.address - ), EVMRevert); + it('reverts if the opening time is in the past', async function () { + await shouldFail.reverting(TimedCrowdsaleImpl.new( + (await time.latest()) - time.duration.days(1), this.closingTime, rate, wallet, this.token.address + )); }); - it('rejects a closing time before the opening time', async function () { - await expectThrow(TimedCrowdsale.new( - this.openingTime, this.openingTime - duration.seconds(1), rate, wallet, this.token.address - ), EVMRevert); + it('reverts if the closing time is before the opening time', async function () { + await shouldFail.reverting(TimedCrowdsaleImpl.new( + this.openingTime, this.openingTime - time.duration.seconds(1), rate, wallet, this.token.address + )); + }); + + it('reverts if the closing time equals the opening time', async function () { + await shouldFail.reverting(TimedCrowdsaleImpl.new( + this.openingTime, this.openingTime, rate, wallet, this.token.address + )); }); context('with crowdsale', function () { beforeEach(async function () { - this.crowdsale = await TimedCrowdsale.new(this.openingTime, this.closingTime, rate, wallet, this.token.address); + this.crowdsale = await TimedCrowdsaleImpl.new( + this.openingTime, this.closingTime, rate, wallet, this.token.address + ); await this.token.transfer(this.crowdsale.address, tokenSupply); }); it('should be ended only after end', async function () { (await this.crowdsale.hasClosed()).should.equal(false); - await increaseTimeTo(this.afterClosingTime); + await time.increaseTo(this.afterClosingTime); (await this.crowdsale.isOpen()).should.equal(false); (await this.crowdsale.hasClosed()).should.equal(true); }); @@ -59,21 +60,21 @@ contract('TimedCrowdsale', function ([_, investor, wallet, purchaser]) { describe('accepting payments', function () { it('should reject payments before start', async function () { (await this.crowdsale.isOpen()).should.equal(false); - await expectThrow(this.crowdsale.send(value), EVMRevert); - await expectThrow(this.crowdsale.buyTokens(investor, { from: purchaser, value: value }), EVMRevert); + await shouldFail.reverting(this.crowdsale.send(value)); + await shouldFail.reverting(this.crowdsale.buyTokens(investor, { from: purchaser, value: value })); }); it('should accept payments after start', async function () { - await increaseTimeTo(this.openingTime); + await time.increaseTo(this.openingTime); (await this.crowdsale.isOpen()).should.equal(true); await this.crowdsale.send(value); await this.crowdsale.buyTokens(investor, { value: value, from: purchaser }); }); it('should reject payments after end', async function () { - await increaseTimeTo(this.afterClosingTime); - await expectThrow(this.crowdsale.send(value), EVMRevert); - await expectThrow(this.crowdsale.buyTokens(investor, { value: value, from: purchaser }), EVMRevert); + await time.increaseTo(this.afterClosingTime); + await shouldFail.reverting(this.crowdsale.send(value)); + await shouldFail.reverting(this.crowdsale.buyTokens(investor, { value: value, from: purchaser })); }); }); }); diff --git a/test/crowdsale/WhitelistCrowdsale.test.js b/test/crowdsale/WhitelistCrowdsale.test.js new file mode 100644 index 000000000..21720973e --- /dev/null +++ b/test/crowdsale/WhitelistCrowdsale.test.js @@ -0,0 +1,57 @@ +require('../helpers/setup'); +const { ether } = require('../helpers/ether'); +const shouldFail = require('../helpers/shouldFail'); + +const BigNumber = web3.BigNumber; + +const WhitelistCrowdsale = artifacts.require('WhitelistCrowdsaleImpl'); +const SimpleToken = artifacts.require('SimpleTokenMock'); + +contract('WhitelistCrowdsale', function ([_, wallet, whitelister, whitelisted, otherWhitelisted, anyone]) { + const rate = 1; + const value = ether(42); + const tokenSupply = new BigNumber('1e22'); + + beforeEach(async function () { + this.token = await SimpleToken.new({ from: whitelister }); + this.crowdsale = await WhitelistCrowdsale.new(rate, wallet, this.token.address, { from: whitelister }); + await this.token.transfer(this.crowdsale.address, tokenSupply, { from: whitelister }); + }); + + async function purchaseShouldSucceed (crowdsale, beneficiary, value) { + await crowdsale.buyTokens(beneficiary, { from: beneficiary, value }); + await crowdsale.sendTransaction({ from: beneficiary, value }); + } + + async function purchaseShouldFail (crowdsale, beneficiary, value) { + await shouldFail.reverting(crowdsale.buyTokens(beneficiary, { from: beneficiary, value })); + await shouldFail.reverting(crowdsale.sendTransaction({ from: beneficiary, value })); + } + + context('with no whitelisted addresses', function () { + it('rejects all purchases', async function () { + await purchaseShouldFail(this.crowdsale, anyone, value); + await purchaseShouldFail(this.crowdsale, whitelisted, value); + }); + }); + + context('with whitelisted addresses', function () { + beforeEach(async function () { + await this.crowdsale.addWhitelisted(whitelisted, { from: whitelister }); + await this.crowdsale.addWhitelisted(otherWhitelisted, { from: whitelister }); + }); + + it('accepts purchases with whitelisted beneficiaries', async function () { + await purchaseShouldSucceed(this.crowdsale, whitelisted, value); + await purchaseShouldSucceed(this.crowdsale, otherWhitelisted, value); + }); + + it('rejects purchases from whitelisted addresses with non-whitelisted beneficiaries', async function () { + await shouldFail(this.crowdsale.buyTokens(anyone, { from: whitelisted, value })); + }); + + it('rejects purchases with non-whitelisted beneficiaries', async function () { + await purchaseShouldFail(this.crowdsale, anyone, value); + }); + }); +}); diff --git a/test/library/ECDSA.test.js b/test/cryptography/ECDSA.test.js similarity index 97% rename from test/library/ECDSA.test.js rename to test/cryptography/ECDSA.test.js index f8d333a5f..1909b848d 100644 --- a/test/library/ECDSA.test.js +++ b/test/cryptography/ECDSA.test.js @@ -1,10 +1,9 @@ const { signMessage, toEthSignedMessageHash } = require('../helpers/sign'); -const { expectThrow } = require('../helpers/expectThrow'); +const shouldFail = require('../helpers/shouldFail'); const ECDSAMock = artifacts.require('ECDSAMock'); -require('chai') - .should(); +require('../helpers/setup'); const TEST_MESSAGE = web3.sha3('OpenZeppelin'); const WRONG_MESSAGE = web3.sha3('Nope'); @@ -113,7 +112,7 @@ contract('ECDSA', function ([_, anyone]) { it.skip('reverts', async function () { // Create the signature const signature = signMessage(anyone, TEST_MESSAGE); - await expectThrow( + await shouldFail.reverting( this.ecdsa.recover(TEST_MESSAGE.substring(2), signature) ); }); diff --git a/test/library/MerkleProof.test.js b/test/cryptography/MerkleProof.test.js similarity index 69% rename from test/library/MerkleProof.test.js rename to test/cryptography/MerkleProof.test.js index 6674880b7..869423048 100644 --- a/test/library/MerkleProof.test.js +++ b/test/cryptography/MerkleProof.test.js @@ -1,16 +1,13 @@ const { MerkleTree } = require('../helpers/merkleTree.js'); -const { sha3, bufferToHex } = require('ethereumjs-util'); +const { keccak256, bufferToHex } = require('ethereumjs-util'); const MerkleProofWrapper = artifacts.require('MerkleProofWrapper'); -require('chai') - .should(); +require('../helpers/setup'); contract('MerkleProof', function () { - let merkleProof; - beforeEach(async function () { - merkleProof = await MerkleProofWrapper.new(); + this.merkleProof = await MerkleProofWrapper.new(); }); describe('verify', function () { @@ -22,9 +19,9 @@ contract('MerkleProof', function () { const proof = merkleTree.getHexProof(elements[0]); - const leaf = bufferToHex(sha3(elements[0])); + const leaf = bufferToHex(keccak256(elements[0])); - (await merkleProof.verify(proof, root, leaf)).should.equal(true); + (await this.merkleProof.verify(proof, root, leaf)).should.equal(true); }); it('should return false for an invalid Merkle proof', async function () { @@ -33,14 +30,14 @@ contract('MerkleProof', function () { const correctRoot = correctMerkleTree.getHexRoot(); - const correctLeaf = bufferToHex(sha3(correctElements[0])); + const correctLeaf = bufferToHex(keccak256(correctElements[0])); const badElements = ['d', 'e', 'f']; const badMerkleTree = new MerkleTree(badElements); const badProof = badMerkleTree.getHexProof(badElements[0]); - (await merkleProof.verify(badProof, correctRoot, correctLeaf)).should.equal(false); + (await this.merkleProof.verify(badProof, correctRoot, correctLeaf)).should.equal(false); }); it('should return false for a Merkle proof of invalid length', async function () { @@ -52,9 +49,9 @@ contract('MerkleProof', function () { const proof = merkleTree.getHexProof(elements[0]); const badProof = proof.slice(0, proof.length - 5); - const leaf = bufferToHex(sha3(elements[0])); + const leaf = bufferToHex(keccak256(elements[0])); - (await merkleProof.verify(badProof, root, leaf)).should.equal(false); + (await this.merkleProof.verify(badProof, root, leaf)).should.equal(false); }); }); }); diff --git a/test/drafts/Counter.test.js b/test/drafts/Counter.test.js index ca661c113..008e76778 100644 --- a/test/drafts/Counter.test.js +++ b/test/drafts/Counter.test.js @@ -1,9 +1,7 @@ -const Counter = artifacts.require('CounterImpl'); +const CounterImpl = artifacts.require('CounterImpl'); -require('chai') - .use(require('chai-bignumber')(web3.BigNumber)) - .should(); +require('../helpers/setup'); const EXPECTED = [1, 2, 3, 4]; const KEY1 = web3.sha3('key1'); @@ -11,7 +9,7 @@ const KEY2 = web3.sha3('key2'); contract('Counter', function ([_, owner]) { beforeEach(async function () { - this.mock = await Counter.new({ from: owner }); + this.mock = await CounterImpl.new({ from: owner }); }); context('custom key', async function () { diff --git a/test/drafts/ERC1046/TokenMetadata.test.js b/test/drafts/ERC1046/TokenMetadata.test.js index ef0a2ca3d..58aaa3a33 100644 --- a/test/drafts/ERC1046/TokenMetadata.test.js +++ b/test/drafts/ERC1046/TokenMetadata.test.js @@ -1,13 +1,12 @@ -const ERC20WithMetadata = artifacts.require('ERC20WithMetadataMock'); +const ERC20WithMetadataMock = artifacts.require('ERC20WithMetadataMock'); -require('chai') - .should(); +require('../../helpers/setup'); const metadataURI = 'https://example.com'; describe('ERC20WithMetadata', function () { beforeEach(async function () { - this.token = await ERC20WithMetadata.new(metadataURI); + this.token = await ERC20WithMetadataMock.new(metadataURI); }); it('responds with the metadata', async function () { diff --git a/test/drafts/ERC20Migrator.test.js b/test/drafts/ERC20Migrator.test.js index e6e0fada7..90a466f8f 100644 --- a/test/drafts/ERC20Migrator.test.js +++ b/test/drafts/ERC20Migrator.test.js @@ -1,22 +1,17 @@ -const { assertRevert } = require('../helpers/assertRevert'); +const shouldFail = require('../helpers/shouldFail'); +const { ZERO_ADDRESS } = require('../helpers/constants'); const ERC20Mock = artifacts.require('ERC20Mock'); const ERC20Mintable = artifacts.require('ERC20MintableMock'); const ERC20Migrator = artifacts.require('ERC20MigratorMock'); -const BigNumber = web3.eth.BigNumber; - -require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); +require('../helpers/setup'); contract('ERC20Migrator', function ([_, owner, recipient, anotherAccount]) { - const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; - const totalSupply = 200; it('reverts with a null legacy token address', async function () { - await assertRevert(ERC20Migrator.new(ZERO_ADDRESS)); + await shouldFail.reverting(ERC20Migrator.new(ZERO_ADDRESS)); }); describe('with tokens and migrator', function () { @@ -32,11 +27,11 @@ contract('ERC20Migrator', function ([_, owner, recipient, anotherAccount]) { describe('beginMigration', function () { it('reverts with a null new token address', async function () { - await assertRevert(this.migrator.beginMigration(ZERO_ADDRESS)); + await shouldFail.reverting(this.migrator.beginMigration(ZERO_ADDRESS)); }); it('reverts if not a minter of the token', async function () { - await assertRevert(this.migrator.beginMigration(this.newToken.address)); + await shouldFail.reverting(this.migrator.beginMigration(this.newToken.address)); }); it('succeeds if it is a minter of the token', async function () { @@ -47,7 +42,7 @@ contract('ERC20Migrator', function ([_, owner, recipient, anotherAccount]) { it('reverts the second time it is called', async function () { await this.newToken.addMinter(this.migrator.address); await this.migrator.beginMigration(this.newToken.address); - await assertRevert(this.migrator.beginMigration(this.newToken.address)); + await shouldFail.reverting(this.migrator.beginMigration(this.newToken.address)); }); }); @@ -147,7 +142,7 @@ contract('ERC20Migrator', function ([_, owner, recipient, anotherAccount]) { const amount = baseAmount + 1; it('reverts', async function () { - await assertRevert(this.migrator.migrate(owner, amount)); + await shouldFail.reverting(this.migrator.migrate(owner, amount)); }); }); }); diff --git a/test/drafts/SignatureBouncer.test.js b/test/drafts/SignatureBouncer.test.js index c234687fc..4e204011a 100644 --- a/test/drafts/SignatureBouncer.test.js +++ b/test/drafts/SignatureBouncer.test.js @@ -1,14 +1,10 @@ -const { assertRevert } = require('../helpers/assertRevert'); +const shouldFail = require('../helpers/shouldFail'); const { getSignFor } = require('../helpers/sign'); const { shouldBehaveLikePublicRole } = require('../access/roles/PublicRole.behavior'); const SignatureBouncerMock = artifacts.require('SignatureBouncerMock'); -const BigNumber = web3.BigNumber; - -require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); +require('../helpers/setup'); const UINT_VALUE = 23; const BYTES_VALUE = web3.toHex('test'); @@ -36,19 +32,19 @@ contract('SignatureBouncer', function ([_, signer, otherSigner, anyone, authoriz }); it('does not allow invalid signature for sender', async function () { - await assertRevert( + await shouldFail.reverting( this.sigBouncer.onlyWithValidSignature(INVALID_SIGNATURE, { from: authorizedUser }) ); }); it('does not allow valid signature for other sender', async function () { - await assertRevert( + await shouldFail.reverting( this.sigBouncer.onlyWithValidSignature(this.signFor(authorizedUser), { from: anyone }) ); }); it('does not allow valid signature for method for sender', async function () { - await assertRevert( + await shouldFail.reverting( this.sigBouncer.onlyWithValidSignature(this.signFor(authorizedUser, 'onlyWithValidSignature'), { from: authorizedUser }) ); @@ -63,13 +59,13 @@ contract('SignatureBouncer', function ([_, signer, otherSigner, anyone, authoriz }); it('does not allow invalid signature with correct method for sender', async function () { - await assertRevert( + await shouldFail.reverting( this.sigBouncer.onlyWithValidSignatureAndMethod(INVALID_SIGNATURE, { from: authorizedUser }) ); }); it('does not allow valid signature with correct method for other sender', async function () { - await assertRevert( + await shouldFail.reverting( this.sigBouncer.onlyWithValidSignatureAndMethod( this.signFor(authorizedUser, 'onlyWithValidSignatureAndMethod'), { from: anyone } ) @@ -77,14 +73,14 @@ contract('SignatureBouncer', function ([_, signer, otherSigner, anyone, authoriz }); it('does not allow valid method signature with incorrect method for sender', async function () { - await assertRevert( + await shouldFail.reverting( this.sigBouncer.onlyWithValidSignatureAndMethod(this.signFor(authorizedUser, 'theWrongMethod'), { from: authorizedUser }) ); }); it('does not allow valid non-method signature method for sender', async function () { - await assertRevert( + await shouldFail.reverting( this.sigBouncer.onlyWithValidSignatureAndMethod(this.signFor(authorizedUser), { from: authorizedUser }) ); }); @@ -98,13 +94,13 @@ contract('SignatureBouncer', function ([_, signer, otherSigner, anyone, authoriz }); it('does not allow invalid signature with correct method and data for sender', async function () { - await assertRevert( + await shouldFail.reverting( this.sigBouncer.onlyWithValidSignatureAndData(UINT_VALUE, INVALID_SIGNATURE, { from: authorizedUser }) ); }); it('does not allow valid signature with correct method and incorrect data for sender', async function () { - await assertRevert( + await shouldFail.reverting( this.sigBouncer.onlyWithValidSignatureAndData(UINT_VALUE + 10, this.signFor(authorizedUser, 'onlyWithValidSignatureAndData', [UINT_VALUE]), { from: authorizedUser } @@ -113,7 +109,7 @@ contract('SignatureBouncer', function ([_, signer, otherSigner, anyone, authoriz }); it('does not allow valid signature with correct method and data for other sender', async function () { - await assertRevert( + await shouldFail.reverting( this.sigBouncer.onlyWithValidSignatureAndData(UINT_VALUE, this.signFor(authorizedUser, 'onlyWithValidSignatureAndData', [UINT_VALUE]), { from: anyone } @@ -122,7 +118,7 @@ contract('SignatureBouncer', function ([_, signer, otherSigner, anyone, authoriz }); it('does not allow valid non-method signature for sender', async function () { - await assertRevert( + await shouldFail.reverting( this.sigBouncer.onlyWithValidSignatureAndData(UINT_VALUE, this.signFor(authorizedUser), { from: authorizedUser } ) @@ -130,7 +126,7 @@ contract('SignatureBouncer', function ([_, signer, otherSigner, anyone, authoriz }); it('does not allow msg.data shorter than SIGNATURE_SIZE', async function () { - await assertRevert( + await shouldFail.reverting( this.sigBouncer.tooShortMsgData({ from: authorizedUser }) ); }); diff --git a/test/drafts/SignedSafeMath.test.js b/test/drafts/SignedSafeMath.test.js new file mode 100644 index 000000000..e144d39f6 --- /dev/null +++ b/test/drafts/SignedSafeMath.test.js @@ -0,0 +1,138 @@ +const shouldFail = require('../helpers/shouldFail'); +const { MIN_INT256, MAX_INT256 } = require('../helpers/constants'); + +const SignedSafeMathMock = artifacts.require('SignedSafeMathMock'); + +const { BigNumber } = require('../helpers/setup'); + +contract('SignedSafeMath', function () { + beforeEach(async function () { + this.safeMath = await SignedSafeMathMock.new(); + }); + + describe('add', function () { + it('adds correctly if it does not overflow and the result is positve', async function () { + const a = new BigNumber(1234); + const b = new BigNumber(5678); + + (await this.safeMath.add(a, b)).should.be.bignumber.equal(a.plus(b)); + }); + + it('adds correctly if it does not overflow and the result is negative', async function () { + const a = MAX_INT256; + const b = MIN_INT256; + + const result = await this.safeMath.add(a, b); + result.should.be.bignumber.equal(a.plus(b)); + }); + + it('reverts on positive addition overflow', async function () { + const a = MAX_INT256; + const b = new BigNumber(1); + + await shouldFail.reverting(this.safeMath.add(a, b)); + }); + + it('reverts on negative addition overflow', async function () { + const a = MIN_INT256; + const b = new BigNumber(-1); + + await shouldFail.reverting(this.safeMath.add(a, b)); + }); + }); + + describe('sub', function () { + it('subtracts correctly if it does not overflow and the result is positive', async function () { + const a = new BigNumber(5678); + const b = new BigNumber(1234); + + const result = await this.safeMath.sub(a, b); + result.should.be.bignumber.equal(a.minus(b)); + }); + + it('subtracts correctly if it does not overflow and the result is negative', async function () { + const a = new BigNumber(1234); + const b = new BigNumber(5678); + + const result = await this.safeMath.sub(a, b); + result.should.be.bignumber.equal(a.minus(b)); + }); + + it('reverts on positive subtraction overflow', async function () { + const a = MAX_INT256; + const b = new BigNumber(-1); + + await shouldFail.reverting(this.safeMath.sub(a, b)); + }); + + it('reverts on negative subtraction overflow', async function () { + const a = MIN_INT256; + const b = new BigNumber(1); + + await shouldFail.reverting(this.safeMath.sub(a, b)); + }); + }); + + describe('mul', function () { + it('multiplies correctly', async function () { + const a = new BigNumber(5678); + const b = new BigNumber(-1234); + + const result = await this.safeMath.mul(a, b); + result.should.be.bignumber.equal(a.times(b)); + }); + + it('handles a zero product correctly', async function () { + const a = new BigNumber(0); + const b = new BigNumber(5678); + + const result = await this.safeMath.mul(a, b); + result.should.be.bignumber.equal(a.times(b)); + }); + + it('reverts on multiplication overflow, positive operands', async function () { + const a = MAX_INT256; + const b = new BigNumber(2); + + await shouldFail.reverting(this.safeMath.mul(a, b)); + }); + + it('reverts when minimum integer is multiplied by -1', async function () { + const a = MIN_INT256; + const b = new BigNumber(-1); + + await shouldFail.reverting(this.safeMath.mul(a, b)); + }); + + it('reverts when -1 is multiplied by minimum integer', async function () { + const a = new BigNumber(-1); + const b = MIN_INT256; + + await shouldFail.reverting(this.safeMath.mul(a, b)); + }); + }); + + describe('div', function () { + it('divides correctly', async function () { + const a = new BigNumber(-5678); + const b = new BigNumber(5678); + + const result = await this.safeMath.div(a, b); + result.should.be.bignumber.equal(a.div(b)); + }); + + it('reverts on zero division', async function () { + const a = new BigNumber(-5678); + const b = new BigNumber(0); + + await shouldFail.reverting(this.safeMath.div(a, b)); + }); + + it('reverts on overflow, negative second', async function () { + const a = new BigNumber(MIN_INT256); + const b = new BigNumber(-1); + + await shouldFail.reverting(this.safeMath.div(a, b)); + }); + }); +}); diff --git a/test/token/ERC20/TokenVesting.test.js b/test/drafts/TokenVesting.test.js similarity index 58% rename from test/token/ERC20/TokenVesting.test.js rename to test/drafts/TokenVesting.test.js index 78cd835bf..6bca11e05 100644 --- a/test/token/ERC20/TokenVesting.test.js +++ b/test/drafts/TokenVesting.test.js @@ -1,45 +1,57 @@ -const { expectThrow } = require('../../helpers/expectThrow'); -const { EVMRevert } = require('../../helpers/EVMRevert'); -const { latestTime } = require('../../helpers/latestTime'); -const { increaseTimeTo, duration } = require('../../helpers/increaseTime'); -const { ethGetBlock } = require('../../helpers/web3'); +const shouldFail = require('../helpers/shouldFail'); +const expectEvent = require('../helpers/expectEvent'); +const time = require('../helpers/time'); +const { ethGetBlock } = require('../helpers/web3'); +const { ZERO_ADDRESS } = require('../helpers/constants'); -const BigNumber = web3.BigNumber; - -require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); +const { BigNumber } = require('../helpers/setup'); const ERC20Mintable = artifacts.require('ERC20MintableMock'); const TokenVesting = artifacts.require('TokenVestingMock'); contract('TokenVesting', function ([_, owner, beneficiary]) { const amount = new BigNumber(1000); - const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; beforeEach(async function () { - this.start = (await latestTime()) + duration.minutes(1); // +1 minute so it starts after contract instantiation - this.cliffDuration = duration.years(1); - this.duration = duration.years(2); + // +1 minute so it starts after contract instantiation + this.start = (await time.latest()) + time.duration.minutes(1); + this.cliffDuration = time.duration.years(1); + this.duration = time.duration.years(2); }); - it('rejects a duration shorter than the cliff', async function () { + it('reverts with a duration shorter than the cliff', async function () { const cliffDuration = this.duration; const duration = this.cliffDuration; cliffDuration.should.be.gt(duration); - await expectThrow( + await shouldFail.reverting( TokenVesting.new(beneficiary, this.start, cliffDuration, duration, true, { from: owner }) ); }); - it('requires a valid beneficiary', async function () { - await expectThrow( + it('reverts with a null beneficiary', async function () { + await shouldFail.reverting( TokenVesting.new(ZERO_ADDRESS, this.start, this.cliffDuration, this.duration, true, { from: owner }) ); }); + it('reverts with a null duration', async function () { + // cliffDuration should also be 0, since the duration must be larger than the cliff + await shouldFail.reverting( + TokenVesting.new(beneficiary, this.start, 0, 0, true, { from: owner }) + ); + }); + + it('reverts if the end time is in the past', async function () { + const now = await time.latest(); + + this.start = now - this.duration - time.duration.minutes(1); + await shouldFail.reverting( + TokenVesting.new(beneficiary, this.start, this.cliffDuration, this.duration, true, { from: owner }) + ); + }); + context('once deployed', function () { beforeEach(async function () { this.vesting = await TokenVesting.new( @@ -58,19 +70,20 @@ contract('TokenVesting', function ([_, owner, beneficiary]) { }); it('cannot be released before cliff', async function () { - await expectThrow( - this.vesting.release(this.token.address), - EVMRevert, - ); + await shouldFail.reverting(this.vesting.release(this.token.address)); }); it('can be released after cliff', async function () { - await increaseTimeTo(this.start + this.cliffDuration + duration.weeks(1)); - await this.vesting.release(this.token.address); + await time.increaseTo(this.start + this.cliffDuration + time.duration.weeks(1)); + const { logs } = await this.vesting.release(this.token.address); + expectEvent.inLogs(logs, 'TokensReleased', { + token: this.token.address, + amount: await this.token.balanceOf(beneficiary), + }); }); it('should release proper amount after cliff', async function () { - await increaseTimeTo(this.start + this.cliffDuration); + await time.increaseTo(this.start + this.cliffDuration); const { receipt } = await this.vesting.release(this.token.address); const block = await ethGetBlock(receipt.blockNumber); @@ -87,7 +100,7 @@ contract('TokenVesting', function ([_, owner, beneficiary]) { for (let i = 1; i <= checkpoints; i++) { const now = this.start + this.cliffDuration + i * (vestingPeriod / checkpoints); - await increaseTimeTo(now); + await time.increaseTo(now); await this.vesting.release(this.token.address); const expectedVesting = amount.mul(now - this.start).div(this.duration).floor(); @@ -97,14 +110,15 @@ contract('TokenVesting', function ([_, owner, beneficiary]) { }); it('should have released all after end', async function () { - await increaseTimeTo(this.start + this.duration); + await time.increaseTo(this.start + this.duration); await this.vesting.release(this.token.address); (await this.token.balanceOf(beneficiary)).should.bignumber.equal(amount); (await this.vesting.released(this.token.address)).should.bignumber.equal(amount); }); it('should be revoked by owner if revocable is set', async function () { - await this.vesting.revoke(this.token.address, { from: owner }); + const { logs } = await this.vesting.revoke(this.token.address, { from: owner }); + expectEvent.inLogs(logs, 'TokenVestingRevoked', { token: this.token.address }); (await this.vesting.revoked(this.token.address)).should.equal(true); }); @@ -113,16 +127,13 @@ contract('TokenVesting', function ([_, owner, beneficiary]) { beneficiary, this.start, this.cliffDuration, this.duration, false, { from: owner } ); - await expectThrow( - vesting.revoke(this.token.address, { from: owner }), - EVMRevert, - ); + await shouldFail.reverting(vesting.revoke(this.token.address, { from: owner })); }); it('should return the non-vested tokens when revoked by owner', async function () { - await increaseTimeTo(this.start + this.cliffDuration + duration.weeks(12)); + await time.increaseTo(this.start + this.cliffDuration + time.duration.weeks(12)); - const vested = await this.vesting.vestedAmount(this.token.address); + const vested = vestedAmount(amount, await time.latest(), this.start, this.cliffDuration, this.duration); await this.vesting.revoke(this.token.address, { from: owner }); @@ -130,28 +141,24 @@ contract('TokenVesting', function ([_, owner, beneficiary]) { }); it('should keep the vested tokens when revoked by owner', async function () { - await increaseTimeTo(this.start + this.cliffDuration + duration.weeks(12)); + await time.increaseTo(this.start + this.cliffDuration + time.duration.weeks(12)); - const vestedPre = await this.vesting.vestedAmount(this.token.address); + const vestedPre = vestedAmount(amount, await time.latest(), this.start, this.cliffDuration, this.duration); await this.vesting.revoke(this.token.address, { from: owner }); - const vestedPost = await this.vesting.vestedAmount(this.token.address); + const vestedPost = vestedAmount(amount, await time.latest(), this.start, this.cliffDuration, this.duration); vestedPre.should.bignumber.equal(vestedPost); }); it('should fail to be revoked a second time', async function () { - await increaseTimeTo(this.start + this.cliffDuration + duration.weeks(12)); - - await this.vesting.vestedAmount(this.token.address); - await this.vesting.revoke(this.token.address, { from: owner }); - - await expectThrow( - this.vesting.revoke(this.token.address, { from: owner }), - EVMRevert, - ); + await shouldFail.reverting(this.vesting.revoke(this.token.address, { from: owner })); }); + + function vestedAmount (total, now, start, cliffDuration, duration) { + return (now < start + cliffDuration) ? 0 : Math.round(total * (now - start) / duration); + } }); }); diff --git a/test/examples/SampleCrowdsale.test.js b/test/examples/SampleCrowdsale.test.js index 82638c5d9..9df145aea 100644 --- a/test/examples/SampleCrowdsale.test.js +++ b/test/examples/SampleCrowdsale.test.js @@ -1,17 +1,9 @@ const { ether } = require('../helpers/ether'); -const { advanceBlock } = require('../helpers/advanceToBlock'); -const { increaseTimeTo, duration } = require('../helpers/increaseTime'); -const { latestTime } = require('../helpers/latestTime'); -const { expectThrow } = require('../helpers/expectThrow'); -const { EVMRevert } = require('../helpers/EVMRevert'); -const { assertRevert } = require('../helpers/assertRevert'); -const { ethGetBalance } = require('../helpers/web3'); +const shouldFail = require('../helpers/shouldFail'); +const time = require('../helpers/time'); +const { balanceDifference } = require('../helpers/balanceDifference'); -const BigNumber = web3.BigNumber; - -const should = require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); +const { should, BigNumber } = require('../helpers/setup'); const SampleCrowdsale = artifacts.require('SampleCrowdsaleMock'); const SampleCrowdsaleToken = artifacts.require('SampleCrowdsaleTokenMock'); @@ -23,13 +15,13 @@ contract('SampleCrowdsale', function ([_, deployer, owner, wallet, investor]) { before(async function () { // Advance to the next block to correctly read time in the solidity "now" function interpreted by ganache - await advanceBlock(); + await time.advanceBlock(); }); beforeEach(async function () { - this.openingTime = (await latestTime()) + duration.weeks(1); - this.closingTime = this.openingTime + duration.weeks(1); - this.afterClosingTime = this.closingTime + duration.seconds(1); + this.openingTime = (await time.latest()) + time.duration.weeks(1); + this.closingTime = this.openingTime + time.duration.weeks(1); + this.afterClosingTime = this.closingTime + time.duration.seconds(1); this.token = await SampleCrowdsaleToken.new({ from: deployer }); this.crowdsale = await SampleCrowdsale.new( @@ -54,21 +46,15 @@ contract('SampleCrowdsale', function ([_, deployer, owner, wallet, investor]) { }); it('should not accept payments before start', async function () { - await expectThrow( - this.crowdsale.send(ether(1)), - EVMRevert, - ); - await expectThrow( - this.crowdsale.buyTokens(investor, { from: investor, value: ether(1) }), - EVMRevert, - ); + await shouldFail.reverting(this.crowdsale.send(ether(1))); + await shouldFail.reverting(this.crowdsale.buyTokens(investor, { from: investor, value: ether(1) })); }); it('should accept payments during the sale', async function () { const investmentAmount = ether(1); const expectedTokenAmount = RATE.mul(investmentAmount); - await increaseTimeTo(this.openingTime); + await time.increaseTo(this.openingTime); await this.crowdsale.buyTokens(investor, { value: investmentAmount, from: investor }); (await this.token.balanceOf(investor)).should.be.bignumber.equal(expectedTokenAmount); @@ -76,41 +62,36 @@ contract('SampleCrowdsale', function ([_, deployer, owner, wallet, investor]) { }); it('should reject payments after end', async function () { - await increaseTimeTo(this.afterClosingTime); - await expectThrow(this.crowdsale.send(ether(1)), EVMRevert); - await expectThrow(this.crowdsale.buyTokens(investor, { value: ether(1), from: investor }), EVMRevert); + await time.increaseTo(this.afterClosingTime); + await shouldFail.reverting(this.crowdsale.send(ether(1))); + await shouldFail.reverting(this.crowdsale.buyTokens(investor, { value: ether(1), from: investor })); }); it('should reject payments over cap', async function () { - await increaseTimeTo(this.openingTime); + await time.increaseTo(this.openingTime); await this.crowdsale.send(CAP); - await expectThrow(this.crowdsale.send(1), EVMRevert); + await shouldFail.reverting(this.crowdsale.send(1)); }); it('should allow finalization and transfer funds to wallet if the goal is reached', async function () { - await increaseTimeTo(this.openingTime); + await time.increaseTo(this.openingTime); await this.crowdsale.send(GOAL); - const beforeFinalization = await ethGetBalance(wallet); - await increaseTimeTo(this.afterClosingTime); - await this.crowdsale.finalize({ from: owner }); - const afterFinalization = await ethGetBalance(wallet); - - afterFinalization.minus(beforeFinalization).should.be.bignumber.equal(GOAL); + (await balanceDifference(wallet, async () => { + await time.increaseTo(this.afterClosingTime); + await this.crowdsale.finalize({ from: owner }); + })).should.be.bignumber.equal(GOAL); }); it('should allow refunds if the goal is not reached', async function () { - const balanceBeforeInvestment = await ethGetBalance(investor); + (await balanceDifference(investor, async () => { + await time.increaseTo(this.openingTime); + await this.crowdsale.sendTransaction({ value: ether(1), from: investor, gasPrice: 0 }); + await time.increaseTo(this.afterClosingTime); - await increaseTimeTo(this.openingTime); - await this.crowdsale.sendTransaction({ value: ether(1), from: investor, gasPrice: 0 }); - await increaseTimeTo(this.afterClosingTime); - - await this.crowdsale.finalize({ from: owner }); - await this.crowdsale.claimRefund(investor, { gasPrice: 0 }); - - const balanceAfterRefund = await ethGetBalance(investor); - balanceBeforeInvestment.should.be.bignumber.equal(balanceAfterRefund); + await this.crowdsale.finalize({ from: owner }); + await this.crowdsale.claimRefund(investor, { gasPrice: 0 }); + })).should.be.bignumber.equal(0); }); describe('when goal > cap', function () { @@ -118,7 +99,7 @@ contract('SampleCrowdsale', function ([_, deployer, owner, wallet, investor]) { const HIGH_GOAL = ether(30); it('creation reverts', async function () { - await assertRevert(SampleCrowdsale.new( + await shouldFail.reverting(SampleCrowdsale.new( this.openingTime, this.closingTime, RATE, wallet, CAP, this.token.address, HIGH_GOAL )); }); diff --git a/test/examples/SimpleToken.test.js b/test/examples/SimpleToken.test.js index 74f56938d..568943f03 100644 --- a/test/examples/SimpleToken.test.js +++ b/test/examples/SimpleToken.test.js @@ -1,45 +1,36 @@ -const { decodeLogs } = require('../helpers/decodeLogs'); +const expectEvent = require('../helpers/expectEvent'); +const { ZERO_ADDRESS } = require('../helpers/constants'); const SimpleToken = artifacts.require('SimpleTokenMock'); -const BigNumber = web3.BigNumber; - -require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); +require('../helpers/setup'); contract('SimpleToken', function ([_, creator]) { - let token; - - const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; - beforeEach(async function () { - token = await SimpleToken.new({ from: creator }); + this.token = await SimpleToken.new({ from: creator }); }); it('has a name', async function () { - (await token.name()).should.equal('SimpleToken'); + (await this.token.name()).should.equal('SimpleToken'); }); it('has a symbol', async function () { - (await token.symbol()).should.equal('SIM'); + (await this.token.symbol()).should.equal('SIM'); }); it('has 18 decimals', async function () { - (await token.decimals()).should.be.bignumber.equal(18); + (await this.token.decimals()).should.be.bignumber.equal(18); }); it('assigns the initial total supply to the creator', async function () { - const totalSupply = await token.totalSupply(); - const creatorBalance = await token.balanceOf(creator); + const totalSupply = await this.token.totalSupply(); + const creatorBalance = await this.token.balanceOf(creator); creatorBalance.should.be.bignumber.equal(totalSupply); - const receipt = await web3.eth.getTransactionReceipt(token.transactionHash); - const logs = decodeLogs(receipt.logs, SimpleToken, token.address); - logs.length.should.equal(1); - logs[0].event.should.equal('Transfer'); - logs[0].args.from.valueOf().should.equal(ZERO_ADDRESS); - logs[0].args.to.valueOf().should.equal(creator); - logs[0].args.value.should.be.bignumber.equal(totalSupply); + await expectEvent.inConstruction(this.token, 'Transfer', { + from: ZERO_ADDRESS, + to: creator, + value: totalSupply, + }); }); }); diff --git a/test/helpers/EVMRevert.js b/test/helpers/EVMRevert.js deleted file mode 100644 index cb0c8e02e..000000000 --- a/test/helpers/EVMRevert.js +++ /dev/null @@ -1,5 +0,0 @@ -const EVMRevert = 'revert'; - -module.exports = { - EVMRevert, -}; diff --git a/test/helpers/EVMThrow.js b/test/helpers/EVMThrow.js deleted file mode 100644 index afe21d277..000000000 --- a/test/helpers/EVMThrow.js +++ /dev/null @@ -1,5 +0,0 @@ -const EVMThrow = 'invalid opcode'; - -module.exports = { - EVMThrow, -}; diff --git a/test/helpers/advanceToBlock.js b/test/helpers/advanceToBlock.js deleted file mode 100644 index 22e5467cc..000000000 --- a/test/helpers/advanceToBlock.js +++ /dev/null @@ -1,27 +0,0 @@ -function advanceBlock () { - return new Promise((resolve, reject) => { - web3.currentProvider.sendAsync({ - jsonrpc: '2.0', - method: 'evm_mine', - id: Date.now(), - }, (err, res) => { - return err ? reject(err) : resolve(res); - }); - }); -} - -// Advances the block number so that the last mined block is `number`. -async function advanceToBlock (number) { - if (web3.eth.blockNumber > number) { - throw Error(`block number ${number} is in the past (current is ${web3.eth.blockNumber})`); - } - - while (web3.eth.blockNumber < number) { - await advanceBlock(); - } -} - -module.exports = { - advanceBlock, - advanceToBlock, -}; diff --git a/test/helpers/assertJump.js b/test/helpers/assertJump.js deleted file mode 100644 index 979307088..000000000 --- a/test/helpers/assertJump.js +++ /dev/null @@ -1,15 +0,0 @@ -const should = require('chai') - .should(); - -async function assertJump (promise) { - try { - await promise; - should.fail('Expected invalid opcode not received'); - } catch (error) { - error.message.should.include('invalid opcode', `Expected "invalid opcode", got ${error} instead`); - } -} - -module.exports = { - assertJump, -}; diff --git a/test/helpers/assertRevert.js b/test/helpers/assertRevert.js deleted file mode 100644 index 3d1aa2e16..000000000 --- a/test/helpers/assertRevert.js +++ /dev/null @@ -1,16 +0,0 @@ -const should = require('chai') - .should(); - -async function assertRevert (promise) { - try { - await promise; - } catch (error) { - error.message.should.include('revert', `Expected "revert", got ${error} instead`); - return; - } - should.fail('Expected revert not received'); -} - -module.exports = { - assertRevert, -}; diff --git a/test/helpers/balanceDifference.js b/test/helpers/balanceDifference.js new file mode 100644 index 000000000..e514b0160 --- /dev/null +++ b/test/helpers/balanceDifference.js @@ -0,0 +1,12 @@ +const { ethGetBalance } = require('./web3'); + +async function balanceDifference (account, promiseFunc) { + const balanceBefore = await ethGetBalance(account); + await promiseFunc(); + const balanceAfter = await ethGetBalance(account); + return balanceAfter.minus(balanceBefore); +} + +module.exports = { + balanceDifference, +}; diff --git a/test/helpers/constants.js b/test/helpers/constants.js new file mode 100644 index 000000000..4c75c6de2 --- /dev/null +++ b/test/helpers/constants.js @@ -0,0 +1,8 @@ +const BigNumber = web3.BigNumber; + +module.exports = { + ZERO_ADDRESS: '0x0000000000000000000000000000000000000000', + MAX_UINT256: new BigNumber(2).pow(256).minus(1), + MAX_INT256: new BigNumber(2).pow(255).minus(1), + MIN_INT256: new BigNumber(2).pow(255).times(-1), +}; diff --git a/test/helpers/decodeLogs.js b/test/helpers/decodeLogs.js deleted file mode 100644 index 1f1bc946c..000000000 --- a/test/helpers/decodeLogs.js +++ /dev/null @@ -1,12 +0,0 @@ -const SolidityEvent = require('web3/lib/web3/event.js'); - -function decodeLogs (logs, contract, address) { - return logs.map(log => { - const event = new SolidityEvent(null, contract.events[log.topics[0]], address); - return event.decode(log); - }); -} - -module.exports = { - decodeLogs, -}; diff --git a/test/helpers/expectEvent.js b/test/helpers/expectEvent.js index 37fa1083e..29d1027c3 100644 --- a/test/helpers/expectEvent.js +++ b/test/helpers/expectEvent.js @@ -1,33 +1,57 @@ -const should = require('chai').should(); +const { should, BigNumber } = require('./setup'); + +const SolidityEvent = require('web3/lib/web3/event.js'); +const { ethGetTransactionReceipt } = require('./web3'); function inLogs (logs, eventName, eventArgs = {}) { const event = logs.find(function (e) { if (e.event === eventName) { - let matches = true; - for (const [k, v] of Object.entries(eventArgs)) { - if (e.args[k] !== v) { - matches = false; - } - } - - if (matches) { - return true; + contains(e.args, k, v); } + return true; } }); - should.exist(event); - return event; } -async function inTransaction (tx, eventName, eventArgs = {}) { - const { logs } = await tx; +async function inConstruction (contract, eventName, eventArgs = {}) { + return inTransaction(contract.transactionHash, contract.constructor, eventName, eventArgs); +} + +async function inTransaction (txHash, emitter, eventName, eventArgs = {}) { + const receipt = await ethGetTransactionReceipt(txHash); + const logs = decodeLogs(receipt.logs, emitter.events); + return inLogs(logs, eventName, eventArgs); } +function contains (args, key, value) { + if (isBigNumber(args[key])) { + args[key].should.be.bignumber.equal(value); + } else { + args[key].should.be.equal(value); + } +} + +function isBigNumber (object) { + return object.isBigNumber || + object instanceof BigNumber || + (object.constructor && object.constructor.name === 'BigNumber'); +} + +function decodeLogs (logs, events) { + return Array.prototype.concat(...logs.map(log => + log.topics.filter(topic => topic in events).map(topic => { + const event = new SolidityEvent(null, events[topic], 0); + return event.decode(log); + }) + )); +} + module.exports = { inLogs, + inConstruction, inTransaction, }; diff --git a/test/helpers/expectThrow.js b/test/helpers/expectThrow.js deleted file mode 100644 index f46a981c8..000000000 --- a/test/helpers/expectThrow.js +++ /dev/null @@ -1,28 +0,0 @@ -const should = require('chai') - .should(); - -async function expectThrow (promise, message) { - try { - await promise; - } catch (error) { - // Message is an optional parameter here - if (message) { - error.message.should.include(message, 'Expected \'' + message + '\', got \'' + error + '\' instead'); - return; - } else { - // TODO: Check jump destination to destinguish between a throw - // and an actual invalid jump. - // TODO: When we contract A calls contract B, and B throws, instead - // of an 'invalid jump', we get an 'out of gas' error. How do - // we distinguish this from an actual out of gas event? (The - // ganache log actually show an 'invalid jump' event.) - error.message.should.match(/[invalid opcode|out of gas|revert]/, 'Expected throw, got \'' + error + '\' instead'); - return; - } - } - should.fail('Expected throw not received'); -} - -module.exports = { - expectThrow, -}; diff --git a/test/helpers/increaseTime.js b/test/helpers/increaseTime.js deleted file mode 100644 index b22ba6b04..000000000 --- a/test/helpers/increaseTime.js +++ /dev/null @@ -1,55 +0,0 @@ -const { latestTime } = require('./latestTime'); - -// Increases ganache time by the passed duration in seconds -function increaseTime (duration) { - const id = Date.now(); - - return new Promise((resolve, reject) => { - web3.currentProvider.sendAsync({ - jsonrpc: '2.0', - method: 'evm_increaseTime', - params: [duration], - id: id, - }, err1 => { - if (err1) return reject(err1); - - web3.currentProvider.sendAsync({ - jsonrpc: '2.0', - method: 'evm_mine', - id: id + 1, - }, (err2, res) => { - return err2 ? reject(err2) : resolve(res); - }); - }); - }); -} - -/** - * Beware that due to the need of calling two separate ganache methods and rpc calls overhead - * it's hard to increase time precisely to a target point so design your test to tolerate - * small fluctuations from time to time. - * - * @param target time in seconds - */ -async function increaseTimeTo (target) { - const now = (await latestTime()); - - if (target < now) throw Error(`Cannot increase current time(${now}) to a moment in the past(${target})`); - const diff = target - now; - return increaseTime(diff); -} - -const duration = { - seconds: function (val) { return val; }, - minutes: function (val) { return val * this.seconds(60); }, - hours: function (val) { return val * this.minutes(60); }, - days: function (val) { return val * this.hours(24); }, - weeks: function (val) { return val * this.days(7); }, - years: function (val) { return val * this.days(365); }, -}; - -module.exports = { - increaseTime, - increaseTimeTo, - duration, -}; diff --git a/test/helpers/latestTime.js b/test/helpers/latestTime.js deleted file mode 100644 index fee9521d6..000000000 --- a/test/helpers/latestTime.js +++ /dev/null @@ -1,11 +0,0 @@ -const { ethGetBlock } = require('./web3'); - -// Returns the time of the last mined block in seconds -async function latestTime () { - const block = await ethGetBlock('latest'); - return block.timestamp; -} - -module.exports = { - latestTime, -}; diff --git a/test/helpers/merkleTree.js b/test/helpers/merkleTree.js index 8afa32511..27a8b201d 100644 --- a/test/helpers/merkleTree.js +++ b/test/helpers/merkleTree.js @@ -1,9 +1,9 @@ -const { sha3, bufferToHex } = require('ethereumjs-util'); +const { keccak256, bufferToHex } = require('ethereumjs-util'); class MerkleTree { constructor (elements) { // Filter empty strings and hash elements - this.elements = elements.filter(el => el).map(el => sha3(el)); + this.elements = elements.filter(el => el).map(el => keccak256(el)); // Deduplicate elements this.elements = this.bufDedup(this.elements); @@ -45,7 +45,7 @@ class MerkleTree { if (!first) { return second; } if (!second) { return first; } - return sha3(this.sortAndConcat(first, second)); + return keccak256(this.sortAndConcat(first, second)); } getRoot () { @@ -97,7 +97,7 @@ class MerkleTree { // Convert element to 32 byte hash if it is not one already if (el.length !== 32 || !Buffer.isBuffer(el)) { - hash = sha3(el); + hash = keccak256(el); } else { hash = el; } diff --git a/test/helpers/sendTransaction.js b/test/helpers/send.js similarity index 58% rename from test/helpers/sendTransaction.js rename to test/helpers/send.js index 741063209..a01fd6bcf 100644 --- a/test/helpers/sendTransaction.js +++ b/test/helpers/send.js @@ -1,22 +1,26 @@ -const _ = require('lodash'); const ethjsABI = require('ethjs-abi'); +const { ethSendTransaction } = require('./web3'); function findMethod (abi, name, args) { for (let i = 0; i < abi.length; i++) { - const methodArgs = _.map(abi[i].inputs, 'type').join(','); + const methodArgs = abi[i].inputs.map(input => input.type).join(','); if ((abi[i].name === name) && (methodArgs === args)) { return abi[i]; } } } -function sendTransaction (target, name, argsTypes, argsValues, opts) { +async function transaction (target, name, argsTypes, argsValues, opts) { const abiMethod = findMethod(target.abi, name, argsTypes); const encodedData = ethjsABI.encodeMethod(abiMethod, argsValues); return target.sendTransaction(Object.assign({ data: encodedData }, opts)); } +function ether (from, to, value) { + return ethSendTransaction({ from, to, value, gasPrice: 0 }); +} + module.exports = { - findMethod, - sendTransaction, + ether, + transaction, }; diff --git a/test/helpers/setup.js b/test/helpers/setup.js new file mode 100644 index 000000000..d27794d5e --- /dev/null +++ b/test/helpers/setup.js @@ -0,0 +1,9 @@ +const chai = require('chai'); + +const BigNumber = web3.BigNumber; +const should = chai.use(require('chai-bignumber')(BigNumber)).should(); + +module.exports = { + BigNumber, + should, +}; diff --git a/test/helpers/shouldFail.js b/test/helpers/shouldFail.js new file mode 100644 index 000000000..139339c7e --- /dev/null +++ b/test/helpers/shouldFail.js @@ -0,0 +1,36 @@ +const { should } = require('./setup'); + +async function shouldFailWithMessage (promise, message) { + try { + await promise; + } catch (error) { + if (message) { + error.message.should.include(message, `Wrong failure type, expected '${message}'`); + } + return; + } + + should.fail('Expected failure not received'); +} + +async function reverting (promise) { + await shouldFailWithMessage(promise, 'revert'); +} + +async function throwing (promise) { + await shouldFailWithMessage(promise, 'invalid opcode'); +} + +async function outOfGas (promise) { + await shouldFailWithMessage(promise, 'out of gas'); +} + +async function shouldFail (promise) { + await shouldFailWithMessage(promise); +} + +shouldFail.reverting = reverting; +shouldFail.throwing = throwing; +shouldFail.outOfGas = outOfGas; + +module.exports = shouldFail; diff --git a/test/helpers/test/balanceDifference.test.js b/test/helpers/test/balanceDifference.test.js new file mode 100644 index 000000000..98846db9d --- /dev/null +++ b/test/helpers/test/balanceDifference.test.js @@ -0,0 +1,22 @@ +const { balanceDifference } = require('../balanceDifference'); +const send = require('../send'); +const { ether } = require('../ether'); + +const BigNumber = web3.BigNumber; +require('chai') + .use(require('chai-bignumber')(BigNumber)) + .should(); + +contract('balanceDifference', function ([sender, receiver]) { + it('returns balance increments', async function () { + (await balanceDifference(receiver, () => + send.ether(sender, receiver, ether(1))) + ).should.be.bignumber.equal(ether(1)); + }); + + it('returns balance decrements', async function () { + (await balanceDifference(sender, () => + send.ether(sender, receiver, ether(1))) + ).should.be.bignumber.equal(ether(-1)); + }); +}); diff --git a/test/helpers/test/ether.test.js b/test/helpers/test/ether.test.js new file mode 100644 index 000000000..c06161571 --- /dev/null +++ b/test/helpers/test/ether.test.js @@ -0,0 +1,16 @@ +const { ether } = require('../ether'); + +const BigNumber = web3.BigNumber; +require('chai') + .use(require('chai-bignumber')(BigNumber)) + .should(); + +describe('ether', function () { + it('returns a BigNumber', function () { + ether(1, 'ether').should.be.bignumber.equal(new BigNumber(1000000000000000000)); + }); + + it('works with negative amounts', function () { + ether(-1, 'ether').should.be.bignumber.equal(new BigNumber(-1000000000000000000)); + }); +}); diff --git a/test/helpers/test/expectEvent.test.js b/test/helpers/test/expectEvent.test.js new file mode 100644 index 000000000..4dd81560f --- /dev/null +++ b/test/helpers/test/expectEvent.test.js @@ -0,0 +1,375 @@ +const expectEvent = require('../expectEvent'); +const shouldFail = require('../shouldFail'); + +const EventEmitter = artifacts.require('EventEmitter'); +const IndirectEventEmitter = artifacts.require('IndirectEventEmitter'); + +const { should, BigNumber } = require('../../helpers/setup'); + +describe('expectEvent', function () { + beforeEach(async function () { + this.constructionValues = { + uint: 42, + boolean: true, + string: 'OpenZeppelin', + }; + + this.emitter = await EventEmitter.new( + this.constructionValues.uint, + this.constructionValues.boolean, + this.constructionValues.string + ); + }); + + describe('inConstructor', function () { + context('short uint value', function () { + it('accepts emitted events with correct number', async function () { + await expectEvent.inConstruction(this.emitter, 'ShortUint', + { value: this.constructionValues.uint } + ); + }); + + it('throws if an incorrect value is passed', async function () { + await shouldFail(expectEvent.inConstruction(this.emitter, 'ShortUint', { value: 23 })); + }); + }); + + context('boolean value', function () { + it('accepts emitted events with correct value', async function () { + await expectEvent.inConstruction(this.emitter, 'Boolean', { value: this.constructionValues.boolean }); + }); + + it('throws if an incorrect value is passed', async function () { + await shouldFail(expectEvent.inConstruction(this.emitter, 'Boolean', + { value: !this.constructionValues.boolean } + )); + }); + }); + + context('string value', function () { + it('accepts emitted events with correct string', async function () { + await expectEvent.inConstruction(this.emitter, 'String', { value: this.constructionValues.string }); + }); + + it('throws if an incorrect string is passed', async function () { + await shouldFail(expectEvent.inConstruction(this.emitter, 'String', { value: 'ClosedZeppelin' })); + }); + }); + + it('throws if an unemitted event is requested', async function () { + await shouldFail(expectEvent.inConstruction(this.emitter, 'UnemittedEvent')); + }); + }); + + describe('inLogs', function () { + describe('with no arguments', function () { + beforeEach(async function () { + ({ logs: this.logs } = await this.emitter.emitArgumentless()); + }); + + it('accepts emitted events', function () { + expectEvent.inLogs(this.logs, 'Argumentless'); + }); + + it('throws if an unemitted event is requested', function () { + should.Throw(() => expectEvent.inLogs(this.logs, 'UnemittedEvent')); + }); + }); + + describe('with single argument', function () { + context('short uint value', function () { + beforeEach(async function () { + this.value = 42; + ({ logs: this.logs } = await this.emitter.emitShortUint(this.value)); + }); + + it('accepts emitted events with correct JavaScript number', function () { + expectEvent.inLogs(this.logs, 'ShortUint', { value: this.value }); + }); + + it('accepts emitted events with correct BigNumber', function () { + expectEvent.inLogs(this.logs, 'ShortUint', { value: new BigNumber(this.value) }); + }); + + it('throws if an unemitted event is requested', function () { + should.Throw(() => expectEvent.inLogs(this.logs, 'UnemittedEvent', { value: this.value })); + }); + + it('throws if an incorrect value is passed', function () { + should.Throw(() => expectEvent.inLogs(this.logs, 'ShortUint', { value: 23 })); + }); + }); + + context('short int value', function () { + beforeEach(async function () { + this.value = -42; + ({ logs: this.logs } = await this.emitter.emitShortInt(this.value)); + }); + + it('accepts emitted events with correct JavaScript number', function () { + expectEvent.inLogs(this.logs, 'ShortInt', { value: this.value }); + }); + + it('accepts emitted events with correct BigNumber', function () { + expectEvent.inLogs(this.logs, 'ShortInt', { value: new BigNumber(this.value) }); + }); + + it('throws if an unemitted event is requested', function () { + should.Throw(() => expectEvent.inLogs(this.logs, 'UnemittedEvent', { value: this.value })); + }); + + it('throws if an incorrect value is passed', function () { + should.Throw(() => expectEvent.inLogs(this.logs, 'ShortInt', { value: -23 })); + }); + }); + + context('long uint value', function () { + beforeEach(async function () { + this.bigNumValue = new BigNumber('123456789012345678901234567890'); + ({ logs: this.logs } = await this.emitter.emitLongUint(this.bigNumValue)); + }); + + it('accepts emitted events with correct BigNumber', function () { + expectEvent.inLogs(this.logs, 'LongUint', { value: this.bigNumValue }); + }); + + it('throws if an unemitted event is requested', function () { + should.Throw(() => expectEvent.inLogs(this.logs, 'UnemittedEvent', { value: this.bigNumValue })); + }); + + it('throws if an incorrect value is passed', function () { + should.Throw(() => expectEvent.inLogs(this.logs, 'LongUint', { value: 2300 })); + }); + }); + + context('long int value', function () { + beforeEach(async function () { + this.bigNumValue = new BigNumber('-123456789012345678901234567890'); + ({ logs: this.logs } = await this.emitter.emitLongInt(this.bigNumValue)); + }); + + it('accepts emitted events with correct BigNumber', function () { + expectEvent.inLogs(this.logs, 'LongInt', { value: this.bigNumValue }); + }); + + it('throws if an unemitted event is requested', function () { + should.Throw(() => expectEvent.inLogs(this.logs, 'UnemittedEvent', { value: this.bigNumValue })); + }); + + it('throws if an incorrect value is passed', function () { + should.Throw(() => expectEvent.inLogs(this.logs, 'LongInt', { value: -2300 })); + }); + }); + + context('address value', function () { + beforeEach(async function () { + this.value = '0x811412068e9fbf25dc300a29e5e316f7122b282c'; + ({ logs: this.logs } = await this.emitter.emitAddress(this.value)); + }); + + it('accepts emitted events with correct address', function () { + expectEvent.inLogs(this.logs, 'Address', { value: this.value }); + }); + + it('throws if an unemitted event is requested', function () { + should.Throw(() => expectEvent.inLogs(this.logs, 'UnemittedEvent', { value: this.value })); + }); + + it('throws if an incorrect value is passed', function () { + should.Throw(() => + expectEvent.inLogs(this.logs, 'Address', { value: '0x21d04e022e0b52b5d5bcf90b7f1aabf406be002d' }) + ); + }); + }); + + context('boolean value', function () { + beforeEach(async function () { + this.value = true; + ({ logs: this.logs } = await this.emitter.emitBoolean(this.value)); + }); + + it('accepts emitted events with correct address', function () { + expectEvent.inLogs(this.logs, 'Boolean', { value: this.value }); + }); + + it('throws if an unemitted event is requested', function () { + should.Throw(() => expectEvent.inLogs(this.logs, 'UnemittedEvent', { value: this.value })); + }); + + it('throws if an incorrect value is passed', function () { + should.Throw(() => expectEvent.inLogs(this.logs, 'Boolean', { value: false })); + }); + }); + + context('string value', function () { + beforeEach(async function () { + this.value = 'OpenZeppelin'; + ({ logs: this.logs } = await this.emitter.emitString(this.value)); + }); + + it('accepts emitted events with correct string', function () { + expectEvent.inLogs(this.logs, 'String', { value: this.value }); + }); + + it('throws if an unemitted event is requested', function () { + should.Throw(() => expectEvent.inLogs(this.logs, 'UnemittedEvent', { value: this.value })); + }); + + it('throws if an incorrect value is passed', function () { + should.Throw(() => expectEvent.inLogs(this.logs, 'String', { value: 'ClosedZeppelin' })); + }); + }); + }); + + describe('with multiple arguments', function () { + beforeEach(async function () { + this.uintValue = new BigNumber('123456789012345678901234567890'); + this.booleanValue = true; + this.stringValue = 'OpenZeppelin'; + ({ logs: this.logs } = + await this.emitter.emitLongUintBooleanString(this.uintValue, this.booleanValue, this.stringValue)); + }); + + it('accepts correct values', function () { + expectEvent.inLogs(this.logs, 'LongUintBooleanString', { + uintValue: this.uintValue, booleanValue: this.booleanValue, stringValue: this.stringValue, + }); + }); + + it('throws with correct values assigned to wrong arguments', function () { + should.Throw(() => expectEvent.inLogs(this.logs, 'LongUintBooleanString', { + uintValue: this.booleanValue, booleanValue: this.uintValue, stringValue: this.stringValue, + })); + }); + + it('throws when any of the values is incorrect', function () { + should.Throw(() => expectEvent.inLogs(this.logs, 'LongUintBooleanString', { + uintValue: 23, booleanValue: this.booleanValue, stringValue: this.stringValue, + })); + + should.Throw(() => expectEvent.inLogs(this.logs, 'LongUintBooleanString', { + uintValue: this.uintValue, booleanValue: false, stringValue: this.stringValue, + })); + + should.Throw(() => expectEvent.inLogs(this.logs, 'LongUintBooleanString', { + uintValue: this.uintValue, booleanValue: this.booleanValue, stringValue: 'ClosedZeppelin', + })); + }); + }); + + describe('with multiple events', function () { + beforeEach(async function () { + this.uintValue = 42; + this.booleanValue = true; + ({ logs: this.logs } = await this.emitter.emitLongUintAndBoolean(this.uintValue, this.booleanValue)); + }); + + it('accepts all emitted events with correct values', function () { + expectEvent.inLogs(this.logs, 'LongUint', { value: this.uintValue }); + expectEvent.inLogs(this.logs, 'Boolean', { value: this.booleanValue }); + }); + + it('throws if an unemitted event is requested', function () { + should.Throw(() => expectEvent.inLogs(this.logs, 'UnemittedEvent', { value: this.uintValue })); + }); + + it('throws if incorrect values are passed', function () { + should.Throw(() => expectEvent.inLogs(this.logs, 'LongUint', { value: 23 })); + should.Throw(() => expectEvent.inLogs(this.logs, 'Boolean', { value: false })); + }); + }); + + describe('with events emitted by an indirectly called contract', function () { + beforeEach(async function () { + this.secondEmitter = await IndirectEventEmitter.new(); + + this.value = 'OpenZeppelin'; + ({ logs: this.logs } = await this.emitter.emitStringAndEmitIndirectly(this.value, this.secondEmitter.address)); + }); + + it('accepts events emitted by the directly called contract', function () { + expectEvent.inLogs(this.logs, 'String', { value: this.value }); + }); + + it('throws when passing events emitted by the indirectly called contract', function () { + should.Throw(() => expectEvent.inLogs(this.logs, 'IndirectString', { value: this.value })); + }); + }); + }); + + describe('inTransaction', function () { + describe('when emitting from called contract and indirect calls', function () { + context('string value', function () { + beforeEach(async function () { + this.secondEmitter = await IndirectEventEmitter.new(); + + this.value = 'OpenZeppelin'; + const receipt = await this.emitter.emitStringAndEmitIndirectly(this.value, this.secondEmitter.address); + this.txHash = receipt.tx; + }); + + context('with directly called contract', function () { + it('accepts emitted events with correct string', async function () { + await expectEvent.inTransaction(this.txHash, EventEmitter, 'String', { value: this.value }); + }); + + it('throws if an unemitted event is requested', async function () { + await shouldFail(expectEvent.inTransaction(this.txHash, EventEmitter, 'UnemittedEvent', + { value: this.value } + )); + }); + + it('throws if an incorrect string is passed', async function () { + await shouldFail(expectEvent.inTransaction(this.txHash, EventEmitter, 'String', + { value: 'ClosedZeppelin' } + )); + }); + + it('throws if an event emitted from other contract is passed', async function () { + await shouldFail(expectEvent.inTransaction(this.txHash, EventEmitter, 'IndirectString', + { value: this.value } + )); + }); + + it('throws if an incorrect emitter is passed', async function () { + await shouldFail(expectEvent.inTransaction(this.txHash, IndirectEventEmitter, 'String', + { value: this.value } + )); + }); + }); + + context('with indirectly called contract', function () { + it('accepts events emitted from other contracts', async function () { + await expectEvent.inTransaction(this.txHash, IndirectEventEmitter, 'IndirectString', + { value: this.value } + ); + }); + + it('throws if an unemitted event is requested', async function () { + await shouldFail(expectEvent.inTransaction(this.txHash, IndirectEventEmitter, 'UnemittedEvent', + { value: this.value } + )); + }); + + it('throws if an incorrect string is passed', async function () { + await shouldFail(expectEvent.inTransaction(this.txHash, IndirectEventEmitter, 'IndirectString', + { value: 'ClosedZeppelin' } + )); + }); + + it('throws if an event emitted from other contract is passed', async function () { + await shouldFail(expectEvent.inTransaction(this.txHash, IndirectEventEmitter, 'String', + { value: this.value } + )); + }); + + it('throws if an incorrect emitter is passed', async function () { + await shouldFail(expectEvent.inTransaction(this.txHash, EventEmitter, 'IndirectString', + { value: this.value } + )); + }); + }); + }); + }); + }); +}); diff --git a/test/helpers/test/makeInterfaceId.test.js b/test/helpers/test/makeInterfaceId.test.js new file mode 100644 index 000000000..fd4920438 --- /dev/null +++ b/test/helpers/test/makeInterfaceId.test.js @@ -0,0 +1,20 @@ +const { makeInterfaceId } = require('../makeInterfaceId'); + +const OwnableInterfaceId = artifacts.require('OwnableInterfaceId'); + +require('chai') + .should(); + +describe('makeInterfaceId', function () { + it('calculates the EIP165 interface id from function signatures', async function () { + const calculator = await OwnableInterfaceId.new(); + const ownableId = await calculator.getInterfaceId(); + + makeInterfaceId([ + 'owner()', + 'isOwner()', + 'renounceOwnership()', + 'transferOwnership(address)', + ]).should.equal(ownableId); + }); +}); diff --git a/test/helpers/test/send.test.js b/test/helpers/test/send.test.js new file mode 100644 index 000000000..c868626a1 --- /dev/null +++ b/test/helpers/test/send.test.js @@ -0,0 +1,70 @@ +const send = require('../send'); +const shouldFail = require('../shouldFail'); +const expectEvent = require('../expectEvent'); +const { ether } = require('../ether'); +const { ethGetBalance } = require('../web3'); + +const Acknowledger = artifacts.require('Acknowledger'); + +const BigNumber = web3.BigNumber; +require('chai') + .use(require('chai-bignumber')(BigNumber)) + .should(); + +contract('send', function ([sender, receiver]) { + describe('ether', function () { + it('sends ether with no gas cost', async function () { + const value = ether(1); + + const initialSenderBalance = await ethGetBalance(sender); + const initialReceiverBalance = await ethGetBalance(receiver); + + await send.ether(sender, receiver, value); + + const finalSenderBalance = await ethGetBalance(sender); + const finalReceiverBalance = await ethGetBalance(receiver); + + finalSenderBalance.sub(initialSenderBalance).should.be.bignumber.equal(-value); + finalReceiverBalance.sub(initialReceiverBalance).should.be.bignumber.equal(value); + }); + + it('throws if the sender balance is insufficient', async function () { + const value = (await ethGetBalance(sender)).plus(1); + + await shouldFail(send.ether(sender, receiver, value)); + }); + }); + + describe('transaction', function () { + beforeEach(async function () { + this.acknowledger = await Acknowledger.new(); + }); + + it('calls a function from its signature ', async function () { + const { logs } = await send.transaction(this.acknowledger, 'foo', 'uint256', [3]); + expectEvent.inLogs(logs, 'AcknowledgeFoo', { a: 3 }); + }); + + it('calls overloaded functions with less arguments', async function () { + const { logs } = await send.transaction(this.acknowledger, 'bar', 'uint256', [3]); + expectEvent.inLogs(logs, 'AcknowledgeBarSingle', { a: 3 }); + }); + + it('calls overloaded functions with more arguments', async function () { + const { logs } = await send.transaction(this.acknowledger, 'bar', 'uint256,uint256', [3, 5]); + expectEvent.inLogs(logs, 'AcknowledgeBarDouble', { a: 3, b: 5 }); + }); + + it('throws if the number of arguments does not match', async function () { + await shouldFail(send.transaction(this.acknowledger, 'foo', 'uint256, uint256', [3, 5])); + }); + + it('throws if the method does not exist', async function () { + await shouldFail(send.transaction(this.acknowledger, 'baz', 'uint256', [3])); + }); + + it('throws if there is a mismatch in the number of types and values', async function () { + await shouldFail(send.transaction(this.acknowledger, 'foo', 'uint256', [3, 3])); + }); + }); +}); diff --git a/test/helpers/test/shouldFail.test.js b/test/helpers/test/shouldFail.test.js new file mode 100644 index 000000000..8f99efe30 --- /dev/null +++ b/test/helpers/test/shouldFail.test.js @@ -0,0 +1,95 @@ +const shouldFail = require('../shouldFail'); + +const BigNumber = web3.BigNumber; +const should = require('chai') + .use(require('chai-bignumber')(BigNumber)) + .should(); + +const Failer = artifacts.require('Failer'); + +async function assertFailure (promise) { + try { + await promise; + } catch (error) { + return; + } + should.fail(); +} + +describe('shouldFail', function () { + beforeEach(async function () { + this.failer = await Failer.new(); + }); + + describe('shouldFail', function () { + it('rejects if no failure occurs', async function () { + await assertFailure(shouldFail(this.failer.dontFail())); + }); + + it('accepts a revert', async function () { + await shouldFail(this.failer.failWithRevert()); + }); + + it('accepts a throw', async function () { + await shouldFail(this.failer.failWithThrow()); + }); + + it('accepts an out of gas', async function () { + await shouldFail(this.failer.failWithOutOfGas({ gas: 2000000 })); + }); + }); + + describe('reverting', function () { + it('rejects if no failure occurs', async function () { + await assertFailure(shouldFail.reverting(this.failer.dontFail())); + }); + + it('accepts a revert', async function () { + await shouldFail.reverting(this.failer.failWithRevert()); + }); + + it('rejects a throw', async function () { + await assertFailure(shouldFail.reverting(this.failer.failWithThrow())); + }); + + it('rejects an outOfGas', async function () { + await assertFailure(shouldFail.reverting(this.failer.failWithOutOfGas({ gas: 2000000 }))); + }); + }); + + describe('throwing', function () { + it('rejects if no failure occurs', async function () { + await assertFailure(shouldFail.throwing(this.failer.dontFail())); + }); + + it('accepts a throw', async function () { + await shouldFail.throwing(this.failer.failWithThrow()); + }); + + it('rejects a throw', async function () { + await assertFailure(shouldFail.throwing(this.failer.failWithRevert())); + }); + + it('rejects an outOfGas', async function () { + await assertFailure(shouldFail.throwing(this.failer.failWithOutOfGas({ gas: 2000000 }))); + }); + }); + + describe('outOfGas', function () { + it('rejects if no failure occurs', async function () { + await assertFailure(shouldFail.outOfGas(this.failer.dontFail())); + }); + + it('accepts an out of gas', async function () { + await shouldFail.outOfGas(this.failer.failWithOutOfGas({ gas: 2000000 })); + }); + + it('rejects a revert', async function () { + await assertFailure(shouldFail.outOfGas(this.failer.failWithRevert())); + }); + + it('rejects a throw', async function () { + await assertFailure(shouldFail.outOfGas(this.failer.failWithThrow())); + }); + }); +}); diff --git a/test/helpers/test/time.test.js b/test/helpers/test/time.test.js new file mode 100644 index 000000000..556ae92f8 --- /dev/null +++ b/test/helpers/test/time.test.js @@ -0,0 +1,77 @@ +const time = require('../time'); +const shouldFail = require('../shouldFail'); + +const BigNumber = web3.BigNumber; +require('chai') + .use(require('chai-bignumber')(BigNumber)) + .should(); + +describe('time', function () { + const TOLERANCE_SECONDS = 1; + + describe('duration', function () { + it('converts seconds to seconds', function () { + time.duration.seconds(1).should.equal(1); + }); + + it('converts minutes to seconds', function () { + time.duration.minutes(1).should.equal(60); + }); + + it('converts hours to seconds', function () { + time.duration.hours(1).should.equal(60 * 60); + }); + + it('converts days to seconds', function () { + time.duration.days(1).should.equal(60 * 60 * 24); + }); + + it('converts weeks to seconds', function () { + time.duration.weeks(1).should.equal(60 * 60 * 24 * 7); + }); + + it('converts years to seconds', function () { + time.duration.years(1).should.equal(60 * 60 * 24 * 365); + }); + }); + + describe('advanceBlock', function () { + it('increases the block number by one', async function () { + const startingBlock = web3.eth.blockNumber; + await time.advanceBlock(); + web3.eth.blockNumber.should.be.bignumber.equal(startingBlock + 1); + }); + }); + + context('with starting time', function () { + beforeEach(async function () { + await time.advanceBlock(); + this.start = await time.latest(); + }); + + describe('increase', function () { + it('increases time by a duration', async function () { + await time.increase(time.duration.hours(1)); + + const end = this.start + time.duration.hours(1); + (await time.latest()).should.be.closeTo(end, TOLERANCE_SECONDS); + }); + + it('throws with negative durations', async function () { + await shouldFail(time.increase(-1)); + }); + }); + + describe('increaseTo', function () { + it('increases time to a time in the future', async function () { + const end = this.start + time.duration.hours(1); + await time.increaseTo(end); + (await time.latest()).should.be.closeTo(end, TOLERANCE_SECONDS); + }); + + it('throws with a time in the past', async function () { + await shouldFail(time.increaseTo(this.start - 30)); + }); + }); + }); +}); diff --git a/test/helpers/time.js b/test/helpers/time.js new file mode 100644 index 000000000..c8c844079 --- /dev/null +++ b/test/helpers/time.js @@ -0,0 +1,60 @@ +const { ethGetBlock } = require('./web3'); +const pify = require('pify'); + +function advanceBlock () { + return pify(web3.currentProvider.sendAsync)({ + jsonrpc: '2.0', + method: 'evm_mine', + }); +} + +// Returns the time of the last mined block in seconds +async function latest () { + const block = await ethGetBlock('latest'); + return block.timestamp; +} + +// Increases ganache time by the passed duration in seconds +async function increase (duration) { + if (duration < 0) throw Error(`Cannot increase time by a negative amount (${duration})`); + + await pify(web3.currentProvider.sendAsync)({ + jsonrpc: '2.0', + method: 'evm_increaseTime', + params: [duration], + }); + + await advanceBlock(); +} + +/** + * Beware that due to the need of calling two separate ganache methods and rpc calls overhead + * it's hard to increase time precisely to a target point so design your test to tolerate + * small fluctuations from time to time. + * + * @param target time in seconds + */ +async function increaseTo (target) { + const now = (await latest()); + + if (target < now) throw Error(`Cannot increase current time (${now}) to a moment in the past (${target})`); + const diff = target - now; + return increase(diff); +} + +const duration = { + seconds: function (val) { return val; }, + minutes: function (val) { return val * this.seconds(60); }, + hours: function (val) { return val * this.minutes(60); }, + days: function (val) { return val * this.hours(24); }, + weeks: function (val) { return val * this.days(7); }, + years: function (val) { return val * this.days(365); }, +}; + +module.exports = { + advanceBlock, + latest, + increase, + increaseTo, + duration, +}; diff --git a/test/helpers/transactionMined.js b/test/helpers/transactionMined.js deleted file mode 100644 index 77401ead6..000000000 --- a/test/helpers/transactionMined.js +++ /dev/null @@ -1,34 +0,0 @@ -// From https://gist.github.com/xavierlepretre/88682e871f4ad07be4534ae560692ee6 -function transactionMined (txnHash, interval) { - interval = interval || 500; - const transactionReceiptAsync = function (txnHash, resolve, reject) { - try { - const receipt = web3.eth.getTransactionReceipt(txnHash); - if (receipt === null) { - setTimeout(function () { - transactionReceiptAsync(txnHash, resolve, reject); - }, interval); - } else { - resolve(receipt); - } - } catch (e) { - reject(e); - } - }; - - if (Array.isArray(txnHash)) { - return Promise.all(txnHash.map(hash => - web3.eth.getTransactionReceiptMined(hash, interval) - )); - } else { - return new Promise(function (resolve, reject) { - transactionReceiptAsync(txnHash, resolve, reject); - }); - } -} - -web3.eth.transactionMined = transactionMined; - -module.exports = { - transactionMined, -}; diff --git a/test/helpers/web3.js b/test/helpers/web3.js index b4fd87199..b6cd493e1 100644 --- a/test/helpers/web3.js +++ b/test/helpers/web3.js @@ -4,6 +4,7 @@ const ethAsync = pify(web3.eth); module.exports = { ethGetBalance: ethAsync.getBalance, - ethSendTransaction: ethAsync.sendTransaction, ethGetBlock: ethAsync.getBlock, + ethGetTransactionReceipt: ethAsync.getTransactionReceipt, + ethSendTransaction: ethAsync.sendTransaction, }; diff --git a/test/introspection/ERC165.test.js b/test/introspection/ERC165.test.js index 37a24637d..0dc2f8471 100644 --- a/test/introspection/ERC165.test.js +++ b/test/introspection/ERC165.test.js @@ -1,18 +1,18 @@ const { shouldSupportInterfaces } = require('./SupportsInterface.behavior'); -const { assertRevert } = require('../helpers/assertRevert'); +const shouldFail = require('../helpers/shouldFail'); -const ERC165 = artifacts.require('ERC165Mock'); +const ERC165Mock = artifacts.require('ERC165Mock'); require('chai') .should(); contract('ERC165', function () { beforeEach(async function () { - this.mock = await ERC165.new(); + this.mock = await ERC165Mock.new(); }); it('does not allow 0xffffffff', async function () { - await assertRevert( + await shouldFail.reverting( this.mock.registerInterface(0xffffffff) ); }); diff --git a/test/introspection/ERC165Checker.test.js b/test/introspection/ERC165Checker.test.js index a6bfc518d..c339c78ab 100644 --- a/test/introspection/ERC165Checker.test.js +++ b/test/introspection/ERC165Checker.test.js @@ -9,8 +9,7 @@ const DUMMY_UNSUPPORTED_ID = '0xbaddcafe'; const DUMMY_UNSUPPORTED_ID_2 = '0xbaadcafe'; const DUMMY_ACCOUNT = '0x1111111111111111111111111111111111111111'; -require('chai') - .should(); +require('../helpers/setup'); contract('ERC165Checker', function () { beforeEach(async function () { @@ -32,8 +31,8 @@ contract('ERC165Checker', function () { supported.should.equal(false); }); - it('does not support mock interface via supportsInterfaces', async function () { - const supported = await this.mock.supportsInterfaces(this.target.address, [DUMMY_ID]); + it('does not support mock interface via supportsAllInterfaces', async function () { + const supported = await this.mock.supportsAllInterfaces(this.target.address, [DUMMY_ID]); supported.should.equal(false); }); }); @@ -53,8 +52,8 @@ contract('ERC165Checker', function () { supported.should.equal(false); }); - it('does not support mock interface via supportsInterfaces', async function () { - const supported = await this.mock.supportsInterfaces(this.target.address, [DUMMY_ID]); + it('does not support mock interface via supportsAllInterfaces', async function () { + const supported = await this.mock.supportsAllInterfaces(this.target.address, [DUMMY_ID]); supported.should.equal(false); }); }); @@ -74,8 +73,8 @@ contract('ERC165Checker', function () { supported.should.equal(true); }); - it('supports mock interface via supportsInterfaces', async function () { - const supported = await this.mock.supportsInterfaces(this.target.address, [DUMMY_ID]); + it('supports mock interface via supportsAllInterfaces', async function () { + const supported = await this.mock.supportsAllInterfaces(this.target.address, [DUMMY_ID]); supported.should.equal(true); }); }); @@ -98,22 +97,22 @@ contract('ERC165Checker', function () { }; }); - it('supports all interfaceIds via supportsInterfaces', async function () { - const supported = await this.mock.supportsInterfaces(this.target.address, this.supportedInterfaces); + it('supports all interfaceIds via supportsAllInterfaces', async function () { + const supported = await this.mock.supportsAllInterfaces(this.target.address, this.supportedInterfaces); supported.should.equal(true); }); - it('supports none of the interfaces queried via supportsInterfaces', async function () { + it('supports none of the interfaces queried via supportsAllInterfaces', async function () { const interfaceIdsToTest = [DUMMY_UNSUPPORTED_ID, DUMMY_UNSUPPORTED_ID_2]; - const supported = await this.mock.supportsInterfaces(this.target.address, interfaceIdsToTest); + const supported = await this.mock.supportsAllInterfaces(this.target.address, interfaceIdsToTest); supported.should.equal(false); }); - it('supports not all of the interfaces queried via supportsInterfaces', async function () { + it('supports not all of the interfaces queried via supportsAllInterfaces', async function () { const interfaceIdsToTest = [...this.supportedInterfaces, DUMMY_UNSUPPORTED_ID]; - const supported = await this.mock.supportsInterfaces(this.target.address, interfaceIdsToTest); + const supported = await this.mock.supportsAllInterfaces(this.target.address, interfaceIdsToTest); supported.should.equal(false); }); }); @@ -129,8 +128,8 @@ contract('ERC165Checker', function () { supported.should.equal(false); }); - it('does not support mock interface via supportsInterfaces', async function () { - const supported = await this.mock.supportsInterfaces(DUMMY_ACCOUNT, [DUMMY_ID]); + it('does not support mock interface via supportsAllInterfaces', async function () { + const supported = await this.mock.supportsAllInterfaces(DUMMY_ACCOUNT, [DUMMY_ID]); supported.should.equal(false); }); }); diff --git a/test/lifecycle/Pausable.test.js b/test/lifecycle/Pausable.test.js index 2ae4c90d7..7b8d3e8cb 100644 --- a/test/lifecycle/Pausable.test.js +++ b/test/lifecycle/Pausable.test.js @@ -1,14 +1,10 @@ -const { assertRevert } = require('../helpers/assertRevert'); +const shouldFail = require('../helpers/shouldFail'); const expectEvent = require('../helpers/expectEvent'); const PausableMock = artifacts.require('PausableMock'); const { shouldBehaveLikePublicRole } = require('../access/roles/PublicRole.behavior'); -const BigNumber = web3.BigNumber; - -require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); +require('../helpers/setup'); contract('Pausable', function ([_, pauser, otherPauser, anyone, ...otherAccounts]) { beforeEach(async function () { @@ -37,7 +33,7 @@ contract('Pausable', function ([_, pauser, otherPauser, anyone, ...otherAccounts }); it('cannot take drastic measure in non-pause', async function () { - await assertRevert(this.pausable.drasticMeasure({ from: anyone })); + await shouldFail.reverting(this.pausable.drasticMeasure({ from: anyone })); (await this.pausable.drasticMeasureTaken()).should.equal(false); }); @@ -48,7 +44,7 @@ contract('Pausable', function ([_, pauser, otherPauser, anyone, ...otherAccounts }); it('reverts when pausing from non-pauser', async function () { - await assertRevert(this.pausable.pause({ from: anyone })); + await shouldFail.reverting(this.pausable.pause({ from: anyone })); }); context('when paused', function () { @@ -57,11 +53,11 @@ contract('Pausable', function ([_, pauser, otherPauser, anyone, ...otherAccounts }); it('emits a Paused event', function () { - expectEvent.inLogs(this.logs, 'Paused'); + expectEvent.inLogs(this.logs, 'Paused', { account: pauser }); }); it('cannot perform normal process in pause', async function () { - await assertRevert(this.pausable.normalProcess({ from: anyone })); + await shouldFail.reverting(this.pausable.normalProcess({ from: anyone })); }); it('can take a drastic measure in a pause', async function () { @@ -70,7 +66,7 @@ contract('Pausable', function ([_, pauser, otherPauser, anyone, ...otherAccounts }); it('reverts when re-pausing', async function () { - await assertRevert(this.pausable.pause({ from: pauser })); + await shouldFail.reverting(this.pausable.pause({ from: pauser })); }); describe('unpausing', function () { @@ -80,7 +76,7 @@ contract('Pausable', function ([_, pauser, otherPauser, anyone, ...otherAccounts }); it('reverts when unpausing from non-pauser', async function () { - await assertRevert(this.pausable.unpause({ from: anyone })); + await shouldFail.reverting(this.pausable.unpause({ from: anyone })); }); context('when unpaused', function () { @@ -89,7 +85,7 @@ contract('Pausable', function ([_, pauser, otherPauser, anyone, ...otherAccounts }); it('emits an Unpaused event', function () { - expectEvent.inLogs(this.logs, 'Unpaused'); + expectEvent.inLogs(this.logs, 'Unpaused', { account: pauser }); }); it('should resume allowing normal process', async function () { @@ -99,11 +95,11 @@ contract('Pausable', function ([_, pauser, otherPauser, anyone, ...otherAccounts }); it('should prevent drastic measure', async function () { - await assertRevert(this.pausable.drasticMeasure({ from: anyone })); + await shouldFail.reverting(this.pausable.drasticMeasure({ from: anyone })); }); it('reverts when re-unpausing', async function () { - await assertRevert(this.pausable.unpause({ from: pauser })); + await shouldFail.reverting(this.pausable.unpause({ from: pauser })); }); }); }); diff --git a/test/library/Math.test.js b/test/math/Math.test.js similarity index 94% rename from test/library/Math.test.js rename to test/math/Math.test.js index 3e801d0e9..99ab04531 100644 --- a/test/library/Math.test.js +++ b/test/math/Math.test.js @@ -1,10 +1,6 @@ const MathMock = artifacts.require('MathMock'); -const BigNumber = web3.BigNumber; - -require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); +const { BigNumber } = require('../helpers/setup'); contract('Math', function () { const min = 1234; diff --git a/test/math/SafeMath.test.js b/test/math/SafeMath.test.js index 0174bd0ac..221c998ff 100644 --- a/test/math/SafeMath.test.js +++ b/test/math/SafeMath.test.js @@ -1,15 +1,11 @@ -const { assertRevert } = require('../helpers/assertRevert'); +const shouldFail = require('../helpers/shouldFail'); +const { MAX_UINT256 } = require('../helpers/constants'); -const BigNumber = web3.BigNumber; const SafeMathMock = artifacts.require('SafeMathMock'); -require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); +const { BigNumber } = require('../helpers/setup'); contract('SafeMath', function () { - const MAX_UINT = new BigNumber(2).pow(256).minus(1); - beforeEach(async function () { this.safeMath = await SafeMathMock.new(); }); @@ -22,11 +18,11 @@ contract('SafeMath', function () { (await this.safeMath.add(a, b)).should.be.bignumber.equal(a.plus(b)); }); - it('throws a revert error on addition overflow', async function () { - const a = MAX_UINT; + it('reverts on addition overflow', async function () { + const a = MAX_UINT256; const b = new BigNumber(1); - await assertRevert(this.safeMath.add(a, b)); + await shouldFail.reverting(this.safeMath.add(a, b)); }); }); @@ -38,11 +34,11 @@ contract('SafeMath', function () { (await this.safeMath.sub(a, b)).should.be.bignumber.equal(a.minus(b)); }); - it('throws a revert error if subtraction result would be negative', async function () { + it('reverts if subtraction result would be negative', async function () { const a = new BigNumber(1234); const b = new BigNumber(5678); - await assertRevert(this.safeMath.sub(a, b)); + await shouldFail.reverting(this.safeMath.sub(a, b)); }); }); @@ -54,18 +50,25 @@ contract('SafeMath', function () { (await this.safeMath.mul(a, b)).should.be.bignumber.equal(a.times(b)); }); - it('handles a zero product correctly', async function () { + it('handles a zero product correctly (first number as zero)', async function () { const a = new BigNumber(0); const b = new BigNumber(5678); (await this.safeMath.mul(a, b)).should.be.bignumber.equal(a.times(b)); }); - it('throws a revert error on multiplication overflow', async function () { - const a = MAX_UINT; + it('handles a zero product correctly (second number as zero)', async function () { + const a = new BigNumber(5678); + const b = new BigNumber(0); + + (await this.safeMath.mul(a, b)).should.be.bignumber.equal(a.times(b)); + }); + + it('reverts on multiplication overflow', async function () { + const a = MAX_UINT256; const b = new BigNumber(2); - await assertRevert(this.safeMath.mul(a, b)); + await shouldFail.reverting(this.safeMath.mul(a, b)); }); }); @@ -77,11 +80,25 @@ contract('SafeMath', function () { (await this.safeMath.div(a, b)).should.be.bignumber.equal(a.div(b)); }); - it('throws a revert error on zero division', async function () { + it('divides zero correctly', async function () { + const a = new BigNumber(0); + const b = new BigNumber(5678); + + (await this.safeMath.div(a, b)).should.be.bignumber.equal(0); + }); + + it('returns complete number result on non-even division', async function () { + const a = new BigNumber(7000); + const b = new BigNumber(5678); + + (await this.safeMath.div(a, b)).should.be.bignumber.equal(1); + }); + + it('reverts on zero division', async function () { const a = new BigNumber(5678); const b = new BigNumber(0); - await assertRevert(this.safeMath.div(a, b)); + await shouldFail.reverting(this.safeMath.div(a, b)); }); }); @@ -120,7 +137,7 @@ contract('SafeMath', function () { const a = new BigNumber(5678); const b = new BigNumber(0); - await assertRevert(this.safeMath.mod(a, b)); + await shouldFail.reverting(this.safeMath.mod(a, b)); }); }); }); diff --git a/test/ownership/Ownable.behavior.js b/test/ownership/Ownable.behavior.js index eac3c10ce..a23030d0b 100644 --- a/test/ownership/Ownable.behavior.js +++ b/test/ownership/Ownable.behavior.js @@ -1,10 +1,7 @@ -const { expectThrow } = require('../helpers/expectThrow'); -const { EVMRevert } = require('../helpers/EVMRevert'); - -const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; - -require('chai') - .should(); +const shouldFail = require('../helpers/shouldFail'); +const expectEvent = require('../helpers/expectEvent'); +const { ZERO_ADDRESS } = require('../helpers/constants'); +require('./../helpers/setup'); function shouldBehaveLikeOwnable (owner, [anyone]) { describe('as an ownable', function () { @@ -14,27 +11,30 @@ function shouldBehaveLikeOwnable (owner, [anyone]) { it('changes owner after transfer', async function () { (await this.ownable.isOwner({ from: anyone })).should.be.equal(false); - await this.ownable.transferOwnership(anyone, { from: owner }); + const { logs } = await this.ownable.transferOwnership(anyone, { from: owner }); + expectEvent.inLogs(logs, 'OwnershipTransferred'); (await this.ownable.owner()).should.equal(anyone); (await this.ownable.isOwner({ from: anyone })).should.be.equal(true); }); it('should prevent non-owners from transfering', async function () { - await expectThrow(this.ownable.transferOwnership(anyone, { from: anyone }), EVMRevert); + await shouldFail.reverting(this.ownable.transferOwnership(anyone, { from: anyone })); }); it('should guard ownership against stuck state', async function () { - await expectThrow(this.ownable.transferOwnership(null, { from: owner }), EVMRevert); + await shouldFail.reverting(this.ownable.transferOwnership(null, { from: owner })); }); it('loses owner after renouncement', async function () { - await this.ownable.renounceOwnership({ from: owner }); + const { logs } = await this.ownable.renounceOwnership({ from: owner }); + expectEvent.inLogs(logs, 'OwnershipTransferred'); + (await this.ownable.owner()).should.equal(ZERO_ADDRESS); }); it('should prevent non-owners from renouncement', async function () { - await expectThrow(this.ownable.renounceOwnership({ from: anyone }), EVMRevert); + await shouldFail.reverting(this.ownable.renounceOwnership({ from: anyone })); }); }); } diff --git a/test/ownership/Secondary.test.js b/test/ownership/Secondary.test.js index 000d0af11..cbc96320a 100644 --- a/test/ownership/Secondary.test.js +++ b/test/ownership/Secondary.test.js @@ -1,13 +1,12 @@ -const { assertRevert } = require('../helpers/assertRevert'); +const shouldFail = require('../helpers/shouldFail'); +const expectEvent = require('../helpers/expectEvent'); +const { ZERO_ADDRESS } = require('../helpers/constants'); const SecondaryMock = artifacts.require('SecondaryMock'); -require('chai') - .should(); +require('../helpers/setup'); contract('Secondary', function ([_, primary, newPrimary, anyone]) { - const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; - beforeEach(async function () { this.secondary = await SecondaryMock.new({ from: primary }); }); @@ -22,22 +21,23 @@ contract('Secondary', function ([_, primary, newPrimary, anyone]) { }); it('reverts when anyone calls onlyPrimary functions', async function () { - await assertRevert(this.secondary.onlyPrimaryMock({ from: anyone })); + await shouldFail.reverting(this.secondary.onlyPrimaryMock({ from: anyone })); }); }); describe('transferPrimary', function () { it('makes the recipient the new primary', async function () { - await this.secondary.transferPrimary(newPrimary, { from: primary }); + const { logs } = await this.secondary.transferPrimary(newPrimary, { from: primary }); + expectEvent.inLogs(logs, 'PrimaryTransferred', { recipient: newPrimary }); (await this.secondary.primary()).should.equal(newPrimary); }); it('reverts when transfering to the null address', async function () { - await assertRevert(this.secondary.transferPrimary(ZERO_ADDRESS, { from: primary })); + await shouldFail.reverting(this.secondary.transferPrimary(ZERO_ADDRESS, { from: primary })); }); it('reverts when called by anyone', async function () { - await assertRevert(this.secondary.transferPrimary(newPrimary, { from: anyone })); + await shouldFail.reverting(this.secondary.transferPrimary(newPrimary, { from: anyone })); }); context('with new primary', function () { @@ -50,7 +50,7 @@ contract('Secondary', function ([_, primary, newPrimary, anyone]) { }); it('reverts when the old primary account calls onlyPrimary functions', async function () { - await assertRevert(this.secondary.onlyPrimaryMock({ from: primary })); + await shouldFail.reverting(this.secondary.onlyPrimaryMock({ from: primary })); }); }); }); diff --git a/test/payment/SplitPayment.test.js b/test/payment/PaymentSplitter.test.js similarity index 59% rename from test/payment/SplitPayment.test.js rename to test/payment/PaymentSplitter.test.js index bb5aad0e9..90391c793 100644 --- a/test/payment/SplitPayment.test.js +++ b/test/payment/PaymentSplitter.test.js @@ -1,41 +1,39 @@ -const { ethGetBalance, ethSendTransaction } = require('../helpers/web3'); +const { ethGetBalance } = require('../helpers/web3'); +const expectEvent = require('../helpers/expectEvent'); +const send = require('./../helpers/send'); +const { ether } = require('../helpers/ether'); +const { ZERO_ADDRESS } = require('./../helpers/constants'); -const BigNumber = web3.BigNumber; +require('../helpers/setup'); -require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); +const shouldFail = require('../helpers/shouldFail'); +const PaymentSplitter = artifacts.require('PaymentSplitterMock'); -const { expectThrow } = require('../helpers/expectThrow'); -const { EVMRevert } = require('../helpers/EVMRevert.js'); -const SplitPayment = artifacts.require('SplitPaymentMock'); - -contract('SplitPayment', function ([_, owner, payee1, payee2, payee3, nonpayee1, payer1]) { - const amount = web3.toWei(1.0, 'ether'); - const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; +contract('PaymentSplitter', function ([_, owner, payee1, payee2, payee3, nonpayee1, payer1]) { + const amount = ether(1.0); it('rejects an empty set of payees', async function () { - await expectThrow(SplitPayment.new([], []), EVMRevert); + await shouldFail.reverting(PaymentSplitter.new([], [])); }); it('rejects more payees than shares', async function () { - await expectThrow(SplitPayment.new([payee1, payee2, payee3], [20, 30]), EVMRevert); + await shouldFail.reverting(PaymentSplitter.new([payee1, payee2, payee3], [20, 30])); }); it('rejects more shares than payees', async function () { - await expectThrow(SplitPayment.new([payee1, payee2], [20, 30, 40]), EVMRevert); + await shouldFail.reverting(PaymentSplitter.new([payee1, payee2], [20, 30, 40])); }); it('rejects null payees', async function () { - await expectThrow(SplitPayment.new([payee1, ZERO_ADDRESS], [20, 30]), EVMRevert); + await shouldFail.reverting(PaymentSplitter.new([payee1, ZERO_ADDRESS], [20, 30])); }); it('rejects zero-valued shares', async function () { - await expectThrow(SplitPayment.new([payee1, payee2], [20, 0]), EVMRevert); + await shouldFail.reverting(PaymentSplitter.new([payee1, payee2], [20, 0])); }); it('rejects repeated payees', async function () { - await expectThrow(SplitPayment.new([payee1, payee1], [20, 30]), EVMRevert); + await shouldFail.reverting(PaymentSplitter.new([payee1, payee1], [20, 30])); }); context('once deployed', function () { @@ -43,7 +41,7 @@ contract('SplitPayment', function ([_, owner, payee1, payee2, payee3, nonpayee1, this.payees = [payee1, payee2, payee3]; this.shares = [20, 10, 70]; - this.contract = await SplitPayment.new(this.payees, this.shares); + this.contract = await PaymentSplitter.new(this.payees, this.shares); }); it('should have total shares', async function () { @@ -58,7 +56,7 @@ contract('SplitPayment', function ([_, owner, payee1, payee2, payee3, nonpayee1, }); it('should accept payments', async function () { - await ethSendTransaction({ from: owner, to: this.contract.address, value: amount }); + await send.ether(owner, this.contract.address, amount); (await ethGetBalance(this.contract.address)).should.be.bignumber.equal(amount); }); @@ -72,16 +70,16 @@ contract('SplitPayment', function ([_, owner, payee1, payee2, payee3, nonpayee1, }); it('should throw if no funds to claim', async function () { - await expectThrow(this.contract.release(payee1), EVMRevert); + await shouldFail.reverting(this.contract.release(payee1)); }); it('should throw if non-payee want to claim', async function () { - await ethSendTransaction({ from: payer1, to: this.contract.address, value: amount }); - await expectThrow(this.contract.release(nonpayee1), EVMRevert); + await send.ether(payer1, this.contract.address, amount); + await shouldFail.reverting(this.contract.release(nonpayee1)); }); it('should distribute funds to payees', async function () { - await ethSendTransaction({ from: payer1, to: this.contract.address, value: amount }); + await send.ether(payer1, this.contract.address, amount); // receive funds const initBalance = await ethGetBalance(this.contract.address); @@ -89,19 +87,22 @@ contract('SplitPayment', function ([_, owner, payee1, payee2, payee3, nonpayee1, // distribute to payees const initAmount1 = await ethGetBalance(payee1); - await this.contract.release(payee1); + const { logs: logs1 } = await this.contract.release(payee1); const profit1 = (await ethGetBalance(payee1)).sub(initAmount1); profit1.sub(web3.toWei(0.20, 'ether')).abs().should.be.bignumber.lt(1e16); + expectEvent.inLogs(logs1, 'PaymentReleased', { to: payee1, amount: profit1 }); const initAmount2 = await ethGetBalance(payee2); - await this.contract.release(payee2); + const { logs: logs2 } = await this.contract.release(payee2); const profit2 = (await ethGetBalance(payee2)).sub(initAmount2); profit2.sub(web3.toWei(0.10, 'ether')).abs().should.be.bignumber.lt(1e16); + expectEvent.inLogs(logs2, 'PaymentReleased', { to: payee2, amount: profit2 }); const initAmount3 = await ethGetBalance(payee3); - await this.contract.release(payee3); + const { logs: logs3 } = await this.contract.release(payee3); const profit3 = (await ethGetBalance(payee3)).sub(initAmount3); profit3.sub(web3.toWei(0.70, 'ether')).abs().should.be.bignumber.lt(1e16); + expectEvent.inLogs(logs3, 'PaymentReleased', { to: payee3, amount: profit3 }); // end balance should be zero (await ethGetBalance(this.contract.address)).should.be.bignumber.equal(0); diff --git a/test/payment/PullPayment.test.js b/test/payment/PullPayment.test.js index 1eab3911f..f82712ef3 100644 --- a/test/payment/PullPayment.test.js +++ b/test/payment/PullPayment.test.js @@ -1,15 +1,12 @@ -const { ethGetBalance } = require('../helpers/web3'); +const { balanceDifference } = require('../helpers/balanceDifference'); +const { ether } = require('../helpers/ether'); -const BigNumber = web3.BigNumber; - -require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); +require('../helpers/setup'); const PullPaymentMock = artifacts.require('PullPaymentMock'); contract('PullPayment', function ([_, payer, payee1, payee2]) { - const amount = web3.toWei(17.0, 'ether'); + const amount = ether(17.0); beforeEach(async function () { this.contract = await PullPaymentMock.new({ value: amount }); @@ -36,16 +33,13 @@ contract('PullPayment', function ([_, payer, payee1, payee2]) { }); it('can withdraw payment', async function () { - const initialBalance = await ethGetBalance(payee1); + (await balanceDifference(payee1, async () => { + await this.contract.callTransfer(payee1, amount, { from: payer }); + (await this.contract.payments(payee1)).should.be.bignumber.equal(amount); - await this.contract.callTransfer(payee1, amount, { from: payer }); + await this.contract.withdrawPayments(payee1); + })).should.be.bignumber.equal(amount); - (await this.contract.payments(payee1)).should.be.bignumber.equal(amount); - - await this.contract.withdrawPayments(payee1); (await this.contract.payments(payee1)).should.be.bignumber.equal(0); - - const balance = await ethGetBalance(payee1); - Math.abs(balance - initialBalance - amount).should.be.lt(1e16); }); }); diff --git a/test/payment/ConditionalEscrow.test.js b/test/payment/escrow/ConditionalEscrow.test.js similarity index 71% rename from test/payment/ConditionalEscrow.test.js rename to test/payment/escrow/ConditionalEscrow.test.js index 5115fee48..bb5b5cf98 100644 --- a/test/payment/ConditionalEscrow.test.js +++ b/test/payment/escrow/ConditionalEscrow.test.js @@ -1,12 +1,9 @@ const { shouldBehaveLikeEscrow } = require('./Escrow.behavior'); -const { expectThrow } = require('../helpers/expectThrow'); -const { EVMRevert } = require('../helpers/EVMRevert'); -const BigNumber = web3.BigNumber; +const shouldFail = require('../../helpers/shouldFail'); +const { ether } = require('../../helpers/ether'); -require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); +require('../../helpers/setup'); const ConditionalEscrowMock = artifacts.require('ConditionalEscrowMock'); @@ -24,7 +21,7 @@ contract('ConditionalEscrow', function ([_, owner, payee, ...otherAccounts]) { }); context('when withdrawal is disallowed', function () { - const amount = web3.toWei(23.0, 'ether'); + const amount = ether(23.0); beforeEach(async function () { await this.escrow.setAllowed(payee, false); @@ -33,7 +30,7 @@ contract('ConditionalEscrow', function ([_, owner, payee, ...otherAccounts]) { it('reverts on withdrawals', async function () { await this.escrow.deposit(payee, { from: owner, value: amount }); - await expectThrow(this.escrow.withdraw(payee, { from: owner }), EVMRevert); + await shouldFail.reverting(this.escrow.withdraw(payee, { from: owner })); }); }); }); diff --git a/test/payment/Escrow.behavior.js b/test/payment/escrow/Escrow.behavior.js similarity index 63% rename from test/payment/Escrow.behavior.js rename to test/payment/escrow/Escrow.behavior.js index 761aecd89..80bde2f5c 100644 --- a/test/payment/Escrow.behavior.js +++ b/test/payment/escrow/Escrow.behavior.js @@ -1,16 +1,13 @@ -const expectEvent = require('../helpers/expectEvent'); -const { expectThrow } = require('../helpers/expectThrow'); -const { EVMRevert } = require('../helpers/EVMRevert'); -const { ethGetBalance } = require('../helpers/web3'); +const expectEvent = require('../../helpers/expectEvent'); +const shouldFail = require('../../helpers/shouldFail'); +const { ethGetBalance } = require('../../helpers/web3'); +const { balanceDifference } = require('../../helpers/balanceDifference'); +const { ether } = require('../../helpers/ether'); -const BigNumber = web3.BigNumber; - -require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); +require('../../helpers/setup'); function shouldBehaveLikeEscrow (primary, [payee1, payee2]) { - const amount = web3.toWei(42.0, 'ether'); + const amount = ether(42.0); describe('as an escrow', function () { describe('deposits', function () { @@ -27,14 +24,15 @@ function shouldBehaveLikeEscrow (primary, [payee1, payee2]) { }); it('only the primary account can deposit', async function () { - await expectThrow(this.escrow.deposit(payee1, { from: payee2 }), EVMRevert); + await shouldFail.reverting(this.escrow.deposit(payee1, { from: payee2 })); }); it('emits a deposited event', async function () { - const receipt = await this.escrow.deposit(payee1, { from: primary, value: amount }); - - const event = expectEvent.inLogs(receipt.logs, 'Deposited', { payee: payee1 }); - event.args.weiAmount.should.be.bignumber.equal(amount); + const { logs } = await this.escrow.deposit(payee1, { from: primary, value: amount }); + expectEvent.inLogs(logs, 'Deposited', { + payee: payee1, + weiAmount: amount, + }); }); it('can add multiple deposits on a single account', async function () { @@ -60,17 +58,13 @@ function shouldBehaveLikeEscrow (primary, [payee1, payee2]) { describe('withdrawals', async function () { it('can withdraw payments', async function () { - const payeeInitialBalance = await ethGetBalance(payee1); - - await this.escrow.deposit(payee1, { from: primary, value: amount }); - await this.escrow.withdraw(payee1, { from: primary }); + (await balanceDifference(payee1, async () => { + await this.escrow.deposit(payee1, { from: primary, value: amount }); + await this.escrow.withdraw(payee1, { from: primary }); + })).should.be.bignumber.equal(amount); (await ethGetBalance(this.escrow.address)).should.be.bignumber.equal(0); - (await this.escrow.depositsOf(payee1)).should.be.bignumber.equal(0); - - const payeeFinalBalance = await ethGetBalance(payee1); - payeeFinalBalance.sub(payeeInitialBalance).should.be.bignumber.equal(amount); }); it('can do an empty withdrawal', async function () { @@ -78,15 +72,16 @@ function shouldBehaveLikeEscrow (primary, [payee1, payee2]) { }); it('only the primary account can withdraw', async function () { - await expectThrow(this.escrow.withdraw(payee1, { from: payee1 }), EVMRevert); + await shouldFail.reverting(this.escrow.withdraw(payee1, { from: payee1 })); }); it('emits a withdrawn event', async function () { await this.escrow.deposit(payee1, { from: primary, value: amount }); - const receipt = await this.escrow.withdraw(payee1, { from: primary }); - - const event = expectEvent.inLogs(receipt.logs, 'Withdrawn', { payee: payee1 }); - event.args.weiAmount.should.be.bignumber.equal(amount); + const { logs } = await this.escrow.withdraw(payee1, { from: primary }); + expectEvent.inLogs(logs, 'Withdrawn', { + payee: payee1, + weiAmount: amount, + }); }); }); }); diff --git a/test/payment/Escrow.test.js b/test/payment/escrow/Escrow.test.js similarity index 100% rename from test/payment/Escrow.test.js rename to test/payment/escrow/Escrow.test.js diff --git a/test/payment/RefundEscrow.test.js b/test/payment/escrow/RefundEscrow.test.js similarity index 54% rename from test/payment/RefundEscrow.test.js rename to test/payment/escrow/RefundEscrow.test.js index 007e9e8bd..cd9f7e412 100644 --- a/test/payment/RefundEscrow.test.js +++ b/test/payment/escrow/RefundEscrow.test.js @@ -1,23 +1,19 @@ -const { expectThrow } = require('../helpers/expectThrow'); -const { EVMRevert } = require('../helpers/EVMRevert'); -const expectEvent = require('../helpers/expectEvent'); -const { ethGetBalance } = require('../helpers/web3'); +const shouldFail = require('../../helpers/shouldFail'); +const expectEvent = require('../../helpers/expectEvent'); +const { balanceDifference } = require('../../helpers/balanceDifference'); +const { ether } = require('../../helpers/ether'); +const { ZERO_ADDRESS } = require('../../helpers/constants'); -const BigNumber = web3.BigNumber; - -require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); +require('../../helpers/setup'); const RefundEscrow = artifacts.require('RefundEscrowMock'); contract('RefundEscrow', function ([_, primary, beneficiary, refundee1, refundee2]) { - const amount = web3.toWei(54.0, 'ether'); + const amount = ether(54.0); const refundees = [refundee1, refundee2]; - const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; it('requires a non-null beneficiary', async function () { - await expectThrow( + await shouldFail.reverting( RefundEscrow.new(ZERO_ADDRESS, { from: primary }) ); }); @@ -41,21 +37,20 @@ contract('RefundEscrow', function ([_, primary, beneficiary, refundee1, refundee it('does not refund refundees', async function () { await this.escrow.deposit(refundee1, { from: primary, value: amount }); - await expectThrow(this.escrow.withdraw(refundee1), EVMRevert); + await shouldFail.reverting(this.escrow.withdraw(refundee1)); }); it('does not allow beneficiary withdrawal', async function () { await this.escrow.deposit(refundee1, { from: primary, value: amount }); - await expectThrow(this.escrow.beneficiaryWithdraw(), EVMRevert); + await shouldFail.reverting(this.escrow.beneficiaryWithdraw()); }); }); it('only the primary account can enter closed state', async function () { - await expectThrow(this.escrow.close({ from: beneficiary }), EVMRevert); + await shouldFail.reverting(this.escrow.close({ from: beneficiary })); - const receipt = await this.escrow.close({ from: primary }); - - expectEvent.inLogs(receipt.logs, 'Closed'); + const { logs } = await this.escrow.close({ from: primary }); + expectEvent.inLogs(logs, 'RefundsClosed'); }); context('closed state', function () { @@ -66,36 +61,33 @@ contract('RefundEscrow', function ([_, primary, beneficiary, refundee1, refundee }); it('rejects deposits', async function () { - await expectThrow(this.escrow.deposit(refundee1, { from: primary, value: amount }), EVMRevert); + await shouldFail.reverting(this.escrow.deposit(refundee1, { from: primary, value: amount })); }); it('does not refund refundees', async function () { - await expectThrow(this.escrow.withdraw(refundee1), EVMRevert); + await shouldFail.reverting(this.escrow.withdraw(refundee1)); }); it('allows beneficiary withdrawal', async function () { - const beneficiaryInitialBalance = await ethGetBalance(beneficiary); - await this.escrow.beneficiaryWithdraw(); - const beneficiaryFinalBalance = await ethGetBalance(beneficiary); - - beneficiaryFinalBalance.sub(beneficiaryInitialBalance).should.be.bignumber.equal(amount * refundees.length); + (await balanceDifference(beneficiary, () => + this.escrow.beneficiaryWithdraw() + )).should.be.bignumber.equal(amount * refundees.length); }); it('prevents entering the refund state', async function () { - await expectThrow(this.escrow.enableRefunds({ from: primary }), EVMRevert); + await shouldFail.reverting(this.escrow.enableRefunds({ from: primary })); }); it('prevents re-entering the closed state', async function () { - await expectThrow(this.escrow.close({ from: primary }), EVMRevert); + await shouldFail.reverting(this.escrow.close({ from: primary })); }); }); it('only the primary account can enter refund state', async function () { - await expectThrow(this.escrow.enableRefunds({ from: beneficiary }), EVMRevert); + await shouldFail.reverting(this.escrow.enableRefunds({ from: beneficiary })); - const receipt = await this.escrow.enableRefunds({ from: primary }); - - expectEvent.inLogs(receipt.logs, 'RefundsEnabled'); + const { logs } = await this.escrow.enableRefunds({ from: primary }); + expectEvent.inLogs(logs, 'RefundsEnabled'); }); context('refund state', function () { @@ -106,29 +98,27 @@ contract('RefundEscrow', function ([_, primary, beneficiary, refundee1, refundee }); it('rejects deposits', async function () { - await expectThrow(this.escrow.deposit(refundee1, { from: primary, value: amount }), EVMRevert); + await shouldFail.reverting(this.escrow.deposit(refundee1, { from: primary, value: amount })); }); it('refunds refundees', async function () { for (const refundee of [refundee1, refundee2]) { - const refundeeInitialBalance = await ethGetBalance(refundee); - await this.escrow.withdraw(refundee, { from: primary }); - const refundeeFinalBalance = await ethGetBalance(refundee); - - refundeeFinalBalance.sub(refundeeInitialBalance).should.be.bignumber.equal(amount); + (await balanceDifference(refundee, () => + this.escrow.withdraw(refundee, { from: primary })) + ).should.be.bignumber.equal(amount); } }); it('does not allow beneficiary withdrawal', async function () { - await expectThrow(this.escrow.beneficiaryWithdraw(), EVMRevert); + await shouldFail.reverting(this.escrow.beneficiaryWithdraw()); }); it('prevents entering the closed state', async function () { - await expectThrow(this.escrow.close({ from: primary }), EVMRevert); + await shouldFail.reverting(this.escrow.close({ from: primary })); }); it('prevents re-entering the refund state', async function () { - await expectThrow(this.escrow.enableRefunds({ from: primary }), EVMRevert); + await shouldFail.reverting(this.escrow.enableRefunds({ from: primary })); }); }); }); diff --git a/test/token/ERC20/ERC20.test.js b/test/token/ERC20/ERC20.test.js index f9568b87e..16d2cab75 100644 --- a/test/token/ERC20/ERC20.test.js +++ b/test/token/ERC20/ERC20.test.js @@ -1,19 +1,14 @@ -const { assertRevert } = require('../../helpers/assertRevert'); +const shouldFail = require('../../helpers/shouldFail'); const expectEvent = require('../../helpers/expectEvent'); +const { ZERO_ADDRESS } = require('../../helpers/constants'); -const ERC20 = artifacts.require('ERC20Mock'); +const ERC20Mock = artifacts.require('ERC20Mock'); -const BigNumber = web3.BigNumber; - -require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); +const { BigNumber } = require('../../helpers/setup'); contract('ERC20', function ([_, owner, recipient, anotherAccount]) { - const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; - beforeEach(async function () { - this.token = await ERC20.new(owner, 100); + this.token = await ERC20Mock.new(owner, 100); }); describe('total supply', function () { @@ -44,7 +39,7 @@ contract('ERC20', function ([_, owner, recipient, anotherAccount]) { const amount = 101; it('reverts', async function () { - await assertRevert(this.token.transfer(to, amount, { from: owner })); + await shouldFail.reverting(this.token.transfer(to, amount, { from: owner })); }); }); @@ -62,12 +57,11 @@ contract('ERC20', function ([_, owner, recipient, anotherAccount]) { it('emits a transfer event', async function () { const { logs } = await this.token.transfer(to, amount, { from: owner }); - const event = expectEvent.inLogs(logs, 'Transfer', { + expectEvent.inLogs(logs, 'Transfer', { from: owner, to: to, + value: amount, }); - - event.args.value.should.be.bignumber.equal(amount); }); }); }); @@ -76,7 +70,7 @@ contract('ERC20', function ([_, owner, recipient, anotherAccount]) { const to = ZERO_ADDRESS; it('reverts', async function () { - await assertRevert(this.token.transfer(to, 100, { from: owner })); + await shouldFail.reverting(this.token.transfer(to, 100, { from: owner })); }); }); }); @@ -91,11 +85,11 @@ contract('ERC20', function ([_, owner, recipient, anotherAccount]) { it('emits an approval event', async function () { const { logs } = await this.token.approve(spender, amount, { from: owner }); - logs.length.should.equal(1); - logs[0].event.should.equal('Approval'); - logs[0].args.owner.should.equal(owner); - logs[0].args.spender.should.equal(spender); - logs[0].args.value.should.be.bignumber.equal(amount); + expectEvent.inLogs(logs, 'Approval', { + owner: owner, + spender: spender, + value: amount, + }); }); describe('when there was no approved amount before', function () { @@ -125,11 +119,11 @@ contract('ERC20', function ([_, owner, recipient, anotherAccount]) { it('emits an approval event', async function () { const { logs } = await this.token.approve(spender, amount, { from: owner }); - logs.length.should.equal(1); - logs[0].event.should.equal('Approval'); - logs[0].args.owner.should.equal(owner); - logs[0].args.spender.should.equal(spender); - logs[0].args.value.should.be.bignumber.equal(amount); + expectEvent.inLogs(logs, 'Approval', { + owner: owner, + spender: spender, + value: amount, + }); }); describe('when there was no approved amount before', function () { @@ -159,7 +153,7 @@ contract('ERC20', function ([_, owner, recipient, anotherAccount]) { const spender = ZERO_ADDRESS; it('reverts', async function () { - await assertRevert(this.token.approve(spender, amount, { from: owner })); + await shouldFail.reverting(this.token.approve(spender, amount, { from: owner })); }); }); }); @@ -195,11 +189,21 @@ contract('ERC20', function ([_, owner, recipient, anotherAccount]) { it('emits a transfer event', async function () { const { logs } = await this.token.transferFrom(owner, to, amount, { from: spender }); - logs.length.should.equal(1); - logs[0].event.should.equal('Transfer'); - logs[0].args.from.should.equal(owner); - logs[0].args.to.should.equal(to); - logs[0].args.value.should.be.bignumber.equal(amount); + expectEvent.inLogs(logs, 'Transfer', { + from: owner, + to: to, + value: amount, + }); + }); + + it('emits an approval event', async function () { + const { logs } = await this.token.transferFrom(owner, to, amount, { from: spender }); + + expectEvent.inLogs(logs, 'Approval', { + owner: owner, + spender: spender, + value: await this.token.allowance(owner, spender), + }); }); }); @@ -207,7 +211,7 @@ contract('ERC20', function ([_, owner, recipient, anotherAccount]) { const amount = 101; it('reverts', async function () { - await assertRevert(this.token.transferFrom(owner, to, amount, { from: spender })); + await shouldFail.reverting(this.token.transferFrom(owner, to, amount, { from: spender })); }); }); }); @@ -221,7 +225,7 @@ contract('ERC20', function ([_, owner, recipient, anotherAccount]) { const amount = 100; it('reverts', async function () { - await assertRevert(this.token.transferFrom(owner, to, amount, { from: spender })); + await shouldFail.reverting(this.token.transferFrom(owner, to, amount, { from: spender })); }); }); @@ -229,7 +233,7 @@ contract('ERC20', function ([_, owner, recipient, anotherAccount]) { const amount = 101; it('reverts', async function () { - await assertRevert(this.token.transferFrom(owner, to, amount, { from: spender })); + await shouldFail.reverting(this.token.transferFrom(owner, to, amount, { from: spender })); }); }); }); @@ -244,7 +248,7 @@ contract('ERC20', function ([_, owner, recipient, anotherAccount]) { }); it('reverts', async function () { - await assertRevert(this.token.transferFrom(owner, to, amount, { from: spender })); + await shouldFail.reverting(this.token.transferFrom(owner, to, amount, { from: spender })); }); }); }); @@ -256,7 +260,7 @@ contract('ERC20', function ([_, owner, recipient, anotherAccount]) { function shouldDecreaseApproval (amount) { describe('when there was no approved amount before', function () { it('reverts', async function () { - await assertRevert(this.token.decreaseAllowance(spender, amount, { from: owner })); + await shouldFail.reverting(this.token.decreaseAllowance(spender, amount, { from: owner })); }); }); @@ -270,11 +274,11 @@ contract('ERC20', function ([_, owner, recipient, anotherAccount]) { it('emits an approval event', async function () { const { logs } = await this.token.decreaseAllowance(spender, approvedAmount, { from: owner }); - logs.length.should.equal(1); - logs[0].event.should.equal('Approval'); - logs[0].args.owner.should.equal(owner); - logs[0].args.spender.should.equal(spender); - logs[0].args.value.should.be.bignumber.equal(0); + expectEvent.inLogs(logs, 'Approval', { + owner: owner, + spender: spender, + value: 0, + }); }); it('decreases the spender allowance subtracting the requested amount', async function () { @@ -289,7 +293,7 @@ contract('ERC20', function ([_, owner, recipient, anotherAccount]) { }); it('reverts when more than the full allowance is removed', async function () { - await assertRevert(this.token.decreaseAllowance(spender, approvedAmount + 1, { from: owner })); + await shouldFail.reverting(this.token.decreaseAllowance(spender, approvedAmount + 1, { from: owner })); }); }); } @@ -312,7 +316,7 @@ contract('ERC20', function ([_, owner, recipient, anotherAccount]) { const spender = ZERO_ADDRESS; it('reverts', async function () { - await assertRevert(this.token.decreaseAllowance(spender, amount, { from: owner })); + await shouldFail.reverting(this.token.decreaseAllowance(spender, amount, { from: owner })); }); }); }); @@ -327,11 +331,11 @@ contract('ERC20', function ([_, owner, recipient, anotherAccount]) { it('emits an approval event', async function () { const { logs } = await this.token.increaseAllowance(spender, amount, { from: owner }); - logs.length.should.equal(1); - logs[0].event.should.equal('Approval'); - logs[0].args.owner.should.equal(owner); - logs[0].args.spender.should.equal(spender); - logs[0].args.value.should.be.bignumber.equal(amount); + expectEvent.inLogs(logs, 'Approval', { + owner: owner, + spender: spender, + value: amount, + }); }); describe('when there was no approved amount before', function () { @@ -361,11 +365,11 @@ contract('ERC20', function ([_, owner, recipient, anotherAccount]) { it('emits an approval event', async function () { const { logs } = await this.token.increaseAllowance(spender, amount, { from: owner }); - logs.length.should.equal(1); - logs[0].event.should.equal('Approval'); - logs[0].args.owner.should.equal(owner); - logs[0].args.spender.should.equal(spender); - logs[0].args.value.should.be.bignumber.equal(amount); + expectEvent.inLogs(logs, 'Approval', { + owner: owner, + spender: spender, + value: amount, + }); }); describe('when there was no approved amount before', function () { @@ -394,7 +398,7 @@ contract('ERC20', function ([_, owner, recipient, anotherAccount]) { const spender = ZERO_ADDRESS; it('reverts', async function () { - await assertRevert(this.token.increaseAllowance(spender, amount, { from: owner })); + await shouldFail.reverting(this.token.increaseAllowance(spender, amount, { from: owner })); }); }); }); @@ -404,7 +408,7 @@ contract('ERC20', function ([_, owner, recipient, anotherAccount]) { const amount = new BigNumber(50); it('rejects a null account', async function () { - await assertRevert(this.token.mint(ZERO_ADDRESS, amount)); + await shouldFail.reverting(this.token.mint(ZERO_ADDRESS, amount)); }); describe('for a non null account', function () { @@ -437,12 +441,12 @@ contract('ERC20', function ([_, owner, recipient, anotherAccount]) { const initialSupply = new BigNumber(100); it('rejects a null account', async function () { - await assertRevert(this.token.burn(ZERO_ADDRESS, 1)); + await shouldFail.reverting(this.token.burn(ZERO_ADDRESS, 1)); }); describe('for a non null account', function () { it('rejects burning more than balance', async function () { - await assertRevert(this.token.burn(owner, initialSupply.plus(1))); + await shouldFail.reverting(this.token.burn(owner, initialSupply.plus(1))); }); const describeBurn = function (description, amount) { @@ -489,16 +493,16 @@ contract('ERC20', function ([_, owner, recipient, anotherAccount]) { }); it('rejects a null account', async function () { - await assertRevert(this.token.burnFrom(ZERO_ADDRESS, 1)); + await shouldFail.reverting(this.token.burnFrom(ZERO_ADDRESS, 1)); }); describe('for a non null account', function () { it('rejects burning more than allowance', async function () { - await assertRevert(this.token.burnFrom(owner, allowance.plus(1))); + await shouldFail.reverting(this.token.burnFrom(owner, allowance.plus(1))); }); it('rejects burning more than balance', async function () { - await assertRevert(this.token.burnFrom(owner, initialSupply.plus(1))); + await shouldFail.reverting(this.token.burnFrom(owner, initialSupply.plus(1))); }); const describeBurnFrom = function (description, amount) { @@ -523,7 +527,7 @@ contract('ERC20', function ([_, owner, recipient, anotherAccount]) { (await this.token.allowance(owner, spender)).should.be.bignumber.equal(expectedAllowance); }); - it('emits Transfer event', async function () { + it('emits a Transfer event', async function () { const event = expectEvent.inLogs(this.logs, 'Transfer', { from: owner, to: ZERO_ADDRESS, @@ -531,6 +535,14 @@ contract('ERC20', function ([_, owner, recipient, anotherAccount]) { event.args.value.should.be.bignumber.equal(amount); }); + + it('emits an Approval event', async function () { + expectEvent.inLogs(this.logs, 'Approval', { + owner: owner, + spender: spender, + value: await this.token.allowance(owner, spender), + }); + }); }); }; diff --git a/test/token/ERC20/ERC20Capped.test.js b/test/token/ERC20/ERC20Capped.test.js index 475f4a65e..dd8f7a850 100644 --- a/test/token/ERC20/ERC20Capped.test.js +++ b/test/token/ERC20/ERC20Capped.test.js @@ -1,4 +1,4 @@ -const { assertRevert } = require('../../helpers/assertRevert'); +const shouldFail = require('../../helpers/shouldFail'); const { ether } = require('../../helpers/ether'); const { shouldBehaveLikeERC20Mintable } = require('./behaviors/ERC20Mintable.behavior'); const { shouldBehaveLikeERC20Capped } = require('./behaviors/ERC20Capped.behavior'); @@ -9,7 +9,7 @@ contract('ERC20Capped', function ([_, minter, ...otherAccounts]) { const cap = ether(1000); it('requires a non-zero cap', async function () { - await assertRevert( + await shouldFail.reverting( ERC20Capped.new(0, { from: minter }) ); }); diff --git a/test/token/ERC20/ERC20Detailed.test.js b/test/token/ERC20/ERC20Detailed.test.js index 71b22a7b9..448487acd 100644 --- a/test/token/ERC20/ERC20Detailed.test.js +++ b/test/token/ERC20/ERC20Detailed.test.js @@ -1,31 +1,25 @@ -const BigNumber = web3.BigNumber; - -require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); +require('../../helpers/setup'); const ERC20DetailedMock = artifacts.require('ERC20DetailedMock'); contract('ERC20Detailed', function () { - let detailedERC20 = null; - const _name = 'My Detailed ERC20'; const _symbol = 'MDT'; const _decimals = 18; beforeEach(async function () { - detailedERC20 = await ERC20DetailedMock.new(_name, _symbol, _decimals); + this.detailedERC20 = await ERC20DetailedMock.new(_name, _symbol, _decimals); }); it('has a name', async function () { - (await detailedERC20.name()).should.be.equal(_name); + (await this.detailedERC20.name()).should.be.equal(_name); }); it('has a symbol', async function () { - (await detailedERC20.symbol()).should.be.equal(_symbol); + (await this.detailedERC20.symbol()).should.be.equal(_symbol); }); it('has an amount of decimals', async function () { - (await detailedERC20.decimals()).should.be.bignumber.equal(_decimals); + (await this.detailedERC20.decimals()).should.be.bignumber.equal(_decimals); }); }); diff --git a/test/token/ERC20/ERC20Pausable.test.js b/test/token/ERC20/ERC20Pausable.test.js index 568b7f147..f89d20e25 100644 --- a/test/token/ERC20/ERC20Pausable.test.js +++ b/test/token/ERC20/ERC20Pausable.test.js @@ -1,11 +1,12 @@ -const { assertRevert } = require('../../helpers/assertRevert'); +const expectEvent = require('../../helpers/expectEvent'); +const shouldFail = require('../../helpers/shouldFail'); -const ERC20Pausable = artifacts.require('ERC20PausableMock'); +const ERC20PausableMock = artifacts.require('ERC20PausableMock'); const { shouldBehaveLikePublicRole } = require('../../access/roles/PublicRole.behavior'); contract('ERC20Pausable', function ([_, pauser, otherPauser, recipient, anotherAccount, ...otherAccounts]) { beforeEach(async function () { - this.token = await ERC20Pausable.new(pauser, 100, { from: pauser }); + this.token = await ERC20PausableMock.new(pauser, 100, { from: pauser }); }); describe('pauser role', function () { @@ -30,8 +31,7 @@ contract('ERC20Pausable', function ([_, pauser, otherPauser, recipient, anotherA it('emits a Pause event', async function () { const { logs } = await this.token.pause({ from }); - logs.length.should.equal(1); - logs[0].event.should.equal('Paused'); + expectEvent.inLogs(logs, 'Paused'); }); }); @@ -41,7 +41,7 @@ contract('ERC20Pausable', function ([_, pauser, otherPauser, recipient, anotherA }); it('reverts', async function () { - await assertRevert(this.token.pause({ from })); + await shouldFail.reverting(this.token.pause({ from })); }); }); }); @@ -50,7 +50,7 @@ contract('ERC20Pausable', function ([_, pauser, otherPauser, recipient, anotherA const from = anotherAccount; it('reverts', async function () { - await assertRevert(this.token.pause({ from })); + await shouldFail.reverting(this.token.pause({ from })); }); }); }); @@ -72,14 +72,13 @@ contract('ERC20Pausable', function ([_, pauser, otherPauser, recipient, anotherA it('emits an Unpause event', async function () { const { logs } = await this.token.unpause({ from }); - logs.length.should.equal(1); - logs[0].event.should.equal('Unpaused'); + expectEvent.inLogs(logs, 'Unpaused'); }); }); describe('when the token is unpaused', function () { it('reverts', async function () { - await assertRevert(this.token.unpause({ from })); + await shouldFail.reverting(this.token.unpause({ from })); }); }); }); @@ -88,7 +87,7 @@ contract('ERC20Pausable', function ([_, pauser, otherPauser, recipient, anotherA const from = anotherAccount; it('reverts', async function () { - await assertRevert(this.token.unpause({ from })); + await shouldFail.reverting(this.token.unpause({ from })); }); }); }); @@ -134,7 +133,7 @@ contract('ERC20Pausable', function ([_, pauser, otherPauser, recipient, anotherA it('reverts when trying to transfer when paused', async function () { await this.token.pause({ from: pauser }); - await assertRevert(this.token.transfer(recipient, 100, { from: pauser })); + await shouldFail.reverting(this.token.transfer(recipient, 100, { from: pauser })); }); }); @@ -145,7 +144,7 @@ contract('ERC20Pausable', function ([_, pauser, otherPauser, recipient, anotherA (await this.token.allowance(pauser, anotherAccount)).should.be.bignumber.equal(40); }); - it('allows to transfer when paused and then unpaused', async function () { + it('allows to approve when paused and then unpaused', async function () { await this.token.pause({ from: pauser }); await this.token.unpause({ from: pauser }); @@ -154,10 +153,10 @@ contract('ERC20Pausable', function ([_, pauser, otherPauser, recipient, anotherA (await this.token.allowance(pauser, anotherAccount)).should.be.bignumber.equal(40); }); - it('reverts when trying to transfer when paused', async function () { + it('reverts when trying to approve when paused', async function () { await this.token.pause({ from: pauser }); - await assertRevert(this.token.approve(anotherAccount, 40, { from: pauser })); + await shouldFail.reverting(this.token.approve(anotherAccount, 40, { from: pauser })); }); }); @@ -186,7 +185,7 @@ contract('ERC20Pausable', function ([_, pauser, otherPauser, recipient, anotherA it('reverts when trying to transfer from when paused', async function () { await this.token.pause({ from: pauser }); - await assertRevert(this.token.transferFrom(pauser, recipient, 40, { from: anotherAccount })); + await shouldFail.reverting(this.token.transferFrom(pauser, recipient, 40, { from: anotherAccount })); }); }); @@ -213,7 +212,7 @@ contract('ERC20Pausable', function ([_, pauser, otherPauser, recipient, anotherA it('reverts when trying to transfer when paused', async function () { await this.token.pause({ from: pauser }); - await assertRevert(this.token.decreaseAllowance(anotherAccount, 40, { from: pauser })); + await shouldFail.reverting(this.token.decreaseAllowance(anotherAccount, 40, { from: pauser })); }); }); @@ -240,7 +239,7 @@ contract('ERC20Pausable', function ([_, pauser, otherPauser, recipient, anotherA it('reverts when trying to increase approval when paused', async function () { await this.token.pause({ from: pauser }); - await assertRevert(this.token.increaseAllowance(anotherAccount, 40, { from: pauser })); + await shouldFail.reverting(this.token.increaseAllowance(anotherAccount, 40, { from: pauser })); }); }); }); diff --git a/test/token/ERC20/SafeERC20.test.js b/test/token/ERC20/SafeERC20.test.js index 6d61a2037..4be44cf38 100644 --- a/test/token/ERC20/SafeERC20.test.js +++ b/test/token/ERC20/SafeERC20.test.js @@ -1,8 +1,6 @@ -const { expectThrow } = require('../../helpers/expectThrow'); -const { EVMRevert } = require('../../helpers/EVMRevert'); +const shouldFail = require('../../helpers/shouldFail'); -require('chai') - .should(); +require('../../helpers/setup'); const SafeERC20Helper = artifacts.require('SafeERC20Helper'); @@ -11,27 +9,85 @@ contract('SafeERC20', function () { this.helper = await SafeERC20Helper.new(); }); - it('should throw on failed transfer', async function () { - await expectThrow(this.helper.doFailingTransfer(), EVMRevert); + describe('with token that returns false on all calls', function () { + it('reverts on transfer', async function () { + await shouldFail.reverting(this.helper.doFailingTransfer()); + }); + + it('reverts on transferFrom', async function () { + await shouldFail.reverting(this.helper.doFailingTransferFrom()); + }); + + it('reverts on approve', async function () { + await shouldFail.reverting(this.helper.doFailingApprove()); + }); + + it('reverts on increaseAllowance', async function () { + await shouldFail.reverting(this.helper.doFailingIncreaseAllowance()); + }); + + it('reverts on decreaseAllowance', async function () { + await shouldFail.reverting(this.helper.doFailingDecreaseAllowance()); + }); }); - it('should throw on failed transferFrom', async function () { - await expectThrow(this.helper.doFailingTransferFrom(), EVMRevert); - }); + describe('with token that returns true on all calls', function () { + it('doesn\'t revert on transfer', async function () { + await this.helper.doSucceedingTransfer(); + }); - it('should throw on failed approve', async function () { - await expectThrow(this.helper.doFailingApprove(), EVMRevert); - }); + it('doesn\'t revert on transferFrom', async function () { + await this.helper.doSucceedingTransferFrom(); + }); - it('should not throw on succeeding transfer', async function () { - await this.helper.doSucceedingTransfer(); - }); + describe('approvals', function () { + context('with zero allowance', function () { + beforeEach(async function () { + await this.helper.setAllowance(0); + }); - it('should not throw on succeeding transferFrom', async function () { - await this.helper.doSucceedingTransferFrom(); - }); + it('doesn\'t revert when approving a non-zero allowance', async function () { + await this.helper.doSucceedingApprove(100); + }); - it('should not throw on succeeding approve', async function () { - await this.helper.doSucceedingApprove(); + it('doesn\'t revert when approving a zero allowance', async function () { + await this.helper.doSucceedingApprove(0); + }); + + it('doesn\'t revert when increasing the allowance', async function () { + await this.helper.doSucceedingIncreaseAllowance(10); + }); + + it('reverts when decreasing the allowance', async function () { + await shouldFail.reverting(this.helper.doSucceedingDecreaseAllowance(10)); + }); + }); + + context('with non-zero allowance', function () { + beforeEach(async function () { + await this.helper.setAllowance(100); + }); + + it('reverts when approving a non-zero allowance', async function () { + await shouldFail.reverting(this.helper.doSucceedingApprove(20)); + }); + + it('doesn\'t revert when approving a zero allowance', async function () { + await this.helper.doSucceedingApprove(0); + }); + + it('doesn\'t revert when increasing the allowance', async function () { + await this.helper.doSucceedingIncreaseAllowance(10); + }); + + it('doesn\'t revert when decreasing the allowance to a positive value', async function () { + await this.helper.doSucceedingDecreaseAllowance(50); + }); + + it('reverts when decreasing the allowance to a negative value', async function () { + await shouldFail.reverting(this.helper.doSucceedingDecreaseAllowance(200)); + }); + }); + }); }); }); diff --git a/test/token/ERC20/TokenTimelock.test.js b/test/token/ERC20/TokenTimelock.test.js index b5c981858..6796f6ada 100644 --- a/test/token/ERC20/TokenTimelock.test.js +++ b/test/token/ERC20/TokenTimelock.test.js @@ -1,12 +1,7 @@ -const { latestTime } = require('../../helpers/latestTime'); -const { increaseTimeTo, duration } = require('../../helpers/increaseTime'); -const { expectThrow } = require('../../helpers/expectThrow'); +const shouldFail = require('../../helpers/shouldFail'); +const time = require('../../helpers/time'); -const BigNumber = web3.BigNumber; - -require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); +const { BigNumber } = require('../../helpers/setup'); const ERC20Mintable = artifacts.require('ERC20MintableMock'); const TokenTimelock = artifacts.require('TokenTimelockMock'); @@ -20,15 +15,15 @@ contract('TokenTimelock', function ([_, minter, beneficiary]) { }); it('rejects a release time in the past', async function () { - const pastReleaseTime = (await latestTime()) - duration.years(1); - await expectThrow( + const pastReleaseTime = (await time.latest()) - time.duration.years(1); + await shouldFail.reverting( TokenTimelock.new(this.token.address, beneficiary, pastReleaseTime) ); }); context('once deployed', function () { beforeEach(async function () { - this.releaseTime = (await latestTime()) + duration.years(1); + this.releaseTime = (await time.latest()) + time.duration.years(1); this.timelock = await TokenTimelock.new(this.token.address, beneficiary, this.releaseTime); await this.token.mint(this.timelock.address, amount, { from: minter }); }); @@ -40,30 +35,30 @@ contract('TokenTimelock', function ([_, minter, beneficiary]) { }); it('cannot be released before time limit', async function () { - await expectThrow(this.timelock.release()); + await shouldFail.reverting(this.timelock.release()); }); it('cannot be released just before time limit', async function () { - await increaseTimeTo(this.releaseTime - duration.seconds(3)); - await expectThrow(this.timelock.release()); + await time.increaseTo(this.releaseTime - time.duration.seconds(3)); + await shouldFail.reverting(this.timelock.release()); }); it('can be released just after limit', async function () { - await increaseTimeTo(this.releaseTime + duration.seconds(1)); + await time.increaseTo(this.releaseTime + time.duration.seconds(1)); await this.timelock.release(); (await this.token.balanceOf(beneficiary)).should.be.bignumber.equal(amount); }); it('can be released after time limit', async function () { - await increaseTimeTo(this.releaseTime + duration.years(1)); + await time.increaseTo(this.releaseTime + time.duration.years(1)); await this.timelock.release(); (await this.token.balanceOf(beneficiary)).should.be.bignumber.equal(amount); }); it('cannot be released twice', async function () { - await increaseTimeTo(this.releaseTime + duration.years(1)); + await time.increaseTo(this.releaseTime + time.duration.years(1)); await this.timelock.release(); - await expectThrow(this.timelock.release()); + await shouldFail.reverting(this.timelock.release()); (await this.token.balanceOf(beneficiary)).should.be.bignumber.equal(amount); }); }); diff --git a/test/token/ERC20/behaviors/ERC20Burnable.behavior.js b/test/token/ERC20/behaviors/ERC20Burnable.behavior.js index cf0190046..6d1c7195b 100644 --- a/test/token/ERC20/behaviors/ERC20Burnable.behavior.js +++ b/test/token/ERC20/behaviors/ERC20Burnable.behavior.js @@ -1,12 +1,8 @@ -const { assertRevert } = require('../../../helpers/assertRevert'); +const shouldFail = require('../../../helpers/shouldFail'); const expectEvent = require('../../../helpers/expectEvent'); +const { ZERO_ADDRESS } = require('../../../helpers/constants'); -const BigNumber = web3.BigNumber; -const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; - -require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); +require('../../../helpers/setup'); function shouldBehaveLikeERC20Burnable (owner, initialBalance, [burner]) { describe('burn', function () { @@ -29,10 +25,11 @@ function shouldBehaveLikeERC20Burnable (owner, initialBalance, [burner]) { }); it('emits a transfer event', async function () { - const event = expectEvent.inLogs(this.logs, 'Transfer'); - event.args.from.should.equal(owner); - event.args.to.should.equal(ZERO_ADDRESS); - event.args.value.should.be.bignumber.equal(amount); + expectEvent.inLogs(this.logs, 'Transfer', { + from: owner, + to: ZERO_ADDRESS, + value: amount, + }); }); } }); @@ -41,7 +38,7 @@ function shouldBehaveLikeERC20Burnable (owner, initialBalance, [burner]) { const amount = initialBalance + 1; it('reverts', async function () { - await assertRevert(this.token.burn(amount, { from: owner })); + await shouldFail.reverting(this.token.burn(amount, { from: owner })); }); }); }); @@ -74,10 +71,11 @@ function shouldBehaveLikeERC20Burnable (owner, initialBalance, [burner]) { }); it('emits a transfer event', async function () { - const event = expectEvent.inLogs(this.logs, 'Transfer'); - event.args.from.should.equal(owner); - event.args.to.should.equal(ZERO_ADDRESS); - event.args.value.should.be.bignumber.equal(amount); + expectEvent.inLogs(this.logs, 'Transfer', { + from: owner, + to: ZERO_ADDRESS, + value: amount, + }); }); } }); @@ -86,7 +84,7 @@ function shouldBehaveLikeERC20Burnable (owner, initialBalance, [burner]) { const amount = initialBalance + 1; it('reverts', async function () { await this.token.approve(burner, amount, { from: owner }); - await assertRevert(this.token.burnFrom(owner, amount, { from: burner })); + await shouldFail.reverting(this.token.burnFrom(owner, amount, { from: burner })); }); }); @@ -94,7 +92,7 @@ function shouldBehaveLikeERC20Burnable (owner, initialBalance, [burner]) { const amount = 100; it('reverts', async function () { await this.token.approve(burner, amount - 1, { from: owner }); - await assertRevert(this.token.burnFrom(owner, amount, { from: burner })); + await shouldFail.reverting(this.token.burnFrom(owner, amount, { from: burner })); }); }); }); diff --git a/test/token/ERC20/behaviors/ERC20Capped.behavior.js b/test/token/ERC20/behaviors/ERC20Capped.behavior.js index 3c3ab7fbf..876dbd329 100644 --- a/test/token/ERC20/behaviors/ERC20Capped.behavior.js +++ b/test/token/ERC20/behaviors/ERC20Capped.behavior.js @@ -1,10 +1,6 @@ -const { expectThrow } = require('../../../helpers/expectThrow'); +const shouldFail = require('../../../helpers/shouldFail'); -const BigNumber = web3.BigNumber; - -require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); +require('../../../helpers/setup'); function shouldBehaveLikeERC20Capped (minter, [anyone], cap) { describe('capped token', function () { @@ -21,12 +17,12 @@ function shouldBehaveLikeERC20Capped (minter, [anyone], cap) { it('should fail to mint if the ammount exceeds the cap', async function () { await this.token.mint(anyone, cap.sub(1), { from }); - await expectThrow(this.token.mint(anyone, 100, { from })); + await shouldFail.reverting(this.token.mint(anyone, 100, { from })); }); it('should fail to mint after cap is reached', async function () { await this.token.mint(anyone, cap, { from }); - await expectThrow(this.token.mint(anyone, 1, { from })); + await shouldFail.reverting(this.token.mint(anyone, 1, { from })); }); }); } diff --git a/test/token/ERC20/behaviors/ERC20Mintable.behavior.js b/test/token/ERC20/behaviors/ERC20Mintable.behavior.js index 16126d99a..987b67752 100644 --- a/test/token/ERC20/behaviors/ERC20Mintable.behavior.js +++ b/test/token/ERC20/behaviors/ERC20Mintable.behavior.js @@ -1,15 +1,10 @@ -const { assertRevert } = require('../../../helpers/assertRevert'); +const shouldFail = require('../../../helpers/shouldFail'); const expectEvent = require('../../../helpers/expectEvent'); +const { ZERO_ADDRESS } = require('../../../helpers/constants'); -const BigNumber = web3.BigNumber; - -require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); +require('../../../helpers/setup'); function shouldBehaveLikeERC20Mintable (minter, [anyone]) { - const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; - describe('as a mintable token', function () { describe('mint', function () { const amount = 100; @@ -35,11 +30,11 @@ function shouldBehaveLikeERC20Mintable (minter, [anyone]) { }); it('emits a mint and a transfer event', async function () { - const transferEvent = expectEvent.inLogs(this.logs, 'Transfer', { + expectEvent.inLogs(this.logs, 'Transfer', { from: ZERO_ADDRESS, to: anyone, + value: amount, }); - transferEvent.args.value.should.be.bignumber.equal(amount); }); } }); @@ -48,7 +43,7 @@ function shouldBehaveLikeERC20Mintable (minter, [anyone]) { const from = anyone; it('reverts', async function () { - await assertRevert(this.token.mint(anyone, amount, { from })); + await shouldFail.reverting(this.token.mint(anyone, amount, { from })); }); }); }); diff --git a/test/token/ERC721/ERC721.behavior.js b/test/token/ERC721/ERC721.behavior.js index 03e83fabe..b7600872c 100644 --- a/test/token/ERC721/ERC721.behavior.js +++ b/test/token/ERC721/ERC721.behavior.js @@ -1,15 +1,11 @@ +const expectEvent = require('../../helpers/expectEvent'); const { shouldSupportInterfaces } = require('../../introspection/SupportsInterface.behavior'); -const { assertRevert } = require('../../helpers/assertRevert'); -const { decodeLogs } = require('../../helpers/decodeLogs'); -const { sendTransaction } = require('../../helpers/sendTransaction'); -const _ = require('lodash'); +const shouldFail = require('../../helpers/shouldFail'); +const { ZERO_ADDRESS } = require('../../helpers/constants'); +const send = require('../../helpers/send'); -const ERC721Receiver = artifacts.require('ERC721ReceiverMock.sol'); -const BigNumber = web3.BigNumber; - -require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); +const ERC721ReceiverMock = artifacts.require('ERC721ReceiverMock.sol'); +require('../../helpers/setup'); function shouldBehaveLikeERC721 ( creator, @@ -19,7 +15,6 @@ function shouldBehaveLikeERC721 ( const firstTokenId = 1; const secondTokenId = 2; const unknownTokenId = 3; - const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; const RECEIVER_MAGIC_VALUE = '0x150b7a02'; describe('like an ERC721', function () { @@ -44,7 +39,7 @@ function shouldBehaveLikeERC721 ( context('when querying the zero address', function () { it('throws', async function () { - await assertRevert(this.token.balanceOf(0)); + await shouldFail.reverting(this.token.balanceOf(0)); }); }); }); @@ -62,7 +57,7 @@ function shouldBehaveLikeERC721 ( const tokenId = unknownTokenId; it('reverts', async function () { - await assertRevert(this.token.ownerOf(tokenId)); + await shouldFail.reverting(this.token.ownerOf(tokenId)); }); }); }); @@ -89,19 +84,19 @@ function shouldBehaveLikeERC721 ( if (approved) { it('emit only a transfer event', async function () { - logs.length.should.be.equal(1); - logs[0].event.should.be.equal('Transfer'); - logs[0].args.from.should.be.equal(owner); - logs[0].args.to.should.be.equal(this.toWhom); - logs[0].args.tokenId.should.be.bignumber.equal(tokenId); + expectEvent.inLogs(logs, 'Transfer', { + from: owner, + to: this.toWhom, + tokenId: tokenId, + }); }); } else { it('emits only a transfer event', async function () { - logs.length.should.be.equal(1); - logs[0].event.should.be.equal('Transfer'); - logs[0].args.from.should.be.equal(owner); - logs[0].args.to.should.be.equal(this.toWhom); - logs[0].args.tokenId.should.be.bignumber.equal(tokenId); + expectEvent.inLogs(logs, 'Transfer', { + from: owner, + to: this.toWhom, + tokenId: tokenId, + }); }); } @@ -162,11 +157,11 @@ function shouldBehaveLikeERC721 ( }); it('emits only a transfer event', async function () { - logs.length.should.be.equal(1); - logs[0].event.should.be.equal('Transfer'); - logs[0].args.from.should.be.equal(owner); - logs[0].args.to.should.be.equal(owner); - logs[0].args.tokenId.should.be.bignumber.equal(tokenId); + expectEvent.inLogs(logs, 'Transfer', { + from: owner, + to: owner, + tokenId: tokenId, + }); }); it('keeps the owner balance', async function () { @@ -175,35 +170,37 @@ function shouldBehaveLikeERC721 ( it('keeps same tokens by index', async function () { if (!this.token.tokenOfOwnerByIndex) return; - const tokensListed = await Promise.all(_.range(2).map(i => this.token.tokenOfOwnerByIndex(owner, i))); + const tokensListed = await Promise.all( + [0, 1].map(i => this.token.tokenOfOwnerByIndex(owner, i)) + ); tokensListed.map(t => t.toNumber()).should.have.members([firstTokenId, secondTokenId]); }); }); context('when the address of the previous owner is incorrect', function () { it('reverts', async function () { - await assertRevert(transferFunction.call(this, anyone, anyone, tokenId, { from: owner }) + await shouldFail.reverting(transferFunction.call(this, anyone, anyone, tokenId, { from: owner }) ); }); }); context('when the sender is not authorized for the token id', function () { it('reverts', async function () { - await assertRevert(transferFunction.call(this, owner, anyone, tokenId, { from: anyone }) + await shouldFail.reverting(transferFunction.call(this, owner, anyone, tokenId, { from: anyone }) ); }); }); context('when the given token ID does not exist', function () { it('reverts', async function () { - await assertRevert(transferFunction.call(this, owner, anyone, unknownTokenId, { from: owner }) + await shouldFail.reverting(transferFunction.call(this, owner, anyone, unknownTokenId, { from: owner }) ); }); }); context('when the address to transfer the token to is the zero address', function () { it('reverts', async function () { - await assertRevert(transferFunction.call(this, owner, ZERO_ADDRESS, tokenId, { from: owner })); + await shouldFail.reverting(transferFunction.call(this, owner, ZERO_ADDRESS, tokenId, { from: owner })); }); }); }; @@ -216,7 +213,7 @@ function shouldBehaveLikeERC721 ( describe('via safeTransferFrom', function () { const safeTransferFromWithData = function (from, to, tokenId, opts) { - return sendTransaction( + return send.transaction( this.token, 'safeTransferFrom', 'address,address,uint256,bytes', @@ -236,43 +233,37 @@ function shouldBehaveLikeERC721 ( describe('to a valid receiver contract', function () { beforeEach(async function () { - this.receiver = await ERC721Receiver.new(RECEIVER_MAGIC_VALUE, false); + this.receiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, false); this.toWhom = this.receiver.address; }); shouldTransferTokensByUsers(transferFun); it('should call onERC721Received', async function () { - const result = await transferFun.call(this, owner, this.receiver.address, tokenId, { from: owner }); - result.receipt.logs.length.should.be.equal(2); - const [log] = decodeLogs([result.receipt.logs[1]], ERC721Receiver, this.receiver.address); - log.event.should.be.equal('Received'); - log.args.operator.should.be.equal(owner); - log.args.from.should.be.equal(owner); - log.args.tokenId.toNumber().should.be.equal(tokenId); - log.args.data.should.be.equal(data); + const receipt = await transferFun.call(this, owner, this.receiver.address, tokenId, { from: owner }); + + await expectEvent.inTransaction(receipt.tx, ERC721ReceiverMock, 'Received', { + operator: owner, + from: owner, + tokenId: tokenId, + data: data, + }); }); it('should call onERC721Received from approved', async function () { - const result = await transferFun.call(this, owner, this.receiver.address, tokenId, { - from: approved, + const receipt = await transferFun.call(this, owner, this.receiver.address, tokenId, { from: approved }); + + await expectEvent.inTransaction(receipt.tx, ERC721ReceiverMock, 'Received', { + operator: approved, + from: owner, + tokenId: tokenId, + data: data, }); - result.receipt.logs.length.should.be.equal(2); - const [log] = decodeLogs( - [result.receipt.logs[1]], - ERC721Receiver, - this.receiver.address - ); - log.event.should.be.equal('Received'); - log.args.operator.should.be.equal(approved); - log.args.from.should.be.equal(owner); - log.args.tokenId.toNumber().should.be.equal(tokenId); - log.args.data.should.be.equal(data); }); describe('with an invalid token id', function () { it('reverts', async function () { - await assertRevert( + await shouldFail.reverting( transferFun.call( this, owner, @@ -296,22 +287,28 @@ function shouldBehaveLikeERC721 ( describe('to a receiver contract returning unexpected value', function () { it('reverts', async function () { - const invalidReceiver = await ERC721Receiver.new('0x42', false); - await assertRevert(this.token.safeTransferFrom(owner, invalidReceiver.address, tokenId, { from: owner })); + const invalidReceiver = await ERC721ReceiverMock.new('0x42', false); + await shouldFail.reverting( + this.token.safeTransferFrom(owner, invalidReceiver.address, tokenId, { from: owner }) + ); }); }); describe('to a receiver contract that throws', function () { it('reverts', async function () { - const invalidReceiver = await ERC721Receiver.new(RECEIVER_MAGIC_VALUE, true); - await assertRevert(this.token.safeTransferFrom(owner, invalidReceiver.address, tokenId, { from: owner })); + const invalidReceiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, true); + await shouldFail.reverting( + this.token.safeTransferFrom(owner, invalidReceiver.address, tokenId, { from: owner }) + ); }); }); describe('to a contract that does not implement the required function', function () { it('reverts', async function () { const invalidReceiver = this.token; - await assertRevert(this.token.safeTransferFrom(owner, invalidReceiver.address, tokenId, { from: owner })); + await shouldFail.reverting( + this.token.safeTransferFrom(owner, invalidReceiver.address, tokenId, { from: owner }) + ); }); }); }); @@ -336,11 +333,11 @@ function shouldBehaveLikeERC721 ( const itEmitsApprovalEvent = function (address) { it('emits an approval event', async function () { - logs.length.should.be.equal(1); - logs[0].event.should.be.equal('Approval'); - logs[0].args.owner.should.be.equal(owner); - logs[0].args.approved.should.be.equal(address); - logs[0].args.tokenId.should.be.bignumber.equal(tokenId); + expectEvent.inLogs(logs, 'Approval', { + owner: owner, + approved: address, + tokenId: tokenId, + }); }); }; @@ -398,7 +395,7 @@ function shouldBehaveLikeERC721 ( context('when the address that receives the approval is the owner', function () { it('reverts', async function () { - await assertRevert( + await shouldFail.reverting( this.token.approve(owner, tokenId, { from: owner }) ); }); @@ -406,14 +403,14 @@ function shouldBehaveLikeERC721 ( context('when the sender does not own the given token ID', function () { it('reverts', async function () { - await assertRevert(this.token.approve(approved, tokenId, { from: anyone })); + await shouldFail.reverting(this.token.approve(approved, tokenId, { from: anyone })); }); }); context('when the sender is approved for the given token ID', function () { it('reverts', async function () { await this.token.approve(approved, tokenId, { from: owner }); - await assertRevert(this.token.approve(anotherApproved, tokenId, { from: approved })); + await shouldFail.reverting(this.token.approve(anotherApproved, tokenId, { from: approved })); }); }); @@ -429,7 +426,7 @@ function shouldBehaveLikeERC721 ( context('when the given token ID does not exist', function () { it('reverts', async function () { - await assertRevert(this.token.approve(approved, unknownTokenId, { from: operator })); + await shouldFail.reverting(this.token.approve(approved, unknownTokenId, { from: operator })); }); }); }); @@ -446,11 +443,11 @@ function shouldBehaveLikeERC721 ( it('emits an approval event', async function () { const { logs } = await this.token.setApprovalForAll(operator, true, { from: owner }); - logs.length.should.be.equal(1); - logs[0].event.should.be.equal('ApprovalForAll'); - logs[0].args.owner.should.be.equal(owner); - logs[0].args.operator.should.be.equal(operator); - logs[0].args.approved.should.equal(true); + expectEvent.inLogs(logs, 'ApprovalForAll', { + owner: owner, + operator: operator, + approved: true, + }); }); }); @@ -468,11 +465,11 @@ function shouldBehaveLikeERC721 ( it('emits an approval event', async function () { const { logs } = await this.token.setApprovalForAll(operator, true, { from: owner }); - logs.length.should.be.equal(1); - logs[0].event.should.be.equal('ApprovalForAll'); - logs[0].args.owner.should.be.equal(owner); - logs[0].args.operator.should.be.equal(operator); - logs[0].args.approved.should.equal(true); + expectEvent.inLogs(logs, 'ApprovalForAll', { + owner: owner, + operator: operator, + approved: true, + }); }); it('can unset the operator approval', async function () { @@ -496,18 +493,18 @@ function shouldBehaveLikeERC721 ( it('emits an approval event', async function () { const { logs } = await this.token.setApprovalForAll(operator, true, { from: owner }); - logs.length.should.be.equal(1); - logs[0].event.should.be.equal('ApprovalForAll'); - logs[0].args.owner.should.be.equal(owner); - logs[0].args.operator.should.be.equal(operator); - logs[0].args.approved.should.equal(true); + expectEvent.inLogs(logs, 'ApprovalForAll', { + owner: owner, + operator: operator, + approved: true, + }); }); }); }); context('when the operator is the owner', function () { it('reverts', async function () { - await assertRevert(this.token.setApprovalForAll(owner, true, { from: owner })); + await shouldFail.reverting(this.token.setApprovalForAll(owner, true, { from: owner })); }); }); }); diff --git a/test/token/ERC721/ERC721.test.js b/test/token/ERC721/ERC721.test.js index 4c40e3972..8ae1c05eb 100644 --- a/test/token/ERC721/ERC721.test.js +++ b/test/token/ERC721/ERC721.test.js @@ -1,16 +1,112 @@ +require('../../helpers/setup'); +const { ZERO_ADDRESS } = require('../../helpers/constants'); +const expectEvent = require('../../helpers/expectEvent'); +const send = require('../../helpers/send'); +const shouldFail = require('../../helpers/shouldFail'); + const { shouldBehaveLikeERC721 } = require('./ERC721.behavior'); +const ERC721Mock = artifacts.require('ERC721Mock.sol'); -const BigNumber = web3.BigNumber; -const ERC721 = artifacts.require('ERC721Mock.sol'); - -require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); - -contract('ERC721', function ([_, creator, ...accounts]) { +contract('ERC721', function ([_, creator, tokenOwner, anyone, ...accounts]) { beforeEach(async function () { - this.token = await ERC721.new({ from: creator }); + this.token = await ERC721Mock.new({ from: creator }); }); shouldBehaveLikeERC721(creator, creator, accounts); + + describe('internal functions', function () { + const tokenId = 5042; + + describe('_mint(address, uint256)', function () { + it('reverts with a null destination address', async function () { + await shouldFail.reverting(this.token.mint(ZERO_ADDRESS, tokenId)); + }); + + context('with minted token', async function () { + beforeEach(async function () { + ({ logs: this.logs } = await this.token.mint(tokenOwner, tokenId)); + }); + + it('emits a Transfer event', function () { + expectEvent.inLogs(this.logs, 'Transfer', { from: ZERO_ADDRESS, to: tokenOwner, tokenId }); + }); + + it('creates the token', async function () { + (await this.token.balanceOf(tokenOwner)).should.be.bignumber.equal(1); + (await this.token.ownerOf(tokenId)).should.equal(tokenOwner); + }); + + it('reverts when adding a token id that already exists', async function () { + await shouldFail.reverting(this.token.mint(tokenOwner, tokenId)); + }); + }); + }); + + describe('_burn(address, uint256)', function () { + it('reverts when burning a non-existent token id', async function () { + await shouldFail.reverting(send.transaction(this.token, 'burn', 'address,uint256', [tokenOwner, tokenId])); + }); + + context('with minted token', function () { + beforeEach(async function () { + await this.token.mint(tokenOwner, tokenId); + }); + + it('reverts when the account is not the owner', async function () { + await shouldFail.reverting(send.transaction(this.token, 'burn', 'address,uint256', [anyone, tokenId])); + }); + + context('with burnt token', function () { + beforeEach(async function () { + ({ logs: this.logs } = + await send.transaction(this.token, 'burn', 'address,uint256', [tokenOwner, tokenId])); + }); + + it('emits a Transfer event', function () { + expectEvent.inLogs(this.logs, 'Transfer', { from: tokenOwner, to: ZERO_ADDRESS, tokenId }); + }); + + it('deletes the token', async function () { + (await this.token.balanceOf(tokenOwner)).should.be.bignumber.equal(0); + await shouldFail.reverting(this.token.ownerOf(tokenId)); + }); + + it('reverts when burning a token id that has been deleted', async function () { + await shouldFail.reverting(send.transaction(this.token, 'burn', 'address,uint256', [tokenOwner, tokenId])); + }); + }); + }); + }); + + describe('_burn(uint256)', function () { + it('reverts when burning a non-existent token id', async function () { + await shouldFail.reverting(send.transaction(this.token, 'burn', 'uint256', [tokenId])); + }); + + context('with minted token', function () { + beforeEach(async function () { + await this.token.mint(tokenOwner, tokenId); + }); + + context('with burnt token', function () { + beforeEach(async function () { + ({ logs: this.logs } = await send.transaction(this.token, 'burn', 'uint256', [tokenId])); + }); + + it('emits a Transfer event', function () { + expectEvent.inLogs(this.logs, 'Transfer', { from: tokenOwner, to: ZERO_ADDRESS, tokenId }); + }); + + it('deletes the token', async function () { + (await this.token.balanceOf(tokenOwner)).should.be.bignumber.equal(0); + await shouldFail.reverting(this.token.ownerOf(tokenId)); + }); + + it('reverts when burning a token id that has been deleted', async function () { + await shouldFail.reverting(send.transaction(this.token, 'burn', 'uint256', [tokenId])); + }); + }); + }); + }); + }); }); diff --git a/test/token/ERC721/ERC721Burnable.test.js b/test/token/ERC721/ERC721Burnable.test.js index a8b011b90..a75e60ff8 100644 --- a/test/token/ERC721/ERC721Burnable.test.js +++ b/test/token/ERC721/ERC721Burnable.test.js @@ -3,18 +3,15 @@ const { shouldBehaveLikeMintAndBurnERC721, } = require('./ERC721MintBurn.behavior'); -const BigNumber = web3.BigNumber; -const ERC721Burnable = artifacts.require('ERC721MintableBurnableImpl.sol'); +const ERC721BurnableImpl = artifacts.require('ERC721MintableBurnableImpl.sol'); -require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); +require('../../helpers/setup'); contract('ERC721Burnable', function ([_, creator, ...accounts]) { const minter = creator; beforeEach(async function () { - this.token = await ERC721Burnable.new({ from: creator }); + this.token = await ERC721BurnableImpl.new({ from: creator }); }); shouldBehaveLikeERC721(creator, minter, accounts); diff --git a/test/token/ERC721/ERC721Full.test.js b/test/token/ERC721/ERC721Full.test.js index ef3f67bc8..a7642184f 100644 --- a/test/token/ERC721/ERC721Full.test.js +++ b/test/token/ERC721/ERC721Full.test.js @@ -1,14 +1,10 @@ -const { assertRevert } = require('../../helpers/assertRevert'); +const shouldFail = require('../../helpers/shouldFail'); const { shouldBehaveLikeERC721 } = require('./ERC721.behavior'); const { shouldSupportInterfaces } = require('../../introspection/SupportsInterface.behavior'); -const _ = require('lodash'); -const BigNumber = web3.BigNumber; const ERC721FullMock = artifacts.require('ERC721FullMock.sol'); -require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); +require('../../helpers/setup'); contract('ERC721Full', function ([ creator, @@ -27,7 +23,6 @@ contract('ERC721Full', function ([ owner, newOwner, another, - anyone, ] = accounts; beforeEach(async function () { @@ -70,37 +65,7 @@ contract('ERC721Full', function ([ it('burns all tokens', async function () { await this.token.burn(secondTokenId, { from: owner }); (await this.token.totalSupply()).toNumber().should.be.equal(0); - await assertRevert(this.token.tokenByIndex(0)); - }); - }); - - describe('removeTokenFrom', function () { - it('reverts if the correct owner is not passed', async function () { - await assertRevert( - this.token.removeTokenFrom(anyone, firstTokenId, { from: owner }) - ); - }); - - context('once removed', function () { - beforeEach(async function () { - await this.token.removeTokenFrom(owner, firstTokenId, { from: owner }); - }); - - it('has been removed', async function () { - await assertRevert(this.token.tokenOfOwnerByIndex(owner, 1)); - }); - - it('adjusts token list', async function () { - (await this.token.tokenOfOwnerByIndex(owner, 0)).toNumber().should.be.equal(secondTokenId); - }); - - it('adjusts owner count', async function () { - (await this.token.balanceOf(owner)).toNumber().should.be.equal(1); - }); - - it('does not adjust supply', async function () { - (await this.token.totalSupply()).toNumber().should.be.equal(2); - }); + await shouldFail.reverting(this.token.tokenByIndex(0)); }); }); @@ -121,7 +86,7 @@ contract('ERC721Full', function ([ }); it('reverts when setting metadata for non existent token id', async function () { - await assertRevert(this.token.setTokenURI(nonExistentTokenId, sampleUri)); + await shouldFail.reverting(this.token.setTokenURI(nonExistentTokenId, sampleUri)); }); it('can burn token with metadata', async function () { @@ -135,7 +100,16 @@ contract('ERC721Full', function ([ }); it('reverts when querying metadata for non existent token id', async function () { - await assertRevert(this.token.tokenURI(nonExistentTokenId)); + await shouldFail.reverting(this.token.tokenURI(nonExistentTokenId)); + }); + }); + + describe('tokensOfOwner', function () { + it('returns total tokens of owner', async function () { + const tokenIds = await this.token.tokensOfOwner(owner); + tokenIds.length.should.equal(2); + tokenIds[0].should.be.bignumber.equal(firstTokenId); + tokenIds[1].should.be.bignumber.equal(secondTokenId); }); }); @@ -154,13 +128,13 @@ contract('ERC721Full', function ([ describe('when the index is greater than or equal to the total tokens owned by the given address', function () { it('reverts', async function () { - await assertRevert(this.token.tokenOfOwnerByIndex(owner, 2)); + await shouldFail.reverting(this.token.tokenOfOwnerByIndex(owner, 2)); }); }); describe('when the given address does not own any token', function () { it('reverts', async function () { - await assertRevert(this.token.tokenOfOwnerByIndex(another, 0)); + await shouldFail.reverting(this.token.tokenOfOwnerByIndex(another, 0)); }); }); @@ -172,25 +146,29 @@ contract('ERC721Full', function ([ it('returns correct token IDs for target', async function () { (await this.token.balanceOf(another)).toNumber().should.be.equal(2); - const tokensListed = await Promise.all(_.range(2).map(i => this.token.tokenOfOwnerByIndex(another, i))); + const tokensListed = await Promise.all( + [0, 1].map(i => this.token.tokenOfOwnerByIndex(another, i)) + ); tokensListed.map(t => t.toNumber()).should.have.members([firstTokenId, secondTokenId]); }); it('returns empty collection for original owner', async function () { (await this.token.balanceOf(owner)).toNumber().should.be.equal(0); - await assertRevert(this.token.tokenOfOwnerByIndex(owner, 0)); + await shouldFail.reverting(this.token.tokenOfOwnerByIndex(owner, 0)); }); }); }); describe('tokenByIndex', function () { it('should return all tokens', async function () { - const tokensListed = await Promise.all(_.range(2).map(i => this.token.tokenByIndex(i))); + const tokensListed = await Promise.all( + [0, 1].map(i => this.token.tokenByIndex(i)) + ); tokensListed.map(t => t.toNumber()).should.have.members([firstTokenId, secondTokenId]); }); it('should revert if index is greater than supply', async function () { - await assertRevert(this.token.tokenByIndex(2)); + await shouldFail.reverting(this.token.tokenByIndex(2)); }); [firstTokenId, secondTokenId].forEach(function (tokenId) { @@ -204,9 +182,10 @@ contract('ERC721Full', function ([ (await this.token.totalSupply()).toNumber().should.be.equal(3); - const tokensListed = await Promise.all(_.range(3).map(i => this.token.tokenByIndex(i))); - const expectedTokens = _.filter( - [firstTokenId, secondTokenId, newTokenId, anotherNewTokenId], + const tokensListed = await Promise.all( + [0, 1, 2].map(i => this.token.tokenByIndex(i)) + ); + const expectedTokens = [firstTokenId, secondTokenId, newTokenId, anotherNewTokenId].filter( x => (x !== tokenId) ); tokensListed.map(t => t.toNumber()).should.have.members(expectedTokens); diff --git a/test/token/ERC721/ERC721Holder.test.js b/test/token/ERC721/ERC721Holder.test.js index 9f6eb856a..1c0b0dcdf 100644 --- a/test/token/ERC721/ERC721Holder.test.js +++ b/test/token/ERC721/ERC721Holder.test.js @@ -1,8 +1,7 @@ const ERC721Holder = artifacts.require('ERC721Holder.sol'); const ERC721Mintable = artifacts.require('ERC721MintableBurnableImpl.sol'); -require('chai') - .should(); +require('../../helpers/setup'); contract('ERC721Holder', function ([creator]) { it('receives an ERC721 token', async function () { diff --git a/test/token/ERC721/ERC721MintBurn.behavior.js b/test/token/ERC721/ERC721MintBurn.behavior.js index ab54a6ae6..97c33ae36 100644 --- a/test/token/ERC721/ERC721MintBurn.behavior.js +++ b/test/token/ERC721/ERC721MintBurn.behavior.js @@ -1,10 +1,7 @@ -const { assertRevert } = require('../../helpers/assertRevert'); +const shouldFail = require('../../helpers/shouldFail'); const expectEvent = require('../../helpers/expectEvent'); -const BigNumber = web3.BigNumber; - -require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); +const { ZERO_ADDRESS } = require('../../helpers/constants'); +require('../../helpers/setup'); function shouldBehaveLikeMintAndBurnERC721 ( creator, @@ -15,7 +12,6 @@ function shouldBehaveLikeMintAndBurnERC721 ( const secondTokenId = 2; const thirdTokenId = 3; const unknownTokenId = 4; - const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; const MOCK_URI = 'https://example.com'; describe('like a mintable and burnable ERC721', function () { @@ -42,23 +38,23 @@ function shouldBehaveLikeMintAndBurnERC721 ( }); it('emits a transfer and minted event', async function () { - await expectEvent.inLogs(logs, 'Transfer', { + expectEvent.inLogs(logs, 'Transfer', { from: ZERO_ADDRESS, to: newOwner, + tokenId: thirdTokenId, }); - logs[0].args.tokenId.should.be.bignumber.equal(thirdTokenId); }); }); describe('when the given owner address is the zero address', function () { it('reverts', async function () { - await assertRevert(this.token.mint(ZERO_ADDRESS, thirdTokenId, { from: minter })); + await shouldFail.reverting(this.token.mint(ZERO_ADDRESS, thirdTokenId, { from: minter })); }); }); describe('when the given token ID was already tracked by this contract', function () { it('reverts', async function () { - await assertRevert(this.token.mint(owner, firstTokenId, { from: minter })); + await shouldFail.reverting(this.token.mint(owner, firstTokenId, { from: minter })); }); }); }); @@ -82,16 +78,16 @@ function shouldBehaveLikeMintAndBurnERC721 ( }); it('burns the given token ID and adjusts the balance of the owner', async function () { - await assertRevert(this.token.ownerOf(tokenId)); + await shouldFail.reverting(this.token.ownerOf(tokenId)); (await this.token.balanceOf(owner)).should.be.bignumber.equal(1); }); it('emits a burn event', async function () { - logs.length.should.be.equal(1); - logs[0].event.should.be.equal('Transfer'); - logs[0].args.from.should.be.equal(owner); - logs[0].args.to.should.be.equal(ZERO_ADDRESS); - logs[0].args.tokenId.should.be.bignumber.equal(tokenId); + expectEvent.inLogs(logs, 'Transfer', { + from: owner, + to: ZERO_ADDRESS, + tokenId: tokenId, + }); }); }); @@ -104,14 +100,14 @@ function shouldBehaveLikeMintAndBurnERC721 ( context('getApproved', function () { it('reverts', async function () { - await assertRevert(this.token.getApproved(tokenId)); + await shouldFail.reverting(this.token.getApproved(tokenId)); }); }); }); describe('when the given token ID was not tracked by this contract', function () { it('reverts', async function () { - await assertRevert( + await shouldFail.reverting( this.token.burn(unknownTokenId, { from: creator }) ); }); diff --git a/test/token/ERC721/ERC721Mintable.test.js b/test/token/ERC721/ERC721Mintable.test.js index 65c568643..97a129efb 100644 --- a/test/token/ERC721/ERC721Mintable.test.js +++ b/test/token/ERC721/ERC721Mintable.test.js @@ -3,18 +3,15 @@ const { shouldBehaveLikeMintAndBurnERC721, } = require('./ERC721MintBurn.behavior'); -const BigNumber = web3.BigNumber; -const ERC721Mintable = artifacts.require('ERC721MintableBurnableImpl.sol'); +const ERC721MintableImpl = artifacts.require('ERC721MintableBurnableImpl.sol'); -require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); +require('../../helpers/setup'); contract('ERC721Mintable', function ([_, creator, ...accounts]) { const minter = creator; beforeEach(async function () { - this.token = await ERC721Mintable.new({ + this.token = await ERC721MintableImpl.new({ from: creator, }); }); diff --git a/test/token/ERC721/ERC721Pausable.test.js b/test/token/ERC721/ERC721Pausable.test.js index 3724655e0..ca728001d 100644 --- a/test/token/ERC721/ERC721Pausable.test.js +++ b/test/token/ERC721/ERC721Pausable.test.js @@ -2,12 +2,9 @@ const { shouldBehaveLikeERC721PausedToken } = require('./ERC721PausedToken.behav const { shouldBehaveLikeERC721 } = require('./ERC721.behavior'); const { shouldBehaveLikePublicRole } = require('../../access/roles/PublicRole.behavior'); -const BigNumber = web3.BigNumber; -const ERC721Pausable = artifacts.require('ERC721PausableMock.sol'); +const ERC721PausableMock = artifacts.require('ERC721PausableMock.sol'); -require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); +require('../../helpers/setup'); contract('ERC721Pausable', function ([ _, @@ -18,7 +15,7 @@ contract('ERC721Pausable', function ([ ...accounts ]) { beforeEach(async function () { - this.token = await ERC721Pausable.new({ from: creator }); + this.token = await ERC721PausableMock.new({ from: creator }); }); describe('pauser role', function () { diff --git a/test/token/ERC721/ERC721PausedToken.behavior.js b/test/token/ERC721/ERC721PausedToken.behavior.js index d14e6a395..6df4b0cc4 100644 --- a/test/token/ERC721/ERC721PausedToken.behavior.js +++ b/test/token/ERC721/ERC721PausedToken.behavior.js @@ -1,17 +1,13 @@ -const { assertRevert } = require('../../helpers/assertRevert'); -const { sendTransaction } = require('../../helpers/sendTransaction'); +const shouldFail = require('../../helpers/shouldFail'); +const send = require('../../helpers/send'); +const { ZERO_ADDRESS } = require('../../helpers/constants'); -const BigNumber = web3.BigNumber; - -require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); +require('../../helpers/setup'); function shouldBehaveLikeERC721PausedToken (owner, [recipient, operator]) { const firstTokenId = 1; const mintedTokens = 1; const mockData = '0x42'; - const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; describe('like a paused ERC721', function () { beforeEach(async function () { @@ -19,24 +15,24 @@ function shouldBehaveLikeERC721PausedToken (owner, [recipient, operator]) { }); it('reverts when trying to approve', async function () { - await assertRevert(this.token.approve(recipient, firstTokenId, { from: owner })); + await shouldFail.reverting(this.token.approve(recipient, firstTokenId, { from: owner })); }); it('reverts when trying to setApprovalForAll', async function () { - await assertRevert(this.token.setApprovalForAll(operator, true, { from: owner })); + await shouldFail.reverting(this.token.setApprovalForAll(operator, true, { from: owner })); }); it('reverts when trying to transferFrom', async function () { - await assertRevert(this.token.transferFrom(owner, recipient, firstTokenId, { from: owner })); + await shouldFail.reverting(this.token.transferFrom(owner, recipient, firstTokenId, { from: owner })); }); it('reverts when trying to safeTransferFrom', async function () { - await assertRevert(this.token.safeTransferFrom(owner, recipient, firstTokenId, { from: owner })); + await shouldFail.reverting(this.token.safeTransferFrom(owner, recipient, firstTokenId, { from: owner })); }); it('reverts when trying to safeTransferFrom with data', async function () { - await assertRevert( - sendTransaction( + await shouldFail.reverting( + send.transaction( this.token, 'safeTransferFrom', 'address,address,uint256,bytes', diff --git a/test/utils/Address.test.js b/test/utils/Address.test.js new file mode 100644 index 000000000..190a5f5d8 --- /dev/null +++ b/test/utils/Address.test.js @@ -0,0 +1,19 @@ +const AddressImpl = artifacts.require('AddressImpl'); +const SimpleToken = artifacts.require('SimpleTokenMock'); + +require('../helpers/setup'); + +contract('Address', function ([_, anyone]) { + beforeEach(async function () { + this.mock = await AddressImpl.new(); + }); + + it('should return false for account address', async function () { + (await this.mock.isContract(anyone)).should.equal(false); + }); + + it('should return true for contract address', async function () { + const contract = await SimpleToken.new(); + (await this.mock.isContract(contract.address)).should.equal(true); + }); +}); diff --git a/test/utils/Arrays.test.js b/test/utils/Arrays.test.js new file mode 100644 index 000000000..1c9bfdfc0 --- /dev/null +++ b/test/utils/Arrays.test.js @@ -0,0 +1,83 @@ +const ArraysImpl = artifacts.require('ArraysImpl'); + +require('../helpers/setup'); + +contract('Arrays', function () { + context('Even number of elements', function () { + const EVEN_ELEMENTS_ARRAY = [11, 12, 13, 14, 15, 16, 17, 18, 19, 20]; + + beforeEach(async function () { + this.arrays = await ArraysImpl.new(EVEN_ELEMENTS_ARRAY); + }); + + it('should return correct index for the basic case', async function () { + (await this.arrays.findUpperBound(16)).should.be.bignumber.equal(5); + }); + + it('should return 0 for the first element', async function () { + (await this.arrays.findUpperBound(11)).should.be.bignumber.equal(0); + }); + + it('should return index of the last element', async function () { + (await this.arrays.findUpperBound(20)).should.be.bignumber.equal(9); + }); + + it('should return first index after last element if searched value is over the upper boundary', async function () { + (await this.arrays.findUpperBound(32)).should.be.bignumber.equal(10); + }); + + it('should return 0 for the element under the lower boundary', async function () { + (await this.arrays.findUpperBound(2)).should.be.bignumber.equal(0); + }); + }); + + context('Odd number of elements', function () { + const ODD_ELEMENTS_ARRAY = [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21]; + + beforeEach(async function () { + this.arrays = await ArraysImpl.new(ODD_ELEMENTS_ARRAY); + }); + + it('should return correct index for the basic case', async function () { + (await this.arrays.findUpperBound(16)).should.be.bignumber.equal(5); + }); + + it('should return 0 for the first element', async function () { + (await this.arrays.findUpperBound(11)).should.be.bignumber.equal(0); + }); + + it('should return index of the last element', async function () { + (await this.arrays.findUpperBound(21)).should.be.bignumber.equal(10); + }); + + it('should return first index after last element if searched value is over the upper boundary', async function () { + (await this.arrays.findUpperBound(32)).should.be.bignumber.equal(11); + }); + + it('should return 0 for the element under the lower boundary', async function () { + (await this.arrays.findUpperBound(2)).should.be.bignumber.equal(0); + }); + }); + + context('Array with gap', function () { + const WITH_GAP_ARRAY = [11, 12, 13, 14, 15, 20, 21, 22, 23, 24]; + + beforeEach(async function () { + this.arrays = await ArraysImpl.new(WITH_GAP_ARRAY); + }); + + it('should return index of first element in next filled range', async function () { + (await this.arrays.findUpperBound(17)).should.be.bignumber.equal(5); + }); + }); + + context('Empty array', function () { + beforeEach(async function () { + this.arrays = await ArraysImpl.new([]); + }); + + it('should always return 0 for empty array', async function () { + (await this.arrays.findUpperBound(10)).should.be.bignumber.equal(0); + }); + }); +}); diff --git a/test/ReentrancyGuard.test.js b/test/utils/ReentrancyGuard.test.js similarity index 53% rename from test/ReentrancyGuard.test.js rename to test/utils/ReentrancyGuard.test.js index 7086f8d94..c6da57a95 100644 --- a/test/ReentrancyGuard.test.js +++ b/test/utils/ReentrancyGuard.test.js @@ -1,25 +1,18 @@ -const { expectThrow } = require('./helpers/expectThrow'); +const shouldFail = require('../helpers/shouldFail'); const ReentrancyMock = artifacts.require('ReentrancyMock'); const ReentrancyAttack = artifacts.require('ReentrancyAttack'); -const BigNumber = web3.BigNumber; - -require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); +require('../helpers/setup'); contract('ReentrancyGuard', function () { - let reentrancyMock; - beforeEach(async function () { - reentrancyMock = await ReentrancyMock.new(); - const initialCounter = await reentrancyMock.counter(); - initialCounter.should.be.bignumber.equal(0); + this.reentrancyMock = await ReentrancyMock.new(); + (await this.reentrancyMock.counter()).should.be.bignumber.equal(0); }); it('should not allow remote callback', async function () { const attacker = await ReentrancyAttack.new(); - await expectThrow(reentrancyMock.countAndCall(attacker.address)); + await shouldFail.reverting(this.reentrancyMock.countAndCall(attacker.address)); }); // The following are more side-effects than intended behavior: @@ -27,10 +20,10 @@ contract('ReentrancyGuard', function () { // in the side-effects. it('should not allow local recursion', async function () { - await expectThrow(reentrancyMock.countLocalRecursive(10)); + await shouldFail.reverting(this.reentrancyMock.countLocalRecursive(10)); }); it('should not allow indirect local recursion', async function () { - await expectThrow(reentrancyMock.countThisRecursive(10)); + await shouldFail.reverting(this.reentrancyMock.countThisRecursive(10)); }); }); diff --git a/truffle-config.js b/truffle-config.js index 52708daa9..eab1846c7 100644 --- a/truffle-config.js +++ b/truffle-config.js @@ -1,19 +1,3 @@ -require('dotenv').config(); - -const HDWalletProvider = require('truffle-hdwallet-provider'); - -const providerWithMnemonic = (mnemonic, rpcEndpoint) => - new HDWalletProvider(mnemonic, rpcEndpoint); - -const infuraProvider = network => providerWithMnemonic( - process.env.MNEMONIC || '', - `https://${network}.infura.io/${process.env.INFURA_API_KEY}` -); - -const ropstenProvider = process.env.SOLIDITY_COVERAGE - ? undefined - : infuraProvider('ropsten'); - module.exports = { networks: { development: { @@ -21,10 +5,6 @@ module.exports = { port: 8545, network_id: '*', // eslint-disable-line camelcase }, - ropsten: { - provider: ropstenProvider, - network_id: 3, // eslint-disable-line camelcase - }, coverage: { host: 'localhost', network_id: '*', // eslint-disable-line camelcase @@ -32,10 +12,5 @@ module.exports = { gas: 0xfffffffffff, gasPrice: 0x01, }, - ganache: { - host: 'localhost', - port: 8545, - network_id: '*', // eslint-disable-line camelcase - }, }, };