From a3af8266db93c65f6e55b97ac18e3aa18636e426 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Venturo?= Date: Wed, 24 Apr 2019 11:35:30 -0300 Subject: [PATCH 01/26] 2.3.0-rc.0 --- ethpm.json | 2 +- package-lock.json | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ethpm.json b/ethpm.json index 255048b2a..1e9826f21 100644 --- a/ethpm.json +++ b/ethpm.json @@ -1,6 +1,6 @@ { "package_name": "zeppelin", - "version": "2.2.0", + "version": "2.3.0-rc.0", "description": "Secure Smart Contract library for Solidity", "authors": [ "OpenZeppelin Community " diff --git a/package-lock.json b/package-lock.json index 802e3ec25..fdb46f78d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "openzeppelin-solidity", - "version": "2.2.0", + "version": "2.3.0-rc.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 47930de8a..c4d02b0f2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "openzeppelin-solidity", - "version": "2.2.0", + "version": "2.3.0-rc.0", "description": "Secure Smart Contract library for Solidity", "files": [ "build", From ae919629cd58f6df60353267f468bef5a29bc052 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Venturo?= Date: Wed, 24 Apr 2019 19:32:08 -0300 Subject: [PATCH 02/26] Revert Solidity version bump. (#1729) (cherry picked from commit 67bca857eedf99bf44a4b6a0fc5b5ed553135316) --- CHANGELOG.md | 2 +- contracts/access/Roles.sol | 2 +- contracts/access/roles/CapperRole.sol | 2 +- contracts/access/roles/MinterRole.sol | 2 +- contracts/access/roles/PauserRole.sol | 2 +- contracts/access/roles/SignerRole.sol | 2 +- contracts/access/roles/WhitelistAdminRole.sol | 2 +- contracts/access/roles/WhitelistedRole.sol | 2 +- contracts/crowdsale/Crowdsale.sol | 2 +- contracts/crowdsale/distribution/FinalizableCrowdsale.sol | 2 +- contracts/crowdsale/distribution/PostDeliveryCrowdsale.sol | 2 +- contracts/crowdsale/distribution/RefundableCrowdsale.sol | 2 +- .../crowdsale/distribution/RefundablePostDeliveryCrowdsale.sol | 2 +- contracts/crowdsale/emission/AllowanceCrowdsale.sol | 2 +- contracts/crowdsale/emission/MintedCrowdsale.sol | 2 +- contracts/crowdsale/price/IncreasingPriceCrowdsale.sol | 2 +- contracts/crowdsale/validation/CappedCrowdsale.sol | 2 +- contracts/crowdsale/validation/IndividuallyCappedCrowdsale.sol | 2 +- contracts/crowdsale/validation/PausableCrowdsale.sol | 2 +- contracts/crowdsale/validation/TimedCrowdsale.sol | 2 +- contracts/crowdsale/validation/WhitelistCrowdsale.sol | 2 +- contracts/cryptography/ECDSA.sol | 2 +- contracts/cryptography/MerkleProof.sol | 2 +- contracts/drafts/Counters.sol | 2 +- contracts/drafts/ERC1046/ERC20Metadata.sol | 2 +- contracts/drafts/ERC1820Implementer.sol | 2 +- contracts/drafts/ERC20Migrator.sol | 2 +- contracts/drafts/ERC20Snapshot.sol | 2 +- contracts/drafts/ERC777/ERC777.sol | 2 +- contracts/drafts/ERC777/IERC777.sol | 2 +- contracts/drafts/ERC777/IERC777Recipient.sol | 2 +- contracts/drafts/ERC777/IERC777Sender.sol | 2 +- contracts/drafts/IERC1820Implementer.sol | 2 +- contracts/drafts/IERC1820Registry.sol | 2 +- contracts/drafts/SignatureBouncer.sol | 2 +- contracts/drafts/SignedSafeMath.sol | 2 +- contracts/drafts/TokenVesting.sol | 2 +- contracts/examples/SampleCrowdsale.sol | 2 +- contracts/examples/SimpleToken.sol | 2 +- contracts/introspection/ERC165.sol | 2 +- contracts/introspection/ERC165Checker.sol | 2 +- contracts/introspection/IERC165.sol | 2 +- contracts/lifecycle/Pausable.sol | 2 +- contracts/math/Math.sol | 2 +- contracts/math/SafeMath.sol | 2 +- contracts/mocks/AddressImpl.sol | 2 +- contracts/mocks/AllowanceCrowdsaleImpl.sol | 2 +- contracts/mocks/ArraysImpl.sol | 2 +- contracts/mocks/CappedCrowdsaleImpl.sol | 2 +- contracts/mocks/CapperRoleMock.sol | 2 +- contracts/mocks/ConditionalEscrowMock.sol | 2 +- contracts/mocks/CountersImpl.sol | 2 +- contracts/mocks/CrowdsaleMock.sol | 2 +- contracts/mocks/ECDSAMock.sol | 2 +- contracts/mocks/ERC165/ERC165InterfacesSupported.sol | 2 +- contracts/mocks/ERC165/ERC165NotSupported.sol | 2 +- contracts/mocks/ERC165CheckerMock.sol | 2 +- contracts/mocks/ERC165Mock.sol | 2 +- contracts/mocks/ERC1820ImplementerMock.sol | 2 +- contracts/mocks/ERC20BurnableMock.sol | 2 +- contracts/mocks/ERC20DetailedMock.sol | 2 +- contracts/mocks/ERC20MetadataMock.sol | 2 +- contracts/mocks/ERC20MintableMock.sol | 2 +- contracts/mocks/ERC20Mock.sol | 2 +- contracts/mocks/ERC20PausableMock.sol | 2 +- contracts/mocks/ERC20SnapshotMock.sol | 2 +- contracts/mocks/ERC721FullMock.sol | 2 +- contracts/mocks/ERC721MintableBurnableImpl.sol | 2 +- contracts/mocks/ERC721Mock.sol | 2 +- contracts/mocks/ERC721PausableMock.sol | 2 +- contracts/mocks/ERC721ReceiverMock.sol | 2 +- contracts/mocks/ERC777Mock.sol | 2 +- contracts/mocks/ERC777SenderRecipientMock.sol | 2 +- contracts/mocks/FinalizableCrowdsaleImpl.sol | 2 +- contracts/mocks/IncreasingPriceCrowdsaleImpl.sol | 2 +- contracts/mocks/IndividuallyCappedCrowdsaleImpl.sol | 2 +- contracts/mocks/MathMock.sol | 2 +- contracts/mocks/MerkleProofWrapper.sol | 2 +- contracts/mocks/MintedCrowdsaleImpl.sol | 2 +- contracts/mocks/MinterRoleMock.sol | 2 +- contracts/mocks/OwnableInterfaceId.sol | 2 +- contracts/mocks/OwnableMock.sol | 2 +- contracts/mocks/PausableCrowdsaleImpl.sol | 2 +- contracts/mocks/PausableMock.sol | 2 +- contracts/mocks/PauserRoleMock.sol | 2 +- contracts/mocks/PostDeliveryCrowdsaleImpl.sol | 2 +- contracts/mocks/PullPaymentMock.sol | 2 +- contracts/mocks/ReentrancyAttack.sol | 2 +- contracts/mocks/ReentrancyMock.sol | 2 +- contracts/mocks/RefundableCrowdsaleImpl.sol | 2 +- contracts/mocks/RefundablePostDeliveryCrowdsaleImpl.sol | 2 +- contracts/mocks/RolesMock.sol | 2 +- contracts/mocks/SafeERC20Helper.sol | 2 +- contracts/mocks/SafeMathMock.sol | 2 +- contracts/mocks/SecondaryMock.sol | 2 +- contracts/mocks/SignatureBouncerMock.sol | 2 +- contracts/mocks/SignedSafeMathMock.sol | 2 +- contracts/mocks/SignerRoleMock.sol | 2 +- contracts/mocks/TimedCrowdsaleImpl.sol | 2 +- contracts/mocks/WhitelistAdminRoleMock.sol | 2 +- contracts/mocks/WhitelistCrowdsaleImpl.sol | 2 +- contracts/mocks/WhitelistedRoleMock.sol | 2 +- contracts/ownership/Ownable.sol | 2 +- contracts/ownership/Secondary.sol | 2 +- contracts/payment/PaymentSplitter.sol | 2 +- contracts/payment/PullPayment.sol | 2 +- contracts/payment/escrow/ConditionalEscrow.sol | 2 +- contracts/payment/escrow/Escrow.sol | 2 +- contracts/payment/escrow/RefundEscrow.sol | 2 +- contracts/token/ERC20/ERC20.sol | 2 +- contracts/token/ERC20/ERC20Burnable.sol | 2 +- contracts/token/ERC20/ERC20Capped.sol | 2 +- contracts/token/ERC20/ERC20Detailed.sol | 2 +- contracts/token/ERC20/ERC20Mintable.sol | 2 +- contracts/token/ERC20/ERC20Pausable.sol | 2 +- contracts/token/ERC20/IERC20.sol | 2 +- contracts/token/ERC20/SafeERC20.sol | 2 +- contracts/token/ERC20/TokenTimelock.sol | 2 +- contracts/token/ERC721/ERC721.sol | 2 +- contracts/token/ERC721/ERC721Burnable.sol | 2 +- contracts/token/ERC721/ERC721Enumerable.sol | 2 +- contracts/token/ERC721/ERC721Full.sol | 2 +- contracts/token/ERC721/ERC721Holder.sol | 2 +- contracts/token/ERC721/ERC721Metadata.sol | 2 +- contracts/token/ERC721/ERC721MetadataMintable.sol | 2 +- contracts/token/ERC721/ERC721Mintable.sol | 2 +- contracts/token/ERC721/ERC721Pausable.sol | 2 +- contracts/token/ERC721/IERC721.sol | 2 +- contracts/token/ERC721/IERC721Enumerable.sol | 2 +- contracts/token/ERC721/IERC721Full.sol | 2 +- contracts/token/ERC721/IERC721Metadata.sol | 2 +- contracts/token/ERC721/IERC721Receiver.sol | 2 +- contracts/utils/Address.sol | 2 +- contracts/utils/Arrays.sol | 2 +- contracts/utils/ReentrancyGuard.sol | 2 +- 135 files changed, 135 insertions(+), 135 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ea469475..c5e753085 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ * All contracts now have revert reason strings, which give insight into error conditions, and help debug failing transactions. ([#1704](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1704)) ### Improvements: - * Upgraded the minimum compiler version to v0.5.7: this prevents users from encountering compiler bugs that were fixed in this version. ([#1724](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1724)) + * Reverted the Solidity version bump done in v2.2.0, setting the minimum compiler version to v0.5.0, to prevent unexpected build breakage. Users are encouraged however to stay on top of new compiler releases, which usually include bugfixes. ([#1728](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1728)) ### Bugfixes: * `PostDeliveryCrowdsale`: some validations where skipped when paired with other crowdsale flavors, such as `AllowanceCrowdsale`, or `MintableCrowdsale` and `ERC20Capped`, which could cause buyers to not be able to claim their purchased tokens. ([#1721](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1721)) diff --git a/contracts/access/Roles.sol b/contracts/access/Roles.sol index 25da77e28..5f3eff6ae 100644 --- a/contracts/access/Roles.sol +++ b/contracts/access/Roles.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; /** * @title Roles diff --git a/contracts/access/roles/CapperRole.sol b/contracts/access/roles/CapperRole.sol index 527097d8b..7c1af8a8c 100644 --- a/contracts/access/roles/CapperRole.sol +++ b/contracts/access/roles/CapperRole.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../Roles.sol"; diff --git a/contracts/access/roles/MinterRole.sol b/contracts/access/roles/MinterRole.sol index fd44a7fb7..a84367cf3 100644 --- a/contracts/access/roles/MinterRole.sol +++ b/contracts/access/roles/MinterRole.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../Roles.sol"; diff --git a/contracts/access/roles/PauserRole.sol b/contracts/access/roles/PauserRole.sol index 1f94c3908..f149139aa 100644 --- a/contracts/access/roles/PauserRole.sol +++ b/contracts/access/roles/PauserRole.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../Roles.sol"; diff --git a/contracts/access/roles/SignerRole.sol b/contracts/access/roles/SignerRole.sol index 0e5e4425d..468d0aef1 100644 --- a/contracts/access/roles/SignerRole.sol +++ b/contracts/access/roles/SignerRole.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../Roles.sol"; diff --git a/contracts/access/roles/WhitelistAdminRole.sol b/contracts/access/roles/WhitelistAdminRole.sol index d7283cbc0..8c16928fe 100644 --- a/contracts/access/roles/WhitelistAdminRole.sol +++ b/contracts/access/roles/WhitelistAdminRole.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../Roles.sol"; diff --git a/contracts/access/roles/WhitelistedRole.sol b/contracts/access/roles/WhitelistedRole.sol index cca313794..326d3343a 100644 --- a/contracts/access/roles/WhitelistedRole.sol +++ b/contracts/access/roles/WhitelistedRole.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../Roles.sol"; import "./WhitelistAdminRole.sol"; diff --git a/contracts/crowdsale/Crowdsale.sol b/contracts/crowdsale/Crowdsale.sol index e9857ab56..824ba83cf 100644 --- a/contracts/crowdsale/Crowdsale.sol +++ b/contracts/crowdsale/Crowdsale.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../token/ERC20/IERC20.sol"; import "../math/SafeMath.sol"; diff --git a/contracts/crowdsale/distribution/FinalizableCrowdsale.sol b/contracts/crowdsale/distribution/FinalizableCrowdsale.sol index a3c3fdd2a..9c42e6146 100644 --- a/contracts/crowdsale/distribution/FinalizableCrowdsale.sol +++ b/contracts/crowdsale/distribution/FinalizableCrowdsale.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../../math/SafeMath.sol"; import "../validation/TimedCrowdsale.sol"; diff --git a/contracts/crowdsale/distribution/PostDeliveryCrowdsale.sol b/contracts/crowdsale/distribution/PostDeliveryCrowdsale.sol index c10677545..41b9059b7 100644 --- a/contracts/crowdsale/distribution/PostDeliveryCrowdsale.sol +++ b/contracts/crowdsale/distribution/PostDeliveryCrowdsale.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../validation/TimedCrowdsale.sol"; import "../../math/SafeMath.sol"; diff --git a/contracts/crowdsale/distribution/RefundableCrowdsale.sol b/contracts/crowdsale/distribution/RefundableCrowdsale.sol index e6af3b69d..7502f69bf 100644 --- a/contracts/crowdsale/distribution/RefundableCrowdsale.sol +++ b/contracts/crowdsale/distribution/RefundableCrowdsale.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../../math/SafeMath.sol"; import "./FinalizableCrowdsale.sol"; diff --git a/contracts/crowdsale/distribution/RefundablePostDeliveryCrowdsale.sol b/contracts/crowdsale/distribution/RefundablePostDeliveryCrowdsale.sol index 7fcd68565..385aa195c 100644 --- a/contracts/crowdsale/distribution/RefundablePostDeliveryCrowdsale.sol +++ b/contracts/crowdsale/distribution/RefundablePostDeliveryCrowdsale.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "./RefundableCrowdsale.sol"; import "./PostDeliveryCrowdsale.sol"; diff --git a/contracts/crowdsale/emission/AllowanceCrowdsale.sol b/contracts/crowdsale/emission/AllowanceCrowdsale.sol index cc9eaff68..beee692a6 100644 --- a/contracts/crowdsale/emission/AllowanceCrowdsale.sol +++ b/contracts/crowdsale/emission/AllowanceCrowdsale.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../Crowdsale.sol"; import "../../token/ERC20/IERC20.sol"; diff --git a/contracts/crowdsale/emission/MintedCrowdsale.sol b/contracts/crowdsale/emission/MintedCrowdsale.sol index fe4567154..7815b8cac 100644 --- a/contracts/crowdsale/emission/MintedCrowdsale.sol +++ b/contracts/crowdsale/emission/MintedCrowdsale.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../Crowdsale.sol"; import "../../token/ERC20/ERC20Mintable.sol"; diff --git a/contracts/crowdsale/price/IncreasingPriceCrowdsale.sol b/contracts/crowdsale/price/IncreasingPriceCrowdsale.sol index 75834b7f1..964514ba2 100644 --- a/contracts/crowdsale/price/IncreasingPriceCrowdsale.sol +++ b/contracts/crowdsale/price/IncreasingPriceCrowdsale.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../validation/TimedCrowdsale.sol"; import "../../math/SafeMath.sol"; diff --git a/contracts/crowdsale/validation/CappedCrowdsale.sol b/contracts/crowdsale/validation/CappedCrowdsale.sol index 44293d48b..e8aeede14 100644 --- a/contracts/crowdsale/validation/CappedCrowdsale.sol +++ b/contracts/crowdsale/validation/CappedCrowdsale.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../../math/SafeMath.sol"; import "../Crowdsale.sol"; diff --git a/contracts/crowdsale/validation/IndividuallyCappedCrowdsale.sol b/contracts/crowdsale/validation/IndividuallyCappedCrowdsale.sol index 8dbcd0ee4..1f9df361d 100644 --- a/contracts/crowdsale/validation/IndividuallyCappedCrowdsale.sol +++ b/contracts/crowdsale/validation/IndividuallyCappedCrowdsale.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../../math/SafeMath.sol"; import "../Crowdsale.sol"; diff --git a/contracts/crowdsale/validation/PausableCrowdsale.sol b/contracts/crowdsale/validation/PausableCrowdsale.sol index 673684e0d..cc89aebab 100644 --- a/contracts/crowdsale/validation/PausableCrowdsale.sol +++ b/contracts/crowdsale/validation/PausableCrowdsale.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../Crowdsale.sol"; import "../../lifecycle/Pausable.sol"; diff --git a/contracts/crowdsale/validation/TimedCrowdsale.sol b/contracts/crowdsale/validation/TimedCrowdsale.sol index a88548619..255a63f34 100644 --- a/contracts/crowdsale/validation/TimedCrowdsale.sol +++ b/contracts/crowdsale/validation/TimedCrowdsale.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../../math/SafeMath.sol"; import "../Crowdsale.sol"; diff --git a/contracts/crowdsale/validation/WhitelistCrowdsale.sol b/contracts/crowdsale/validation/WhitelistCrowdsale.sol index 8cdd478a4..0f5965352 100644 --- a/contracts/crowdsale/validation/WhitelistCrowdsale.sol +++ b/contracts/crowdsale/validation/WhitelistCrowdsale.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../Crowdsale.sol"; import "../../access/roles/WhitelistedRole.sol"; diff --git a/contracts/cryptography/ECDSA.sol b/contracts/cryptography/ECDSA.sol index eca3dfa95..c54fe6a56 100644 --- a/contracts/cryptography/ECDSA.sol +++ b/contracts/cryptography/ECDSA.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; /** * @title Elliptic curve signature operations diff --git a/contracts/cryptography/MerkleProof.sol b/contracts/cryptography/MerkleProof.sol index 702916c72..2a964c8ba 100644 --- a/contracts/cryptography/MerkleProof.sol +++ b/contracts/cryptography/MerkleProof.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; /** * @title MerkleProof diff --git a/contracts/drafts/Counters.sol b/contracts/drafts/Counters.sol index 0ebf221e2..2d4db92b8 100644 --- a/contracts/drafts/Counters.sol +++ b/contracts/drafts/Counters.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../math/SafeMath.sol"; diff --git a/contracts/drafts/ERC1046/ERC20Metadata.sol b/contracts/drafts/ERC1046/ERC20Metadata.sol index 0960dc683..b42181650 100644 --- a/contracts/drafts/ERC1046/ERC20Metadata.sol +++ b/contracts/drafts/ERC1046/ERC20Metadata.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../../token/ERC20/IERC20.sol"; diff --git a/contracts/drafts/ERC1820Implementer.sol b/contracts/drafts/ERC1820Implementer.sol index a0e7abfe6..48746a7ce 100644 --- a/contracts/drafts/ERC1820Implementer.sol +++ b/contracts/drafts/ERC1820Implementer.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "./IERC1820Implementer.sol"; diff --git a/contracts/drafts/ERC20Migrator.sol b/contracts/drafts/ERC20Migrator.sol index f0daf9087..9c6a65d65 100644 --- a/contracts/drafts/ERC20Migrator.sol +++ b/contracts/drafts/ERC20Migrator.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../token/ERC20/IERC20.sol"; import "../token/ERC20/ERC20Mintable.sol"; diff --git a/contracts/drafts/ERC20Snapshot.sol b/contracts/drafts/ERC20Snapshot.sol index f226a2037..597fd2fbf 100644 --- a/contracts/drafts/ERC20Snapshot.sol +++ b/contracts/drafts/ERC20Snapshot.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../math/SafeMath.sol"; import "../utils/Arrays.sol"; diff --git a/contracts/drafts/ERC777/ERC777.sol b/contracts/drafts/ERC777/ERC777.sol index a56a91266..80609666b 100644 --- a/contracts/drafts/ERC777/ERC777.sol +++ b/contracts/drafts/ERC777/ERC777.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "./IERC777.sol"; import "./IERC777Recipient.sol"; diff --git a/contracts/drafts/ERC777/IERC777.sol b/contracts/drafts/ERC777/IERC777.sol index 29778c08d..1f85d22ce 100644 --- a/contracts/drafts/ERC777/IERC777.sol +++ b/contracts/drafts/ERC777/IERC777.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; /** * @title ERC777 token interface diff --git a/contracts/drafts/ERC777/IERC777Recipient.sol b/contracts/drafts/ERC777/IERC777Recipient.sol index 752c96fe7..01429c2af 100644 --- a/contracts/drafts/ERC777/IERC777Recipient.sol +++ b/contracts/drafts/ERC777/IERC777Recipient.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; /** * @title ERC777 token recipient interface diff --git a/contracts/drafts/ERC777/IERC777Sender.sol b/contracts/drafts/ERC777/IERC777Sender.sol index 89ae7e3e6..d9a8421a9 100644 --- a/contracts/drafts/ERC777/IERC777Sender.sol +++ b/contracts/drafts/ERC777/IERC777Sender.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; /** * @title ERC777 token sender interface diff --git a/contracts/drafts/IERC1820Implementer.sol b/contracts/drafts/IERC1820Implementer.sol index 234c76989..eb4e7eaea 100644 --- a/contracts/drafts/IERC1820Implementer.sol +++ b/contracts/drafts/IERC1820Implementer.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; /** * @title IERC1820Implementer diff --git a/contracts/drafts/IERC1820Registry.sol b/contracts/drafts/IERC1820Registry.sol index c07e34b14..a979f79d9 100644 --- a/contracts/drafts/IERC1820Registry.sol +++ b/contracts/drafts/IERC1820Registry.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; /** * @title ERC1820 Pseudo-introspection Registry Contract diff --git a/contracts/drafts/SignatureBouncer.sol b/contracts/drafts/SignatureBouncer.sol index 5564e117b..b3c9304f6 100644 --- a/contracts/drafts/SignatureBouncer.sol +++ b/contracts/drafts/SignatureBouncer.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../access/roles/SignerRole.sol"; import "../cryptography/ECDSA.sol"; diff --git a/contracts/drafts/SignedSafeMath.sol b/contracts/drafts/SignedSafeMath.sol index 808bd563e..95a68df0a 100644 --- a/contracts/drafts/SignedSafeMath.sol +++ b/contracts/drafts/SignedSafeMath.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; /** * @title SignedSafeMath diff --git a/contracts/drafts/TokenVesting.sol b/contracts/drafts/TokenVesting.sol index 951895d5e..626db459d 100644 --- a/contracts/drafts/TokenVesting.sol +++ b/contracts/drafts/TokenVesting.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../token/ERC20/SafeERC20.sol"; import "../ownership/Ownable.sol"; diff --git a/contracts/examples/SampleCrowdsale.sol b/contracts/examples/SampleCrowdsale.sol index 1d8d65ee5..fefed16fc 100644 --- a/contracts/examples/SampleCrowdsale.sol +++ b/contracts/examples/SampleCrowdsale.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../crowdsale/validation/CappedCrowdsale.sol"; import "../crowdsale/distribution/RefundableCrowdsale.sol"; diff --git a/contracts/examples/SimpleToken.sol b/contracts/examples/SimpleToken.sol index f5e59a4b5..50a4f433f 100644 --- a/contracts/examples/SimpleToken.sol +++ b/contracts/examples/SimpleToken.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../token/ERC20/ERC20.sol"; import "../token/ERC20/ERC20Detailed.sol"; diff --git a/contracts/introspection/ERC165.sol b/contracts/introspection/ERC165.sol index 4765f83fa..05feab5bc 100644 --- a/contracts/introspection/ERC165.sol +++ b/contracts/introspection/ERC165.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "./IERC165.sol"; diff --git a/contracts/introspection/ERC165Checker.sol b/contracts/introspection/ERC165Checker.sol index 1dea5cb27..a569b46c5 100644 --- a/contracts/introspection/ERC165Checker.sol +++ b/contracts/introspection/ERC165Checker.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; /** * @title ERC165Checker diff --git a/contracts/introspection/IERC165.sol b/contracts/introspection/IERC165.sol index 373058db6..c5e90e6a1 100644 --- a/contracts/introspection/IERC165.sol +++ b/contracts/introspection/IERC165.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; /** * @title IERC165 diff --git a/contracts/lifecycle/Pausable.sol b/contracts/lifecycle/Pausable.sol index 8cbb3e8cd..f9656f8ef 100644 --- a/contracts/lifecycle/Pausable.sol +++ b/contracts/lifecycle/Pausable.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../access/roles/PauserRole.sol"; diff --git a/contracts/math/Math.sol b/contracts/math/Math.sol index 9a9e4cb2a..f50e874c1 100644 --- a/contracts/math/Math.sol +++ b/contracts/math/Math.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; /** * @title Math diff --git a/contracts/math/SafeMath.sol b/contracts/math/SafeMath.sol index 8e5d7bd6f..56076405f 100644 --- a/contracts/math/SafeMath.sol +++ b/contracts/math/SafeMath.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; /** * @title SafeMath diff --git a/contracts/mocks/AddressImpl.sol b/contracts/mocks/AddressImpl.sol index 07fd1c066..a73591c37 100644 --- a/contracts/mocks/AddressImpl.sol +++ b/contracts/mocks/AddressImpl.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../utils/Address.sol"; diff --git a/contracts/mocks/AllowanceCrowdsaleImpl.sol b/contracts/mocks/AllowanceCrowdsaleImpl.sol index 97d8b5200..9c6fdb511 100644 --- a/contracts/mocks/AllowanceCrowdsaleImpl.sol +++ b/contracts/mocks/AllowanceCrowdsaleImpl.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../token/ERC20/IERC20.sol"; import "../crowdsale/emission/AllowanceCrowdsale.sol"; diff --git a/contracts/mocks/ArraysImpl.sol b/contracts/mocks/ArraysImpl.sol index ab3ff72cb..b2067526d 100644 --- a/contracts/mocks/ArraysImpl.sol +++ b/contracts/mocks/ArraysImpl.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../utils/Arrays.sol"; diff --git a/contracts/mocks/CappedCrowdsaleImpl.sol b/contracts/mocks/CappedCrowdsaleImpl.sol index 1f62fe10f..d0c59db4c 100644 --- a/contracts/mocks/CappedCrowdsaleImpl.sol +++ b/contracts/mocks/CappedCrowdsaleImpl.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../token/ERC20/IERC20.sol"; import "../crowdsale/validation/CappedCrowdsale.sol"; diff --git a/contracts/mocks/CapperRoleMock.sol b/contracts/mocks/CapperRoleMock.sol index 5189d7ab9..0090d1ff6 100644 --- a/contracts/mocks/CapperRoleMock.sol +++ b/contracts/mocks/CapperRoleMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../access/roles/CapperRole.sol"; diff --git a/contracts/mocks/ConditionalEscrowMock.sol b/contracts/mocks/ConditionalEscrowMock.sol index 1dcbab927..4b39ba386 100644 --- a/contracts/mocks/ConditionalEscrowMock.sol +++ b/contracts/mocks/ConditionalEscrowMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../payment/escrow/ConditionalEscrow.sol"; diff --git a/contracts/mocks/CountersImpl.sol b/contracts/mocks/CountersImpl.sol index ef4a7392b..cc53139f7 100644 --- a/contracts/mocks/CountersImpl.sol +++ b/contracts/mocks/CountersImpl.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../drafts/Counters.sol"; diff --git a/contracts/mocks/CrowdsaleMock.sol b/contracts/mocks/CrowdsaleMock.sol index d3f955d32..6dafa4b7e 100644 --- a/contracts/mocks/CrowdsaleMock.sol +++ b/contracts/mocks/CrowdsaleMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../crowdsale/Crowdsale.sol"; diff --git a/contracts/mocks/ECDSAMock.sol b/contracts/mocks/ECDSAMock.sol index babec0f8c..977f324ac 100644 --- a/contracts/mocks/ECDSAMock.sol +++ b/contracts/mocks/ECDSAMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../cryptography/ECDSA.sol"; diff --git a/contracts/mocks/ERC165/ERC165InterfacesSupported.sol b/contracts/mocks/ERC165/ERC165InterfacesSupported.sol index 40c74b020..ab4d5a5df 100644 --- a/contracts/mocks/ERC165/ERC165InterfacesSupported.sol +++ b/contracts/mocks/ERC165/ERC165InterfacesSupported.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../../introspection/IERC165.sol"; diff --git a/contracts/mocks/ERC165/ERC165NotSupported.sol b/contracts/mocks/ERC165/ERC165NotSupported.sol index 833c2ad9b..d154da33e 100644 --- a/contracts/mocks/ERC165/ERC165NotSupported.sol +++ b/contracts/mocks/ERC165/ERC165NotSupported.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +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 fb64c72a1..db1853de0 100644 --- a/contracts/mocks/ERC165CheckerMock.sol +++ b/contracts/mocks/ERC165CheckerMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../introspection/ERC165Checker.sol"; diff --git a/contracts/mocks/ERC165Mock.sol b/contracts/mocks/ERC165Mock.sol index b6adec9ca..e21581b52 100644 --- a/contracts/mocks/ERC165Mock.sol +++ b/contracts/mocks/ERC165Mock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../introspection/ERC165.sol"; diff --git a/contracts/mocks/ERC1820ImplementerMock.sol b/contracts/mocks/ERC1820ImplementerMock.sol index 50996ea3c..94f1db951 100644 --- a/contracts/mocks/ERC1820ImplementerMock.sol +++ b/contracts/mocks/ERC1820ImplementerMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../drafts/ERC1820Implementer.sol"; diff --git a/contracts/mocks/ERC20BurnableMock.sol b/contracts/mocks/ERC20BurnableMock.sol index 37e771bb6..20db0b9a4 100644 --- a/contracts/mocks/ERC20BurnableMock.sol +++ b/contracts/mocks/ERC20BurnableMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../token/ERC20/ERC20Burnable.sol"; diff --git a/contracts/mocks/ERC20DetailedMock.sol b/contracts/mocks/ERC20DetailedMock.sol index 469fd4c28..f2761b348 100644 --- a/contracts/mocks/ERC20DetailedMock.sol +++ b/contracts/mocks/ERC20DetailedMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../token/ERC20/ERC20.sol"; import "../token/ERC20/ERC20Detailed.sol"; diff --git a/contracts/mocks/ERC20MetadataMock.sol b/contracts/mocks/ERC20MetadataMock.sol index 9bae3c70b..9807cc4ae 100644 --- a/contracts/mocks/ERC20MetadataMock.sol +++ b/contracts/mocks/ERC20MetadataMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../token/ERC20/ERC20.sol"; import "../drafts/ERC1046/ERC20Metadata.sol"; diff --git a/contracts/mocks/ERC20MintableMock.sol b/contracts/mocks/ERC20MintableMock.sol index 34a57d2f6..3ea65ef62 100644 --- a/contracts/mocks/ERC20MintableMock.sol +++ b/contracts/mocks/ERC20MintableMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../token/ERC20/ERC20Mintable.sol"; import "./MinterRoleMock.sol"; diff --git a/contracts/mocks/ERC20Mock.sol b/contracts/mocks/ERC20Mock.sol index eb5c0112b..b5ed2fc7e 100644 --- a/contracts/mocks/ERC20Mock.sol +++ b/contracts/mocks/ERC20Mock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../token/ERC20/ERC20.sol"; diff --git a/contracts/mocks/ERC20PausableMock.sol b/contracts/mocks/ERC20PausableMock.sol index db7f8b348..4c9cdb7f8 100644 --- a/contracts/mocks/ERC20PausableMock.sol +++ b/contracts/mocks/ERC20PausableMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../token/ERC20/ERC20Pausable.sol"; import "./PauserRoleMock.sol"; diff --git a/contracts/mocks/ERC20SnapshotMock.sol b/contracts/mocks/ERC20SnapshotMock.sol index e0f9668fd..a877a9209 100644 --- a/contracts/mocks/ERC20SnapshotMock.sol +++ b/contracts/mocks/ERC20SnapshotMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../drafts/ERC20Snapshot.sol"; diff --git a/contracts/mocks/ERC721FullMock.sol b/contracts/mocks/ERC721FullMock.sol index 8a41ab329..b0f00918b 100644 --- a/contracts/mocks/ERC721FullMock.sol +++ b/contracts/mocks/ERC721FullMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../token/ERC721/ERC721Full.sol"; import "../token/ERC721/ERC721Mintable.sol"; diff --git a/contracts/mocks/ERC721MintableBurnableImpl.sol b/contracts/mocks/ERC721MintableBurnableImpl.sol index 6fe33a123..fcb692723 100644 --- a/contracts/mocks/ERC721MintableBurnableImpl.sol +++ b/contracts/mocks/ERC721MintableBurnableImpl.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../token/ERC721/ERC721Full.sol"; import "../token/ERC721/ERC721Mintable.sol"; diff --git a/contracts/mocks/ERC721Mock.sol b/contracts/mocks/ERC721Mock.sol index ded7b0f7b..b02df5d21 100644 --- a/contracts/mocks/ERC721Mock.sol +++ b/contracts/mocks/ERC721Mock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../token/ERC721/ERC721.sol"; diff --git a/contracts/mocks/ERC721PausableMock.sol b/contracts/mocks/ERC721PausableMock.sol index 1d03a5e22..f46f9e776 100644 --- a/contracts/mocks/ERC721PausableMock.sol +++ b/contracts/mocks/ERC721PausableMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../token/ERC721/ERC721Pausable.sol"; import "./PauserRoleMock.sol"; diff --git a/contracts/mocks/ERC721ReceiverMock.sol b/contracts/mocks/ERC721ReceiverMock.sol index 07f5d204b..a0932eca6 100644 --- a/contracts/mocks/ERC721ReceiverMock.sol +++ b/contracts/mocks/ERC721ReceiverMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../token/ERC721/IERC721Receiver.sol"; diff --git a/contracts/mocks/ERC777Mock.sol b/contracts/mocks/ERC777Mock.sol index 232117dd2..30657ca2e 100644 --- a/contracts/mocks/ERC777Mock.sol +++ b/contracts/mocks/ERC777Mock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../drafts/ERC777/ERC777.sol"; diff --git a/contracts/mocks/ERC777SenderRecipientMock.sol b/contracts/mocks/ERC777SenderRecipientMock.sol index 08bac0fc7..abebfc6e2 100644 --- a/contracts/mocks/ERC777SenderRecipientMock.sol +++ b/contracts/mocks/ERC777SenderRecipientMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../drafts/ERC777/IERC777.sol"; import "../drafts/ERC777/IERC777Sender.sol"; diff --git a/contracts/mocks/FinalizableCrowdsaleImpl.sol b/contracts/mocks/FinalizableCrowdsaleImpl.sol index 204c58507..99f7a255d 100644 --- a/contracts/mocks/FinalizableCrowdsaleImpl.sol +++ b/contracts/mocks/FinalizableCrowdsaleImpl.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../token/ERC20/IERC20.sol"; import "../crowdsale/distribution/FinalizableCrowdsale.sol"; diff --git a/contracts/mocks/IncreasingPriceCrowdsaleImpl.sol b/contracts/mocks/IncreasingPriceCrowdsaleImpl.sol index 5b43e40b2..c5b0e7957 100644 --- a/contracts/mocks/IncreasingPriceCrowdsaleImpl.sol +++ b/contracts/mocks/IncreasingPriceCrowdsaleImpl.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../crowdsale/price/IncreasingPriceCrowdsale.sol"; import "../math/SafeMath.sol"; diff --git a/contracts/mocks/IndividuallyCappedCrowdsaleImpl.sol b/contracts/mocks/IndividuallyCappedCrowdsaleImpl.sol index 0f531971d..43b0366ee 100644 --- a/contracts/mocks/IndividuallyCappedCrowdsaleImpl.sol +++ b/contracts/mocks/IndividuallyCappedCrowdsaleImpl.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../token/ERC20/IERC20.sol"; import "../crowdsale/validation/IndividuallyCappedCrowdsale.sol"; diff --git a/contracts/mocks/MathMock.sol b/contracts/mocks/MathMock.sol index 869a2c5c2..2461fe902 100644 --- a/contracts/mocks/MathMock.sol +++ b/contracts/mocks/MathMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../math/Math.sol"; diff --git a/contracts/mocks/MerkleProofWrapper.sol b/contracts/mocks/MerkleProofWrapper.sol index 8b09affd7..23c72b269 100644 --- a/contracts/mocks/MerkleProofWrapper.sol +++ b/contracts/mocks/MerkleProofWrapper.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import { MerkleProof } from "../cryptography/MerkleProof.sol"; diff --git a/contracts/mocks/MintedCrowdsaleImpl.sol b/contracts/mocks/MintedCrowdsaleImpl.sol index f0465b3a6..22f4d36c0 100644 --- a/contracts/mocks/MintedCrowdsaleImpl.sol +++ b/contracts/mocks/MintedCrowdsaleImpl.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../token/ERC20/ERC20Mintable.sol"; import "../crowdsale/emission/MintedCrowdsale.sol"; diff --git a/contracts/mocks/MinterRoleMock.sol b/contracts/mocks/MinterRoleMock.sol index 55f060880..4b0401d87 100644 --- a/contracts/mocks/MinterRoleMock.sol +++ b/contracts/mocks/MinterRoleMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../access/roles/MinterRole.sol"; diff --git a/contracts/mocks/OwnableInterfaceId.sol b/contracts/mocks/OwnableInterfaceId.sol index 49b56382b..996ab88e9 100644 --- a/contracts/mocks/OwnableInterfaceId.sol +++ b/contracts/mocks/OwnableInterfaceId.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../ownership/Ownable.sol"; diff --git a/contracts/mocks/OwnableMock.sol b/contracts/mocks/OwnableMock.sol index 3e0c7281e..c7b1cf5c7 100644 --- a/contracts/mocks/OwnableMock.sol +++ b/contracts/mocks/OwnableMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../ownership/Ownable.sol"; diff --git a/contracts/mocks/PausableCrowdsaleImpl.sol b/contracts/mocks/PausableCrowdsaleImpl.sol index 237ea7fd9..11f44c7b8 100644 --- a/contracts/mocks/PausableCrowdsaleImpl.sol +++ b/contracts/mocks/PausableCrowdsaleImpl.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../token/ERC20/ERC20.sol"; import "../crowdsale/validation/PausableCrowdsale.sol"; diff --git a/contracts/mocks/PausableMock.sol b/contracts/mocks/PausableMock.sol index a9e9d58df..8e9ae03d3 100644 --- a/contracts/mocks/PausableMock.sol +++ b/contracts/mocks/PausableMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../lifecycle/Pausable.sol"; import "./PauserRoleMock.sol"; diff --git a/contracts/mocks/PauserRoleMock.sol b/contracts/mocks/PauserRoleMock.sol index 67fc61019..fc2ed16d9 100644 --- a/contracts/mocks/PauserRoleMock.sol +++ b/contracts/mocks/PauserRoleMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../access/roles/PauserRole.sol"; diff --git a/contracts/mocks/PostDeliveryCrowdsaleImpl.sol b/contracts/mocks/PostDeliveryCrowdsaleImpl.sol index bbc08aef0..efb67c084 100644 --- a/contracts/mocks/PostDeliveryCrowdsaleImpl.sol +++ b/contracts/mocks/PostDeliveryCrowdsaleImpl.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../token/ERC20/IERC20.sol"; import "../crowdsale/distribution/PostDeliveryCrowdsale.sol"; diff --git a/contracts/mocks/PullPaymentMock.sol b/contracts/mocks/PullPaymentMock.sol index 9e7180f1f..1a26b6242 100644 --- a/contracts/mocks/PullPaymentMock.sol +++ b/contracts/mocks/PullPaymentMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../payment/PullPayment.sol"; diff --git a/contracts/mocks/ReentrancyAttack.sol b/contracts/mocks/ReentrancyAttack.sol index e9fbebecf..09d52a260 100644 --- a/contracts/mocks/ReentrancyAttack.sol +++ b/contracts/mocks/ReentrancyAttack.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; contract ReentrancyAttack { function callSender(bytes4 data) public { diff --git a/contracts/mocks/ReentrancyMock.sol b/contracts/mocks/ReentrancyMock.sol index 20eaa8739..50233287d 100644 --- a/contracts/mocks/ReentrancyMock.sol +++ b/contracts/mocks/ReentrancyMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../utils/ReentrancyGuard.sol"; import "./ReentrancyAttack.sol"; diff --git a/contracts/mocks/RefundableCrowdsaleImpl.sol b/contracts/mocks/RefundableCrowdsaleImpl.sol index 16da92229..5ed5d1ed5 100644 --- a/contracts/mocks/RefundableCrowdsaleImpl.sol +++ b/contracts/mocks/RefundableCrowdsaleImpl.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../token/ERC20/IERC20.sol"; import "../crowdsale/distribution/RefundableCrowdsale.sol"; diff --git a/contracts/mocks/RefundablePostDeliveryCrowdsaleImpl.sol b/contracts/mocks/RefundablePostDeliveryCrowdsaleImpl.sol index aff64e7f5..b81f0757c 100644 --- a/contracts/mocks/RefundablePostDeliveryCrowdsaleImpl.sol +++ b/contracts/mocks/RefundablePostDeliveryCrowdsaleImpl.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../token/ERC20/IERC20.sol"; import "../crowdsale/distribution/RefundablePostDeliveryCrowdsale.sol"; diff --git a/contracts/mocks/RolesMock.sol b/contracts/mocks/RolesMock.sol index ab8bf3628..4b0f0de0a 100644 --- a/contracts/mocks/RolesMock.sol +++ b/contracts/mocks/RolesMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../access/Roles.sol"; diff --git a/contracts/mocks/SafeERC20Helper.sol b/contracts/mocks/SafeERC20Helper.sol index 6d77d8030..b36dc35a7 100644 --- a/contracts/mocks/SafeERC20Helper.sol +++ b/contracts/mocks/SafeERC20Helper.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../token/ERC20/IERC20.sol"; import "../token/ERC20/SafeERC20.sol"; diff --git a/contracts/mocks/SafeMathMock.sol b/contracts/mocks/SafeMathMock.sol index abfdf3eb5..43dac5ec2 100644 --- a/contracts/mocks/SafeMathMock.sol +++ b/contracts/mocks/SafeMathMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../math/SafeMath.sol"; diff --git a/contracts/mocks/SecondaryMock.sol b/contracts/mocks/SecondaryMock.sol index 69f3a57cd..1ff45b11e 100644 --- a/contracts/mocks/SecondaryMock.sol +++ b/contracts/mocks/SecondaryMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../ownership/Secondary.sol"; diff --git a/contracts/mocks/SignatureBouncerMock.sol b/contracts/mocks/SignatureBouncerMock.sol index 6c1e17ad4..59c59b437 100644 --- a/contracts/mocks/SignatureBouncerMock.sol +++ b/contracts/mocks/SignatureBouncerMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../drafts/SignatureBouncer.sol"; import "./SignerRoleMock.sol"; diff --git a/contracts/mocks/SignedSafeMathMock.sol b/contracts/mocks/SignedSafeMathMock.sol index fe096222a..90a3ee642 100644 --- a/contracts/mocks/SignedSafeMathMock.sol +++ b/contracts/mocks/SignedSafeMathMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../drafts/SignedSafeMath.sol"; diff --git a/contracts/mocks/SignerRoleMock.sol b/contracts/mocks/SignerRoleMock.sol index 06e782b6b..71b4c792a 100644 --- a/contracts/mocks/SignerRoleMock.sol +++ b/contracts/mocks/SignerRoleMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../access/roles/SignerRole.sol"; diff --git a/contracts/mocks/TimedCrowdsaleImpl.sol b/contracts/mocks/TimedCrowdsaleImpl.sol index 7cae42acf..b85817c77 100644 --- a/contracts/mocks/TimedCrowdsaleImpl.sol +++ b/contracts/mocks/TimedCrowdsaleImpl.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../token/ERC20/IERC20.sol"; import "../crowdsale/validation/TimedCrowdsale.sol"; diff --git a/contracts/mocks/WhitelistAdminRoleMock.sol b/contracts/mocks/WhitelistAdminRoleMock.sol index 332c5acfa..7a267ca21 100644 --- a/contracts/mocks/WhitelistAdminRoleMock.sol +++ b/contracts/mocks/WhitelistAdminRoleMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../access/roles/WhitelistAdminRole.sol"; diff --git a/contracts/mocks/WhitelistCrowdsaleImpl.sol b/contracts/mocks/WhitelistCrowdsaleImpl.sol index dc02d2255..0200f7f7f 100644 --- a/contracts/mocks/WhitelistCrowdsaleImpl.sol +++ b/contracts/mocks/WhitelistCrowdsaleImpl.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../token/ERC20/IERC20.sol"; import "../crowdsale/validation/WhitelistCrowdsale.sol"; diff --git a/contracts/mocks/WhitelistedRoleMock.sol b/contracts/mocks/WhitelistedRoleMock.sol index c9b45b3fa..7f7c89412 100644 --- a/contracts/mocks/WhitelistedRoleMock.sol +++ b/contracts/mocks/WhitelistedRoleMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../access/roles/WhitelistedRole.sol"; diff --git a/contracts/ownership/Ownable.sol b/contracts/ownership/Ownable.sol index c03fa2c26..5b402cacd 100644 --- a/contracts/ownership/Ownable.sol +++ b/contracts/ownership/Ownable.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; /** * @title Ownable diff --git a/contracts/ownership/Secondary.sol b/contracts/ownership/Secondary.sol index 49784989d..d7342969d 100644 --- a/contracts/ownership/Secondary.sol +++ b/contracts/ownership/Secondary.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; /** * @title Secondary diff --git a/contracts/payment/PaymentSplitter.sol b/contracts/payment/PaymentSplitter.sol index cbf142293..706440448 100644 --- a/contracts/payment/PaymentSplitter.sol +++ b/contracts/payment/PaymentSplitter.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../math/SafeMath.sol"; diff --git a/contracts/payment/PullPayment.sol b/contracts/payment/PullPayment.sol index 0975f80d5..9e326514b 100644 --- a/contracts/payment/PullPayment.sol +++ b/contracts/payment/PullPayment.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "./escrow/Escrow.sol"; diff --git a/contracts/payment/escrow/ConditionalEscrow.sol b/contracts/payment/escrow/ConditionalEscrow.sol index 96a2a0139..0cbe8f044 100644 --- a/contracts/payment/escrow/ConditionalEscrow.sol +++ b/contracts/payment/escrow/ConditionalEscrow.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "./Escrow.sol"; diff --git a/contracts/payment/escrow/Escrow.sol b/contracts/payment/escrow/Escrow.sol index 14562e920..72da21b76 100644 --- a/contracts/payment/escrow/Escrow.sol +++ b/contracts/payment/escrow/Escrow.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../../math/SafeMath.sol"; import "../../ownership/Secondary.sol"; diff --git a/contracts/payment/escrow/RefundEscrow.sol b/contracts/payment/escrow/RefundEscrow.sol index 95e43ba3a..18d38f6bc 100644 --- a/contracts/payment/escrow/RefundEscrow.sol +++ b/contracts/payment/escrow/RefundEscrow.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "./ConditionalEscrow.sol"; diff --git a/contracts/token/ERC20/ERC20.sol b/contracts/token/ERC20/ERC20.sol index c767898e0..63c87d2f2 100644 --- a/contracts/token/ERC20/ERC20.sol +++ b/contracts/token/ERC20/ERC20.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "./IERC20.sol"; import "../../math/SafeMath.sol"; diff --git a/contracts/token/ERC20/ERC20Burnable.sol b/contracts/token/ERC20/ERC20Burnable.sol index a71aaebc1..3345d3507 100644 --- a/contracts/token/ERC20/ERC20Burnable.sol +++ b/contracts/token/ERC20/ERC20Burnable.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "./ERC20.sol"; diff --git a/contracts/token/ERC20/ERC20Capped.sol b/contracts/token/ERC20/ERC20Capped.sol index 9d44cf73b..f49300152 100644 --- a/contracts/token/ERC20/ERC20Capped.sol +++ b/contracts/token/ERC20/ERC20Capped.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "./ERC20Mintable.sol"; diff --git a/contracts/token/ERC20/ERC20Detailed.sol b/contracts/token/ERC20/ERC20Detailed.sol index 1606d4550..71c0b0159 100644 --- a/contracts/token/ERC20/ERC20Detailed.sol +++ b/contracts/token/ERC20/ERC20Detailed.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "./IERC20.sol"; diff --git a/contracts/token/ERC20/ERC20Mintable.sol b/contracts/token/ERC20/ERC20Mintable.sol index de9443309..e69df4605 100644 --- a/contracts/token/ERC20/ERC20Mintable.sol +++ b/contracts/token/ERC20/ERC20Mintable.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "./ERC20.sol"; import "../../access/roles/MinterRole.sol"; diff --git a/contracts/token/ERC20/ERC20Pausable.sol b/contracts/token/ERC20/ERC20Pausable.sol index 53b956ef9..3304cc033 100644 --- a/contracts/token/ERC20/ERC20Pausable.sol +++ b/contracts/token/ERC20/ERC20Pausable.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "./ERC20.sol"; import "../../lifecycle/Pausable.sol"; diff --git a/contracts/token/ERC20/IERC20.sol b/contracts/token/ERC20/IERC20.sol index 4bee8eb22..7c3230b96 100644 --- a/contracts/token/ERC20/IERC20.sol +++ b/contracts/token/ERC20/IERC20.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; /** * @title ERC20 interface diff --git a/contracts/token/ERC20/SafeERC20.sol b/contracts/token/ERC20/SafeERC20.sol index 3c4e032a0..63378b71b 100644 --- a/contracts/token/ERC20/SafeERC20.sol +++ b/contracts/token/ERC20/SafeERC20.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "./IERC20.sol"; import "../../math/SafeMath.sol"; diff --git a/contracts/token/ERC20/TokenTimelock.sol b/contracts/token/ERC20/TokenTimelock.sol index a03b75036..23dc2f9c3 100644 --- a/contracts/token/ERC20/TokenTimelock.sol +++ b/contracts/token/ERC20/TokenTimelock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "./SafeERC20.sol"; diff --git a/contracts/token/ERC721/ERC721.sol b/contracts/token/ERC721/ERC721.sol index 643d6706f..933a15c6d 100644 --- a/contracts/token/ERC721/ERC721.sol +++ b/contracts/token/ERC721/ERC721.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "./IERC721.sol"; import "./IERC721Receiver.sol"; diff --git a/contracts/token/ERC721/ERC721Burnable.sol b/contracts/token/ERC721/ERC721Burnable.sol index 52291eef2..562a17e8e 100644 --- a/contracts/token/ERC721/ERC721Burnable.sol +++ b/contracts/token/ERC721/ERC721Burnable.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "./ERC721.sol"; diff --git a/contracts/token/ERC721/ERC721Enumerable.sol b/contracts/token/ERC721/ERC721Enumerable.sol index 0ef5ea00f..ed987e3ab 100644 --- a/contracts/token/ERC721/ERC721Enumerable.sol +++ b/contracts/token/ERC721/ERC721Enumerable.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "./IERC721Enumerable.sol"; import "./ERC721.sol"; diff --git a/contracts/token/ERC721/ERC721Full.sol b/contracts/token/ERC721/ERC721Full.sol index 95ccff8df..308ea5265 100644 --- a/contracts/token/ERC721/ERC721Full.sol +++ b/contracts/token/ERC721/ERC721Full.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "./ERC721.sol"; import "./ERC721Enumerable.sol"; diff --git a/contracts/token/ERC721/ERC721Holder.sol b/contracts/token/ERC721/ERC721Holder.sol index 87bebfa83..bcc10d7e2 100644 --- a/contracts/token/ERC721/ERC721Holder.sol +++ b/contracts/token/ERC721/ERC721Holder.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "./IERC721Receiver.sol"; diff --git a/contracts/token/ERC721/ERC721Metadata.sol b/contracts/token/ERC721/ERC721Metadata.sol index 685505ca3..ce263ddc7 100644 --- a/contracts/token/ERC721/ERC721Metadata.sol +++ b/contracts/token/ERC721/ERC721Metadata.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "./ERC721.sol"; import "./IERC721Metadata.sol"; diff --git a/contracts/token/ERC721/ERC721MetadataMintable.sol b/contracts/token/ERC721/ERC721MetadataMintable.sol index b245f7c69..a1421d1dd 100644 --- a/contracts/token/ERC721/ERC721MetadataMintable.sol +++ b/contracts/token/ERC721/ERC721MetadataMintable.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "./ERC721Metadata.sol"; import "../../access/roles/MinterRole.sol"; diff --git a/contracts/token/ERC721/ERC721Mintable.sol b/contracts/token/ERC721/ERC721Mintable.sol index 8de0fc033..98cd7a3a8 100644 --- a/contracts/token/ERC721/ERC721Mintable.sol +++ b/contracts/token/ERC721/ERC721Mintable.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "./ERC721.sol"; import "../../access/roles/MinterRole.sol"; diff --git a/contracts/token/ERC721/ERC721Pausable.sol b/contracts/token/ERC721/ERC721Pausable.sol index 89ac5ca6a..7cfd39ae6 100644 --- a/contracts/token/ERC721/ERC721Pausable.sol +++ b/contracts/token/ERC721/ERC721Pausable.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "./ERC721.sol"; import "../../lifecycle/Pausable.sol"; diff --git a/contracts/token/ERC721/IERC721.sol b/contracts/token/ERC721/IERC721.sol index 670a8dd07..afb94028c 100644 --- a/contracts/token/ERC721/IERC721.sol +++ b/contracts/token/ERC721/IERC721.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../../introspection/IERC165.sol"; diff --git a/contracts/token/ERC721/IERC721Enumerable.sol b/contracts/token/ERC721/IERC721Enumerable.sol index ad34e77aa..4c1dfb564 100644 --- a/contracts/token/ERC721/IERC721Enumerable.sol +++ b/contracts/token/ERC721/IERC721Enumerable.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "./IERC721.sol"; diff --git a/contracts/token/ERC721/IERC721Full.sol b/contracts/token/ERC721/IERC721Full.sol index 2d15b964a..e543aefeb 100644 --- a/contracts/token/ERC721/IERC721Full.sol +++ b/contracts/token/ERC721/IERC721Full.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "./IERC721.sol"; import "./IERC721Enumerable.sol"; diff --git a/contracts/token/ERC721/IERC721Metadata.sol b/contracts/token/ERC721/IERC721Metadata.sol index 77dc23914..05835aff8 100644 --- a/contracts/token/ERC721/IERC721Metadata.sol +++ b/contracts/token/ERC721/IERC721Metadata.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "./IERC721.sol"; diff --git a/contracts/token/ERC721/IERC721Receiver.sol b/contracts/token/ERC721/IERC721Receiver.sol index 4cd43a66b..b0618c0ec 100644 --- a/contracts/token/ERC721/IERC721Receiver.sol +++ b/contracts/token/ERC721/IERC721Receiver.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; /** * @title ERC721 token receiver interface diff --git a/contracts/utils/Address.sol b/contracts/utils/Address.sol index 570b947cb..500467212 100644 --- a/contracts/utils/Address.sol +++ b/contracts/utils/Address.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; /** * Utility library of inline functions on addresses diff --git a/contracts/utils/Arrays.sol b/contracts/utils/Arrays.sol index 5337a5da9..1713faf1c 100644 --- a/contracts/utils/Arrays.sol +++ b/contracts/utils/Arrays.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; import "../math/Math.sol"; diff --git a/contracts/utils/ReentrancyGuard.sol b/contracts/utils/ReentrancyGuard.sol index 19a2b6bc8..b7d2cb43f 100644 --- a/contracts/utils/ReentrancyGuard.sol +++ b/contracts/utils/ReentrancyGuard.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity ^0.5.0; /** * @title Helps contracts guard against reentrancy attacks. From 4b2229783ddaa42f1f58f80b326c93de102c2c53 Mon Sep 17 00:00:00 2001 From: Francisco Giordano Date: Wed, 24 Apr 2019 19:35:30 -0300 Subject: [PATCH 03/26] fix pr number in changelog (cherry picked from commit af55a843e3e2d9c941712788a3e0318988f2bd06) --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c5e753085..61e9ac41b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ * All contracts now have revert reason strings, which give insight into error conditions, and help debug failing transactions. ([#1704](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1704)) ### Improvements: - * Reverted the Solidity version bump done in v2.2.0, setting the minimum compiler version to v0.5.0, to prevent unexpected build breakage. Users are encouraged however to stay on top of new compiler releases, which usually include bugfixes. ([#1728](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1728)) + * Reverted the Solidity version bump done in v2.2.0, setting the minimum compiler version to v0.5.0, to prevent unexpected build breakage. Users are encouraged however to stay on top of new compiler releases, which usually include bugfixes. ([#1729](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1729)) ### Bugfixes: * `PostDeliveryCrowdsale`: some validations where skipped when paired with other crowdsale flavors, such as `AllowanceCrowdsale`, or `MintableCrowdsale` and `ERC20Capped`, which could cause buyers to not be able to claim their purchased tokens. ([#1721](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1721)) From 31bc231c2c059c288c45a90d4a198453468b8b86 Mon Sep 17 00:00:00 2001 From: Francisco Giordano Date: Wed, 24 Apr 2019 19:43:26 -0300 Subject: [PATCH 04/26] fix typo in release script --- scripts/release/release.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/release/release.sh b/scripts/release/release.sh index c96f9ea55..c2d5552f3 100755 --- a/scripts/release/release.sh +++ b/scripts/release/release.sh @@ -88,7 +88,7 @@ elif [[ "$*" == "rc" ]]; then assert_current_branch "$(current_release_branch)" # Bumps rc number, commits and tags - npm version prelease + npm version prerelease push_and_publish next From 2d467268e5c4c75e5accb7b4697535c02497724f Mon Sep 17 00:00:00 2001 From: Francisco Giordano Date: Wed, 24 Apr 2019 19:44:43 -0300 Subject: [PATCH 05/26] 2.3.0-rc.1 --- ethpm.json | 2 +- package-lock.json | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ethpm.json b/ethpm.json index 1e9826f21..b981ad1d5 100644 --- a/ethpm.json +++ b/ethpm.json @@ -1,6 +1,6 @@ { "package_name": "zeppelin", - "version": "2.3.0-rc.0", + "version": "2.3.0-rc.1", "description": "Secure Smart Contract library for Solidity", "authors": [ "OpenZeppelin Community " diff --git a/package-lock.json b/package-lock.json index fdb46f78d..98bb0fd27 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "openzeppelin-solidity", - "version": "2.3.0-rc.0", + "version": "2.3.0-rc.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index c4d02b0f2..dbd2d0f4c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "openzeppelin-solidity", - "version": "2.3.0-rc.0", + "version": "2.3.0-rc.1", "description": "Secure Smart Contract library for Solidity", "files": [ "build", From 6782f91425c7270bd9c4a2691377a28a46f56b9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Venturo?= Date: Thu, 2 May 2019 15:52:27 -0300 Subject: [PATCH 06/26] Update vulnerable dependencies. (cherry picked from commit e287ea6fe5c26ad9e54497b1c1669669ed548aaf) --- package-lock.json | 114 +++++++++++++++++++++++++--------------------- package.json | 2 +- 2 files changed, 62 insertions(+), 54 deletions(-) diff --git a/package-lock.json b/package-lock.json index 98bb0fd27..f3b299af1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2297,17 +2297,17 @@ } }, "chai": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz", - "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", + "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", "dev": true, "requires": { - "assertion-error": "^1.0.1", - "check-error": "^1.0.1", - "deep-eql": "^3.0.0", + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", "get-func-name": "^2.0.0", - "pathval": "^1.0.0", - "type-detect": "^4.0.0" + "pathval": "^1.1.0", + "type-detect": "^4.0.5" } }, "chai-bn": { @@ -4025,9 +4025,9 @@ } }, "esprima": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", - "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", + "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 }, "globals": { @@ -4037,9 +4037,9 @@ "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==", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", "dev": true, "requires": { "argparse": "^1.0.7", @@ -4434,9 +4434,9 @@ }, "dependencies": { "@types/node": { - "version": "10.14.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.4.tgz", - "integrity": "sha512-DT25xX/YgyPKiHFOpNuANIQIVvYEwCWXgK2jYYwqgaMrYE6+tq+DtmMwlD3drl6DJbUwtlIDnn0d7tIn/EbXBg==", + "version": "10.14.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.6.tgz", + "integrity": "sha512-Fvm24+u85lGmV4hT5G++aht2C5I4Z4dYlWZIh62FAfFO/TfzXtPpoLI6I7AuBWkIFqZCnhFOoTT7RjjaIL5Fjg==", "dev": true }, "elliptic": { @@ -6355,9 +6355,9 @@ } }, "handlebars": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.1.tgz", - "integrity": "sha512-3Zhi6C0euYZL5sM0Zcy7lInLXKQ+YLcF/olbN010mzGQ4XVm50JeyBnMqofHh696GrciGruC7kCcApPDJvVgwA==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.2.tgz", + "integrity": "sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw==", "dev": true, "requires": { "neo-async": "^2.6.0", @@ -7493,13 +7493,21 @@ "dev": true }, "js-yaml": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.6.1.tgz", - "integrity": "sha1-bl/mfYsgXOTSL60Ft3geja3MSzA=", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", "dev": true, "requires": { "argparse": "^1.0.7", - "esprima": "^2.6.0" + "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 + } } }, "jsbn": { @@ -7737,7 +7745,7 @@ "dependencies": { "pify": { "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true } @@ -8332,9 +8340,9 @@ } }, "mock-fs": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.8.0.tgz", - "integrity": "sha512-Gwj4KnJOW15YeTJKO5frFd/WDO5Mc0zxXqL9oHx3+e9rBqW8EVARqQHSaIXznUdljrD6pvbNGW2ZGXKPEfYJfw==", + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.9.0.tgz", + "integrity": "sha512-aUj0qIniTNxzGqAC61Bvro7YD37tIBnMw3wpClucUVgNBS7r6YQn/M4wuoH7SGteKz4SvC1OBeDsfpG0MYC+1Q==", "dev": true }, "mout": { @@ -9017,7 +9025,7 @@ "dependencies": { "pify": { "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true } @@ -12098,9 +12106,9 @@ "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==", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", "dev": true, "requires": { "argparse": "^1.0.7", @@ -13139,17 +13147,17 @@ "dev": true }, "truffle-contract": { - "version": "4.0.11", - "resolved": "https://registry.npmjs.org/truffle-contract/-/truffle-contract-4.0.11.tgz", - "integrity": "sha512-lzKFdLngTSt7MQMOvsUhOEPUjagSbGVkhQm7rSant4Y/VSWIppL3GXqpTOzdcOJMHgL9iYlMEm42+pHXq6DZxg==", + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/truffle-contract/-/truffle-contract-4.0.14.tgz", + "integrity": "sha512-gPSNNR/ozIkEVJO+rOu6wElNgy6NT6uH4+Bm6Kwerpnzo8eCTCTTSmBbJcaTKm+YAei7Dw7v427yU3gXPDkK/A==", "dev": true, "requires": { "bignumber.js": "^7.2.1", "ethers": "^4.0.0-beta.1", "truffle-blockchain-utils": "^0.0.8", - "truffle-contract-schema": "^3.0.6", + "truffle-contract-schema": "^3.0.9", "truffle-error": "^0.0.4", - "truffle-interface-adapter": "^0.1.2", + "truffle-interface-adapter": "^0.1.4", "web3": "1.0.0-beta.37", "web3-core-promievent": "1.0.0-beta.37", "web3-eth-abi": "1.0.0-beta.37", @@ -13157,9 +13165,9 @@ } }, "truffle-contract-schema": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/truffle-contract-schema/-/truffle-contract-schema-3.0.6.tgz", - "integrity": "sha512-oAMPr/ecr06ViJMSatfp1VpbDNul0Q1dSrFkWSF4/6WWK4orhNL90A8uhtEt61doLz5n0Yjf59KWE0p7qToPXw==", + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/truffle-contract-schema/-/truffle-contract-schema-3.0.9.tgz", + "integrity": "sha512-V1gwOeOPj7h0cM427KeMnTJZfotBqkISMLb9zq7bDj+iy/i05Ug7vyYaqCYnC5ignSnfNYgmJt8VsIt0UGI4lg==", "dev": true, "requires": { "ajv": "^5.1.1", @@ -13191,9 +13199,9 @@ "dev": true }, "truffle-interface-adapter": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/truffle-interface-adapter/-/truffle-interface-adapter-0.1.2.tgz", - "integrity": "sha512-1+pZprFU94mN8ydy4wVI2reW4iELDmsUADpa2ti++HwsX/T02yHK5+GxK3wQ9lXglRiI/B694fKFbHcv3t+Vxg==", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/truffle-interface-adapter/-/truffle-interface-adapter-0.1.4.tgz", + "integrity": "sha512-BVqHzsqHO1KKjTLLmkphmPxdeSvlpqPmDrAVg5QzOpAjqtBE0QV6bQOtBcZGCVY6eh37mfbNpaKKSXauziRr6w==", "dev": true, "requires": { "bn.js": "^4.11.8", @@ -13273,20 +13281,20 @@ } }, "uglify-js": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.5.2.tgz", - "integrity": "sha512-imog1WIsi9Yb56yRt5TfYVxGmnWs3WSGU73ieSOlMVFwhJCA9W8fqFFMMj4kgDqiS/80LGdsYnWL7O9UcjEBlg==", + "version": "3.5.10", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.5.10.tgz", + "integrity": "sha512-/GTF0nosyPLbdJBd+AwYiZ+Hu5z8KXWnO0WCGt1BQ/u9Iamhejykqmz5o1OHJ53+VAk6xVxychonnApDjuqGsw==", "dev": true, "optional": true, "requires": { - "commander": "~2.19.0", + "commander": "~2.20.0", "source-map": "~0.6.1" }, "dependencies": { "commander": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", - "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", + "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", "dev": true, "optional": true } @@ -13763,9 +13771,9 @@ }, "dependencies": { "@types/node": { - "version": "10.14.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.4.tgz", - "integrity": "sha512-DT25xX/YgyPKiHFOpNuANIQIVvYEwCWXgK2jYYwqgaMrYE6+tq+DtmMwlD3drl6DJbUwtlIDnn0d7tIn/EbXBg==", + "version": "10.14.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.6.tgz", + "integrity": "sha512-Fvm24+u85lGmV4hT5G++aht2C5I4Z4dYlWZIh62FAfFO/TfzXtPpoLI6I7AuBWkIFqZCnhFOoTT7RjjaIL5Fjg==", "dev": true }, "elliptic": { diff --git a/package.json b/package.json index dbd2d0f4c..489734e16 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ }, "homepage": "https://github.com/OpenZeppelin/zeppelin-solidity", "devDependencies": { - "chai": "^4.1.2", + "chai": "^4.2.0", "coveralls": "^3.0.1", "eslint": "^4.19.1", "eslint-config-standard": "^10.2.1", From 835c23d6f75b6994c825a8f48b44ee616c6cef29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Venturo?= Date: Tue, 7 May 2019 17:05:12 -0300 Subject: [PATCH 07/26] Hardcode ERC777 granularity to 1, remove tests. (#1739) * Hardcode ERC777 granularity to 1, remove tests. * Add clarifying title comment. (cherry picked from commit 376820d55cbf193e470186e8be733b3e211a3737) --- contracts/drafts/ERC777/ERC777.sol | 13 +- contracts/mocks/ERC777Mock.sol | 3 +- test/drafts/ERC777/ERC777.behavior.js | 3 - test/drafts/ERC777/ERC777.test.js | 529 ++++++++++++-------------- 4 files changed, 240 insertions(+), 308 deletions(-) diff --git a/contracts/drafts/ERC777/ERC777.sol b/contracts/drafts/ERC777/ERC777.sol index 80609666b..ab2e53dae 100644 --- a/contracts/drafts/ERC777/ERC777.sol +++ b/contracts/drafts/ERC777/ERC777.sol @@ -8,7 +8,7 @@ import "../../utils/Address.sol"; import "../IERC1820Registry.sol"; /** - * @title ERC777 token implementation + * @title ERC777 token implementation, with granularity harcoded to 1. * @author etsvigun , Bertrand Masius */ contract ERC777 is IERC777 { @@ -25,8 +25,6 @@ contract ERC777 is IERC777 { uint256 private _totalSupply; - uint256 private _granularity; - bytes32 constant private TOKENS_SENDER_INTERFACE_HASH = keccak256("ERC777TokensSender"); bytes32 constant private TOKENS_RECIPIENT_INTERFACE_HASH = keccak256("ERC777TokensRecipient"); @@ -43,14 +41,10 @@ contract ERC777 is IERC777 { constructor( string memory name, string memory symbol, - uint256 granularity, address[] memory defaultOperators ) public { - require(granularity > 0); - _name = name; _symbol = symbol; - _granularity = granularity; _defaultOperatorsArray = defaultOperators; for (uint256 i = 0; i < _defaultOperatorsArray.length; i++) { @@ -182,7 +176,7 @@ contract ERC777 is IERC777 { * @return uint256 granularity */ function granularity() public view returns (uint256) { - return _granularity; + return 1; } /** @@ -228,7 +222,6 @@ contract ERC777 is IERC777 { internal { require(to != address(0)); - require((amount % _granularity) == 0); // Update state variables _totalSupply = _totalSupply.add(amount); @@ -260,7 +253,6 @@ contract ERC777 is IERC777 { { require(from != address(0)); require(to != address(0)); - require((amount % _granularity) == 0); _callTokensToSend(operator, from, to, amount, userData, operatorData); @@ -291,7 +283,6 @@ contract ERC777 is IERC777 { private { require(from != address(0)); - require((amount % _granularity) == 0); _callTokensToSend(operator, from, address(0), amount, data, operatorData); diff --git a/contracts/mocks/ERC777Mock.sol b/contracts/mocks/ERC777Mock.sol index 30657ca2e..bb4c4ead2 100644 --- a/contracts/mocks/ERC777Mock.sol +++ b/contracts/mocks/ERC777Mock.sol @@ -8,9 +8,8 @@ contract ERC777Mock is ERC777 { uint256 initialBalance, string memory name, string memory symbol, - uint256 granularity, address[] memory defaultOperators - ) public ERC777(name, symbol, granularity, defaultOperators) { + ) public ERC777(name, symbol, defaultOperators) { _mint(msg.sender, initialHolder, initialBalance, "", ""); } diff --git a/test/drafts/ERC777/ERC777.behavior.js b/test/drafts/ERC777/ERC777.behavior.js index 771f4a1f2..a2b16073e 100644 --- a/test/drafts/ERC777/ERC777.behavior.js +++ b/test/drafts/ERC777/ERC777.behavior.js @@ -524,10 +524,7 @@ module.exports = { shouldBehaveLikeERC777DirectSendBurn, shouldBehaveLikeERC777OperatorSendBurn, shouldBehaveLikeERC777UnauthorizedOperatorSendBurn, - shouldDirectSendTokens, - shouldDirectBurnTokens, shouldBehaveLikeERC777InternalMint, - shouldInternalMintTokens, shouldBehaveLikeERC777SendBurnMintInternalWithReceiveHook, shouldBehaveLikeERC777SendBurnWithSendHook, }; diff --git a/test/drafts/ERC777/ERC777.test.js b/test/drafts/ERC777/ERC777.test.js index 7cc609917..8a12539b8 100644 --- a/test/drafts/ERC777/ERC777.test.js +++ b/test/drafts/ERC777/ERC777.test.js @@ -4,10 +4,7 @@ const { shouldBehaveLikeERC777DirectSendBurn, shouldBehaveLikeERC777OperatorSendBurn, shouldBehaveLikeERC777UnauthorizedOperatorSendBurn, - shouldDirectSendTokens, - shouldDirectBurnTokens, shouldBehaveLikeERC777InternalMint, - shouldInternalMintTokens, shouldBehaveLikeERC777SendBurnMintInternalWithReceiveHook, shouldBehaveLikeERC777SendBurnWithSendHook, } = require('./ERC777.behavior'); @@ -30,419 +27,367 @@ contract('ERC777', function ([ this.erc1820 = await singletons.ERC1820Registry(registryFunder); }); - it('reverts with a granularity of zero', async function () { - await shouldFail.reverting(ERC777.new(holder, initialSupply, name, symbol, 0, [])); - }); + context('with default operators', function () { + beforeEach(async function () { + this.token = await ERC777.new(holder, initialSupply, name, symbol, defaultOperators); + }); - context('with a granularity of one', function () { - const granularity = new BN('1'); + it.skip('does not emit AuthorizedOperator events for default operators', async function () { + expectEvent.not.inConstructor(this.token, 'AuthorizedOperator'); // This helper needs to be implemented + }); - context('with default operators', function () { - beforeEach(async function () { - this.token = await ERC777.new(holder, initialSupply, name, symbol, granularity, defaultOperators); + describe('basic information', function () { + it('returns the name', async function () { + (await this.token.name()).should.equal(name); }); - it.skip('does not emit AuthorizedOperator events for default operators', async function () { - expectEvent.not.inConstructor(this.token, 'AuthorizedOperator'); // This helper needs to be implemented + it('returns the symbol', async function () { + (await this.token.symbol()).should.equal(symbol); }); - describe('basic information', function () { - it('returns the name', async function () { - (await this.token.name()).should.equal(name); - }); + it('has a granularity of 1', async function () { + (await this.token.granularity()).should.be.bignumber.equal('1'); + }); + + it('returns the default operators', async function () { + (await this.token.defaultOperators()).should.deep.equal(defaultOperators); + }); + + it('default operators are operators for all accounts', async function () { + for (const operator of defaultOperators) { + (await this.token.isOperatorFor(operator, anyone)).should.equal(true); + } + }); + + it('returns thte total supply', async function () { + (await this.token.totalSupply()).should.be.bignumber.equal(initialSupply); + }); - it('returns the symbol', async function () { - (await this.token.symbol()).should.equal(symbol); + it('is registered in the registry', async function () { + (await this.erc1820.getInterfaceImplementer(this.token.address, web3.utils.soliditySha3('ERC777Token'))) + .should.equal(this.token.address); + }); + }); + + describe('balanceOf', function () { + context('for an account with no tokens', function () { + it('returns zero', async function () { + (await this.token.balanceOf(anyone)).should.be.bignumber.equal('0'); }); + }); - it('returns the granularity', async function () { - (await this.token.granularity()).should.be.bignumber.equal(granularity); + context('for an account with tokens', function () { + it('returns their balance', async function () { + (await this.token.balanceOf(holder)).should.be.bignumber.equal(initialSupply); }); + }); + }); - it('returns the default operators', async function () { - (await this.token.defaultOperators()).should.deep.equal(defaultOperators); + context('with no ERC777TokensSender and no ERC777TokensRecipient implementers', function () { + describe('send/burn', function () { + shouldBehaveLikeERC777DirectSendBurn(holder, anyone, data); + + context('with self operator', function () { + shouldBehaveLikeERC777OperatorSendBurn(holder, anyone, holder, data, operatorData); }); - it('default operators are operators for all accounts', async function () { - for (const operator of defaultOperators) { - (await this.token.isOperatorFor(operator, anyone)).should.equal(true); - } + context('with first default operator', function () { + shouldBehaveLikeERC777OperatorSendBurn(holder, anyone, defaultOperatorA, data, operatorData); }); - it('returns thte total supply', async function () { - (await this.token.totalSupply()).should.be.bignumber.equal(initialSupply); + context('with second default operator', function () { + shouldBehaveLikeERC777OperatorSendBurn(holder, anyone, defaultOperatorB, data, operatorData); }); - it('is registered in the registry', async function () { - (await this.erc1820.getInterfaceImplementer(this.token.address, web3.utils.soliditySha3('ERC777Token'))) - .should.equal(this.token.address); + context('before authorizing a new operator', function () { + shouldBehaveLikeERC777UnauthorizedOperatorSendBurn(holder, anyone, newOperator, data, operatorData); }); - }); - describe('balanceOf', function () { - context('for an account with no tokens', function () { - it('returns zero', async function () { - (await this.token.balanceOf(anyone)).should.be.bignumber.equal('0'); + context('with new authorized operator', function () { + beforeEach(async function () { + await this.token.authorizeOperator(newOperator, { from: holder }); }); - }); - context('for an account with tokens', function () { - it('returns their balance', async function () { - (await this.token.balanceOf(holder)).should.be.bignumber.equal(initialSupply); + shouldBehaveLikeERC777OperatorSendBurn(holder, anyone, newOperator, data, operatorData); + + context('with revoked operator', function () { + beforeEach(async function () { + await this.token.revokeOperator(newOperator, { from: holder }); + }); + + shouldBehaveLikeERC777UnauthorizedOperatorSendBurn(holder, anyone, newOperator, data, operatorData); }); }); }); - context('with no ERC777TokensSender and no ERC777TokensRecipient implementers', function () { - describe('send/burn', function () { - shouldBehaveLikeERC777DirectSendBurn(holder, anyone, data); + describe('mint (internal)', function () { + const to = anyone; + const amount = new BN('5'); - context('with self operator', function () { - shouldBehaveLikeERC777OperatorSendBurn(holder, anyone, holder, data, operatorData); - }); + context('with default operator', function () { + const operator = defaultOperatorA; - context('with first default operator', function () { - shouldBehaveLikeERC777OperatorSendBurn(holder, anyone, defaultOperatorA, data, operatorData); - }); + shouldBehaveLikeERC777InternalMint(to, operator, amount, data, operatorData); + }); - context('with second default operator', function () { - shouldBehaveLikeERC777OperatorSendBurn(holder, anyone, defaultOperatorB, data, operatorData); - }); + context('with non operator', function () { + const operator = newOperator; - context('before authorizing a new operator', function () { - shouldBehaveLikeERC777UnauthorizedOperatorSendBurn(holder, anyone, newOperator, data, operatorData); - }); + shouldBehaveLikeERC777InternalMint(to, operator, amount, data, operatorData); + }); + }); + }); - context('with new authorized operator', function () { - beforeEach(async function () { - await this.token.authorizeOperator(newOperator, { from: holder }); - }); + describe('operator management', function () { + it('accounts are their own operator', async function () { + (await this.token.isOperatorFor(holder, holder)).should.equal(true); + }); - shouldBehaveLikeERC777OperatorSendBurn(holder, anyone, newOperator, data, operatorData); + it('reverts when self-authorizing', async function () { + await shouldFail.reverting(this.token.authorizeOperator(holder, { from: holder })); + }); - context('with revoked operator', function () { - beforeEach(async function () { - await this.token.revokeOperator(newOperator, { from: holder }); - }); + it('reverts when self-revoking', async function () { + await shouldFail.reverting(this.token.revokeOperator(holder, { from: holder })); + }); - shouldBehaveLikeERC777UnauthorizedOperatorSendBurn(holder, anyone, newOperator, data, operatorData); - }); - }); - }); + it('non-operators can be revoked', async function () { + (await this.token.isOperatorFor(newOperator, holder)).should.equal(false); - describe('mint (internal)', function () { - const to = anyone; - const amount = new BN('5'); + const { logs } = await this.token.revokeOperator(newOperator, { from: holder }); + expectEvent.inLogs(logs, 'RevokedOperator', { operator: newOperator, tokenHolder: holder }); - context('with default operator', function () { - const operator = defaultOperatorA; + (await this.token.isOperatorFor(newOperator, holder)).should.equal(false); + }); - shouldBehaveLikeERC777InternalMint(to, operator, amount, data, operatorData); - }); + it('non-operators can be authorized', async function () { + (await this.token.isOperatorFor(newOperator, holder)).should.equal(false); - context('with non operator', function () { - const operator = newOperator; + const { logs } = await this.token.authorizeOperator(newOperator, { from: holder }); + expectEvent.inLogs(logs, 'AuthorizedOperator', { operator: newOperator, tokenHolder: holder }); - shouldBehaveLikeERC777InternalMint(to, operator, amount, data, operatorData); - }); - }); + (await this.token.isOperatorFor(newOperator, holder)).should.equal(true); }); - describe('operator management', function () { - it('accounts are their own operator', async function () { - (await this.token.isOperatorFor(holder, holder)).should.equal(true); + describe('new operators', function () { + beforeEach(async function () { + await this.token.authorizeOperator(newOperator, { from: holder }); }); - it('reverts when self-authorizing', async function () { - await shouldFail.reverting(this.token.authorizeOperator(holder, { from: holder })); + it('are not added to the default operators list', async function () { + (await this.token.defaultOperators()).should.deep.equal(defaultOperators); }); - it('reverts when self-revoking', async function () { - await shouldFail.reverting(this.token.revokeOperator(holder, { from: holder })); - }); + it('can be re-authorized', async function () { + const { logs } = await this.token.authorizeOperator(newOperator, { from: holder }); + expectEvent.inLogs(logs, 'AuthorizedOperator', { operator: newOperator, tokenHolder: holder }); - it('non-operators can be revoked', async function () { - (await this.token.isOperatorFor(newOperator, holder)).should.equal(false); + (await this.token.isOperatorFor(newOperator, holder)).should.equal(true); + }); + it('can be revoked', async function () { const { logs } = await this.token.revokeOperator(newOperator, { from: holder }); expectEvent.inLogs(logs, 'RevokedOperator', { operator: newOperator, tokenHolder: holder }); (await this.token.isOperatorFor(newOperator, holder)).should.equal(false); }); + }); - it('non-operators can be authorized', async function () { - (await this.token.isOperatorFor(newOperator, holder)).should.equal(false); + describe('default operators', function () { + it('can be re-authorized', async function () { + const { logs } = await this.token.authorizeOperator(defaultOperatorA, { from: holder }); + expectEvent.inLogs(logs, 'AuthorizedOperator', { operator: defaultOperatorA, tokenHolder: holder }); - const { logs } = await this.token.authorizeOperator(newOperator, { from: holder }); - expectEvent.inLogs(logs, 'AuthorizedOperator', { operator: newOperator, tokenHolder: holder }); + (await this.token.isOperatorFor(defaultOperatorA, holder)).should.equal(true); + }); - (await this.token.isOperatorFor(newOperator, holder)).should.equal(true); + it('can be revoked', async function () { + const { logs } = await this.token.revokeOperator(defaultOperatorA, { from: holder }); + expectEvent.inLogs(logs, 'RevokedOperator', { operator: defaultOperatorA, tokenHolder: holder }); + + (await this.token.isOperatorFor(defaultOperatorA, holder)).should.equal(false); + }); + + it('cannot be revoked for themselves', async function () { + await shouldFail.reverting(this.token.revokeOperator(defaultOperatorA, { from: defaultOperatorA })); }); - describe('new operators', function () { + context('with revoked default operator', function () { beforeEach(async function () { - await this.token.authorizeOperator(newOperator, { from: holder }); + await this.token.revokeOperator(defaultOperatorA, { from: holder }); }); - it('are not added to the default operators list', async function () { - (await this.token.defaultOperators()).should.deep.equal(defaultOperators); + it('default operator is not revoked for other holders', async function () { + (await this.token.isOperatorFor(defaultOperatorA, anyone)).should.equal(true); }); - it('can be re-authorized', async function () { - const { logs } = await this.token.authorizeOperator(newOperator, { from: holder }); - expectEvent.inLogs(logs, 'AuthorizedOperator', { operator: newOperator, tokenHolder: holder }); - - (await this.token.isOperatorFor(newOperator, holder)).should.equal(true); + it('other default operators are not revoked', async function () { + (await this.token.isOperatorFor(defaultOperatorB, holder)).should.equal(true); }); - it('can be revoked', async function () { - const { logs } = await this.token.revokeOperator(newOperator, { from: holder }); - expectEvent.inLogs(logs, 'RevokedOperator', { operator: newOperator, tokenHolder: holder }); - - (await this.token.isOperatorFor(newOperator, holder)).should.equal(false); + it('default operators list is not modified', async function () { + (await this.token.defaultOperators()).should.deep.equal(defaultOperators); }); - }); - describe('default operators', function () { - it('can be re-authorized', async function () { + it('revoked default operator can be re-authorized', async function () { const { logs } = await this.token.authorizeOperator(defaultOperatorA, { from: holder }); expectEvent.inLogs(logs, 'AuthorizedOperator', { operator: defaultOperatorA, tokenHolder: holder }); (await this.token.isOperatorFor(defaultOperatorA, holder)).should.equal(true); }); + }); + }); + }); - it('can be revoked', async function () { - const { logs } = await this.token.revokeOperator(defaultOperatorA, { from: holder }); - expectEvent.inLogs(logs, 'RevokedOperator', { operator: defaultOperatorA, tokenHolder: holder }); - - (await this.token.isOperatorFor(defaultOperatorA, holder)).should.equal(false); - }); + describe('send and receive hooks', function () { + const amount = new BN('1'); + const operator = defaultOperatorA; + // sender and recipient are stored inside 'this', since in some tests their addresses are determined dynamically - it('cannot be revoked for themselves', async function () { - await shouldFail.reverting(this.token.revokeOperator(defaultOperatorA, { from: defaultOperatorA })); - }); + describe('tokensReceived', function () { + beforeEach(function () { + this.sender = holder; + }); - context('with revoked default operator', function () { + context('with no ERC777TokensRecipient implementer', function () { + context('with contract recipient', function () { beforeEach(async function () { - await this.token.revokeOperator(defaultOperatorA, { from: holder }); - }); + this.tokensRecipientImplementer = await ERC777SenderRecipientMock.new(); + this.recipient = this.tokensRecipientImplementer.address; - it('default operator is not revoked for other holders', async function () { - (await this.token.isOperatorFor(defaultOperatorA, anyone)).should.equal(true); + // Note that tokensRecipientImplementer doesn't implement the recipient interface for the recipient }); - it('other default operators are not revoked', async function () { - (await this.token.isOperatorFor(defaultOperatorB, holder)).should.equal(true); + it('send reverts', async function () { + await shouldFail.reverting(this.token.send(this.recipient, amount, data)); }); - it('default operators list is not modified', async function () { - (await this.token.defaultOperators()).should.deep.equal(defaultOperators); + it('operatorSend reverts', async function () { + await shouldFail.reverting( + this.token.operatorSend(this.sender, this.recipient, amount, data, operatorData, { from: operator }) + ); }); - it('revoked default operator can be re-authorized', async function () { - const { logs } = await this.token.authorizeOperator(defaultOperatorA, { from: holder }); - expectEvent.inLogs(logs, 'AuthorizedOperator', { operator: defaultOperatorA, tokenHolder: holder }); - - (await this.token.isOperatorFor(defaultOperatorA, holder)).should.equal(true); + it('mint (internal) reverts', async function () { + await shouldFail.reverting( + this.token.mintInternal(operator, this.recipient, amount, data, operatorData) + ); }); }); }); - }); - describe('send and receive hooks', function () { - const amount = new BN('1'); - const operator = defaultOperatorA; - // sender and recipient are stored inside 'this', since in some tests their addresses are determined dynamically + context('with ERC777TokensRecipient implementer', function () { + context('with contract as implementer for an externally owned account', function () { + beforeEach(async function () { + this.tokensRecipientImplementer = await ERC777SenderRecipientMock.new(); + this.recipient = anyone; - describe('tokensReceived', function () { - beforeEach(function () { - this.sender = holder; - }); + await this.tokensRecipientImplementer.recipientFor(this.recipient); - context('with no ERC777TokensRecipient implementer', function () { - context('with contract recipient', function () { - beforeEach(async function () { - this.tokensRecipientImplementer = await ERC777SenderRecipientMock.new(); - this.recipient = this.tokensRecipientImplementer.address; - - // Note that tokensRecipientImplementer doesn't implement the recipient interface for the recipient - }); - - it('send reverts', async function () { - await shouldFail.reverting(this.token.send(this.recipient, amount, data)); - }); - - it('operatorSend reverts', async function () { - await shouldFail.reverting( - this.token.operatorSend(this.sender, this.recipient, amount, data, operatorData, { from: operator }) - ); - }); - - it('mint (internal) reverts', async function () { - await shouldFail.reverting( - this.token.mintInternal(operator, this.recipient, amount, data, operatorData) - ); - }); + await this.erc1820.setInterfaceImplementer( + this.recipient, + web3.utils.soliditySha3('ERC777TokensRecipient'), this.tokensRecipientImplementer.address, + { from: this.recipient }, + ); }); - }); - - context('with ERC777TokensRecipient implementer', function () { - context('with contract as implementer for an externally owned account', function () { - beforeEach(async function () { - this.tokensRecipientImplementer = await ERC777SenderRecipientMock.new(); - this.recipient = anyone; - await this.tokensRecipientImplementer.recipientFor(this.recipient); + shouldBehaveLikeERC777SendBurnMintInternalWithReceiveHook(operator, amount, data, operatorData); + }); - await this.erc1820.setInterfaceImplementer( - this.recipient, - web3.utils.soliditySha3('ERC777TokensRecipient'), this.tokensRecipientImplementer.address, - { from: this.recipient }, - ); - }); + context('with contract as implementer for another contract', function () { + beforeEach(async function () { + this.recipientContract = await ERC777SenderRecipientMock.new(); + this.recipient = this.recipientContract.address; - shouldBehaveLikeERC777SendBurnMintInternalWithReceiveHook(operator, amount, data, operatorData); + this.tokensRecipientImplementer = await ERC777SenderRecipientMock.new(); + await this.tokensRecipientImplementer.recipientFor(this.recipient); + await this.recipientContract.registerRecipient(this.tokensRecipientImplementer.address); }); - context('with contract as implementer for another contract', function () { - beforeEach(async function () { - this.recipientContract = await ERC777SenderRecipientMock.new(); - this.recipient = this.recipientContract.address; + shouldBehaveLikeERC777SendBurnMintInternalWithReceiveHook(operator, amount, data, operatorData); + }); - this.tokensRecipientImplementer = await ERC777SenderRecipientMock.new(); - await this.tokensRecipientImplementer.recipientFor(this.recipient); - await this.recipientContract.registerRecipient(this.tokensRecipientImplementer.address); - }); + context('with contract as implementer for itself', function () { + beforeEach(async function () { + this.tokensRecipientImplementer = await ERC777SenderRecipientMock.new(); + this.recipient = this.tokensRecipientImplementer.address; - shouldBehaveLikeERC777SendBurnMintInternalWithReceiveHook(operator, amount, data, operatorData); + await this.tokensRecipientImplementer.recipientFor(this.recipient); }); - context('with contract as implementer for itself', function () { - beforeEach(async function () { - this.tokensRecipientImplementer = await ERC777SenderRecipientMock.new(); - this.recipient = this.tokensRecipientImplementer.address; - - await this.tokensRecipientImplementer.recipientFor(this.recipient); - }); - - shouldBehaveLikeERC777SendBurnMintInternalWithReceiveHook(operator, amount, data, operatorData); - }); + shouldBehaveLikeERC777SendBurnMintInternalWithReceiveHook(operator, amount, data, operatorData); }); }); + }); - describe('tokensToSend', function () { - beforeEach(function () { - this.recipient = anyone; - }); - - context('with a contract as implementer for an externally owned account', function () { - beforeEach(async function () { - this.tokensSenderImplementer = await ERC777SenderRecipientMock.new(); - this.sender = holder; + describe('tokensToSend', function () { + beforeEach(function () { + this.recipient = anyone; + }); - await this.tokensSenderImplementer.senderFor(this.sender); + context('with a contract as implementer for an externally owned account', function () { + beforeEach(async function () { + this.tokensSenderImplementer = await ERC777SenderRecipientMock.new(); + this.sender = holder; - await this.erc1820.setInterfaceImplementer( - this.sender, - web3.utils.soliditySha3('ERC777TokensSender'), this.tokensSenderImplementer.address, - { from: this.sender }, - ); - }); + await this.tokensSenderImplementer.senderFor(this.sender); - shouldBehaveLikeERC777SendBurnWithSendHook(operator, amount, data, operatorData); + await this.erc1820.setInterfaceImplementer( + this.sender, + web3.utils.soliditySha3('ERC777TokensSender'), this.tokensSenderImplementer.address, + { from: this.sender }, + ); }); - context('with contract as implementer for another contract', function () { - beforeEach(async function () { - this.senderContract = await ERC777SenderRecipientMock.new(); - this.sender = this.senderContract.address; + shouldBehaveLikeERC777SendBurnWithSendHook(operator, amount, data, operatorData); + }); - this.tokensSenderImplementer = await ERC777SenderRecipientMock.new(); - await this.tokensSenderImplementer.senderFor(this.sender); - await this.senderContract.registerSender(this.tokensSenderImplementer.address); + context('with contract as implementer for another contract', function () { + beforeEach(async function () { + this.senderContract = await ERC777SenderRecipientMock.new(); + this.sender = this.senderContract.address; - // For the contract to be able to receive tokens (that it can later send), it must also implement the - // recipient interface. + this.tokensSenderImplementer = await ERC777SenderRecipientMock.new(); + await this.tokensSenderImplementer.senderFor(this.sender); + await this.senderContract.registerSender(this.tokensSenderImplementer.address); - await this.senderContract.recipientFor(this.sender); - await this.token.send(this.sender, amount, data, { from: holder }); - }); + // For the contract to be able to receive tokens (that it can later send), it must also implement the + // recipient interface. - shouldBehaveLikeERC777SendBurnWithSendHook(operator, amount, data, operatorData); + await this.senderContract.recipientFor(this.sender); + await this.token.send(this.sender, amount, data, { from: holder }); }); - context('with a contract as implementer for itself', function () { - beforeEach(async function () { - this.tokensSenderImplementer = await ERC777SenderRecipientMock.new(); - this.sender = this.tokensSenderImplementer.address; + shouldBehaveLikeERC777SendBurnWithSendHook(operator, amount, data, operatorData); + }); - await this.tokensSenderImplementer.senderFor(this.sender); + context('with a contract as implementer for itself', function () { + beforeEach(async function () { + this.tokensSenderImplementer = await ERC777SenderRecipientMock.new(); + this.sender = this.tokensSenderImplementer.address; - // For the contract to be able to receive tokens (that it can later send), it must also implement the - // recipient interface. + await this.tokensSenderImplementer.senderFor(this.sender); - await this.tokensSenderImplementer.recipientFor(this.sender); - await this.token.send(this.sender, amount, data, { from: holder }); - }); + // For the contract to be able to receive tokens (that it can later send), it must also implement the + // recipient interface. - shouldBehaveLikeERC777SendBurnWithSendHook(operator, amount, data, operatorData); + await this.tokensSenderImplementer.recipientFor(this.sender); + await this.token.send(this.sender, amount, data, { from: holder }); }); - }); - }); - }); - - context('with no default operators', function () { - beforeEach(async function () { - this.token = await ERC777.new(holder, initialSupply, name, symbol, granularity, []); - }); - it('default operators list is empty', async function () { - (await this.token.defaultOperators()).should.deep.equal([]); + shouldBehaveLikeERC777SendBurnWithSendHook(operator, amount, data, operatorData); + }); }); }); }); - context('with granularity larger than 1', function () { - const granularity = new BN('4'); - + context('with no default operators', function () { beforeEach(async function () { - initialSupply.mod(granularity).should.be.bignumber.equal('0'); - - this.token = await ERC777.new(holder, initialSupply, name, symbol, granularity, defaultOperators); - }); - - it('returns the granularity', async function () { - (await this.token.granularity()).should.be.bignumber.equal(granularity); + this.token = await ERC777.new(holder, initialSupply, name, symbol, []); }); - context('when the sender has tokens', function () { - const from = holder; - - shouldDirectSendTokens(from, anyone, new BN('0'), data); - shouldDirectSendTokens(from, anyone, granularity, data); - shouldDirectSendTokens(from, anyone, granularity.muln(2), data); - - it('reverts when sending an amount non-multiple of the granularity', async function () { - await shouldFail.reverting(this.token.send(anyone, granularity.subn(1), data, { from })); - }); - - shouldDirectBurnTokens(from, new BN('0'), data); - shouldDirectBurnTokens(from, granularity, data); - shouldDirectBurnTokens(from, granularity.muln(2), data); - - it('reverts when burning an amount non-multiple of the granularity', async function () { - await shouldFail.reverting(this.token.burn(granularity.subn(1), data, { from })); - }); - }); - - shouldInternalMintTokens(anyone, defaultOperatorA, new BN('0'), data, operatorData); - shouldInternalMintTokens(anyone, defaultOperatorA, granularity, data, operatorData); - shouldInternalMintTokens(anyone, defaultOperatorA, granularity.muln(2), data, operatorData); - - it('reverts when minting an amount non-multiple of the granularity', async function () { - await shouldFail.reverting( - this.token.mintInternal(defaultOperatorA, anyone, granularity.subn(1), data, operatorData) - ); + it('default operators list is empty', async function () { + (await this.token.defaultOperators()).should.deep.equal([]); }); }); }); From 6c2b7c260d0baa406c86d3a873b80b9062451afd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Venturo?= Date: Wed, 8 May 2019 13:13:19 -0300 Subject: [PATCH 08/26] Add ERC20 compatibility to ERC777. (#1735) * Add ERC20 compatibility. * Reusing ERC20 tests for ERC777. * Improve documentation. * Add changelog entry. * Improved ERC20 behavior tests. * Add revert reasons to ERC777. * ERC20 methods allow sending tokens to contracts with no interface. * Register ERC20 interface. * Add comment about avoidLockingTokens. * Improve revert reason string. * Make ERC777 implement IERC20. * Fix test revert string. * Remove unnecesary require. * Add private _transfer. * Update contracts/drafts/ERC777/ERC777.sol Co-Authored-By: nventuro * Update private helper names. (cherry picked from commit aa4c9feabd25a9ffb42d0bf782ceac59aab24017) --- CHANGELOG.md | 2 +- contracts/drafts/ERC777/ERC777.sol | 172 ++++++++++++++--- contracts/token/ERC20/ERC20.sol | 18 +- test/drafts/ERC777/ERC777.behavior.js | 29 ++- test/drafts/ERC777/ERC777.test.js | 59 ++++-- test/token/ERC20/ERC20.behavior.js | 268 ++++++++++++++++++++++++++ test/token/ERC20/ERC20.test.js | 265 +------------------------ 7 files changed, 499 insertions(+), 314 deletions(-) create mode 100644 test/token/ERC20/ERC20.behavior.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 61e9ac41b..2eb697988 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ ### New features: * `ERC1820`: added support for interacting with the [ERC1820](https://eips.ethereum.org/EIPS/eip-1820) registry contract (`IERC1820Registry`), as well as base contracts that can be registered as implementers there. ([#1677](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1677)) - * `ERC777`: initial support for the [ERC777 token](https://eips.ethereum.org/EIPS/eip-777), which has multiple improvements over `ERC20` such as built-in burning, a more straightforward permission system, and optional sender and receiver hooks on transfer (mandatory for contracts!). ([#1684](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1684)) + * `ERC777`: support for the [ERC777 token](https://eips.ethereum.org/EIPS/eip-777), which has multiple improvements over `ERC20` (but is backwards compatible with it) such as built-in burning, a more straightforward permission system, and optional sender and receiver hooks on transfer (mandatory for contracts!). ([#1684](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1684)) * All contracts now have revert reason strings, which give insight into error conditions, and help debug failing transactions. ([#1704](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1704)) ### Improvements: diff --git a/contracts/drafts/ERC777/ERC777.sol b/contracts/drafts/ERC777/ERC777.sol index ab2e53dae..1810aa2d9 100644 --- a/contracts/drafts/ERC777/ERC777.sol +++ b/contracts/drafts/ERC777/ERC777.sol @@ -3,6 +3,7 @@ pragma solidity ^0.5.0; import "./IERC777.sol"; import "./IERC777Recipient.sol"; import "./IERC777Sender.sol"; +import "../../token/ERC20/IERC20.sol"; import "../../math/SafeMath.sol"; import "../../utils/Address.sol"; import "../IERC1820Registry.sol"; @@ -11,20 +12,19 @@ import "../IERC1820Registry.sol"; * @title ERC777 token implementation, with granularity harcoded to 1. * @author etsvigun , Bertrand Masius */ -contract ERC777 is IERC777 { +contract ERC777 is IERC777, IERC20 { using SafeMath for uint256; using Address for address; IERC1820Registry private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24); - string private _name; - - string private _symbol; - mapping(address => uint256) private _balances; uint256 private _totalSupply; + string private _name; + string private _symbol; + bytes32 constant private TOKENS_SENDER_INTERFACE_HASH = keccak256("ERC777TokensSender"); bytes32 constant private TOKENS_RECIPIENT_INTERFACE_HASH = keccak256("ERC777TokensRecipient"); @@ -38,6 +38,9 @@ contract ERC777 is IERC777 { mapping(address => mapping(address => bool)) private _operators; mapping(address => mapping(address => bool)) private _revokedDefaultOperators; + // ERC20-allowances + mapping (address => mapping (address => uint256)) private _allowances; + constructor( string memory name, string memory symbol, @@ -51,8 +54,9 @@ contract ERC777 is IERC777 { _defaultOperators[_defaultOperatorsArray[i]] = true; } - // register interface + // register interfaces _erc1820.setInterfaceImplementer(address(this), keccak256("ERC777Token"), address(this)); + _erc1820.setInterfaceImplementer(address(this), keccak256("ERC20Token"), address(this)); } /** @@ -62,7 +66,7 @@ contract ERC777 is IERC777 { * @param data bytes information attached to the send, and intended for the recipient (to) */ function send(address to, uint256 amount, bytes calldata data) external { - _send(msg.sender, msg.sender, to, amount, data, ""); + _sendRequiringReceptionAck(msg.sender, msg.sender, to, amount, data, ""); } /** @@ -82,8 +86,36 @@ contract ERC777 is IERC777 { ) external { - require(isOperatorFor(msg.sender, from)); - _send(msg.sender, from, to, amount, data, operatorData); + require(isOperatorFor(msg.sender, from), "ERC777: caller is not an operator for holder"); + _sendRequiringReceptionAck(msg.sender, from, to, amount, data, operatorData); + } + + /** + * @dev Transfer token to a specified address. + * Required for ERC20 compatiblity. Note that transferring tokens this way may result in locked tokens (i.e. tokens + * can be sent to a contract that does not implement the ERC777TokensRecipient interface). + * @param to The address to transfer to. + * @param value The amount to be transferred. + */ + function transfer(address to, uint256 value) external returns (bool) { + _transfer(msg.sender, msg.sender, to, value); + return true; + } + + /** + * @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. + * Required for ERC20 compatiblity. Note that transferring tokens this way may result in locked tokens (i.e. tokens + * can be sent to a contract that does not implement the ERC777TokensRecipient interface). + * @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) external returns (bool) { + _transfer(msg.sender, from, to, value); + _approve(from, msg.sender, _allowances[from][msg.sender].sub(value)); + return true; } /** @@ -103,7 +135,7 @@ contract ERC777 is IERC777 { * @param operatorData bytes extra information provided by the operator (if any) */ function operatorBurn(address from, uint256 amount, bytes calldata data, bytes calldata operatorData) external { - require(isOperatorFor(msg.sender, from)); + require(isOperatorFor(msg.sender, from), "ERC777: caller is not an operator for holder"); _burn(msg.sender, from, amount, data, operatorData); } @@ -112,7 +144,7 @@ contract ERC777 is IERC777 { * @param operator address to be authorized as operator */ function authorizeOperator(address operator) external { - require(msg.sender != operator); + require(msg.sender != operator, "ERC777: authorizing self as operator"); if (_defaultOperators[operator]) { delete _revokedDefaultOperators[msg.sender][operator]; @@ -128,7 +160,7 @@ contract ERC777 is IERC777 { * @param operator address to revoke operator rights from */ function revokeOperator(address operator) external { - require(operator != msg.sender); + require(operator != msg.sender, "ERC777: revoking self as operator"); if (_defaultOperators[operator]) { _revokedDefaultOperators[msg.sender][operator] = true; @@ -140,17 +172,18 @@ contract ERC777 is IERC777 { } /** - * @return the name of the token. - */ - function name() public view returns (string memory) { - return _name; - } - - /** - * @return the symbol of the token. + * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender. + * Beware that changing an allowance with this method brings the risk that someone may use both the old + * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this + * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: + * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 + * Required for ERC20 compatilibity. + * @param spender The address which will spend the funds. + * @param value The amount of tokens to be spent. */ - function symbol() public view returns (string memory) { - return _symbol; + function approve(address spender, uint256 value) external returns (bool) { + _approve(msg.sender, spender, value); + return true; } /** @@ -169,6 +202,27 @@ contract ERC777 is IERC777 { return _balances[tokenHolder]; } + /** + * @return the name of the token. + */ + function name() public view returns (string memory) { + return _name; + } + + /** + * @return the symbol of the token. + */ + function symbol() public view returns (string memory) { + return _symbol; + } + + /** + * @return the number of decimals of the token. + */ + function decimals() public pure returns (uint8) { + return 18; // The spec requires that decimals be 18 + } + /** * @dev Gets the token's granularity, * i.e. the smallest number of tokens (in the basic unit) @@ -203,6 +257,17 @@ contract ERC777 is IERC777 { _operators[tokenHolder][operator]; } + /** + * @dev Function to check the amount of tokens that an owner allowed to a spender. + * Required for ERC20 compatibility. + * @param owner address The address which owns the funds. + * @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) { + return _allowances[owner][spender]; + } + /** * @dev Mint tokens. Does not check authorization of operator * @dev the caller may ckeck that operator is authorized before calling @@ -221,15 +286,42 @@ contract ERC777 is IERC777 { ) internal { - require(to != address(0)); + require(to != address(0), "ERC777: mint to the zero address"); // Update state variables _totalSupply = _totalSupply.add(amount); _balances[to] = _balances[to].add(amount); - _callTokensReceived(operator, address(0), to, amount, userData, operatorData); + _callTokensReceived(operator, address(0), to, amount, userData, operatorData, true); emit Minted(operator, to, amount, userData, operatorData); + emit Transfer(address(0), to, amount); + } + + function _transfer(address operator, address from, address to, uint256 amount) private { + _sendAllowingNoReceptionAck(operator, from, to, amount, "", ""); + } + + function _sendRequiringReceptionAck( + address operator, + address from, + address to, + uint256 amount, + bytes memory userData, + bytes memory operatorData + ) private { + _send(operator, from, to, amount, userData, operatorData, true); + } + + function _sendAllowingNoReceptionAck( + address operator, + address from, + address to, + uint256 amount, + bytes memory userData, + bytes memory operatorData + ) private { + _send(operator, from, to, amount, userData, operatorData, false); } /** @@ -240,6 +332,7 @@ contract ERC777 is IERC777 { * @param amount uint256 amount of tokens to transfer * @param userData bytes extra information provided by the token holder (if any) * @param operatorData bytes extra information provided by the operator (if any) + * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient */ function _send( address operator, @@ -247,12 +340,13 @@ contract ERC777 is IERC777 { address to, uint256 amount, bytes memory userData, - bytes memory operatorData + bytes memory operatorData, + bool requireReceptionAck ) private { - require(from != address(0)); - require(to != address(0)); + require(from != address(0), "ERC777: transfer from the zero address"); + require(to != address(0), "ERC777: transfer to the zero address"); _callTokensToSend(operator, from, to, amount, userData, operatorData); @@ -260,9 +354,10 @@ contract ERC777 is IERC777 { _balances[from] = _balances[from].sub(amount); _balances[to] = _balances[to].add(amount); - _callTokensReceived(operator, from, to, amount, userData, operatorData); + _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck); emit Sent(operator, from, to, amount, userData, operatorData); + emit Transfer(from, to, amount); } /** @@ -282,7 +377,7 @@ contract ERC777 is IERC777 { ) private { - require(from != address(0)); + require(from != address(0), "ERC777: burn from the zero address"); _callTokensToSend(operator, from, address(0), amount, data, operatorData); @@ -291,6 +386,17 @@ contract ERC777 is IERC777 { _balances[from] = _balances[from].sub(amount); emit Burned(operator, from, amount, data, operatorData); + emit Transfer(from, address(0), amount); + } + + function _approve(address owner, address spender, uint256 value) private { + // TODO: restore this require statement if this function becomes internal, or is called at a new callsite. It is + // currently unnecessary. + //require(owner != address(0), "ERC777: approve from the zero address"); + require(spender != address(0), "ERC777: approve to the zero address"); + + _allowances[owner][spender] = value; + emit Approval(owner, spender, value); } /** @@ -327,6 +433,7 @@ contract ERC777 is IERC777 { * @param amount uint256 amount of tokens to transfer * @param userData bytes extra information provided by the token holder (if any) * @param operatorData bytes extra information provided by the operator (if any) + * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient */ function _callTokensReceived( address operator, @@ -334,15 +441,16 @@ contract ERC777 is IERC777 { address to, uint256 amount, bytes memory userData, - bytes memory operatorData + bytes memory operatorData, + bool requireReceptionAck ) private { address implementer = _erc1820.getInterfaceImplementer(to, TOKENS_RECIPIENT_INTERFACE_HASH); if (implementer != address(0)) { IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData); - } else { - require(!to.isContract()); + } else if (requireReceptionAck) { + require(!to.isContract(), "ERC777: token recipient contract has no implementer for ERC777TokensRecipient"); } } } diff --git a/contracts/token/ERC20/ERC20.sol b/contracts/token/ERC20/ERC20.sol index 63c87d2f2..30039d274 100644 --- a/contracts/token/ERC20/ERC20.sol +++ b/contracts/token/ERC20/ERC20.sol @@ -20,7 +20,7 @@ contract ERC20 is IERC20 { mapping (address => uint256) private _balances; - mapping (address => mapping (address => uint256)) private _allowed; + mapping (address => mapping (address => uint256)) private _allowances; uint256 private _totalSupply; @@ -47,7 +47,7 @@ contract ERC20 is IERC20 { * @return A uint256 specifying the amount of tokens still available for the spender. */ function allowance(address owner, address spender) public view returns (uint256) { - return _allowed[owner][spender]; + return _allowances[owner][spender]; } /** @@ -84,13 +84,13 @@ contract ERC20 is IERC20 { */ function transferFrom(address from, address to, uint256 value) public returns (bool) { _transfer(from, to, value); - _approve(from, msg.sender, _allowed[from][msg.sender].sub(value)); + _approve(from, msg.sender, _allowances[from][msg.sender].sub(value)); return true; } /** * @dev Increase the amount of tokens that an owner allowed to a spender. - * approve should be called when _allowed[msg.sender][spender] == 0. To increment + * approve should be called when _allowances[msg.sender][spender] == 0. To increment * allowed value is better to use this function to avoid 2 calls (and wait until * the first transaction is mined) * From MonolithDAO Token.sol @@ -99,13 +99,13 @@ contract ERC20 is IERC20 { * @param addedValue The amount of tokens to increase the allowance by. */ function increaseAllowance(address spender, uint256 addedValue) public returns (bool) { - _approve(msg.sender, spender, _allowed[msg.sender][spender].add(addedValue)); + _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue)); return true; } /** * @dev Decrease the amount of tokens that an owner allowed to a spender. - * approve should be called when _allowed[msg.sender][spender] == 0. To decrement + * approve should be called when _allowances[msg.sender][spender] == 0. To decrement * allowed value is better to use this function to avoid 2 calls (and wait until * the first transaction is mined) * From MonolithDAO Token.sol @@ -114,7 +114,7 @@ contract ERC20 is IERC20 { * @param subtractedValue The amount of tokens to decrease the allowance by. */ function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) { - _approve(msg.sender, spender, _allowed[msg.sender][spender].sub(subtractedValue)); + _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue)); return true; } @@ -171,7 +171,7 @@ contract ERC20 is IERC20 { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); - _allowed[owner][spender] = value; + _allowances[owner][spender] = value; emit Approval(owner, spender, value); } @@ -185,6 +185,6 @@ contract ERC20 is IERC20 { */ function _burnFrom(address account, uint256 value) internal { _burn(account, value); - _approve(account, msg.sender, _allowed[account][msg.sender].sub(value)); + _approve(account, msg.sender, _allowances[account][msg.sender].sub(value)); } } diff --git a/test/drafts/ERC777/ERC777.behavior.js b/test/drafts/ERC777/ERC777.behavior.js index a2b16073e..2a8db2aca 100644 --- a/test/drafts/ERC777/ERC777.behavior.js +++ b/test/drafts/ERC777/ERC777.behavior.js @@ -184,8 +184,9 @@ function shouldSendTokens (from, operator, to, amount, data, operatorData) { const initialFromBalance = await this.token.balanceOf(from); const initialToBalance = await this.token.balanceOf(to); + let logs; if (!operatorCall) { - const { logs } = await this.token.send(to, amount, data, { from }); + ({ logs } = await this.token.send(to, amount, data, { from })); expectEvent.inLogs(logs, 'Sent', { operator: from, from, @@ -195,7 +196,7 @@ function shouldSendTokens (from, operator, to, amount, data, operatorData) { operatorData: null, }); } else { - const { logs } = await this.token.operatorSend(from, to, amount, data, operatorData, { from: operator }); + ({ logs } = await this.token.operatorSend(from, to, amount, data, operatorData, { from: operator })); expectEvent.inLogs(logs, 'Sent', { operator, from, @@ -206,6 +207,12 @@ function shouldSendTokens (from, operator, to, amount, data, operatorData) { }); } + expectEvent.inLogs(logs, 'Transfer', { + from, + to, + value: amount, + }); + const finalTotalSupply = await this.token.totalSupply(); const finalFromBalance = await this.token.balanceOf(from); const finalToBalance = await this.token.balanceOf(to); @@ -231,8 +238,9 @@ function shouldBurnTokens (from, operator, amount, data, operatorData) { const initialTotalSupply = await this.token.totalSupply(); const initialFromBalance = await this.token.balanceOf(from); + let logs; if (!operatorCall) { - const { logs } = await this.token.burn(amount, data, { from }); + ({ logs } = await this.token.burn(amount, data, { from })); expectEvent.inLogs(logs, 'Burned', { operator: from, from, @@ -241,7 +249,7 @@ function shouldBurnTokens (from, operator, amount, data, operatorData) { operatorData: null, }); } else { - const { logs } = await this.token.operatorBurn(from, amount, data, operatorData, { from: operator }); + ({ logs } = await this.token.operatorBurn(from, amount, data, operatorData, { from: operator })); expectEvent.inLogs(logs, 'Burned', { operator, from, @@ -251,6 +259,12 @@ function shouldBurnTokens (from, operator, amount, data, operatorData) { }); } + expectEvent.inLogs(logs, 'Transfer', { + from, + to: ZERO_ADDRESS, + value: amount, + }); + const finalTotalSupply = await this.token.totalSupply(); const finalFromBalance = await this.token.balanceOf(from); @@ -274,6 +288,7 @@ function shouldInternalMintTokens (operator, to, amount, data, operatorData) { const initialToBalance = await this.token.balanceOf(to); const { logs } = await this.token.mintInternal(operator, to, amount, data, operatorData); + expectEvent.inLogs(logs, 'Minted', { operator, to, @@ -282,6 +297,12 @@ function shouldInternalMintTokens (operator, to, amount, data, operatorData) { operatorData, }); + expectEvent.inLogs(logs, 'Transfer', { + from: ZERO_ADDRESS, + to, + value: amount, + }); + const finalTotalSupply = await this.token.totalSupply(); const finalToBalance = await this.token.balanceOf(to); diff --git a/test/drafts/ERC777/ERC777.test.js b/test/drafts/ERC777/ERC777.test.js index 8a12539b8..8d758f6f9 100644 --- a/test/drafts/ERC777/ERC777.test.js +++ b/test/drafts/ERC777/ERC777.test.js @@ -9,6 +9,10 @@ const { shouldBehaveLikeERC777SendBurnWithSendHook, } = require('./ERC777.behavior'); +const { + shouldBehaveLikeERC20, +} = require('../../token/ERC20/ERC20.behavior'); + const ERC777 = artifacts.require('ERC777Mock'); const ERC777SenderRecipientMock = artifacts.require('ERC777SenderRecipientMock'); @@ -32,6 +36,8 @@ contract('ERC777', function ([ this.token = await ERC777.new(holder, initialSupply, name, symbol, defaultOperators); }); + shouldBehaveLikeERC20('ERC777', initialSupply, holder, anyone, defaultOperatorA); + it.skip('does not emit AuthorizedOperator events for default operators', async function () { expectEvent.not.inConstructor(this.token, 'AuthorizedOperator'); // This helper needs to be implemented }); @@ -45,7 +51,7 @@ contract('ERC777', function ([ (await this.token.symbol()).should.equal(symbol); }); - it('has a granularity of 1', async function () { + it('returns a granularity of 1', async function () { (await this.token.granularity()).should.be.bignumber.equal('1'); }); @@ -59,14 +65,23 @@ contract('ERC777', function ([ } }); - it('returns thte total supply', async function () { + it('returns the total supply', async function () { (await this.token.totalSupply()).should.be.bignumber.equal(initialSupply); }); - it('is registered in the registry', async function () { + it('returns 18 when decimals is called', async function () { + (await this.token.decimals()).should.be.bignumber.equal('18'); + }); + + it('the ERC777Token interface is registered in the registry', async function () { (await this.erc1820.getInterfaceImplementer(this.token.address, web3.utils.soliditySha3('ERC777Token'))) .should.equal(this.token.address); }); + + it('the ERC20Token interface is registered in the registry', async function () { + (await this.erc1820.getInterfaceImplementer(this.token.address, web3.utils.soliditySha3('ERC20Token'))) + .should.equal(this.token.address); + }); }); describe('balanceOf', function () { @@ -144,11 +159,15 @@ contract('ERC777', function ([ }); it('reverts when self-authorizing', async function () { - await shouldFail.reverting(this.token.authorizeOperator(holder, { from: holder })); + await shouldFail.reverting.withMessage( + this.token.authorizeOperator(holder, { from: holder }), 'ERC777: authorizing self as operator' + ); }); it('reverts when self-revoking', async function () { - await shouldFail.reverting(this.token.revokeOperator(holder, { from: holder })); + await shouldFail.reverting.withMessage( + this.token.revokeOperator(holder, { from: holder }), 'ERC777: revoking self as operator' + ); }); it('non-operators can be revoked', async function () { @@ -209,7 +228,10 @@ contract('ERC777', function ([ }); it('cannot be revoked for themselves', async function () { - await shouldFail.reverting(this.token.revokeOperator(defaultOperatorA, { from: defaultOperatorA })); + await shouldFail.reverting.withMessage( + this.token.revokeOperator(defaultOperatorA, { from: defaultOperatorA }), + 'ERC777: revoking self as operator' + ); }); context('with revoked default operator', function () { @@ -259,20 +281,35 @@ contract('ERC777', function ([ }); it('send reverts', async function () { - await shouldFail.reverting(this.token.send(this.recipient, amount, data)); + await shouldFail.reverting.withMessage( + this.token.send(this.recipient, amount, data, { from: holder }), + 'ERC777: token recipient contract has no implementer for ERC777TokensRecipient', + ); }); it('operatorSend reverts', async function () { - await shouldFail.reverting( - this.token.operatorSend(this.sender, this.recipient, amount, data, operatorData, { from: operator }) + await shouldFail.reverting.withMessage( + this.token.operatorSend(this.sender, this.recipient, amount, data, operatorData, { from: operator }), + 'ERC777: token recipient contract has no implementer for ERC777TokensRecipient', ); }); it('mint (internal) reverts', async function () { - await shouldFail.reverting( - this.token.mintInternal(operator, this.recipient, amount, data, operatorData) + await shouldFail.reverting.withMessage( + this.token.mintInternal(operator, this.recipient, amount, data, operatorData), + 'ERC777: token recipient contract has no implementer for ERC777TokensRecipient', ); }); + + it('(ERC20) transfer succeeds', async function () { + await this.token.transfer(this.recipient, amount, { from: holder }); + }); + + it('(ERC20) transferFrom succeeds', async function () { + const approved = anyone; + await this.token.approve(approved, amount, { from: this.sender }); + await this.token.transferFrom(this.sender, this.recipient, amount, { from: approved }); + }); }); }); diff --git a/test/token/ERC20/ERC20.behavior.js b/test/token/ERC20/ERC20.behavior.js new file mode 100644 index 000000000..2536df005 --- /dev/null +++ b/test/token/ERC20/ERC20.behavior.js @@ -0,0 +1,268 @@ +const { BN, constants, expectEvent, shouldFail } = require('openzeppelin-test-helpers'); +const { ZERO_ADDRESS } = constants; + +function shouldBehaveLikeERC20 (errorPrefix, initialSupply, initialHolder, recipient, anotherAccount) { + describe('total supply', function () { + it('returns the total amount of tokens', async function () { + (await this.token.totalSupply()).should.be.bignumber.equal(initialSupply); + }); + }); + + describe('balanceOf', function () { + describe('when the requested account has no tokens', function () { + it('returns zero', async function () { + (await this.token.balanceOf(anotherAccount)).should.be.bignumber.equal('0'); + }); + }); + + describe('when the requested account has some tokens', function () { + it('returns the total amount of tokens', async function () { + (await this.token.balanceOf(initialHolder)).should.be.bignumber.equal(initialSupply); + }); + }); + }); + + describe('transfer', function () { + describe('when the recipient is not the zero address', function () { + const to = recipient; + + describe('when the sender does not have enough balance', function () { + const amount = initialSupply.addn(1); + + it('reverts', async function () { + await shouldFail.reverting.withMessage(this.token.transfer(to, amount, { from: initialHolder }), + 'SafeMath: subtraction overflow' + ); + }); + }); + + describe('when the sender has enough balance', function () { + const amount = initialSupply; + + it('transfers the requested amount', async function () { + await this.token.transfer(to, amount, { from: initialHolder }); + + (await this.token.balanceOf(initialHolder)).should.be.bignumber.equal('0'); + + (await this.token.balanceOf(to)).should.be.bignumber.equal(amount); + }); + + it('emits a transfer event', async function () { + const { logs } = await this.token.transfer(to, amount, { from: initialHolder }); + + expectEvent.inLogs(logs, 'Transfer', { + from: initialHolder, + to: to, + value: amount, + }); + }); + }); + }); + + describe('when the recipient is the zero address', function () { + const to = ZERO_ADDRESS; + + it('reverts', async function () { + await shouldFail.reverting.withMessage(this.token.transfer(to, initialSupply, { from: initialHolder }), + `${errorPrefix}: transfer to the zero address` + ); + }); + }); + }); + + describe('transfer from', function () { + const spender = recipient; + + describe('when the recipient is not the zero address', function () { + const to = anotherAccount; + + describe('when the spender has enough approved balance', function () { + beforeEach(async function () { + await this.token.approve(spender, initialSupply, { from: initialHolder }); + }); + + describe('when the initial holder has enough balance', function () { + const amount = initialSupply; + + it('transfers the requested amount', async function () { + await this.token.transferFrom(initialHolder, to, amount, { from: spender }); + + (await this.token.balanceOf(initialHolder)).should.be.bignumber.equal('0'); + + (await this.token.balanceOf(to)).should.be.bignumber.equal(amount); + }); + + it('decreases the spender allowance', async function () { + await this.token.transferFrom(initialHolder, to, amount, { from: spender }); + + (await this.token.allowance(initialHolder, spender)).should.be.bignumber.equal('0'); + }); + + it('emits a transfer event', async function () { + const { logs } = await this.token.transferFrom(initialHolder, to, amount, { from: spender }); + + expectEvent.inLogs(logs, 'Transfer', { + from: initialHolder, + to: to, + value: amount, + }); + }); + + it('emits an approval event', async function () { + const { logs } = await this.token.transferFrom(initialHolder, to, amount, { from: spender }); + + expectEvent.inLogs(logs, 'Approval', { + owner: initialHolder, + spender: spender, + value: await this.token.allowance(initialHolder, spender), + }); + }); + }); + + describe('when the initial holder does not have enough balance', function () { + const amount = initialSupply.addn(1); + + it('reverts', async function () { + await shouldFail.reverting.withMessage(this.token.transferFrom( + initialHolder, to, amount, { from: spender }), 'SafeMath: subtraction overflow' + ); + }); + }); + }); + + describe('when the spender does not have enough approved balance', function () { + beforeEach(async function () { + await this.token.approve(spender, initialSupply.subn(1), { from: initialHolder }); + }); + + describe('when the initial holder has enough balance', function () { + const amount = initialSupply; + + it('reverts', async function () { + await shouldFail.reverting.withMessage(this.token.transferFrom( + initialHolder, to, amount, { from: spender }), 'SafeMath: subtraction overflow' + ); + }); + }); + + describe('when the initial holder does not have enough balance', function () { + const amount = initialSupply.addn(1); + + it('reverts', async function () { + await shouldFail.reverting.withMessage(this.token.transferFrom( + initialHolder, to, amount, { from: spender }), 'SafeMath: subtraction overflow' + ); + }); + }); + }); + }); + + describe('when the recipient is the zero address', function () { + const amount = initialSupply; + const to = ZERO_ADDRESS; + + beforeEach(async function () { + await this.token.approve(spender, amount, { from: initialHolder }); + }); + + it('reverts', async function () { + await shouldFail.reverting.withMessage(this.token.transferFrom( + initialHolder, to, amount, { from: spender }), `${errorPrefix}: transfer to the zero address` + ); + }); + }); + }); + + describe('approve', function () { + shouldBehaveLikeERC20Approve(errorPrefix, initialHolder, recipient, initialSupply, + function (owner, spender, amount) { + return this.token.approve(spender, amount, { from: owner }); + } + ); + }); +} + +function shouldBehaveLikeERC20Approve (errorPrefix, owner, spender, supply, approve) { + describe('when the spender is not the zero address', function () { + describe('when the sender has enough balance', function () { + const amount = supply; + + it('emits an approval event', async function () { + const { logs } = await approve.call(this, owner, spender, amount); + + expectEvent.inLogs(logs, 'Approval', { + owner: owner, + spender: spender, + value: amount, + }); + }); + + describe('when there was no approved amount before', function () { + it('approves the requested amount', async function () { + await approve.call(this, owner, spender, amount); + + (await this.token.allowance(owner, spender)).should.be.bignumber.equal(amount); + }); + }); + + describe('when the spender had an approved amount', function () { + beforeEach(async function () { + await approve.call(this, owner, spender, new BN(1)); + }); + + it('approves the requested amount and replaces the previous one', async function () { + await approve.call(this, owner, spender, amount); + + (await this.token.allowance(owner, spender)).should.be.bignumber.equal(amount); + }); + }); + }); + + describe('when the sender does not have enough balance', function () { + const amount = supply.addn(1); + + it('emits an approval event', async function () { + const { logs } = await approve.call(this, owner, spender, amount); + + expectEvent.inLogs(logs, 'Approval', { + owner: owner, + spender: spender, + value: amount, + }); + }); + + describe('when there was no approved amount before', function () { + it('approves the requested amount', async function () { + await approve.call(this, owner, spender, amount); + + (await this.token.allowance(owner, spender)).should.be.bignumber.equal(amount); + }); + }); + + describe('when the spender had an approved amount', function () { + beforeEach(async function () { + await approve.call(this, owner, spender, new BN(1)); + }); + + it('approves the requested amount and replaces the previous one', async function () { + await approve.call(this, owner, spender, amount); + + (await this.token.allowance(owner, spender)).should.be.bignumber.equal(amount); + }); + }); + }); + }); + + describe('when the spender is the zero address', function () { + it('reverts', async function () { + await shouldFail.reverting.withMessage(approve.call(this, owner, ZERO_ADDRESS, supply), + `${errorPrefix}: approve to the zero address` + ); + }); + }); +} + +module.exports = { + shouldBehaveLikeERC20, + shouldBehaveLikeERC20Approve, +}; diff --git a/test/token/ERC20/ERC20.test.js b/test/token/ERC20/ERC20.test.js index ba506d519..be7726559 100644 --- a/test/token/ERC20/ERC20.test.js +++ b/test/token/ERC20/ERC20.test.js @@ -1,184 +1,21 @@ const { BN, constants, expectEvent, shouldFail } = require('openzeppelin-test-helpers'); const { ZERO_ADDRESS } = constants; +const { + shouldBehaveLikeERC20, + shouldBehaveLikeERC20Approve, +} = require('./ERC20.behavior'); + const ERC20Mock = artifacts.require('ERC20Mock'); contract('ERC20', function ([_, initialHolder, recipient, anotherAccount]) { const initialSupply = new BN(100); + beforeEach(async function () { this.token = await ERC20Mock.new(initialHolder, initialSupply); }); - describe('total supply', function () { - it('returns the total amount of tokens', async function () { - (await this.token.totalSupply()).should.be.bignumber.equal(initialSupply); - }); - }); - - describe('balanceOf', function () { - describe('when the requested account has no tokens', function () { - it('returns zero', async function () { - (await this.token.balanceOf(anotherAccount)).should.be.bignumber.equal('0'); - }); - }); - - describe('when the requested account has some tokens', function () { - it('returns the total amount of tokens', async function () { - (await this.token.balanceOf(initialHolder)).should.be.bignumber.equal(initialSupply); - }); - }); - }); - - describe('transfer', function () { - describe('when the recipient is not the zero address', function () { - const to = recipient; - - describe('when the sender does not have enough balance', function () { - const amount = initialSupply.addn(1); - - it('reverts', async function () { - await shouldFail.reverting.withMessage(this.token.transfer(to, amount, { from: initialHolder }), - 'SafeMath: subtraction overflow' - ); - }); - }); - - describe('when the sender has enough balance', function () { - const amount = initialSupply; - - it('transfers the requested amount', async function () { - await this.token.transfer(to, amount, { from: initialHolder }); - - (await this.token.balanceOf(initialHolder)).should.be.bignumber.equal('0'); - - (await this.token.balanceOf(to)).should.be.bignumber.equal(amount); - }); - - it('emits a transfer event', async function () { - const { logs } = await this.token.transfer(to, amount, { from: initialHolder }); - - expectEvent.inLogs(logs, 'Transfer', { - from: initialHolder, - to: to, - value: amount, - }); - }); - }); - }); - - describe('when the recipient is the zero address', function () { - const to = ZERO_ADDRESS; - - it('reverts', async function () { - await shouldFail.reverting.withMessage(this.token.transfer(to, initialSupply, { from: initialHolder }), - 'ERC20: transfer to the zero address' - ); - }); - }); - }); - - describe('transfer from', function () { - const spender = recipient; - - describe('when the recipient is not the zero address', function () { - const to = anotherAccount; - - describe('when the spender has enough approved balance', function () { - beforeEach(async function () { - await this.token.approve(spender, initialSupply, { from: initialHolder }); - }); - - describe('when the initial holder has enough balance', function () { - const amount = initialSupply; - - it('transfers the requested amount', async function () { - await this.token.transferFrom(initialHolder, to, amount, { from: spender }); - - (await this.token.balanceOf(initialHolder)).should.be.bignumber.equal('0'); - - (await this.token.balanceOf(to)).should.be.bignumber.equal(amount); - }); - - it('decreases the spender allowance', async function () { - await this.token.transferFrom(initialHolder, to, amount, { from: spender }); - - (await this.token.allowance(initialHolder, spender)).should.be.bignumber.equal('0'); - }); - - it('emits a transfer event', async function () { - const { logs } = await this.token.transferFrom(initialHolder, to, amount, { from: spender }); - - expectEvent.inLogs(logs, 'Transfer', { - from: initialHolder, - to: to, - value: amount, - }); - }); - - it('emits an approval event', async function () { - const { logs } = await this.token.transferFrom(initialHolder, to, amount, { from: spender }); - - expectEvent.inLogs(logs, 'Approval', { - owner: initialHolder, - spender: spender, - value: await this.token.allowance(initialHolder, spender), - }); - }); - }); - - describe('when the initial holder does not have enough balance', function () { - const amount = initialSupply.addn(1); - - it('reverts', async function () { - await shouldFail.reverting.withMessage(this.token.transferFrom( - initialHolder, to, amount, { from: spender }), 'SafeMath: subtraction overflow' - ); - }); - }); - }); - - describe('when the spender does not have enough approved balance', function () { - beforeEach(async function () { - await this.token.approve(spender, initialSupply.subn(1), { from: initialHolder }); - }); - - describe('when the initial holder has enough balance', function () { - const amount = initialSupply; - - it('reverts', async function () { - await shouldFail.reverting.withMessage(this.token.transferFrom( - initialHolder, to, amount, { from: spender }), 'SafeMath: subtraction overflow' - ); - }); - }); - - describe('when the initial holder does not have enough balance', function () { - const amount = initialSupply.addn(1); - - it('reverts', async function () { - await shouldFail.reverting.withMessage(this.token.transferFrom( - initialHolder, to, amount, { from: spender }), 'SafeMath: subtraction overflow' - ); - }); - }); - }); - }); - - describe('when the recipient is the zero address', function () { - const amount = initialSupply; - const to = ZERO_ADDRESS; - - beforeEach(async function () { - await this.token.approve(spender, amount, { from: initialHolder }); - }); - - it('reverts', async function () { - await shouldFail.reverting.withMessage(this.token.transferFrom( - initialHolder, to, amount, { from: spender }), 'ERC20: transfer to the zero address' - ); - }); - }); - }); + shouldBehaveLikeERC20('ERC20', initialSupply, initialHolder, recipient, anotherAccount); describe('decrease allowance', function () { describe('when the spender is not the zero address', function () { @@ -493,14 +330,8 @@ contract('ERC20', function ([_, initialHolder, recipient, anotherAccount]) { }); }); - describe('approve', function () { - testApprove(initialHolder, recipient, initialSupply, function (owner, spender, amount) { - return this.token.approve(spender, amount, { from: owner }); - }); - }); - describe('_approve', function () { - testApprove(initialHolder, recipient, initialSupply, function (owner, spender, amount) { + shouldBehaveLikeERC20Approve('ERC20', initialHolder, recipient, initialSupply, function (owner, spender, amount) { return this.token.approveInternal(owner, spender, amount); }); @@ -512,84 +343,4 @@ contract('ERC20', function ([_, initialHolder, recipient, anotherAccount]) { }); }); }); - - function testApprove (owner, spender, supply, approve) { - describe('when the spender is not the zero address', function () { - describe('when the sender has enough balance', function () { - const amount = supply; - - it('emits an approval event', async function () { - const { logs } = await approve.call(this, owner, spender, amount); - - expectEvent.inLogs(logs, 'Approval', { - owner: owner, - spender: spender, - value: amount, - }); - }); - - describe('when there was no approved amount before', function () { - it('approves the requested amount', async function () { - await approve.call(this, owner, spender, amount); - - (await this.token.allowance(owner, spender)).should.be.bignumber.equal(amount); - }); - }); - - describe('when the spender had an approved amount', function () { - beforeEach(async function () { - await approve.call(this, owner, spender, new BN(1)); - }); - - it('approves the requested amount and replaces the previous one', async function () { - await approve.call(this, owner, spender, amount); - - (await this.token.allowance(owner, spender)).should.be.bignumber.equal(amount); - }); - }); - }); - - describe('when the sender does not have enough balance', function () { - const amount = supply.addn(1); - - it('emits an approval event', async function () { - const { logs } = await approve.call(this, owner, spender, amount); - - expectEvent.inLogs(logs, 'Approval', { - owner: owner, - spender: spender, - value: amount, - }); - }); - - describe('when there was no approved amount before', function () { - it('approves the requested amount', async function () { - await approve.call(this, owner, spender, amount); - - (await this.token.allowance(owner, spender)).should.be.bignumber.equal(amount); - }); - }); - - describe('when the spender had an approved amount', function () { - beforeEach(async function () { - await approve.call(this, owner, spender, new BN(1)); - }); - - it('approves the requested amount and replaces the previous one', async function () { - await approve.call(this, owner, spender, amount); - - (await this.token.allowance(owner, spender)).should.be.bignumber.equal(amount); - }); - }); - }); - }); - - describe('when the spender is the zero address', function () { - it('reverts', async function () { - await shouldFail.reverting.withMessage(approve.call(this, owner, ZERO_ADDRESS, supply), - 'ERC20: approve to the zero address' - ); - }); - }); - } }); From 44590fe0b6f21eebf27c792ca9d04f54e876c547 Mon Sep 17 00:00:00 2001 From: Francisco Giordano Date: Wed, 8 May 2019 15:12:13 -0300 Subject: [PATCH 09/26] Inline keccak256 result (#1741) * inline keccak256 result * Update ERC777.sol * switch hex constant style * Update ERC777.sol (cherry picked from commit e60c7904d4d205137969efc2b5cf48670a422c6e) --- contracts/drafts/ERC777/ERC777.sol | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/contracts/drafts/ERC777/ERC777.sol b/contracts/drafts/ERC777/ERC777.sol index 1810aa2d9..7a46276e4 100644 --- a/contracts/drafts/ERC777/ERC777.sol +++ b/contracts/drafts/ERC777/ERC777.sol @@ -25,8 +25,15 @@ contract ERC777 is IERC777, IERC20 { string private _name; string private _symbol; - bytes32 constant private TOKENS_SENDER_INTERFACE_HASH = keccak256("ERC777TokensSender"); - bytes32 constant private TOKENS_RECIPIENT_INTERFACE_HASH = keccak256("ERC777TokensRecipient"); + // We inline the result of the following hashes because Solidity doesn't resolve them at compile time. + // See https://github.com/ethereum/solidity/issues/4024. + // + // keccak256("ERC777TokensSender") + bytes32 constant private TOKENS_SENDER_INTERFACE_HASH = + 0x29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe895; + // keccak256("ERC777TokensRecipient") + bytes32 constant private TOKENS_RECIPIENT_INTERFACE_HASH = + 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b; // This isn't ever read from - it's only used to respond to the defaultOperators query. address[] private _defaultOperatorsArray; From 1292b6abab424aee491e4d9ce2cd1c5a5022b0cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Venturo?= Date: Wed, 8 May 2019 16:11:00 -0300 Subject: [PATCH 10/26] Move ERC1820 and ERC777 out of drafts (#1742) * Moved ERC1820 related contracts out of drafts and into introspection. * Moved ERC777 related contracts out of drafts and into token. (cherry picked from commit c794c9661722ad44a93fe163b3fcc624eacd4361) --- .../{drafts => introspection}/ERC1820Implementer.sol | 0 .../{drafts => introspection}/IERC1820Implementer.sol | 0 .../{drafts => introspection}/IERC1820Registry.sol | 0 contracts/mocks/ERC1820ImplementerMock.sol | 2 +- contracts/mocks/ERC777Mock.sol | 2 +- contracts/mocks/ERC777SenderRecipientMock.sol | 10 +++++----- contracts/{drafts => token}/ERC777/ERC777.sol | 2 +- contracts/{drafts => token}/ERC777/IERC777.sol | 0 .../{drafts => token}/ERC777/IERC777Recipient.sol | 0 contracts/{drafts => token}/ERC777/IERC777Sender.sol | 0 10 files changed, 8 insertions(+), 8 deletions(-) rename contracts/{drafts => introspection}/ERC1820Implementer.sol (100%) rename contracts/{drafts => introspection}/IERC1820Implementer.sol (100%) rename contracts/{drafts => introspection}/IERC1820Registry.sol (100%) rename contracts/{drafts => token}/ERC777/ERC777.sol (99%) rename contracts/{drafts => token}/ERC777/IERC777.sol (100%) rename contracts/{drafts => token}/ERC777/IERC777Recipient.sol (100%) rename contracts/{drafts => token}/ERC777/IERC777Sender.sol (100%) diff --git a/contracts/drafts/ERC1820Implementer.sol b/contracts/introspection/ERC1820Implementer.sol similarity index 100% rename from contracts/drafts/ERC1820Implementer.sol rename to contracts/introspection/ERC1820Implementer.sol diff --git a/contracts/drafts/IERC1820Implementer.sol b/contracts/introspection/IERC1820Implementer.sol similarity index 100% rename from contracts/drafts/IERC1820Implementer.sol rename to contracts/introspection/IERC1820Implementer.sol diff --git a/contracts/drafts/IERC1820Registry.sol b/contracts/introspection/IERC1820Registry.sol similarity index 100% rename from contracts/drafts/IERC1820Registry.sol rename to contracts/introspection/IERC1820Registry.sol diff --git a/contracts/mocks/ERC1820ImplementerMock.sol b/contracts/mocks/ERC1820ImplementerMock.sol index 94f1db951..e3b2e3a05 100644 --- a/contracts/mocks/ERC1820ImplementerMock.sol +++ b/contracts/mocks/ERC1820ImplementerMock.sol @@ -1,6 +1,6 @@ pragma solidity ^0.5.0; -import "../drafts/ERC1820Implementer.sol"; +import "../introspection/ERC1820Implementer.sol"; contract ERC1820ImplementerMock is ERC1820Implementer { function registerInterfaceForAddress(bytes32 interfaceHash, address account) public { diff --git a/contracts/mocks/ERC777Mock.sol b/contracts/mocks/ERC777Mock.sol index bb4c4ead2..5df02dd46 100644 --- a/contracts/mocks/ERC777Mock.sol +++ b/contracts/mocks/ERC777Mock.sol @@ -1,6 +1,6 @@ pragma solidity ^0.5.0; -import "../drafts/ERC777/ERC777.sol"; +import "../token/ERC777/ERC777.sol"; contract ERC777Mock is ERC777 { constructor( diff --git a/contracts/mocks/ERC777SenderRecipientMock.sol b/contracts/mocks/ERC777SenderRecipientMock.sol index abebfc6e2..d329c221e 100644 --- a/contracts/mocks/ERC777SenderRecipientMock.sol +++ b/contracts/mocks/ERC777SenderRecipientMock.sol @@ -1,10 +1,10 @@ pragma solidity ^0.5.0; -import "../drafts/ERC777/IERC777.sol"; -import "../drafts/ERC777/IERC777Sender.sol"; -import "../drafts/ERC777/IERC777Recipient.sol"; -import "../drafts/IERC1820Registry.sol"; -import "../drafts/ERC1820Implementer.sol"; +import "../token/ERC777/IERC777.sol"; +import "../token/ERC777/IERC777Sender.sol"; +import "../token/ERC777/IERC777Recipient.sol"; +import "../introspection/IERC1820Registry.sol"; +import "../introspection/ERC1820Implementer.sol"; contract ERC777SenderRecipientMock is IERC777Sender, IERC777Recipient, ERC1820Implementer { event TokensToSendCalled( diff --git a/contracts/drafts/ERC777/ERC777.sol b/contracts/token/ERC777/ERC777.sol similarity index 99% rename from contracts/drafts/ERC777/ERC777.sol rename to contracts/token/ERC777/ERC777.sol index 7a46276e4..b431c3532 100644 --- a/contracts/drafts/ERC777/ERC777.sol +++ b/contracts/token/ERC777/ERC777.sol @@ -6,7 +6,7 @@ import "./IERC777Sender.sol"; import "../../token/ERC20/IERC20.sol"; import "../../math/SafeMath.sol"; import "../../utils/Address.sol"; -import "../IERC1820Registry.sol"; +import "../../introspection/IERC1820Registry.sol"; /** * @title ERC777 token implementation, with granularity harcoded to 1. diff --git a/contracts/drafts/ERC777/IERC777.sol b/contracts/token/ERC777/IERC777.sol similarity index 100% rename from contracts/drafts/ERC777/IERC777.sol rename to contracts/token/ERC777/IERC777.sol diff --git a/contracts/drafts/ERC777/IERC777Recipient.sol b/contracts/token/ERC777/IERC777Recipient.sol similarity index 100% rename from contracts/drafts/ERC777/IERC777Recipient.sol rename to contracts/token/ERC777/IERC777Recipient.sol diff --git a/contracts/drafts/ERC777/IERC777Sender.sol b/contracts/token/ERC777/IERC777Sender.sol similarity index 100% rename from contracts/drafts/ERC777/IERC777Sender.sol rename to contracts/token/ERC777/IERC777Sender.sol From 81d04101ff5f928aefd6551941dae0b429eb1736 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Venturo?= Date: Wed, 8 May 2019 16:09:30 -0300 Subject: [PATCH 11/26] Fix linter. (cherry picked from commit c92b75305ea671fb18c01687f1ed22462a8c56c9) --- contracts/token/ERC777/ERC777.sol | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/contracts/token/ERC777/ERC777.sol b/contracts/token/ERC777/ERC777.sol index b431c3532..b331902c5 100644 --- a/contracts/token/ERC777/ERC777.sol +++ b/contracts/token/ERC777/ERC777.sol @@ -27,13 +27,14 @@ contract ERC777 is IERC777, IERC20 { // We inline the result of the following hashes because Solidity doesn't resolve them at compile time. // See https://github.com/ethereum/solidity/issues/4024. - // + // keccak256("ERC777TokensSender") bytes32 constant private TOKENS_SENDER_INTERFACE_HASH = - 0x29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe895; + 0x29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe895; + // keccak256("ERC777TokensRecipient") bytes32 constant private TOKENS_RECIPIENT_INTERFACE_HASH = - 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b; + 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b; // This isn't ever read from - it's only used to respond to the defaultOperators query. address[] private _defaultOperatorsArray; From b6b2aea21214a86cf3222e70760ae711eec46092 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Venturo?= Date: Wed, 8 May 2019 16:22:46 -0300 Subject: [PATCH 12/26] Remove broken linter rule. (cherry picked from commit 3112c1b95e669d76d0f8377789eab93104960491) --- .solhint.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.solhint.json b/.solhint.json index 7a85f3cf2..8df942a10 100644 --- a/.solhint.json +++ b/.solhint.json @@ -6,6 +6,7 @@ "bracket-align": false, "compiler-fixed": false, "no-simple-event-func-name": false, + "separate-by-one-line-in-contract": false, "two-lines-top-level-separator": false } } From 74ef942bd1eb0e595150b5f74d462455c3d73008 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Venturo?= Date: Wed, 8 May 2019 17:03:46 -0300 Subject: [PATCH 13/26] 2.3.0-rc.2 --- ethpm.json | 2 +- package-lock.json | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ethpm.json b/ethpm.json index b981ad1d5..852544ffd 100644 --- a/ethpm.json +++ b/ethpm.json @@ -1,6 +1,6 @@ { "package_name": "zeppelin", - "version": "2.3.0-rc.1", + "version": "2.3.0-rc.2", "description": "Secure Smart Contract library for Solidity", "authors": [ "OpenZeppelin Community " diff --git a/package-lock.json b/package-lock.json index f3b299af1..f25c0e67b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "openzeppelin-solidity", - "version": "2.3.0-rc.1", + "version": "2.3.0-rc.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 489734e16..fe04f411b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "openzeppelin-solidity", - "version": "2.3.0-rc.1", + "version": "2.3.0-rc.2", "description": "Secure Smart Contract library for Solidity", "files": [ "build", From f7ff3e7e678347322218514c406a77b4b4f09ef7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Venturo?= Date: Thu, 16 May 2019 11:50:54 -0300 Subject: [PATCH 14/26] Disallow ERC20._transfer from the zero address. (#1752) * Add requirement of non-zero from to ERC20 transfer. * Add test for transferFrom zero address to behavior. * Create ERC20.transfer behavior. * Add tests for _transfer. * Add changelog entry. * Fix linter error. * Delete repeated test. * Fix hardcoded error prefix. * Update CHANGELOG.md Co-Authored-By: Francisco Giordano * Address review comments. (cherry picked from commit ad18098d65bbb5e41dcf1a286b8550470039d056) --- CHANGELOG.md | 1 + contracts/mocks/ERC20Mock.sol | 4 + contracts/token/ERC20/ERC20.sol | 1 + test/token/ERC20/ERC20.behavior.js | 253 +++++++++++++++++------------ test/token/ERC20/ERC20.test.js | 15 ++ 5 files changed, 169 insertions(+), 105 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2eb697988..f85c53153 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ ### Bugfixes: * `PostDeliveryCrowdsale`: some validations where skipped when paired with other crowdsale flavors, such as `AllowanceCrowdsale`, or `MintableCrowdsale` and `ERC20Capped`, which could cause buyers to not be able to claim their purchased tokens. ([#1721](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1721)) + * `ERC20._transfer`: the `from` argument was allowed to be the zero address, so it was possible to internally trigger a transfer of 0 tokens from the zero address. This address is not a valid destinatary of transfers, nor can it give or receive allowance, so this behavior was inconsistent. It now reverts. ([#1752](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1752)) ## 2.2.0 (2019-03-14) diff --git a/contracts/mocks/ERC20Mock.sol b/contracts/mocks/ERC20Mock.sol index b5ed2fc7e..0fdfa6953 100644 --- a/contracts/mocks/ERC20Mock.sol +++ b/contracts/mocks/ERC20Mock.sol @@ -20,6 +20,10 @@ contract ERC20Mock is ERC20 { _burnFrom(account, amount); } + function transferInternal(address from, address to, uint256 value) public { + _transfer(from, to, value); + } + function approveInternal(address owner, address spender, uint256 value) public { _approve(owner, spender, value); } diff --git a/contracts/token/ERC20/ERC20.sol b/contracts/token/ERC20/ERC20.sol index 30039d274..7c7d36fec 100644 --- a/contracts/token/ERC20/ERC20.sol +++ b/contracts/token/ERC20/ERC20.sol @@ -125,6 +125,7 @@ contract ERC20 is IERC20 { * @param value The amount to be transferred. */ function _transfer(address from, address to, uint256 value) internal { + require(from != address(0), "ERC20: transfer from the zero address"); require(to != address(0), "ERC20: transfer to the zero address"); _balances[from] = _balances[from].sub(value); diff --git a/test/token/ERC20/ERC20.behavior.js b/test/token/ERC20/ERC20.behavior.js index 2536df005..8f4c0c32a 100644 --- a/test/token/ERC20/ERC20.behavior.js +++ b/test/token/ERC20/ERC20.behavior.js @@ -23,151 +23,127 @@ function shouldBehaveLikeERC20 (errorPrefix, initialSupply, initialHolder, recip }); describe('transfer', function () { - describe('when the recipient is not the zero address', function () { - const to = recipient; - - describe('when the sender does not have enough balance', function () { - const amount = initialSupply.addn(1); - - it('reverts', async function () { - await shouldFail.reverting.withMessage(this.token.transfer(to, amount, { from: initialHolder }), - 'SafeMath: subtraction overflow' - ); - }); - }); - - describe('when the sender has enough balance', function () { - const amount = initialSupply; - - it('transfers the requested amount', async function () { - await this.token.transfer(to, amount, { from: initialHolder }); + shouldBehaveLikeERC20Transfer(errorPrefix, initialHolder, recipient, initialSupply, + function (from, to, value) { + return this.token.transfer(to, value, { from }); + } + ); + }); - (await this.token.balanceOf(initialHolder)).should.be.bignumber.equal('0'); + describe('transfer from', function () { + const spender = recipient; - (await this.token.balanceOf(to)).should.be.bignumber.equal(amount); - }); + describe('when the token owner is not the zero address', function () { + const tokenOwner = initialHolder; - it('emits a transfer event', async function () { - const { logs } = await this.token.transfer(to, amount, { from: initialHolder }); + describe('when the recipient is not the zero address', function () { + const to = anotherAccount; - expectEvent.inLogs(logs, 'Transfer', { - from: initialHolder, - to: to, - value: amount, + describe('when the spender has enough approved balance', function () { + beforeEach(async function () { + await this.token.approve(spender, initialSupply, { from: initialHolder }); }); - }); - }); - }); - - describe('when the recipient is the zero address', function () { - const to = ZERO_ADDRESS; - it('reverts', async function () { - await shouldFail.reverting.withMessage(this.token.transfer(to, initialSupply, { from: initialHolder }), - `${errorPrefix}: transfer to the zero address` - ); - }); - }); - }); + describe('when the token owner has enough balance', function () { + const amount = initialSupply; - describe('transfer from', function () { - const spender = recipient; + it('transfers the requested amount', async function () { + await this.token.transferFrom(tokenOwner, to, amount, { from: spender }); - describe('when the recipient is not the zero address', function () { - const to = anotherAccount; + (await this.token.balanceOf(tokenOwner)).should.be.bignumber.equal('0'); - describe('when the spender has enough approved balance', function () { - beforeEach(async function () { - await this.token.approve(spender, initialSupply, { from: initialHolder }); - }); + (await this.token.balanceOf(to)).should.be.bignumber.equal(amount); + }); - describe('when the initial holder has enough balance', function () { - const amount = initialSupply; + it('decreases the spender allowance', async function () { + await this.token.transferFrom(tokenOwner, to, amount, { from: spender }); - it('transfers the requested amount', async function () { - await this.token.transferFrom(initialHolder, to, amount, { from: spender }); + (await this.token.allowance(tokenOwner, spender)).should.be.bignumber.equal('0'); + }); - (await this.token.balanceOf(initialHolder)).should.be.bignumber.equal('0'); + it('emits a transfer event', async function () { + const { logs } = await this.token.transferFrom(tokenOwner, to, amount, { from: spender }); - (await this.token.balanceOf(to)).should.be.bignumber.equal(amount); - }); + expectEvent.inLogs(logs, 'Transfer', { + from: tokenOwner, + to: to, + value: amount, + }); + }); - it('decreases the spender allowance', async function () { - await this.token.transferFrom(initialHolder, to, amount, { from: spender }); + it('emits an approval event', async function () { + const { logs } = await this.token.transferFrom(tokenOwner, to, amount, { from: spender }); - (await this.token.allowance(initialHolder, spender)).should.be.bignumber.equal('0'); + expectEvent.inLogs(logs, 'Approval', { + owner: tokenOwner, + spender: spender, + value: await this.token.allowance(tokenOwner, spender), + }); + }); }); - it('emits a transfer event', async function () { - const { logs } = await this.token.transferFrom(initialHolder, to, amount, { from: spender }); + describe('when the token owner does not have enough balance', function () { + const amount = initialSupply.addn(1); - expectEvent.inLogs(logs, 'Transfer', { - from: initialHolder, - to: to, - value: amount, + it('reverts', async function () { + await shouldFail.reverting.withMessage(this.token.transferFrom( + tokenOwner, to, amount, { from: spender }), 'SafeMath: subtraction overflow' + ); }); }); + }); + + describe('when the spender does not have enough approved balance', function () { + beforeEach(async function () { + await this.token.approve(spender, initialSupply.subn(1), { from: tokenOwner }); + }); - it('emits an approval event', async function () { - const { logs } = await this.token.transferFrom(initialHolder, to, amount, { from: spender }); + describe('when the token owner has enough balance', function () { + const amount = initialSupply; - expectEvent.inLogs(logs, 'Approval', { - owner: initialHolder, - spender: spender, - value: await this.token.allowance(initialHolder, spender), + it('reverts', async function () { + await shouldFail.reverting.withMessage(this.token.transferFrom( + tokenOwner, to, amount, { from: spender }), 'SafeMath: subtraction overflow' + ); }); }); - }); - describe('when the initial holder does not have enough balance', function () { - const amount = initialSupply.addn(1); + describe('when the token owner does not have enough balance', function () { + const amount = initialSupply.addn(1); - it('reverts', async function () { - await shouldFail.reverting.withMessage(this.token.transferFrom( - initialHolder, to, amount, { from: spender }), 'SafeMath: subtraction overflow' - ); + it('reverts', async function () { + await shouldFail.reverting.withMessage(this.token.transferFrom( + tokenOwner, to, amount, { from: spender }), 'SafeMath: subtraction overflow' + ); + }); }); }); }); - describe('when the spender does not have enough approved balance', function () { - beforeEach(async function () { - await this.token.approve(spender, initialSupply.subn(1), { from: initialHolder }); - }); - - describe('when the initial holder has enough balance', function () { - const amount = initialSupply; + describe('when the recipient is the zero address', function () { + const amount = initialSupply; + const to = ZERO_ADDRESS; - it('reverts', async function () { - await shouldFail.reverting.withMessage(this.token.transferFrom( - initialHolder, to, amount, { from: spender }), 'SafeMath: subtraction overflow' - ); - }); + beforeEach(async function () { + await this.token.approve(spender, amount, { from: tokenOwner }); }); - describe('when the initial holder does not have enough balance', function () { - const amount = initialSupply.addn(1); - - it('reverts', async function () { - await shouldFail.reverting.withMessage(this.token.transferFrom( - initialHolder, to, amount, { from: spender }), 'SafeMath: subtraction overflow' - ); - }); + it('reverts', async function () { + await shouldFail.reverting.withMessage(this.token.transferFrom( + tokenOwner, to, amount, { from: spender }), `${errorPrefix}: transfer to the zero address` + ); }); }); }); - describe('when the recipient is the zero address', function () { - const amount = initialSupply; - const to = ZERO_ADDRESS; - - beforeEach(async function () { - await this.token.approve(spender, amount, { from: initialHolder }); - }); + describe('when the token owner is the zero address', function () { + const amount = 0; + const tokenOwner = ZERO_ADDRESS; + const to = recipient; it('reverts', async function () { await shouldFail.reverting.withMessage(this.token.transferFrom( - initialHolder, to, amount, { from: spender }), `${errorPrefix}: transfer to the zero address` + tokenOwner, to, amount, { from: spender }), `${errorPrefix}: transfer from the zero address` ); }); }); @@ -182,6 +158,72 @@ function shouldBehaveLikeERC20 (errorPrefix, initialSupply, initialHolder, recip }); } +function shouldBehaveLikeERC20Transfer (errorPrefix, from, to, balance, transfer) { + describe('when the recipient is not the zero address', function () { + describe('when the sender does not have enough balance', function () { + const amount = balance.addn(1); + + it('reverts', async function () { + await shouldFail.reverting.withMessage(transfer.call(this, from, to, amount), + 'SafeMath: subtraction overflow' + ); + }); + }); + + describe('when the sender transfers all balance', function () { + const amount = balance; + + it('transfers the requested amount', async function () { + await transfer.call(this, from, to, amount); + + (await this.token.balanceOf(from)).should.be.bignumber.equal('0'); + + (await this.token.balanceOf(to)).should.be.bignumber.equal(amount); + }); + + it('emits a transfer event', async function () { + const { logs } = await transfer.call(this, from, to, amount); + + expectEvent.inLogs(logs, 'Transfer', { + from, + to, + value: amount, + }); + }); + }); + + describe('when the sender transfers zero tokens', function () { + const amount = new BN('0'); + + it('transfers the requested amount', async function () { + await transfer.call(this, from, to, amount); + + (await this.token.balanceOf(from)).should.be.bignumber.equal(balance); + + (await this.token.balanceOf(to)).should.be.bignumber.equal('0'); + }); + + it('emits a transfer event', async function () { + const { logs } = await transfer.call(this, from, to, amount); + + expectEvent.inLogs(logs, 'Transfer', { + from, + to, + value: amount, + }); + }); + }); + }); + + describe('when the recipient is the zero address', function () { + it('reverts', async function () { + await shouldFail.reverting.withMessage(transfer.call(this, from, ZERO_ADDRESS, balance), + `${errorPrefix}: transfer to the zero address` + ); + }); + }); +} + function shouldBehaveLikeERC20Approve (errorPrefix, owner, spender, supply, approve) { describe('when the spender is not the zero address', function () { describe('when the sender has enough balance', function () { @@ -264,5 +306,6 @@ function shouldBehaveLikeERC20Approve (errorPrefix, owner, spender, supply, appr module.exports = { shouldBehaveLikeERC20, + shouldBehaveLikeERC20Transfer, shouldBehaveLikeERC20Approve, }; diff --git a/test/token/ERC20/ERC20.test.js b/test/token/ERC20/ERC20.test.js index be7726559..847bce2df 100644 --- a/test/token/ERC20/ERC20.test.js +++ b/test/token/ERC20/ERC20.test.js @@ -3,6 +3,7 @@ const { ZERO_ADDRESS } = constants; const { shouldBehaveLikeERC20, + shouldBehaveLikeERC20Transfer, shouldBehaveLikeERC20Approve, } = require('./ERC20.behavior'); @@ -330,6 +331,20 @@ contract('ERC20', function ([_, initialHolder, recipient, anotherAccount]) { }); }); + describe('_transfer', function () { + shouldBehaveLikeERC20Transfer('ERC20', initialHolder, recipient, initialSupply, function (from, to, amount) { + return this.token.transferInternal(from, to, amount); + }); + + describe('when the sender is the zero address', function () { + it('reverts', async function () { + await shouldFail.reverting.withMessage(this.token.transferInternal(ZERO_ADDRESS, recipient, initialSupply), + 'ERC20: transfer from the zero address' + ); + }); + }); + }); + describe('_approve', function () { shouldBehaveLikeERC20Approve('ERC20', initialHolder, recipient, initialSupply, function (owner, spender, amount) { return this.token.approveInternal(owner, spender, amount); From 9ab93f8ae499ab211afc0591ef18a63d0d1182fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Venturo?= Date: Thu, 16 May 2019 16:01:02 -0300 Subject: [PATCH 15/26] Update transferFrom to modify allowance in-between hook calls. (#1751) * Fix transferFrom not updating allowance before calling receiver. * Fix from being passed as operator. (cherry picked from commit 2ccc12b328e6d5d1d3faa5b99bec8d1de8b92fea) --- contracts/token/ERC777/ERC777.sol | 83 ++++++++++++++++--------------- 1 file changed, 44 insertions(+), 39 deletions(-) diff --git a/contracts/token/ERC777/ERC777.sol b/contracts/token/ERC777/ERC777.sol index b331902c5..e70298ecc 100644 --- a/contracts/token/ERC777/ERC777.sol +++ b/contracts/token/ERC777/ERC777.sol @@ -74,7 +74,7 @@ contract ERC777 is IERC777, IERC20 { * @param data bytes information attached to the send, and intended for the recipient (to) */ function send(address to, uint256 amount, bytes calldata data) external { - _sendRequiringReceptionAck(msg.sender, msg.sender, to, amount, data, ""); + _send(msg.sender, msg.sender, to, amount, data, "", true); } /** @@ -95,7 +95,7 @@ contract ERC777 is IERC777, IERC20 { external { require(isOperatorFor(msg.sender, from), "ERC777: caller is not an operator for holder"); - _sendRequiringReceptionAck(msg.sender, from, to, amount, data, operatorData); + _send(msg.sender, from, to, amount, data, operatorData, true); } /** @@ -106,7 +106,16 @@ contract ERC777 is IERC777, IERC20 { * @param value The amount to be transferred. */ function transfer(address to, uint256 value) external returns (bool) { - _transfer(msg.sender, msg.sender, to, value); + require(to != address(0), "ERC777: transfer to the zero address"); + + address from = msg.sender; + + _callTokensToSend(from, from, to, value, "", ""); + + _move(from, from, to, value, "", ""); + + _callTokensReceived(from, from, to, value, "", "", false); + return true; } @@ -121,8 +130,18 @@ contract ERC777 is IERC777, IERC20 { * @param value uint256 the amount of tokens to be transferred */ function transferFrom(address from, address to, uint256 value) external returns (bool) { - _transfer(msg.sender, from, to, value); - _approve(from, msg.sender, _allowances[from][msg.sender].sub(value)); + require(to != address(0), "ERC777: transfer to the zero address"); + require(from != address(0), "ERC777: transfer from the zero address"); + + address operator = msg.sender; + + _callTokensToSend(operator, from, to, value, "", ""); + + _move(operator, from, to, value, "", ""); + _approve(from, operator, _allowances[from][operator].sub(value)); + + _callTokensReceived(operator, from, to, value, "", "", false); + return true; } @@ -306,32 +325,6 @@ contract ERC777 is IERC777, IERC20 { emit Transfer(address(0), to, amount); } - function _transfer(address operator, address from, address to, uint256 amount) private { - _sendAllowingNoReceptionAck(operator, from, to, amount, "", ""); - } - - function _sendRequiringReceptionAck( - address operator, - address from, - address to, - uint256 amount, - bytes memory userData, - bytes memory operatorData - ) private { - _send(operator, from, to, amount, userData, operatorData, true); - } - - function _sendAllowingNoReceptionAck( - address operator, - address from, - address to, - uint256 amount, - bytes memory userData, - bytes memory operatorData - ) private { - _send(operator, from, to, amount, userData, operatorData, false); - } - /** * @dev Send tokens * @param operator address operator requesting the transfer @@ -353,19 +346,14 @@ contract ERC777 is IERC777, IERC20 { ) private { - require(from != address(0), "ERC777: transfer from the zero address"); - require(to != address(0), "ERC777: transfer to the zero address"); + require(from != address(0), "ERC777: send from the zero address"); + require(to != address(0), "ERC777: send to the zero address"); _callTokensToSend(operator, from, to, amount, userData, operatorData); - // Update state variables - _balances[from] = _balances[from].sub(amount); - _balances[to] = _balances[to].add(amount); + _move(operator, from, to, amount, userData, operatorData); _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck); - - emit Sent(operator, from, to, amount, userData, operatorData); - emit Transfer(from, to, amount); } /** @@ -397,6 +385,23 @@ contract ERC777 is IERC777, IERC20 { emit Transfer(from, address(0), amount); } + function _move( + address operator, + address from, + address to, + uint256 amount, + bytes memory userData, + bytes memory operatorData + ) + private + { + _balances[from] = _balances[from].sub(amount); + _balances[to] = _balances[to].add(amount); + + emit Sent(operator, from, to, amount, userData, operatorData); + emit Transfer(from, to, amount); + } + function _approve(address owner, address spender, uint256 value) private { // TODO: restore this require statement if this function becomes internal, or is called at a new callsite. It is // currently unnecessary. From a289314426df78094cd326cca9f55339bc59c628 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Venturo?= Date: Thu, 16 May 2019 16:09:19 -0300 Subject: [PATCH 16/26] 2.3.0-rc.3 --- ethpm.json | 2 +- package-lock.json | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ethpm.json b/ethpm.json index 852544ffd..4b3efbd11 100644 --- a/ethpm.json +++ b/ethpm.json @@ -1,6 +1,6 @@ { "package_name": "zeppelin", - "version": "2.3.0-rc.2", + "version": "2.3.0-rc.3", "description": "Secure Smart Contract library for Solidity", "authors": [ "OpenZeppelin Community " diff --git a/package-lock.json b/package-lock.json index f25c0e67b..49f11af30 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "openzeppelin-solidity", - "version": "2.3.0-rc.2", + "version": "2.3.0-rc.3", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index fe04f411b..9588a5313 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "openzeppelin-solidity", - "version": "2.3.0-rc.2", + "version": "2.3.0-rc.3", "description": "Secure Smart Contract library for Solidity", "files": [ "build", From b7b8fa947ebf9cd29e68f1e7016f6d300a1e514c Mon Sep 17 00:00:00 2001 From: Francisco Giordano Date: Fri, 10 May 2019 22:21:36 -0300 Subject: [PATCH 17/26] fix prepack script (cherry picked from commit fa004a7f5de572b3dbcde1a8a81f9a87e353e799) --- package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index 9588a5313..4526d4ebb 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,6 @@ "test/behaviors" ], "scripts": { - "build": "scripts/build.sh", "compile": "truffle compile", "console": "truffle console", "coverage": "scripts/coverage.sh", @@ -19,7 +18,7 @@ "lint:js": "eslint .", "lint:js:fix": "eslint . --fix", "lint:sol": "solhint --max-warnings 0 \"contracts/**/*.sol\"", - "prepack": "npm run build", + "prepack": "scripts/prepack.sh", "release": "scripts/release/release.sh", "version": "scripts/release/update-changelog-release-date.js && scripts/release/update-ethpm-version.js", "test": "npm run compile && scripts/test.sh" From ee7ff81728d86648ce8d72ba70c25906d4a82abb Mon Sep 17 00:00:00 2001 From: Francisco Giordano Date: Tue, 14 May 2019 16:04:40 -0300 Subject: [PATCH 18/26] Improve prepack script (#1747) * improve prepack script * remove .npmignore * make prepack use pkg.files * fix linter errors (cherry picked from commit cc19ccfdb32911258d3f34c573f492dfd973e512) --- contracts/.npmignore | 2 - package-lock.json | 247 +++++++++++++++++++++++++++++-------------- package.json | 7 +- scripts/build.sh | 26 ----- scripts/compile.sh | 10 ++ scripts/prepack.js | 42 ++++++++ 6 files changed, 222 insertions(+), 112 deletions(-) delete mode 100644 contracts/.npmignore delete mode 100755 scripts/build.sh create mode 100755 scripts/compile.sh create mode 100644 scripts/prepack.js diff --git a/contracts/.npmignore b/contracts/.npmignore deleted file mode 100644 index e792d8bc6..000000000 --- a/contracts/.npmignore +++ /dev/null @@ -1,2 +0,0 @@ -mocks -examples diff --git a/package-lock.json b/package-lock.json index 49f11af30..f9082e520 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1874,32 +1874,12 @@ } }, "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "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" - } - } + "fill-range": "^7.0.1" } }, "brorand": { @@ -4900,6 +4880,111 @@ "is-glob": "^4.0.0", "merge2": "^1.2.3", "micromatch": "^3.1.10" + }, + "dependencies": { + "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", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "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" + } + } + } + }, + "fill-range": { + "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", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "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" + } + } + } + }, + "is-number": { + "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" + }, + "dependencies": { + "kind-of": { + "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" + } + } + } + }, + "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", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "to-regex-range": { + "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" + } + } } }, "fast-json-stable-stringify": { @@ -4990,26 +5075,12 @@ "dev": true }, "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "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" - } - } + "to-regex-range": "^5.0.1" } }, "finalhandler": { @@ -6448,6 +6519,26 @@ "kind-of": "^4.0.0" }, "dependencies": { + "is-number": { + "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" + }, + "dependencies": { + "kind-of": { + "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" + } + } + } + }, "kind-of": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", @@ -7197,24 +7288,10 @@ "dev": true }, "is-number": { - "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" - }, - "dependencies": { - "kind-of": { - "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" - } - } - } + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true }, "is-object": { "version": "1.0.1", @@ -8150,24 +8227,13 @@ "dev": true }, "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", "dev": true, "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" + "braces": "^3.0.1", + "picomatch": "^2.0.5" } }, "miller-rabin": { @@ -8698,7 +8764,8 @@ "docusaurus": "1.7.2", "glob": "^7.1.3", "gray-matter": "^4.0.2", - "lodash": "^4.17.11" + "lodash": "^4.17.11", + "shelljs": "^0.8.3" }, "dependencies": { "glob": { @@ -8714,6 +8781,17 @@ "once": "^1.3.0", "path-is-absolute": "^1.0.0" } + }, + "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" + } } } }, @@ -9068,6 +9146,12 @@ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", "dev": true }, + "picomatch": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.0.6.tgz", + "integrity": "sha512-Btng9qVvFsW6FkXYQQK5nEI5i8xdXFDmlKxC7Q8S2Bu5HGWnbQf7ts2kOoxJIrZn5hmw61RZIayAg2zBuJDtyQ==", + "dev": true + }, "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", @@ -13060,13 +13144,12 @@ } }, "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" + "is-number": "^7.0.0" } }, "toml": { diff --git a/package.json b/package.json index 4526d4ebb..e69c37f50 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,8 @@ "files": [ "build", "contracts", + "!contracts/mocks", + "!contracts/examples", "test/behaviors" ], "scripts": { @@ -18,10 +20,10 @@ "lint:js": "eslint .", "lint:js:fix": "eslint . --fix", "lint:sol": "solhint --max-warnings 0 \"contracts/**/*.sol\"", - "prepack": "scripts/prepack.sh", + "prepack": "node scripts/prepack.js", "release": "scripts/release/release.sh", "version": "scripts/release/update-changelog-release-date.js && scripts/release/update-ethpm-version.js", - "test": "npm run compile && scripts/test.sh" + "test": "scripts/test.sh" }, "repository": { "type": "git", @@ -54,6 +56,7 @@ "ethereumjs-util": "^6.0.0", "ganache-cli": "^6.4.1", "ganache-cli-coverage": "https://github.com/frangio/ganache-cli/releases/download/v6.4.1-coverage/ganache-cli-coverage-6.4.1.tgz", + "micromatch": "^4.0.2", "openzeppelin-docsite": "github:OpenZeppelin/openzeppelin-docsite", "openzeppelin-test-helpers": "^0.3.2", "solhint": "^1.5.0", diff --git a/scripts/build.sh b/scripts/build.sh deleted file mode 100755 index ec4607756..000000000 --- a/scripts/build.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/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..a3d853960 --- /dev/null +++ b/scripts/compile.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env sh + +if [ "$SOLC_NIGHTLY" = true ]; then + docker pull ethereum/solc:nightly +fi + +# Necessary to avoid an error in Truffle +rm -rf build/contracts + +truffle compile diff --git a/scripts/prepack.js b/scripts/prepack.js new file mode 100644 index 000000000..5b0e80e51 --- /dev/null +++ b/scripts/prepack.js @@ -0,0 +1,42 @@ +#!/usr/bin/env node + +// This script removes the build artifacts of ignored contracts. + +const fs = require('fs'); +const path = require('path'); +const cp = require('child_process'); +const match = require('micromatch'); + +function exec (cmd, ...args) { + cp.execFileSync(cmd, args, { stdio: 'inherit' }); +} + +function readJSON (path) { + return JSON.parse(fs.readFileSync(path)); +} + +exec('npm', 'run', 'compile'); + +const pkgFiles = readJSON('package.json').files; + +// Get only negated patterns. +const ignorePatterns = pkgFiles + .filter(pat => pat.startsWith('!')) +// Add **/* to ignore all files contained in the directories. + .flatMap(pat => [pat, path.join(pat, '**/*')]) +// Remove the negation part. Makes micromatch usage more intuitive. + .map(pat => pat.slice(1)); + +const artifactsDir = 'build/contracts'; + +for (const artifact of fs.readdirSync(artifactsDir)) { + const fullArtifactPath = path.join(artifactsDir, artifact); + const { sourcePath: fullSourcePath } = readJSON(fullArtifactPath); + const sourcePath = path.relative('.', fullSourcePath); + + const ignore = match.any(sourcePath, ignorePatterns); + + if (ignore) { + fs.unlinkSync(fullArtifactPath); + } +} From ca922c8fed51777a5ee3a8b0c4dd8149a2f7e402 Mon Sep 17 00:00:00 2001 From: Francisco Giordano Date: Wed, 15 May 2019 16:32:35 -0300 Subject: [PATCH 19/26] add log about removed artifacts in prepack.js (cherry picked from commit dd6ec21951cfccc98ef6ea4ae84836dda7b5c5a1) --- scripts/prepack.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/prepack.js b/scripts/prepack.js index 5b0e80e51..bb00b3ec9 100644 --- a/scripts/prepack.js +++ b/scripts/prepack.js @@ -29,6 +29,8 @@ const ignorePatterns = pkgFiles const artifactsDir = 'build/contracts'; +let n = 0; + for (const artifact of fs.readdirSync(artifactsDir)) { const fullArtifactPath = path.join(artifactsDir, artifact); const { sourcePath: fullSourcePath } = readJSON(fullArtifactPath); @@ -38,5 +40,8 @@ for (const artifact of fs.readdirSync(artifactsDir)) { if (ignore) { fs.unlinkSync(fullArtifactPath); + n += 1; } } + +console.error(`Removed ${n} mock artifacts`); From 96fbe823ff5d4cf440e5ffa5ee7a3bed620062e9 Mon Sep 17 00:00:00 2001 From: Francisco Giordano Date: Wed, 22 May 2019 18:35:40 -0300 Subject: [PATCH 20/26] Change prepack npm script to prepare (take 2) (#1755) * update truffle to include bugfix * change prepack script to prepare * add npx in compile script * fix for older node * rename script file to prepare (cherry picked from commit 036dd9bd6ec834a2882e0f2e5d1209eaf4296979) --- package-lock.json | 115 ++--------------------------- package.json | 4 +- scripts/compile.sh | 5 +- scripts/{prepack.js => prepare.js} | 8 +- 4 files changed, 14 insertions(+), 118 deletions(-) rename scripts/{prepack.js => prepare.js} (86%) diff --git a/package-lock.json b/package-lock.json index f9082e520..27fd702e1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11800,114 +11800,11 @@ "yargs": "^11.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 - }, - "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" - } - }, "semver": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", - "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", - "dev": 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, - "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=", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", "dev": true - }, - "yargs": { - "version": "11.1.0", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", - "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==", - "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": "^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=", - "dev": true, - "requires": { - "camelcase": "^4.1.0" - } } } }, @@ -13212,9 +13109,9 @@ "dev": true }, "truffle": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/truffle/-/truffle-5.0.0.tgz", - "integrity": "sha512-la0TJu+E59Ut62i6cGY0sugeubglDqH5w49a7IrpxZ1nnsDqv6qWB3ibiyYiCp/jr+iI0bLtcr3DKkfQjVDd+g==", + "version": "5.0.19", + "resolved": "https://registry.npmjs.org/truffle/-/truffle-5.0.19.tgz", + "integrity": "sha512-d4fxChHYCjccW33IO/4KLcGqjTDn+mw7vqdGvGi307CMo+KTtns+5c91+1iOKDQcSKiv8SHYgvtyF7cn/+FPAg==", "dev": true, "requires": { "app-module-path": "^2.2.0", diff --git a/package.json b/package.json index e69c37f50..69501633f 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "lint:js": "eslint .", "lint:js:fix": "eslint . --fix", "lint:sol": "solhint --max-warnings 0 \"contracts/**/*.sol\"", - "prepack": "node scripts/prepack.js", + "prepare": "node scripts/prepare.js", "release": "scripts/release/release.sh", "version": "scripts/release/update-changelog-release-date.js && scripts/release/update-ethpm-version.js", "test": "scripts/test.sh" @@ -62,6 +62,6 @@ "solhint": "^1.5.0", "solidity-coverage": "github:rotcivegaf/solidity-coverage#5875f5b7bc74d447f3312c9c0e9fc7814b482477", "solidity-docgen": "^0.2.0-alpha.0", - "truffle": "^5.0.0" + "truffle": "^5.0.18" } } diff --git a/scripts/compile.sh b/scripts/compile.sh index a3d853960..02eea1761 100755 --- a/scripts/compile.sh +++ b/scripts/compile.sh @@ -4,7 +4,4 @@ if [ "$SOLC_NIGHTLY" = true ]; then docker pull ethereum/solc:nightly fi -# Necessary to avoid an error in Truffle -rm -rf build/contracts - -truffle compile +npx truffle compile diff --git a/scripts/prepack.js b/scripts/prepare.js similarity index 86% rename from scripts/prepack.js rename to scripts/prepare.js index bb00b3ec9..7ba752346 100644 --- a/scripts/prepack.js +++ b/scripts/prepare.js @@ -22,11 +22,13 @@ const pkgFiles = readJSON('package.json').files; // Get only negated patterns. const ignorePatterns = pkgFiles .filter(pat => pat.startsWith('!')) -// Add **/* to ignore all files contained in the directories. - .flatMap(pat => [pat, path.join(pat, '**/*')]) // Remove the negation part. Makes micromatch usage more intuitive. .map(pat => pat.slice(1)); +const ignorePatternsSubtrees = ignorePatterns +// Add **/* to ignore all files contained in the directories. + .concat(ignorePatterns.map(pat => path.join(pat, '**/*'))); + const artifactsDir = 'build/contracts'; let n = 0; @@ -36,7 +38,7 @@ for (const artifact of fs.readdirSync(artifactsDir)) { const { sourcePath: fullSourcePath } = readJSON(fullArtifactPath); const sourcePath = path.relative('.', fullSourcePath); - const ignore = match.any(sourcePath, ignorePatterns); + const ignore = match.any(sourcePath, ignorePatternsSubtrees); if (ignore) { fs.unlinkSync(fullArtifactPath); From e41daba7b47afbe8e7a18ca541b1d3779a86e020 Mon Sep 17 00:00:00 2001 From: Francisco Giordano Date: Thu, 23 May 2019 18:17:07 -0300 Subject: [PATCH 21/26] merge api docs changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Squashed commit of the following: commit 06243c3e8e86074ff8e9e3f22b7829a2c315d707 Merge: 991882ec 99373558 Author: Francisco Giordano Date: Thu May 23 18:15:37 2019 -0300 Merge branch 'api-docs' into api-docs-merge commit 991882eca5bb8a3391995154bfb9d53d8a69cb4f Author: Francisco Giordano Date: Thu May 23 18:08:02 2019 -0300 manually apply docs changes and renamings commit fa1f6e97dd67a76c3cd828d0a5e19b4ac6c37acb Author: Francisco Giordano Date: Thu May 23 17:36:03 2019 -0300 move functions to new order commit 99373558e3af4905d29bc6f3f542ba93d28a24ab Author: Francisco Giordano Date: Thu May 23 16:23:40 2019 -0300 add missing docs links commit d180d6c36a6f5460e85473ee5a18992d1449a6ff Author: Francisco Giordano Date: Thu May 23 16:14:12 2019 -0300 update solidity-docgen dependency fixes uri encoded links commit faab0e50da91cd2f0a409e3ad32e2db127ad319a Author: Francisco Giordano Date: Thu May 23 16:05:03 2019 -0300 update openzeppelin-docsite and solidity-docgen dependencies add visibility specifiers commit ef305268bb2735e488e35d16819a4b432b3a35e3 Author: Nicolás Venturo Date: Thu May 23 15:36:45 2019 -0300 Fix guide links. commit 339b20dbfa2d5f6ea02e63c2f3fdcba0fe879c3c Author: Nicolás Venturo Date: Thu May 23 13:37:51 2019 -0300 Fix typos. commit 6c7b97460578b9eea90b53c280454e361f8f0052 Author: Francisco Giordano Date: Thu May 23 15:26:29 2019 -0300 fix utilities guide links commit 0e7692a8fd8516a11becc4121d77d792439600b1 Author: Francisco Giordano Date: Thu May 23 15:23:19 2019 -0300 update solidity-docgen dependency commit ebb8a8651516ece21736c6c3b2577eb1b3487651 Author: Francisco Giordano Date: Thu May 23 15:15:01 2019 -0300 fix utilities guide links commit 5ec47d62785e1d6e5f8e91edca58f2dc7f87d7a3 Author: Francisco Giordano Date: Thu May 23 15:14:49 2019 -0300 fix escrow docs ordering commit cdcdc909b16f219a9a3272036b6a8f21e34b48ef Author: Francisco Giordano Date: Thu May 23 13:35:07 2019 -0300 add wip notice commit 987e2951ae93211c8c70c8288e30573555c57830 Author: Francisco Giordano Date: Thu May 23 13:09:35 2019 -0300 update openzeppelin-docsite dependency fixes links to old versions commit b00d22c0affac2e2108df8b773dfa1706afcb44e Author: Francisco Giordano Date: Thu May 23 13:09:28 2019 -0300 fix guide links commit f112a9400c5e5ad495c8e0fdb972e26987b34244 Author: Francisco Giordano Date: Wed May 22 20:42:37 2019 -0300 update docsite commit 68aacdd56a29e35a84f6732f9293612bbcaf7520 Author: Nicolás Venturo Date: Wed May 22 20:00:39 2019 -0300 ERC20Capped commit 4edce78bab2c6d140f3ea3f33db71e92ca4d8aaf Author: Nicolás Venturo Date: Wed May 22 19:52:30 2019 -0300 Unnecessary polish on token docs. commit 2a4c91cf49c2736dc09c1c03cf383911def1a1b2 Author: Francisco Giordano Date: Wed May 22 19:20:05 2019 -0300 rename guides commit 61dd818ea76d4c170c4ab175c6be0d6067d21a29 Author: Nicolás Venturo Date: Wed May 22 17:04:09 2019 -0300 ERC1820 docs. commit 77b5f0353123b76358dc6d86bdc646c86c9b0bea Author: Nicolás Venturo Date: Wed May 22 16:17:34 2019 -0300 Introspection and ERC165. commit 76641a253b3b70279802c5134dd107532eea4b2c Author: Francisco Giordano Date: Wed May 22 17:59:53 2019 -0300 update docgen commit 7be98bc3fbd3566231f943f01b9acb58567d755b Author: Francisco Giordano Date: Wed May 22 17:23:50 2019 -0300 update solidity-docgen commit f7268e6e010f8ef9ac83df241a803f91efc08c0c Author: Francisco Giordano Date: Wed May 22 16:58:31 2019 -0300 update docgen commit 2a8c7a378e8962a5baeb334b2492815f05075f98 Author: Nicolás Venturo Date: Wed May 22 14:36:35 2019 -0300 Util docs. commit 327ae8ff45a1a523c7591bf4996c4a9b52d7ec7a Author: Francisco Giordano Date: Wed May 22 13:08:50 2019 -0300 add missing drafts commit 5e7f71335ac8423c0e363ae8c7ad9b2977f202f8 Author: Francisco Giordano Date: Wed May 22 12:47:41 2019 -0300 tweak ierc20 docs commit cd0e86a0b712f74ffd406e072d4b1fbf4dd2c176 Author: Francisco Giordano Date: Wed May 22 12:46:45 2019 -0300 add some erc721 docs commit e081184159417f71da14bc0fc110b7b11e29d75d Author: Francisco Giordano Date: Wed May 22 12:41:46 2019 -0300 update docsite commit 0beb75784022419d47123c2a9fe7a5f1eb87f9b2 Author: Francisco Giordano Date: Wed May 22 12:22:27 2019 -0300 correct drafts structure commit 2e94b287c7cead7a6c0603205670566461c31abb Author: Francisco Giordano Date: Wed May 22 11:56:25 2019 -0300 fix docsite-start script commit 0fa4160484309d0851584fe57c0d81a3600977db Author: Francisco Giordano Date: Wed May 22 11:47:44 2019 -0300 improve docsite start script (automatically watch docgen) commit 9d571897cc03bee92035964cf7a2cfeda1e2f690 Author: Francisco Giordano Date: Wed May 22 11:30:37 2019 -0300 update solidity-docgen commit 82980f5aefbdfb8a9815a3b7b0e88e970b65dd5d Author: Francisco Giordano Date: Tue May 21 19:15:13 2019 -0300 edit docs for Secondary commit 00d7a005b0530bee730b77a1b69a95f1b4ffe315 Author: Francisco Giordano Date: Tue May 21 19:15:13 2019 -0300 edit docs for ownable commit b0c4c2bdf83eca5d4a71792daac603236733d46e Author: Francisco Giordano Date: Tue May 21 18:27:13 2019 -0300 change title of Math section commit deb788583f191780e55b7f673520eaf13a5c7e23 Author: Francisco Giordano Date: Tue May 21 18:26:59 2019 -0300 capitalization commit f2bcf85d343ea4a0739fe22a77b1e22c2296ddea Author: Francisco Giordano Date: Tue May 21 18:26:06 2019 -0300 edit docs for Pausable commit 73ba0cf43dbb44c39c1bf2ee63ef9fe558faa919 Author: Nicolás Venturo Date: Sat May 18 19:08:06 2019 -0300 Crypto docs. commit 9d6fc6223f51cf2321b2e3217c512579654c3917 Merge: 7e21f8f7 9f1cec12 Author: Nicolás Venturo Date: Fri May 17 17:23:15 2019 -0300 Merge branch 'api-docs-777' into api-docs commit 9f1cec12e3351fb1b5fc0b59f5ded39928064a56 Author: Nicolás Venturo Date: Fri May 17 17:22:54 2019 -0300 ERC777 done. commit 7e21f8f7b6982d2f92df302cdf6ec62522d8ffff Author: Francisco Giordano Date: Fri May 17 16:39:47 2019 -0300 add math docs commit f18d1f17023b6e5b42ae04fc38aa1170e6863864 Author: Nicolás Venturo Date: Thu May 16 20:01:46 2019 -0300 First draft of ERC777 docs. commit 985c5d305329fd9d400120d86dce5c386e19cd50 Author: Nicolás Venturo Date: Thu May 16 19:14:32 2019 -0300 Final draft for IERC777. commit bf53f133d987b67f938a329e6d659ba3483aab0b Author: Francisco Giordano Date: Thu May 16 19:13:37 2019 -0300 more work on ERC20 api docs commit b7c250b7cb4669448cfab5535c4ff70b94a15635 Author: Nicolás Venturo Date: Thu May 16 17:08:47 2019 -0300 Fix typo. commit 197bbfbfc67a09607ead492b834879c62b3d905a Author: Nicolás Venturo Date: Thu May 16 17:05:14 2019 -0300 Initial draft of IERC777. commit 7dc3b55161c860437a8f13a2ce5808b1c3dd70a2 Author: Francisco Giordano Date: Thu May 16 11:58:32 2019 -0300 add payment docs structure commit da16fc4480243181e58c3440e977e76a91a1839a Author: Nicolás Venturo Date: Thu May 16 16:05:33 2019 -0300 Initial ERC777 docstrings. commit 9f6a7e35bd2f045e6063ca2f93c67b792c0ef47c Author: Francisco Giordano Date: Wed May 15 22:13:17 2019 -0300 partial pass through ERC20 docs (cherry picked from commit 2f9ae975c8bdc5c7f7fa26204896f6c717f07164) --- .solhint.json | 2 +- contracts/access/README.md | 2 + contracts/crowdsale/README.md | 2 + .../distribution/RefundableCrowdsale.sol | 4 +- contracts/cryptography/ECDSA.sol | 37 +- contracts/cryptography/MerkleProof.sol | 13 +- contracts/cryptography/README.md | 9 + contracts/drafts/README.md | 16 + contracts/introspection/ERC165.sol | 27 +- contracts/introspection/ERC165Checker.sol | 37 +- .../introspection/ERC1820Implementer.sol | 21 +- contracts/introspection/IERC165.sol | 19 +- .../introspection/IERC1820Implementer.sol | 16 +- contracts/introspection/IERC1820Registry.sol | 113 +- contracts/introspection/README.md | 23 + contracts/lifecycle/Pausable.sol | 22 +- contracts/math/Math.sol | 8 +- contracts/math/README.md | 10 + contracts/math/SafeMath.sol | 94 +- contracts/ownership/Ownable.sol | 32 +- contracts/ownership/README.md | 3 + contracts/ownership/Secondary.sol | 4 +- contracts/payment/README.md | 10 + contracts/payment/escrow/README.md | 8 + contracts/token/ERC20/ERC20.sol | 229 +- contracts/token/ERC20/ERC20Burnable.sol | 22 +- contracts/token/ERC20/ERC20Capped.sol | 16 +- contracts/token/ERC20/ERC20Detailed.sol | 26 +- contracts/token/ERC20/ERC20Mintable.sol | 19 +- contracts/token/ERC20/IERC20.sol | 69 +- contracts/token/ERC20/README.md | 25 +- contracts/token/ERC721/ERC721.sol | 2 + contracts/token/ERC721/IERC721.sol | 34 +- contracts/token/ERC721/README.md | 37 + contracts/token/ERC777/ERC777.sol | 310 +- contracts/token/ERC777/IERC777.sol | 169 +- contracts/token/ERC777/IERC777Recipient.sol | 22 +- contracts/token/ERC777/IERC777Sender.sol | 20 +- contracts/token/ERC777/README.md | 17 + contracts/utils/Address.sol | 25 +- contracts/utils/Arrays.sol | 21 +- contracts/utils/README.md | 11 + contracts/utils/ReentrancyGuard.sol | 14 +- ...ut-access-control.md => access-control.md} | 20 +- ...earn-about-crowdsales.md => crowdsales.md} | 28 +- docs/get-started.md | 10 +- docs/learn-about-utilities.md | 94 - docs/sidebar.json | 8 +- docs/{learn-about-tokens.md => tokens.md} | 32 +- docs/utilities.md | 94 + package-lock.json | 6540 +++++++++++------ package.json | 6 +- scripts/docsite.sh | 9 +- 53 files changed, 5434 insertions(+), 3027 deletions(-) create mode 100644 contracts/cryptography/README.md create mode 100644 contracts/drafts/README.md create mode 100644 contracts/introspection/README.md create mode 100644 contracts/math/README.md create mode 100644 contracts/ownership/README.md create mode 100644 contracts/payment/README.md create mode 100644 contracts/payment/escrow/README.md create mode 100644 contracts/token/ERC721/README.md create mode 100644 contracts/token/ERC777/README.md create mode 100644 contracts/utils/README.md rename docs/{learn-about-access-control.md => access-control.md} (60%) rename docs/{learn-about-crowdsales.md => crowdsales.md} (75%) delete mode 100644 docs/learn-about-utilities.md rename docs/{learn-about-tokens.md => tokens.md} (58%) create mode 100644 docs/utilities.md diff --git a/.solhint.json b/.solhint.json index 8df942a10..928e7ae96 100644 --- a/.solhint.json +++ b/.solhint.json @@ -2,7 +2,7 @@ "extends": "default", "rules": { "indent": ["error", 4], - + "func-order": false, "bracket-align": false, "compiler-fixed": false, "no-simple-event-func-name": false, diff --git a/contracts/access/README.md b/contracts/access/README.md index a1bedcde6..e39860b62 100644 --- a/contracts/access/README.md +++ b/contracts/access/README.md @@ -5,3 +5,5 @@ sections: - Roles - subdirectory: roles --- + +> This page is incomplete. We're working to improve it for the next release. Stay tuned! diff --git a/contracts/crowdsale/README.md b/contracts/crowdsale/README.md index fcc1e43fa..5a0ab479d 100644 --- a/contracts/crowdsale/README.md +++ b/contracts/crowdsale/README.md @@ -9,3 +9,5 @@ sections: - subdirectory: validation - subdirectory: distribution --- + +> This page is incomplete. We're working to improve it for the next release. Stay tuned! diff --git a/contracts/crowdsale/distribution/RefundableCrowdsale.sol b/contracts/crowdsale/distribution/RefundableCrowdsale.sol index 7502f69bf..d91044131 100644 --- a/contracts/crowdsale/distribution/RefundableCrowdsale.sol +++ b/contracts/crowdsale/distribution/RefundableCrowdsale.sol @@ -6,10 +6,10 @@ import "../../payment/escrow/RefundEscrow.sol"; /** * @title RefundableCrowdsale - * @dev Extension of FinalizableCrowdsale contract that adds a funding goal, and the possibility of users + * @dev Extension of `FinalizableCrowdsale` 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 + * 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. diff --git a/contracts/cryptography/ECDSA.sol b/contracts/cryptography/ECDSA.sol index c54fe6a56..630362127 100644 --- a/contracts/cryptography/ECDSA.sol +++ b/contracts/cryptography/ECDSA.sol @@ -1,17 +1,29 @@ pragma solidity ^0.5.0; /** - * @title Elliptic curve signature operations - * @dev Based on https://gist.github.com/axic/5b33912c6f61ae6fd96d6c4a47afde6d - * TODO Remove this library once solidity supports passing a signature to ecrecover. - * See https://github.com/ethereum/solidity/issues/864 + * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. + * + * These functions can be used to verify that a message was signed by the holder + * of the private keys of a given address. */ - 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() + * @dev Returns the address that signed a hashed message (`hash`) with + * `signature`. This address can then be used for verification purposes. + * + * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: + * this function rejects them by requiring the `s` value to be in the lower + * half order, and the `v` value to be either 27 or 28. + * + * (.note) This call _does not revert_ if the signature is invalid, or + * if the signer is otherwise unable to be retrieved. In those scenarios, + * the zero address is returned. + * + * (.warning) `hash` _must_ be the result of a hash operation for the + * verification to be secure: it is possible to craft signatures that + * recover to arbitrary addresses for non-hashed data. A safe way to ensure + * this is by receiving a hash of the original message (which may otherwise) + * be too long), and then calling `toEthSignedMessageHash` on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { // Check the signature length @@ -55,9 +67,12 @@ library ECDSA { } /** - * toEthSignedMessageHash - * @dev Prefix a bytes32 value with "\x19Ethereum Signed Message:" - * and hash the result. + * @dev Returns an Ethereum Signed Message, created from a `hash`. This + * replicates the behavior of the + * [`eth_sign`](https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign) + * JSON-RPC method. + * + * See `recover`. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, diff --git a/contracts/cryptography/MerkleProof.sol b/contracts/cryptography/MerkleProof.sol index 2a964c8ba..83a861546 100644 --- a/contracts/cryptography/MerkleProof.sol +++ b/contracts/cryptography/MerkleProof.sol @@ -1,17 +1,14 @@ pragma solidity ^0.5.0; /** - * @title MerkleProof - * @dev Merkle proof verification based on - * https://github.com/ameensol/merkle-tree-solidity/blob/master/src/MerkleProof.sol + * @dev These functions deal with verification of Merkle trees (hash trees), */ library MerkleProof { /** - * @dev Verifies a Merkle proof proving the existence of a leaf in a Merkle tree. Assumes that each pair of leaves - * and each pair of pre-images are sorted. - * @param proof Merkle proof containing sibling hashes on the branch from the leaf to the root of the Merkle tree - * @param root Merkle root - * @param leaf Leaf of Merkle tree + * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree + * defined by `root`. For this, a `proof` must be provided, containing + * sibling hashes on the branch from the leaf to the root of the tree. Each + * pair of leaves and each pair of pre-images are assumed to be sorted. */ function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { bytes32 computedHash = leaf; diff --git a/contracts/cryptography/README.md b/contracts/cryptography/README.md new file mode 100644 index 000000000..e2ac68521 --- /dev/null +++ b/contracts/cryptography/README.md @@ -0,0 +1,9 @@ +--- +sections: + - title: Libraries + contracts: + - ECDSA + - MerkleProof +--- + +This collection of libraries provides simple and safe ways to use different cryptographic primitives. diff --git a/contracts/drafts/README.md b/contracts/drafts/README.md new file mode 100644 index 000000000..36f2749b8 --- /dev/null +++ b/contracts/drafts/README.md @@ -0,0 +1,16 @@ +--- +sections: + - title: ERC 20 + contracts: + - ERC20Migrator + - ERC20Snapshot + - TokenVesting + - title: Miscellenous + contracts: + - Counters + - SignatureBouncer + - SignedSafeMath + - subdirectory: ERC1046 +--- + +> This page is incomplete. We're working to improve it for the next release. Stay tuned! diff --git a/contracts/introspection/ERC165.sol b/contracts/introspection/ERC165.sol index 05feab5bc..adea7391f 100644 --- a/contracts/introspection/ERC165.sol +++ b/contracts/introspection/ERC165.sol @@ -3,9 +3,10 @@ pragma solidity ^0.5.0; import "./IERC165.sol"; /** - * @title ERC165 - * @author Matt Condon (@shrugs) - * @dev Implements ERC165 using a lookup table. + * @dev Implementation of the `IERC165` interface. + * + * Contracts may inherit from this and call `_registerInterface` to declare + * their support of an interface. */ contract ERC165 is IERC165 { /* @@ -18,23 +19,31 @@ contract ERC165 is IERC165 { */ mapping(bytes4 => bool) private _supportedInterfaces; - /** - * @dev A contract implementing SupportsInterfaceWithLookup - * implements ERC165 itself. - */ constructor () internal { + // Derived contracts need only register support for their own interfaces, + // we register support for ERC165 itself here _registerInterface(_INTERFACE_ID_ERC165); } /** - * @dev Implement supportsInterface(bytes4) using a lookup table. + * @dev See `IERC165.supportsInterface`. + * + * Time complexity O(1), guaranteed to always use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool) { return _supportedInterfaces[interfaceId]; } /** - * @dev Internal method for registering an interface. + * @dev Registers the contract as an implementer of the interface defined by + * `interfaceId`. Support of the actual ERC165 interface is automatic and + * registering its interface id is not required. + * + * See `IERC165.supportsInterface`. + * + * Requirements: + * + * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`). */ function _registerInterface(bytes4 interfaceId) internal { require(interfaceId != 0xffffffff, "ERC165: invalid interface id"); diff --git a/contracts/introspection/ERC165Checker.sol b/contracts/introspection/ERC165Checker.sol index a569b46c5..d8788c477 100644 --- a/contracts/introspection/ERC165Checker.sol +++ b/contracts/introspection/ERC165Checker.sol @@ -1,9 +1,11 @@ pragma solidity ^0.5.0; /** - * @title ERC165Checker - * @dev Use `using ERC165Checker for address`; to include this library - * https://eips.ethereum.org/EIPS/eip-165 + * @dev Library used to query support of an interface declared via `IERC165`. + * + * Note that these functions return the actual result of the query: they do not + * `revert` if an interface is not supported. It is up to the caller to decide + * what to do in these cases. */ library ERC165Checker { // As per the EIP-165 spec, no interface should ever match 0xffffffff @@ -15,9 +17,7 @@ library ERC165Checker { bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7; /** - * @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 + * @dev Returns true if `account` supports the `IERC165` interface, */ function _supportsERC165(address account) internal view returns (bool) { // Any contract that implements ERC165 must explicitly indicate support of @@ -27,12 +27,10 @@ library ERC165Checker { } /** - * @notice Query if a contract implements an interface, also checks support of ERC165 - * @param account The address of the contract to query for support of an interface - * @param interfaceId The interface identifier, as specified in ERC-165 - * @return true if the contract at account indicates support of the interface with - * identifier interfaceId, false otherwise - * @dev Interface identification is specified in ERC-165. + * @dev Returns true if `account` supports the interface defined by + * `interfaceId`. Support for `IERC165` itself is queried automatically. + * + * See `IERC165.supportsInterface`. */ function _supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) { // query support of both ERC165 as per the spec and support of _interfaceId @@ -41,14 +39,15 @@ library ERC165Checker { } /** - * @notice Query if a contract implements interfaces, also checks support of ERC165 - * @param account The address of the contract to query for support of an interface - * @param interfaceIds A list of interface identifiers, as specified in ERC-165 - * @return true if the contract at account indicates support all interfaces in the - * interfaceIds list, false otherwise - * @dev Interface identification is specified in ERC-165. + * @dev Returns true if `account` supports all the interfaces defined in + * `interfaceIds`. Support for `IERC165` itself is queried automatically. + * + * Batch-querying can lead to gas savings by skipping repeated checks for + * `IERC165` support. + * + * See `IERC165.supportsInterface`. */ - function _supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) { + function _supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) { // query support of ERC165 itself if (!_supportsERC165(account)) { return false; diff --git a/contracts/introspection/ERC1820Implementer.sol b/contracts/introspection/ERC1820Implementer.sol index 48746a7ce..6132022b4 100644 --- a/contracts/introspection/ERC1820Implementer.sol +++ b/contracts/introspection/ERC1820Implementer.sol @@ -3,21 +3,32 @@ pragma solidity ^0.5.0; import "./IERC1820Implementer.sol"; /** - * @dev ERC1820Implementer allows your contract to implement an interface for another account in the sense of ERC1820. - * That account or one of its ERC1820 managers can register the implementer in the ERC1820 registry, but the registry - * will first check with the implementer if it agrees to it, and only allow it if it does. Using the internal - * function _registerInterfaceForAddress provided by this contract, you are expressing this agreement, - * and you will be able to register the contract as an implementer in the registry for that account. + * @dev Implementation of the `IERC1820Implementer` interface. + * + * Contracts may inherit from this and call `_registerInterfaceForAddress` to + * declare their willingness to be implementers. + * `IERC1820Registry.setInterfaceImplementer` should then be called for the + * registration to be complete. */ contract ERC1820Implementer is IERC1820Implementer { bytes32 constant private ERC1820_ACCEPT_MAGIC = keccak256(abi.encodePacked("ERC1820_ACCEPT_MAGIC")); mapping(bytes32 => mapping(address => bool)) private _supportedInterfaces; + /** + * See `IERC1820Implementer.canImplementInterfaceForAddress`. + */ function canImplementInterfaceForAddress(bytes32 interfaceHash, address account) external view returns (bytes32) { return _supportedInterfaces[interfaceHash][account] ? ERC1820_ACCEPT_MAGIC : bytes32(0x00); } + /** + * @dev Declares the contract as willing to be an implementer of + * `interfaceHash` for `account`. + * + * See `IERC1820Registry.setInterfaceImplementer` and + * `IERC1820Registry.interfaceHash`. + */ function _registerInterfaceForAddress(bytes32 interfaceHash, address account) internal { _supportedInterfaces[interfaceHash][account] = true; } diff --git a/contracts/introspection/IERC165.sol b/contracts/introspection/IERC165.sol index c5e90e6a1..5702b588e 100644 --- a/contracts/introspection/IERC165.sol +++ b/contracts/introspection/IERC165.sol @@ -1,15 +1,22 @@ pragma solidity ^0.5.0; /** - * @title IERC165 - * @dev https://eips.ethereum.org/EIPS/eip-165 + * @dev Interface of the ERC165 standard, as defined in the + * [EIP](https://eips.ethereum.org/EIPS/eip-165). + * + * Implementers can declare support of contract interfaces, which can then be + * queried by others (`ERC165Checker`). + * + * For an implementation, see `ERC165`. */ 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. + * @dev Returns true if this contract implements the interface defined by + * `interfaceId`. See the corresponding + * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) + * to learn more about how these ids are created. + * + * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } diff --git a/contracts/introspection/IERC1820Implementer.sol b/contracts/introspection/IERC1820Implementer.sol index eb4e7eaea..965676faa 100644 --- a/contracts/introspection/IERC1820Implementer.sol +++ b/contracts/introspection/IERC1820Implementer.sol @@ -1,17 +1,17 @@ pragma solidity ^0.5.0; /** - * @title IERC1820Implementer - * Interface for contracts that will be registered as implementers in the ERC1820 registry. - * @notice For more details, see https://eips.ethereum.org/EIPS/eip-1820 + * @dev Interface for an ERC1820 implementer, as defined in the + * [EIP](https://eips.ethereum.org/EIPS/eip-1820#interface-implementation-erc1820implementerinterface). + * Used by contracts that will be registered as implementers in the + * `IERC1820Registry`. */ interface IERC1820Implementer { /** - * @notice Indicates whether the contract implements the interface `interfaceHash` for the address `account` or - * not. - * @param interfaceHash keccak256 hash of the name of the interface - * @param account Address for which the contract will implement the interface - * @return ERC1820_ACCEPT_MAGIC only if the contract implements `interfaceHash` for the address `account`. + * @dev Returns a special value (`ERC1820_ACCEPT_MAGIC`) if this contract + * implements `interfaceHash` for `account`. + * + * See `IERC1820Registry.setInterfaceImplementer`. */ function canImplementInterfaceForAddress(bytes32 interfaceHash, address account) external view returns (bytes32); } diff --git a/contracts/introspection/IERC1820Registry.sol b/contracts/introspection/IERC1820Registry.sol index a979f79d9..02a5f630e 100644 --- a/contracts/introspection/IERC1820Registry.sol +++ b/contracts/introspection/IERC1820Registry.sol @@ -1,56 +1,88 @@ pragma solidity ^0.5.0; /** - * @title ERC1820 Pseudo-introspection Registry Contract - * @author Jordi Baylina and Jacques Dafflon - * @notice For more details, see https://eips.ethereum.org/EIPS/eip-1820 + * @dev Interface of the global ERC1820 Registry, as defined in the + * [EIP](https://eips.ethereum.org/EIPS/eip-1820). Accounts may register + * implementers for interfaces in this registry, as well as query support. + * + * Implementers may be shared by multiple accounts, and can also implement more + * than a single interface for each account. Contracts can implement interfaces + * for themselves, but externally-owned accounts (EOA) must delegate this to a + * contract. + * + * `IERC165` interfaces can also be queried via the registry. + * + * For an in-depth explanation and source code analysis, see the EIP text. */ interface IERC1820Registry { /** - * @notice Sets the contract which implements a specific interface for an address. - * Only the manager defined for that address can set it. - * (Each address is the manager for itself until it sets a new manager.) - * @param account Address for which to set the interface. - * (If 'account' is the zero address then 'msg.sender' is assumed.) - * @param interfaceHash Keccak256 hash of the name of the interface as a string. - * E.g., 'web3.utils.keccak256("ERC777TokensRecipient")' for the 'ERC777TokensRecipient' interface. - * @param implementer Contract address implementing `interfaceHash` for `account.address()`. + * @dev Sets `newManager` as the manager for `account`. A manager of an + * account is able to set interface implementers for it. + * + * By default, each account is its own manager. Passing a value of `0x0` in + * `newManager` will reset the manager to this initial state. + * + * Emits a `ManagerChanged` event. + * + * Requirements: + * + * - the caller must be the current manager for `account`. */ - function setInterfaceImplementer(address account, bytes32 interfaceHash, address implementer) external; + function setManager(address account, address newManager) external; /** - * @notice Sets `newManager.address()` as manager for `account.address()`. - * The new manager will be able to call 'setInterfaceImplementer' for `account.address()`. - * @param account Address for which to set the new manager. - * @param newManager Address of the new manager for `addr.address()`. - * (Pass '0x0' to reset the manager to `account.address()`.) + * @dev Returns the manager for `account`. + * + * See `setManager`. */ - function setManager(address account, address newManager) external; + function getManager(address account) external view returns (address); /** - * @notice Updates the cache with whether the contract implements an ERC165 interface or not. - * @param account Address of the contract for which to update the cache. - * @param interfaceId ERC165 interface for which to update the cache. + * @dev Sets the `implementer` contract as `account`'s implementer for + * `interfaceHash`. + * + * `account` being the zero address is an alias for the caller's address. + * The zero address can also be used in `implementer` to remove an old one. + * + * See `interfaceHash` to learn how these are created. + * + * Emits an `InterfaceImplementerSet` event. + * + * Requirements: + * + * - the caller must be the current manager for `account`. + * - `interfaceHash` must not be an `IERC165` interface id (i.e. it must not + * end in 28 zeroes). + * - `implementer` must implement `IERC1820Implementer` and return true when + * queried for support, unless `implementer` is the caller. See + * `IERC1820Implementer.canImplementInterfaceForAddress`. */ - function updateERC165Cache(address account, bytes4 interfaceId) external; + function setInterfaceImplementer(address account, bytes32 interfaceHash, address implementer) external; /** - * @notice Get the manager of an address. - * @param account Address for which to return the manager. - * @return Address of the manager for a given address. + * @dev Returns the implementer of `interfaceHash` for `account`. If no such + * implementer is registered, returns the zero address. + * + * If `interfaceHash` is an `IERC165` interface id (i.e. it ends with 28 + * zeroes), `account` will be queried for support of it. + * + * `account` being the zero address is an alias for the caller's address. */ - function getManager(address account) external view returns (address); + function getInterfaceImplementer(address account, bytes32 interfaceHash) external view returns (address); /** - * @notice Query if an address implements an interface and through which contract. - * @param account Address being queried for the implementer of an interface. - * (If 'account' is the zero address then 'msg.sender' is assumed.) - * @param interfaceHash Keccak256 hash of the name of the interface as a string. - * E.g., 'web3.utils.keccak256("ERC777TokensRecipient")' for the 'ERC777TokensRecipient' interface. - * @return The address of the contract which implements the interface `interfaceHash` for `account.address()` - * or '0' if `account.address()` did not register an implementer for this interface. + * @dev Returns the interface hash for an `interfaceName`, as defined in the + * corresponding + * [section of the EIP](https://eips.ethereum.org/EIPS/eip-1820#interface-name). */ - function getInterfaceImplementer(address account, bytes32 interfaceHash) external view returns (address); + function interfaceHash(string calldata interfaceName) external pure returns (bytes32); + + /** + * @notice Updates the cache with whether the contract implements an ERC165 interface or not. + * @param account Address of the contract for which to update the cache. + * @param interfaceId ERC165 interface for which to update the cache. + */ + function updateERC165Cache(address account, bytes4 interfaceId) external; /** * @notice Checks whether a contract implements an ERC165 interface or not. @@ -71,20 +103,7 @@ interface IERC1820Registry { */ function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool); - /** - * @notice Compute the keccak256 hash of an interface given its name. - * @param interfaceName Name of the interface. - * @return The keccak256 hash of an interface name. - */ - function interfaceHash(string calldata interfaceName) external pure returns (bytes32); - - /** - * @notice Indicates a contract is the `implementer` of `interfaceHash` for `account`. - */ event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer); - /** - * @notice Indicates `newManager` is the address of the new manager for `account`. - */ event ManagerChanged(address indexed account, address indexed newManager); } diff --git a/contracts/introspection/README.md b/contracts/introspection/README.md new file mode 100644 index 000000000..239b9c4aa --- /dev/null +++ b/contracts/introspection/README.md @@ -0,0 +1,23 @@ +--- +sections: + - title: Local + contracts: + - IERC165 + - ERC165 + - ERC165Checker + - title: Global + contracts: + - IERC1820Registry + - IERC1820Implementer + - ERC1820Implementer +--- + +This set of interfaces and contracts deal with [type introspection](https://en.wikipedia.org/wiki/Type_introspection) of contracts, that is, examining which functions can be called on them. This is usually referred to as a contract's _interface_. + +Ethereum contracts have no native concept of an interface, so applications must usually simply trust they are not making an incorrect call. For trusted setups this is a non-issue, but often unknown and untrusted third-party addresses need to be interacted with. There may even not be any direct calls to them! (e.g. `ERC20` tokens may be sent to a contract that lacks a way to transfer them out of it, locking them forever). In these cases, a contract _declaring_ its interface can be very helpful in preventing errors. + +There are two main ways to approach this. + - Locally, where a contract implements `IERC165` and declares an interface, and a second one queries it directly via `ERC165Checker`. + - Globally, where a global and unique registry (`IERC1820Registry`) is used to register implementers of a certain interface (`IERC1820Implementer`). It is then the registry that is queried, which allows for more complex setups, like contracts implementing interfaces for externally-owned accounts. + +Note that, in all cases, accounts simply _declare_ their interfaces, but they are not required to actually implement them. This mechanism can therefore be used to both prevent errors and allow for complex interactions (see `ERC777`), but it must not be relied on for security. diff --git a/contracts/lifecycle/Pausable.sol b/contracts/lifecycle/Pausable.sol index f9656f8ef..ab74d47fd 100644 --- a/contracts/lifecycle/Pausable.sol +++ b/contracts/lifecycle/Pausable.sol @@ -3,21 +3,37 @@ pragma solidity ^0.5.0; import "../access/roles/PauserRole.sol"; /** - * @title Pausable - * @dev Base contract which allows children to implement an emergency stop mechanism. + * @dev Contract module which allows children to implement an emergency stop + * mechanism that can be triggered by an authorized account. + * + * This module is used through inheritance. It will make available the + * modifiers `whenNotPaused` and `whenPaused`, which can be applied to + * the functions of your contract. Note that they will not be pausable by + * simply including this module, only once the modifiers are put in place. */ contract Pausable is PauserRole { + /** + * @dev Emitted when the pause is triggered by a pauser (`account`). + */ event Paused(address account); + + /** + * @dev Emitted when the pause is lifted by a pauser (`account`). + */ event Unpaused(address account); bool private _paused; + /** + * @dev Initializes the contract in unpaused state. Assigns the Pauser role + * to the deployer. + */ constructor () internal { _paused = false; } /** - * @return True if the contract is paused, false otherwise. + * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view returns (bool) { return _paused; diff --git a/contracts/math/Math.sol b/contracts/math/Math.sol index f50e874c1..4970a6cc6 100644 --- a/contracts/math/Math.sol +++ b/contracts/math/Math.sol @@ -1,8 +1,7 @@ pragma solidity ^0.5.0; /** - * @title Math - * @dev Assorted math operations. + * @dev Standard math utilities missing in the Solidity language. */ library Math { /** @@ -20,9 +19,8 @@ library Math { } /** - * @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. + * @dev Returns the average of two numbers. The result is rounded towards + * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow, so we distribute diff --git a/contracts/math/README.md b/contracts/math/README.md new file mode 100644 index 000000000..1d83bb662 --- /dev/null +++ b/contracts/math/README.md @@ -0,0 +1,10 @@ +--- +title: Math +sections: + - title: Libraries + contracts: + - SafeMath + - Math +--- + +These are math-related utilities. diff --git a/contracts/math/SafeMath.sol b/contracts/math/SafeMath.sol index 56076405f..932733e91 100644 --- a/contracts/math/SafeMath.sol +++ b/contracts/math/SafeMath.sol @@ -1,12 +1,59 @@ pragma solidity ^0.5.0; /** - * @title SafeMath - * @dev Unsigned math operations with safety checks that revert on error. + * @dev Wrappers over Solidity's arithmetic operations with added overflow + * checks. + * + * Arithmetic operations in Solidity wrap on overflow. This can easily result + * in bugs, because programmers usually assume that an overflow raises an + * error, which is the standard behavior in high level programming languages. + * `SafeMath` restores this intuition by reverting the transaction when an + * operation overflows. + * + * Using this library instead of the unchecked operations eliminates an entire + * class of bugs, so it's recommended to use it always. */ library SafeMath { /** - * @dev Multiplies two unsigned integers, reverts on overflow. + * @dev Returns the addition of two unsigned integers, reverting on + * overflow. + * + * Counterpart to Solidity's `+` operator. + * + * Requirements: + * - Addition cannot overflow. + */ + function add(uint256 a, uint256 b) internal pure returns (uint256) { + uint256 c = a + b; + require(c >= a, "SafeMath: addition overflow"); + + return c; + } + + /** + * @dev Returns the subtraction of two unsigned integers, reverting on + * overflow (when the result is negative). + * + * Counterpart to Solidity's `-` operator. + * + * Requirements: + * - Subtraction cannot overflow. + */ + function sub(uint256 a, uint256 b) internal pure returns (uint256) { + require(b <= a, "SafeMath: subtraction overflow"); + uint256 c = a - b; + + return c; + } + + /** + * @dev Returns the multiplication of two unsigned integers, reverting on + * overflow. + * + * Counterpart to Solidity's `*` operator. + * + * Requirements: + * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the @@ -23,7 +70,15 @@ library SafeMath { } /** - * @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero. + * @dev Returns the integer division of two unsigned integers. Reverts on + * division by zero. The result is rounded towards zero. + * + * Counterpart to Solidity's `/` operator. Note: this function uses a + * `revert` opcode (which leaves remaining gas untouched) while Solidity + * uses an invalid opcode to revert (consuming all remaining gas). + * + * Requirements: + * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 @@ -35,28 +90,15 @@ library SafeMath { } /** - * @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, "SafeMath: subtraction overflow"); - uint256 c = a - b; - - return c; - } - - /** - * @dev Adds two unsigned integers, reverts on overflow. - */ - function add(uint256 a, uint256 b) internal pure returns (uint256) { - uint256 c = a + b; - require(c >= a, "SafeMath: addition overflow"); - - return c; - } - - /** - * @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo), - * reverts when dividing by zero. + * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), + * Reverts when dividing by zero. + * + * Counterpart to Solidity's `%` operator. This function uses a `revert` + * opcode (which leaves remaining gas untouched) while Solidity uses an + * invalid opcode to revert (consuming all remaining gas). + * + * Requirements: + * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b != 0, "SafeMath: modulo by zero"); diff --git a/contracts/ownership/Ownable.sol b/contracts/ownership/Ownable.sol index 5b402cacd..9c7b5dedc 100644 --- a/contracts/ownership/Ownable.sol +++ b/contracts/ownership/Ownable.sol @@ -1,9 +1,13 @@ pragma solidity ^0.5.0; /** - * @title Ownable - * @dev The Ownable contract has an owner address, and provides basic authorization control - * functions, this simplifies the implementation of "user permissions". + * @dev Contract module which provides a basic access control mechanism, where + * there is an account (an owner) that can be granted exclusive access to + * specific functions. + * + * This module is used through inheritance. It will make available the modifier + * `onlyOwner`, which can be aplied to your functions to restrict their use to + * the owner. */ contract Ownable { address private _owner; @@ -11,8 +15,7 @@ contract Ownable { event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** - * @dev The Ownable constructor sets the original `owner` of the contract to the sender - * account. + * @dev Initializes the contract setting the deployer as the initial owner. */ constructor () internal { _owner = msg.sender; @@ -20,7 +23,7 @@ contract Ownable { } /** - * @return the address of the owner. + * @dev Returns the address of the current owner. */ function owner() public view returns (address) { return _owner; @@ -35,17 +38,17 @@ contract Ownable { } /** - * @return true if `msg.sender` is the owner of the contract. + * @dev Returns true if the caller is the current owner. */ function isOwner() public view returns (bool) { return msg.sender == _owner; } /** - * @dev Allows the current owner to relinquish control of the contract. - * It will not be possible to call the functions with the `onlyOwner` - * modifier anymore. - * @notice Renouncing ownership will leave the contract without an owner, + * @dev Leaves the contract without owner. It will not be possible to call + * `onlyOwner` functions anymore. Can only be called by the current owner. + * + * > Note: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public onlyOwner { @@ -54,16 +57,15 @@ contract Ownable { } /** - * @dev Allows the current owner to transfer control of the contract to a newOwner. - * @param newOwner The address to transfer ownership to. + * @dev Transfers ownership of the contract to a new account (`newOwner`). + * Can only be called by the current owner. */ function transferOwnership(address newOwner) public onlyOwner { _transferOwnership(newOwner); } /** - * @dev Transfers control of the contract to a newOwner. - * @param newOwner The address to transfer ownership to. + * @dev Transfers ownership of the contract to a new account (`newOwner`). */ function _transferOwnership(address newOwner) internal { require(newOwner != address(0), "Ownable: new owner is the zero address"); diff --git a/contracts/ownership/README.md b/contracts/ownership/README.md new file mode 100644 index 000000000..5e112d068 --- /dev/null +++ b/contracts/ownership/README.md @@ -0,0 +1,3 @@ +Contract modules for simple authorization and access control mechanisms. + +For more complex needs see [Access](access). diff --git a/contracts/ownership/Secondary.sol b/contracts/ownership/Secondary.sol index d7342969d..b34be41fd 100644 --- a/contracts/ownership/Secondary.sol +++ b/contracts/ownership/Secondary.sol @@ -1,12 +1,14 @@ pragma solidity ^0.5.0; /** - * @title Secondary * @dev A Secondary contract can only be used by its primary account (the one that created it). */ contract Secondary { address private _primary; + /** + * @dev Emitted when the primary contract changes. + */ event PrimaryTransferred( address recipient ); diff --git a/contracts/payment/README.md b/contracts/payment/README.md new file mode 100644 index 000000000..a026e6ebb --- /dev/null +++ b/contracts/payment/README.md @@ -0,0 +1,10 @@ +--- +sections: + - title: Payment Utilities + contracts: + - PaymentSplitter + - PullPayment + - subdirectory: escrow +--- + +> This page is incomplete. We're working to improve it for the next release. Stay tuned! diff --git a/contracts/payment/escrow/README.md b/contracts/payment/escrow/README.md new file mode 100644 index 000000000..96b731a29 --- /dev/null +++ b/contracts/payment/escrow/README.md @@ -0,0 +1,8 @@ +--- +title: Escrows +sections: + - contracts: + - Escrow + - ConditionalEscrow + - RefundEscrow +--- diff --git a/contracts/token/ERC20/ERC20.sol b/contracts/token/ERC20/ERC20.sol index 7c7d36fec..23cbcb845 100644 --- a/contracts/token/ERC20/ERC20.sol +++ b/contracts/token/ERC20/ERC20.sol @@ -4,16 +4,27 @@ import "./IERC20.sol"; import "../../math/SafeMath.sol"; /** - * @title Standard ERC20 token + * @dev Implementation of the `IERC20` interface. * - * @dev Implementation of the basic standard token. - * https://eips.ethereum.org/EIPS/eip-20 - * Originally based on code by FirstBlood: - * https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol + * This implementation is agnostic to the way tokens are created. This means + * that a supply mechanism has to be added in a derived contract using `_mint`. + * For a generic mechanism see `ERC20Mintable`. * - * 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. + * *For a detailed writeup see our guide [How to implement supply + * mechanisms](https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226).* + * + * We have followed general OpenZeppelin guidelines: functions revert instead + * of returning `false` on failure. This behavior is nonetheless conventional + * and does not conflict with the expectations of ERC20 applications. + * + * Additionally, an `Approval` event is emitted on calls to `transferFrom`. + * This allows applications to reconstruct the allowance for all accounts just + * by listening to said events. Other implementations of the EIP may not emit + * these events, as it isn't required by the specification. + * + * Finally, the non-standard `decreaseAllowance` and `increaseAllowance` + * functions have been added to mitigate the well-known issues around setting + * allowances. See `IERC20.approve`. */ contract ERC20 is IERC20 { using SafeMath for uint256; @@ -25,49 +36,45 @@ contract ERC20 is IERC20 { uint256 private _totalSupply; /** - * @dev Total number of tokens in existence. + * @dev See `IERC20.totalSupply`. */ function totalSupply() public view returns (uint256) { return _totalSupply; } /** - * @dev Gets the balance of the specified address. - * @param owner The address to query the balance of. - * @return A uint256 representing the amount owned by the passed address. + * @dev See `IERC20.balanceOf`. */ - function balanceOf(address owner) public view returns (uint256) { - return _balances[owner]; + function balanceOf(address account) public view returns (uint256) { + return _balances[account]; } /** - * @dev Function to check the amount of tokens that an owner allowed to a spender. - * @param owner address The address which owns the funds. - * @param spender address The address which will spend the funds. - * @return A uint256 specifying the amount of tokens still available for the spender. + * @dev See `IERC20.transfer`. + * + * Requirements: + * + * - `recipient` cannot be the zero address. + * - the caller must have a balance of at least `amount`. */ - function allowance(address owner, address spender) public view returns (uint256) { - return _allowances[owner][spender]; + function transfer(address recipient, uint256 amount) public returns (bool) { + _transfer(msg.sender, recipient, amount); + return true; } /** - * @dev Transfer token to a specified address. - * @param to The address to transfer to. - * @param value The amount to be transferred. + * @dev See `IERC20.allowance`. */ - function transfer(address to, uint256 value) public returns (bool) { - _transfer(msg.sender, to, value); - return true; + function allowance(address owner, address spender) public view returns (uint256) { + return _allowances[owner][spender]; } /** - * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender. - * Beware that changing an allowance with this method brings the risk that someone may use both the old - * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this - * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: - * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 - * @param spender The address which will spend the funds. - * @param value The amount of tokens to be spent. + * @dev See `IERC20.approve`. + * + * Requirements: + * + * - `spender` cannot be the zero address. */ function approve(address spender, uint256 value) public returns (bool) { _approve(msg.sender, spender, value); @@ -75,28 +82,34 @@ contract ERC20 is IERC20 { } /** - * @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 + * @dev See `IERC20.transferFrom`. + * + * Emits an `Approval` event indicating the updated allowance. This is not + * required by the EIP. See the note at the beginning of `ERC20`; + * + * Requirements: + * - `sender` and `recipient` cannot be the zero address. + * - `sender` must have a balance of at least `value`. + * - the caller must have allowance for `sender`'s tokens of at least + * `amount`. */ - function transferFrom(address from, address to, uint256 value) public returns (bool) { - _transfer(from, to, value); - _approve(from, msg.sender, _allowances[from][msg.sender].sub(value)); + function transferFrom(address sender, address recipient, uint256 amount) public returns (bool) { + _transfer(sender, recipient, amount); + _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount)); return true; } /** - * @dev Increase the amount of tokens that an owner allowed to a spender. - * approve should be called when _allowances[msg.sender][spender] == 0. To increment - * 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. + * @dev Atomically increases the allowance granted to `spender` by the caller. + * + * This is an alternative to `approve` that can be used as a mitigation for + * problems described in `IERC20.approve`. + * + * Emits an `Approval` event indicating the updated allowance. + * + * Requirements: + * + * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public returns (bool) { _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue)); @@ -104,14 +117,18 @@ contract ERC20 is IERC20 { } /** - * @dev Decrease the amount of tokens that an owner allowed to a spender. - * approve should be called when _allowances[msg.sender][spender] == 0. To decrement - * 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. + * @dev Atomically decreases the allowance granted to `spender` by the caller. + * + * This is an alternative to `approve` that can be used as a mitigation for + * problems described in `IERC20.approve`. + * + * Emits an `Approval` event indicating the updated allowance. + * + * Requirements: + * + * - `spender` cannot be the zero address. + * - `spender` must have allowance for the caller of at least + * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) { _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue)); @@ -119,40 +136,55 @@ contract ERC20 is IERC20 { } /** - * @dev Transfer token for a specified addresses. - * @param from The address to transfer from. - * @param to The address to transfer to. - * @param value The amount to be transferred. + * @dev Moves tokens `amount` from `sender` to `recipient`. + * + * This is internal function is equivalent to `transfer`, and can be used to + * e.g. implement automatic token fees, slashing mechanisms, etc. + * + * Emits a `Transfer` event. + * + * Requirements: + * + * - `sender` cannot be the zero address. + * - `recipient` cannot be the zero address. + * - `sender` must have a balance of at least `amount`. */ - function _transfer(address from, address to, uint256 value) internal { - require(from != address(0), "ERC20: transfer from the zero address"); - require(to != address(0), "ERC20: transfer to the zero address"); + function _transfer(address sender, address recipient, uint256 amount) internal { + require(sender != address(0), "ERC20: transfer from the zero address"); + require(recipient != address(0), "ERC20: transfer to the zero address"); - _balances[from] = _balances[from].sub(value); - _balances[to] = _balances[to].add(value); - emit Transfer(from, to, value); + _balances[sender] = _balances[sender].sub(amount); + _balances[recipient] = _balances[recipient].add(amount); + emit Transfer(sender, recipient, amount); } - /** - * @dev Internal function that mints an amount of the token and assigns it to - * 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 value The amount that will be created. + /** @dev Creates `amount` tokens and assigns them to `account`, increasing + * the total supply. + * + * Emits a `Transfer` event with `from` set to the zero address. + * + * Requirements + * + * - `to` cannot be the zero address. */ - function _mint(address account, uint256 value) internal { + function _mint(address account, uint256 amount) internal { require(account != address(0), "ERC20: mint to the zero address"); - _totalSupply = _totalSupply.add(value); - _balances[account] = _balances[account].add(value); - emit Transfer(address(0), account, value); + _totalSupply = _totalSupply.add(amount); + _balances[account] = _balances[account].add(amount); + emit Transfer(address(0), account, amount); } - /** - * @dev Internal function that burns an amount of the token of a given - * account. - * @param account The account whose tokens will be burnt. - * @param value The amount that will be burnt. + /** + * @dev Destoys `amount` tokens from `account`, reducing the + * total supply. + * + * Emits a `Transfer` event with `to` set to the zero address. + * + * Requirements + * + * - `account` cannot be the zero address. + * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 value) internal { require(account != address(0), "ERC20: burn from the zero address"); @@ -163,10 +195,17 @@ contract ERC20 is IERC20 { } /** - * @dev Approve an address to spend another addresses' tokens. - * @param owner The address that owns the tokens. - * @param spender The address that will spend the tokens. - * @param value The number of tokens that can be spent. + * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens. + * + * This is internal function is equivalent to `approve`, and can be used to + * e.g. set automatic allowances for certain subsystems, etc. + * + * Emits an `Approval` event. + * + * Requirements: + * + * - `owner` cannot be the zero address. + * - `spender` cannot be the zero address. */ function _approve(address owner, address spender, uint256 value) internal { require(owner != address(0), "ERC20: approve from the zero address"); @@ -177,15 +216,13 @@ contract ERC20 is IERC20 { } /** - * @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 value The amount that will be burnt. + * @dev Destoys `amount` tokens from `account`.`amount` is then deducted + * from the caller's allowance. + * + * See `_burn` and `_approve`. */ - function _burnFrom(address account, uint256 value) internal { - _burn(account, value); - _approve(account, msg.sender, _allowances[account][msg.sender].sub(value)); + function _burnFrom(address account, uint256 amount) internal { + _burn(account, amount); + _approve(account, msg.sender, _allowances[account][msg.sender].sub(amount)); } } diff --git a/contracts/token/ERC20/ERC20Burnable.sol b/contracts/token/ERC20/ERC20Burnable.sol index 3345d3507..de2234da5 100644 --- a/contracts/token/ERC20/ERC20Burnable.sol +++ b/contracts/token/ERC20/ERC20Burnable.sol @@ -3,24 +3,24 @@ pragma solidity ^0.5.0; import "./ERC20.sol"; /** - * @title Burnable Token - * @dev Token that can be irreversibly burned (destroyed). + * @dev Extension of `ERC20` that allows token holders to destroy both their own + * tokens and those that they have an allowance for, in a way that can be + * recognized off-chain (via event analysis). */ contract ERC20Burnable is ERC20 { /** - * @dev Burns a specific amount of tokens. - * @param value The amount of token to be burned. + * @dev Destoys `amount` tokens from the caller. + * + * See `ERC20._burn`. */ - function burn(uint256 value) public { - _burn(msg.sender, value); + function burn(uint256 amount) public { + _burn(msg.sender, amount); } /** - * @dev Burns a specific amount of tokens from the target address and decrements allowance. - * @param from address The account whose tokens will be burned. - * @param value uint256 The amount of token to be burned. + * @dev See `ERC20._burnFrom`. */ - function burnFrom(address from, uint256 value) public { - _burnFrom(from, value); + function burnFrom(address account, uint256 amount) public { + _burnFrom(account, amount); } } diff --git a/contracts/token/ERC20/ERC20Capped.sol b/contracts/token/ERC20/ERC20Capped.sol index f49300152..36bc9a9b0 100644 --- a/contracts/token/ERC20/ERC20Capped.sol +++ b/contracts/token/ERC20/ERC20Capped.sol @@ -3,24 +3,34 @@ pragma solidity ^0.5.0; import "./ERC20Mintable.sol"; /** - * @title Capped token - * @dev Mintable token with a token cap. + * @dev Extension of `ERC20Mintable` that adds a cap to the supply of tokens. */ contract ERC20Capped is ERC20Mintable { uint256 private _cap; + /** + * @dev Sets the value of the `cap`. This value is immutable, it can only be + * set once during construction. + */ constructor (uint256 cap) public { require(cap > 0, "ERC20Capped: cap is 0"); _cap = cap; } /** - * @return the cap for the token minting. + * @dev Returns the cap on the token's total supply. */ function cap() public view returns (uint256) { return _cap; } + /** + * @dev See `ERC20Mintable.mint`. + * + * Requirements: + * + * - `value` must not cause the total supply to go over the cap. + */ function _mint(address account, uint256 value) internal { require(totalSupply().add(value) <= _cap, "ERC20Capped: cap exceeded"); super._mint(account, value); diff --git a/contracts/token/ERC20/ERC20Detailed.sol b/contracts/token/ERC20/ERC20Detailed.sol index 71c0b0159..baa9ba5c4 100644 --- a/contracts/token/ERC20/ERC20Detailed.sol +++ b/contracts/token/ERC20/ERC20Detailed.sol @@ -3,16 +3,18 @@ pragma solidity ^0.5.0; import "./IERC20.sol"; /** - * @title ERC20Detailed token - * @dev The decimals are only for visualization purposes. - * All the operations are done using the smallest and indivisible token unit, - * just as on Ethereum all the operations are done in wei. + * @dev Optional functions from the ERC20 standard. */ contract ERC20Detailed is IERC20 { string private _name; string private _symbol; uint8 private _decimals; + /** + * @dev Sets the values for `name`, `symbol`, and `decimals`. All three of + * these values are immutable: they can only be set once during + * construction. + */ constructor (string memory name, string memory symbol, uint8 decimals) public { _name = name; _symbol = symbol; @@ -20,21 +22,31 @@ contract ERC20Detailed is IERC20 { } /** - * @return the name of the token. + * @dev Returns the name of the token. */ function name() public view returns (string memory) { return _name; } /** - * @return the symbol of the token. + * @dev Returns the symbol of the token, usually a shorter version of the + * name. */ function symbol() public view returns (string memory) { return _symbol; } /** - * @return the number of decimals of the token. + * @dev Returns the number of decimals used to get its user representation. + * For example, if `decimals` equals `2`, a balance of `505` tokens should + * be displayed to a user as `5,05` (`505 / 10 ** 2`). + * + * Tokens usually opt for a value of 18, imitating the relationship between + * Ether and Wei. + * + * > Note that this information is only used for _display_ purposes: it in + * no way affects any of the arithmetic of the contract, including + * `IERC20.balanceOf` and `IERC20.transfer`. */ function decimals() public view returns (uint8) { return _decimals; diff --git a/contracts/token/ERC20/ERC20Mintable.sol b/contracts/token/ERC20/ERC20Mintable.sol index e69df4605..1f81e7d77 100644 --- a/contracts/token/ERC20/ERC20Mintable.sol +++ b/contracts/token/ERC20/ERC20Mintable.sol @@ -4,18 +4,21 @@ import "./ERC20.sol"; import "../../access/roles/MinterRole.sol"; /** - * @title ERC20Mintable - * @dev ERC20 minting logic. + * @dev Extension of `ERC20` that adds a set of accounts with the `MinterRole`, + * which have permission to mint (create) new tokens as they see fit. + * + * At construction, the deployer of the contract is the only minter. */ contract ERC20Mintable is ERC20, MinterRole { /** - * @dev Function to mint tokens - * @param to The address that will receive the minted tokens. - * @param value The amount of tokens to mint. - * @return A boolean that indicates if the operation was successful. + * @dev See `ERC20._mint`. + * + * Requirements: + * + * - the caller must have the `MinterRole`. */ - function mint(address to, uint256 value) public onlyMinter returns (bool) { - _mint(to, value); + function mint(address account, uint256 amount) public onlyMinter returns (bool) { + _mint(account, amount); return true; } } diff --git a/contracts/token/ERC20/IERC20.sol b/contracts/token/ERC20/IERC20.sol index 7c3230b96..0aca0f00e 100644 --- a/contracts/token/ERC20/IERC20.sol +++ b/contracts/token/ERC20/IERC20.sol @@ -1,23 +1,76 @@ pragma solidity ^0.5.0; /** - * @title ERC20 interface - * @dev see https://eips.ethereum.org/EIPS/eip-20 + * @dev Interface of the ERC20 standard as defined in the EIP. Does not include + * the optional functions; to access them see `ERC20Detailed`. */ interface IERC20 { - function transfer(address to, uint256 value) external returns (bool); + /** + * @dev Returns the amount of tokens in existence. + */ + function totalSupply() external view returns (uint256); - function approve(address spender, uint256 value) external returns (bool); + /** + * @dev Returns the amount of tokens owned by `account`. + */ + function balanceOf(address account) external view returns (uint256); - function transferFrom(address from, address to, uint256 value) external returns (bool); + /** + * @dev Moves `amount` tokens from the caller's account to `recipient`. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * Emits a `Transfer` event. + */ + function transfer(address recipient, uint256 amount) external returns (bool); - function totalSupply() external view returns (uint256); + /** + * @dev Returns the remaining number of tokens that `spender` will be + * allowed to spend on behalf of `owner` through `transferFrom`. This is + * zero by default. + * + * This value changes when `approve` or `transferFrom` are called. + */ + function allowance(address owner, address spender) external view returns (uint256); - function balanceOf(address who) external view returns (uint256); + /** + * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * > Beware that changing an allowance with this method brings the risk + * that someone may use both the old and the new allowance by unfortunate + * transaction ordering. One possible solution to mitigate this race + * condition is to first reduce the spender's allowance to 0 and set the + * desired value afterwards: + * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 + * + * Emits an `Approval` event. + */ + function approve(address spender, uint256 amount) external returns (bool); - function allowance(address owner, address spender) external view returns (uint256); + /** + * @dev Moves `amount` tokens from `sender` to `recipient` using the + * allowance mechanism. `amount` is then deducted from the caller's + * allowance. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * Emits a `Transfer` event. + */ + function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); + /** + * @dev Emitted when `value` tokens are moved from one account (`from`) to + * another (`to`). + * + * Note that `value` may be zero. + */ event Transfer(address indexed from, address indexed to, uint256 value); + /** + * @dev Emitted when the allowance of a `spender` for an `owner` is set by + * a call to `approve`. `value` is the new allowance. + */ event Approval(address indexed owner, address indexed spender, uint256 value); } diff --git a/contracts/token/ERC20/README.md b/contracts/token/ERC20/README.md index 4e0b25ba3..8ad614cbc 100644 --- a/contracts/token/ERC20/README.md +++ b/contracts/token/ERC20/README.md @@ -1,18 +1,35 @@ --- sections: - - title: Interfaces + - title: Core contracts: - IERC20 - - title: Contracts - contracts: - ERC20 - ERC20Detailed + - title: Extensions + contracts: - ERC20Mintable - ERC20Burnable - - ERC20Capped - ERC20Pausable + - ERC20Capped - title: Utilities contracts: - SafeERC20 - TokenTimelock --- + +This set of interfaces, contracts, and utilities are all related to the [ERC20 Token Standard](https://eips.ethereum.org/EIPS/eip-20). + +*For a walkthrough on how to create an ERC20 token read our [ERC20 guide](../../tokens.md#constructing-a-nice-erc20-token).* + +There a few core contracts that implement the behavior specified in the EIP: `IERC20`, `ERC20`, `ERC20Detailed`. + +Additionally there are multiple extensions, including: +- designation of addresses that can create token supply (`ERC20Mintable`), with an optional maximum cap (`ERC20Capped`), +- destruction of own tokens (`ERC20Burnable`), +- designation of addresses that can pause token operations for all users (`ERC20Pausable`). + +Finally, there are some utilities to interact with ERC20 contracts in various ways. +- `SafeERC20` is a wrapper around the interface that eliminates the need to handle boolean return values. +- `TokenTimelock` can hold tokens for a beneficiary until a specified time. + +> This page is incomplete. We're working to improve it for the next release. Stay tuned! diff --git a/contracts/token/ERC721/ERC721.sol b/contracts/token/ERC721/ERC721.sol index 933a15c6d..1c9a79de3 100644 --- a/contracts/token/ERC721/ERC721.sol +++ b/contracts/token/ERC721/ERC721.sol @@ -268,6 +268,8 @@ contract ERC721 is ERC165, IERC721 { /** * @dev Internal function to invoke `onERC721Received` on a target address. * The call is not executed if the target address is not a contract. + * + * This function is deprecated. * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred diff --git a/contracts/token/ERC721/IERC721.sol b/contracts/token/ERC721/IERC721.sol index afb94028c..960c1f902 100644 --- a/contracts/token/ERC721/IERC721.sol +++ b/contracts/token/ERC721/IERC721.sol @@ -3,25 +3,51 @@ pragma solidity ^0.5.0; import "../../introspection/IERC165.sol"; /** - * @title ERC721 Non-Fungible Token Standard basic interface - * @dev see https://eips.ethereum.org/EIPS/eip-721 + * @dev Required interface of an ERC721 compliant contract. */ contract IERC721 is 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); + /** + * @dev Returns the number of NFTs in `owner`'s account. + */ function balanceOf(address owner) public view returns (uint256 balance); + + /** + * @dev Returns the owner of the NFT specified by `tokenId`. + */ function ownerOf(uint256 tokenId) public view returns (address owner); + /** + * @dev Transfers a specific NFT (`tokenId`) from one account (`from`) to + * another (`to`). + * + * + * + * Requirements: + * - `from`, `to` cannot be zero. + * - `tokenId` must be owned by `from`. + * - If the caller is not `from`, it must be have been allowed to move this + * NFT by either `approve` or `setApproveForAll`. + */ + function safeTransferFrom(address from, address to, uint256 tokenId) public; + /** + * @dev Transfers a specific NFT (`tokenId`) from one account (`from`) to + * another (`to`). + * + * Requirements: + * - If the caller is not `from`, it must be approved to move this NFT by + * either `approve` or `setApproveForAll`. + */ + function transferFrom(address from, address to, uint256 tokenId) public; function approve(address to, uint256 tokenId) public; 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 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, bytes memory data) public; } diff --git a/contracts/token/ERC721/README.md b/contracts/token/ERC721/README.md new file mode 100644 index 000000000..1df47377d --- /dev/null +++ b/contracts/token/ERC721/README.md @@ -0,0 +1,37 @@ +--- +sections: + - title: Core + contracts: + - IERC721 + - ERC721 + - IERC721Metadata + - ERC721Metadata + - ERC721Enumerable + - IERC721Enumerable + - IERC721Full + - ERC721Full + - IERC721Receiver + - title: Extensions + contracts: + - ERC721Mintable + - ERC721MetadataMintable + - ERC721Burnable + - ERC721Pausable + - title: Convenience + contracts: + - ERC721Holder +--- + +This set of interfaces, contracts, and utilities are all related to the [ERC721 Non-Fungible Token Standard](https://eips.ethereum.org/EIPS/eip-721). + +*For a walkthrough on how to create an ERC721 token read our [ERC721 guide](../../tokens.md#erc721).* + +The EIP consists of three interfaces, found here as `IERC721`, +`IERC721Metadata`, and `IERC721Enumerable`. Only the first one is required in a +contract to be ERC721 compliant. Each interface is implemented separately in +`ERC721`, `ERC721Metadata`, and `ERC721Enumerable`. You can choose the subset +of functionality you would like to support in your token by combining the +desired subset through inheritance. The fully featured token implementing all +three interfaces is prepackaged as `ERC721Full`. + +> This page is incomplete. We're working to improve it for the next release. Stay tuned! diff --git a/contracts/token/ERC777/ERC777.sol b/contracts/token/ERC777/ERC777.sol index e70298ecc..9038e8039 100644 --- a/contracts/token/ERC777/ERC777.sol +++ b/contracts/token/ERC777/ERC777.sol @@ -9,8 +9,19 @@ import "../../utils/Address.sol"; import "../../introspection/IERC1820Registry.sol"; /** - * @title ERC777 token implementation, with granularity harcoded to 1. - * @author etsvigun , Bertrand Masius + * @dev Implementation of the `IERC777` interface. + * + * This implementation is agnostic to the way tokens are created. This means + * that a supply mechanism has to be added in a derived contract using `_mint`. + * + * Support for ERC20 is included in this contract, as specified by the EIP: both + * the ERC777 and ERC20 interfaces can be safely used when interacting with it. + * Both `IERC777.Sent` and `IERC20.Transfer` events are emitted on token + * movements. + * + * Additionally, the `granularity` value is hard-coded to `1`, meaning that there + * are no special restrictions in the amount of tokens that created, moved, or + * destroyed. This makes integration with ERC20 applications seamless. */ contract ERC777 is IERC777, IERC20 { using SafeMath for uint256; @@ -49,6 +60,9 @@ contract ERC777 is IERC777, IERC20 { // ERC20-allowances mapping (address => mapping (address => uint256)) private _allowances; + /** + * @dev `defaultOperators` may be an empty array. + */ constructor( string memory name, string memory symbol, @@ -68,107 +82,106 @@ contract ERC777 is IERC777, IERC20 { } /** - * @dev Send the amount of tokens from the address msg.sender to the address to - * @param to address recipient address - * @param amount uint256 amount of tokens to transfer - * @param data bytes information attached to the send, and intended for the recipient (to) + * @dev See `IERC777.name`. */ - function send(address to, uint256 amount, bytes calldata data) external { - _send(msg.sender, msg.sender, to, amount, data, "", true); + function name() public view returns (string memory) { + return _name; } /** - * @dev Send the amount of tokens on behalf of the address from to the address to - * @param from address token holder address. - * @param to address recipient address - * @param amount uint256 amount of tokens to transfer - * @param data bytes information attached to the send, and intended for the recipient (to) - * @param operatorData bytes extra information provided by the operator (if any) + * @dev See `IERC777.symbol`. */ - function operatorSend( - address from, - address to, - uint256 amount, - bytes calldata data, - bytes calldata operatorData - ) - external - { - require(isOperatorFor(msg.sender, from), "ERC777: caller is not an operator for holder"); - _send(msg.sender, from, to, amount, data, operatorData, true); + function symbol() public view returns (string memory) { + return _symbol; } /** - * @dev Transfer token to a specified address. - * Required for ERC20 compatiblity. Note that transferring tokens this way may result in locked tokens (i.e. tokens - * can be sent to a contract that does not implement the ERC777TokensRecipient interface). - * @param to The address to transfer to. - * @param value The amount to be transferred. + * @dev See `ERC20Detailed.decimals`. + * + * Always returns 18, as per the + * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility). */ - function transfer(address to, uint256 value) external returns (bool) { - require(to != address(0), "ERC777: transfer to the zero address"); - - address from = msg.sender; + function decimals() public pure returns (uint8) { + return 18; + } - _callTokensToSend(from, from, to, value, "", ""); + /** + * @dev See `IERC777.granularity`. + * + * This implementation always returns `1`. + */ + function granularity() public view returns (uint256) { + return 1; + } - _move(from, from, to, value, "", ""); + /** + * @dev See `IERC777.totalSupply`. + */ + function totalSupply() public view returns (uint256) { + return _totalSupply; + } - _callTokensReceived(from, from, to, value, "", "", false); + /** + * @dev Returns the amount of tokens owned by an account (`owner`). + */ + function balanceOf(address tokenHolder) public view returns (uint256) { + return _balances[tokenHolder]; + } - return true; + /** + * @dev See `IERC777.send`. + * + * Also emits a `Transfer` event for ERC20 compatibility. + */ + function send(address recipient, uint256 amount, bytes calldata data) external { + _send(msg.sender, msg.sender, recipient, amount, data, "", true); } /** - * @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. - * Required for ERC20 compatiblity. Note that transferring tokens this way may result in locked tokens (i.e. tokens - * can be sent to a contract that does not implement the ERC777TokensRecipient interface). - * @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 + * @dev See `IERC20.transfer`. + * + * Unlike `send`, `recipient` is _not_ required to implement the `tokensReceived` + * interface if it is a contract. + * + * Also emits a `Sent` event. */ - function transferFrom(address from, address to, uint256 value) external returns (bool) { - require(to != address(0), "ERC777: transfer to the zero address"); - require(from != address(0), "ERC777: transfer from the zero address"); + function transfer(address recipient, uint256 amount) external returns (bool) { + require(recipient != address(0), "ERC777: transfer to the zero address"); - address operator = msg.sender; + address from = msg.sender; - _callTokensToSend(operator, from, to, value, "", ""); + _callTokensToSend(from, from, recipient, amount, "", ""); - _move(operator, from, to, value, "", ""); - _approve(from, operator, _allowances[from][operator].sub(value)); + _move(from, from, recipient, amount, "", ""); - _callTokensReceived(operator, from, to, value, "", "", false); + _callTokensReceived(from, from, recipient, amount, "", "", false); return true; } /** - * @dev Burn the amount of tokens from the address msg.sender - * @param amount uint256 amount of tokens to transfer - * @param data bytes extra information provided by the token holder + * @dev See `IERC777.burn`. + * + * Also emits a `Transfer` event for ERC20 compatibility. */ function burn(uint256 amount, bytes calldata data) external { _burn(msg.sender, msg.sender, amount, data, ""); } /** - * @dev Burn the amount of tokens on behalf of the address from - * @param from address token holder address. - * @param amount uint256 amount of tokens to transfer - * @param data bytes extra information provided by the token holder - * @param operatorData bytes extra information provided by the operator (if any) + * @dev See `IERC777.isOperatorFor`. */ - function operatorBurn(address from, uint256 amount, bytes calldata data, bytes calldata operatorData) external { - require(isOperatorFor(msg.sender, from), "ERC777: caller is not an operator for holder"); - _burn(msg.sender, from, amount, data, operatorData); + function isOperatorFor( + address operator, + address tokenHolder + ) public view returns (bool) { + return operator == tokenHolder || + (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) || + _operators[tokenHolder][operator]; } /** - * @dev Authorize an operator for the sender - * @param operator address to be authorized as operator + * @dev See `IERC777.authorizeOperator`. */ function authorizeOperator(address operator) external { require(msg.sender != operator, "ERC777: authorizing self as operator"); @@ -183,8 +196,7 @@ contract ERC777 is IERC777, IERC20 { } /** - * @dev Revoke operator rights from one of the default operators - * @param operator address to revoke operator rights from + * @dev See `IERC777.revokeOperator`. */ function revokeOperator(address operator) external { require(operator != msg.sender, "ERC777: revoking self as operator"); @@ -199,130 +211,122 @@ contract ERC777 is IERC777, IERC20 { } /** - * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender. - * Beware that changing an allowance with this method brings the risk that someone may use both the old - * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this - * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: - * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 - * Required for ERC20 compatilibity. - * @param spender The address which will spend the funds. - * @param value The amount of tokens to be spent. + * @dev See `IERC777.defaultOperators`. */ - function approve(address spender, uint256 value) external returns (bool) { - _approve(msg.sender, spender, value); - return true; + function defaultOperators() public view returns (address[] memory) { + return _defaultOperatorsArray; } /** - * @dev Total number of tokens in existence + * @dev See `IERC777.operatorSend`. + * + * Emits `Sent` and `Transfer` events. */ - function totalSupply() public view returns (uint256) { - return _totalSupply; + function operatorSend( + address sender, + address recipient, + uint256 amount, + bytes calldata data, + bytes calldata operatorData + ) + external + { + require(isOperatorFor(msg.sender, sender), "ERC777: caller is not an operator for holder"); + _send(msg.sender, sender, recipient, amount, data, operatorData, true); } /** - * @dev Gets the balance of the specified address. - * @param tokenHolder The address to query the balance of. - * @return uint256 representing the amount owned by the specified address. + * @dev See `IERC777.operatorBurn`. + * + * Emits `Sent` and `Transfer` events. */ - function balanceOf(address tokenHolder) public view returns (uint256) { - return _balances[tokenHolder]; + function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData) external { + require(isOperatorFor(msg.sender, account), "ERC777: caller is not an operator for holder"); + _burn(msg.sender, account, amount, data, operatorData); } /** - * @return the name of the token. + * @dev See `IERC20.allowance`. + * + * Note that operator and allowance concepts are orthogonal: operators may + * not have allowance, and accounts with allowance may not be operators + * themselves. */ - function name() public view returns (string memory) { - return _name; + function allowance(address owner, address spender) public view returns (uint256) { + return _allowances[owner][spender]; } /** - * @return the symbol of the token. + * @dev See `IERC20.approve`. + * + * Note that accounts cannot have allowance issued by their operators. */ - function symbol() public view returns (string memory) { - return _symbol; + function approve(address spender, uint256 value) external returns (bool) { + _approve(msg.sender, spender, value); + return true; } - /** - * @return the number of decimals of the token. - */ - function decimals() public pure returns (uint8) { - return 18; // The spec requires that decimals be 18 - } + /** + * @dev See `IERC20.transferFrom`. + * + * Note that operator and allowance concepts are orthogonal: operators cannot + * call `transferFrom` (unless they have allowance), and accounts with + * allowance cannot call `operatorSend` (unless they are operators). + * + * Emits `Sent` and `Transfer` events. + */ + function transferFrom(address sender, address recipient, uint256 amount) external returns (bool) { + require(recipient != address(0), "ERC777: transfer to the zero address"); + require(sender != address(0), "ERC777: transfer from the zero address"); - /** - * @dev Gets the token's granularity, - * i.e. the smallest number of tokens (in the basic unit) - * which may be minted, sent or burned at any time - * @return uint256 granularity - */ - function granularity() public view returns (uint256) { - return 1; - } + address operator = msg.sender; - /** - * @dev Get the list of default operators as defined by the token contract. - * @return address[] default operators - */ - function defaultOperators() public view returns (address[] memory) { - return _defaultOperatorsArray; - } + _callTokensToSend(operator, sender, recipient, amount, "", ""); - /** - * @dev Indicate whether an address - * is an operator of the tokenHolder address - * @param operator address which may be an operator of tokenHolder - * @param tokenHolder address of a token holder which may have the operator - * address as an operator. - */ - function isOperatorFor( - address operator, - address tokenHolder - ) public view returns (bool) { - return operator == tokenHolder || - (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) || - _operators[tokenHolder][operator]; - } + _move(operator, sender, recipient, amount, "", ""); + _approve(sender, operator, _allowances[sender][operator].sub(amount)); - /** - * @dev Function to check the amount of tokens that an owner allowed to a spender. - * Required for ERC20 compatibility. - * @param owner address The address which owns the funds. - * @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) { - return _allowances[owner][spender]; + _callTokensReceived(operator, sender, recipient, amount, "", "", false); + + return true; } /** - * @dev Mint tokens. Does not check authorization of operator - * @dev the caller may ckeck that operator is authorized before calling - * @param operator address operator requesting the operation - * @param to address token recipient address - * @param amount uint256 amount of tokens to mint - * @param userData bytes extra information defined by the token recipient (if any) - * @param operatorData bytes extra information provided by the operator (if any) + * @dev Creates `amount` tokens and assigns them to `account`, increasing + * the total supply. + * + * If a send hook is registered for `raccount`, the corresponding function + * will be called with `operator`, `data` and `operatorData`. + * + * See `IERC777Sender` and `IERC777Recipient`. + * + * Emits `Sent` and `Transfer` events. + * + * Requirements + * + * - `account` cannot be the zero address. + * - if `account` is a contract, it must implement the `tokensReceived` + * interface. */ function _mint( address operator, - address to, + address account, uint256 amount, bytes memory userData, bytes memory operatorData ) internal { - require(to != address(0), "ERC777: mint to the zero address"); + require(account != address(0), "ERC777: mint to the zero address"); // Update state variables _totalSupply = _totalSupply.add(amount); - _balances[to] = _balances[to].add(amount); + _balances[account] = _balances[account].add(amount); - _callTokensReceived(operator, address(0), to, amount, userData, operatorData, true); + _callTokensReceived(operator, address(0), account, amount, userData, operatorData, true); - emit Minted(operator, to, amount, userData, operatorData); - emit Transfer(address(0), to, amount); + emit Minted(operator, account, amount, userData, operatorData); + emit Transfer(address(0), account, amount); } /** diff --git a/contracts/token/ERC777/IERC777.sol b/contracts/token/ERC777/IERC777.sol index 1f85d22ce..6643969bd 100644 --- a/contracts/token/ERC777/IERC777.sol +++ b/contracts/token/ERC777/IERC777.sol @@ -1,47 +1,172 @@ pragma solidity ^0.5.0; /** - * @title ERC777 token interface - * @dev See https://eips.ethereum.org/EIPS/eip-777 + * @dev Interface of the ERC777Token standard as defined in the EIP. + * + * This contract uses the + * [ERC1820 registry standard](https://eips.ethereum.org/EIPS/eip-1820) to let + * token holders and recipients react to token movements by using setting implementers + * for the associated interfaces in said registry. See `IERC1820Registry` and + * `ERC1820Implementer`. */ interface IERC777 { + /** + * @dev Returns the name of the token. + */ + function name() external view returns (string memory); + + /** + * @dev Returns the symbol of the token, usually a shorter version of the + * name. + */ + function symbol() external view returns (string memory); + + /** + * @dev Returns the smallest part of the token that is not divisible. This + * means all token operations (creation, movement and destruction) must have + * amounts that are a multiple of this number. + * + * For most token contracts, this value will equal 1. + */ + function granularity() external view returns (uint256); + + /** + * @dev Returns the amount of tokens in existence. + */ + function totalSupply() external view returns (uint256); + + /** + * @dev Returns the amount of tokens owned by an account (`owner`). + */ + function balanceOf(address owner) external view returns (uint256); + + /** + * @dev Moves `amount` tokens from the caller's account to `recipient`. + * + * If send or receive hooks are registered for the caller and `recipient`, + * the corresponding functions will be called with `data` and empty + * `operatorData`. See `IERC777Sender` and `IERC777Recipient`. + * + * Emits a `Sent` event. + * + * Requirements + * + * - the caller must have at least `amount` tokens. + * - `recipient` cannot be the zero address. + * - if `recipient` is a contract, it must implement the `tokensReceived` + * interface. + */ + function send(address recipient, uint256 amount, bytes calldata data) external; + + /** + * @dev Destoys `amount` tokens from the caller's account, reducing the + * total supply. + * + * If a send hook is registered for the caller, the corresponding function + * will be called with `data` and empty `operatorData`. See `IERC777Sender`. + * + * Emits a `Burned` event. + * + * Requirements + * + * - the caller must have at least `amount` tokens. + */ + function burn(uint256 amount, bytes calldata data) external; + + /** + * @dev Returns true if an account is an operator of `tokenHolder`. + * Operators can send and burn tokens on behalf of their owners. All + * accounts are their own operator. + * + * See `operatorSend` and `operatorBurn`. + */ + function isOperatorFor(address operator, address tokenHolder) external view returns (bool); + + /** + * @dev Make an account an operator of the caller. + * + * See `isOperatorFor`. + * + * Emits an `AuthorizedOperator` event. + * + * Requirements + * + * - `operator` cannot be calling address. + */ function authorizeOperator(address operator) external; + /** + * @dev Make an account an operator of the caller. + * + * See `isOperatorFor` and `defaultOperators`. + * + * Emits a `RevokedOperator` event. + * + * Requirements + * + * - `operator` cannot be calling address. + */ function revokeOperator(address operator) external; - function send(address to, uint256 amount, bytes calldata data) external; + /** + * @dev Returns the list of default operators. These accounts are operators + * for all token holders, even if `authorizeOperator` was never called on + * them. + * + * This list is immutable, but individual holders may revoke these via + *`revokeOperator`, in which case `isOperatorFor` will return false. + */ + function defaultOperators() external view returns (address[] memory); + /** + * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must + * be an operator of `sender`. + * + * If send or receive hooks are registered for `sender` and `recipient`, + * the corresponding functions will be called with `data` and + * `operatorData`. See `IERC777Sender` and `IERC777Recipient`. + * + * Emits a `Sent` event. + * + * Requirements + * + * - `sender` cannot be the zero address. + * - `sender` must have at least `amount` tokens. + * - the caller must be an operator for `sender`. + * - `recipient` cannot be the zero address. + * - if `recipient` is a contract, it must implement the `tokensReceived` + * interface. + */ function operatorSend( - address from, - address to, + address sender, + address recipient, uint256 amount, bytes calldata data, bytes calldata operatorData ) external; - function burn(uint256 amount, bytes calldata data) external; - + /** + * @dev Destoys `amount` tokens from `account`, reducing the total supply. + * The caller must be an operator of `account`. + * + * If a send hook is registered for `account`, the corresponding function + * will be called with `data` and `operatorData`. See `IERC777Sender`. + * + * Emits a `Burned` event. + * + * Requirements + * + * - `account` cannot be the zero address. + * - `account` must have at least `amount` tokens. + * - the caller must be an operator for `account`. + */ function operatorBurn( - address from, + address account, uint256 amount, bytes calldata data, bytes calldata operatorData ) external; - function name() external view returns (string memory); - - function symbol() external view returns (string memory); - - function totalSupply() external view returns (uint256); - - function balanceOf(address owner) external view returns (uint256); - - function granularity() external view returns (uint256); - - function defaultOperators() external view returns (address[] memory); - - function isOperatorFor(address operator, address tokenHolder) external view returns (bool); - event Sent( address indexed operator, address indexed from, diff --git a/contracts/token/ERC777/IERC777Recipient.sol b/contracts/token/ERC777/IERC777Recipient.sol index 01429c2af..c1d47ebae 100644 --- a/contracts/token/ERC777/IERC777Recipient.sol +++ b/contracts/token/ERC777/IERC777Recipient.sol @@ -1,10 +1,26 @@ pragma solidity ^0.5.0; /** - * @title ERC777 token recipient interface - * @dev See https://eips.ethereum.org/EIPS/eip-777 + * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP. + * + * Accounts can be notified of `IERC777` tokens being sent to them by having a + * contract implement this interface (contract holders can be their own + * implementer) and registering it on the + * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820). + * + * See `IERC1820Registry` and `ERC1820Implementer`. */ -interface IERC777Recipient { + interface IERC777Recipient { + /** + * @dev Called by an `IERC777` token contract whenever tokens are being + * moved or created into a registered account (`to`). The type of operation + * is conveyed by `from` being the zero address or not. + * + * This call occurs _after_ the token contract's state is updated, so + * `IERC777.balanceOf`, etc., can be used to query the post-operation state. + * + * This function may revert to prevent the operation from being executed. + */ function tokensReceived( address operator, address from, diff --git a/contracts/token/ERC777/IERC777Sender.sol b/contracts/token/ERC777/IERC777Sender.sol index d9a8421a9..6a158c52d 100644 --- a/contracts/token/ERC777/IERC777Sender.sol +++ b/contracts/token/ERC777/IERC777Sender.sol @@ -1,10 +1,26 @@ pragma solidity ^0.5.0; /** - * @title ERC777 token sender interface - * @dev See https://eips.ethereum.org/EIPS/eip-777 + * @dev Interface of the ERC777TokensSender standard as defined in the EIP. + * + * `IERC777` Token holders can be notified of operations performed on their + * tokens by having a contract implement this interface (contract holders can be + * their own implementer) and registering it on the + * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820). + * + * See `IERC1820Registry` and `ERC1820Implementer`. */ interface IERC777Sender { + /** + * @dev Called by an `IERC777` token contract whenever a registered holder's + * (`from`) tokens are about to be moved or destroyed. The type of operation + * is conveyed by `to` being the zero address or not. + * + * This call occurs _before_ the token contract's state is updated, so + * `IERC777.balanceOf`, etc., can be used to query the pre-operation state. + * + * This function may revert to prevent the operation from being executed. + */ function tokensToSend( address operator, address from, diff --git a/contracts/token/ERC777/README.md b/contracts/token/ERC777/README.md new file mode 100644 index 000000000..dba6bc7f1 --- /dev/null +++ b/contracts/token/ERC777/README.md @@ -0,0 +1,17 @@ +--- +sections: + - title: Core + contracts: + - IERC777 + - ERC777 + - title: Hooks + contracts: + - IERC777Sender + - IERC777Recipient +--- + +This set of interfaces and contracts are all related to the [ERC777 token standard](https://eips.ethereum.org/EIPS/eip-777). + +The token behavior itself is implemented in the core contracts: `IERC777`, `ERC777`. + +Additionally there are interfaces used to develop contracts that react to token movements: `IERC777Sender`, `IERC777Recipient`. diff --git a/contracts/utils/Address.sol b/contracts/utils/Address.sol index 500467212..4a07b92da 100644 --- a/contracts/utils/Address.sol +++ b/contracts/utils/Address.sol @@ -1,24 +1,25 @@ pragma solidity ^0.5.0; /** - * Utility library of inline functions on addresses + * @dev Collection of functions related to the address type, */ library Address { /** - * Returns whether the target address is a contract - * @dev This function will return false if invoked during the constructor of a contract, - * as the code is not actually created until after the constructor finishes. - * @param account address of the account to check - * @return whether the target address is a contract + * @dev Returns true if `account` is a contract. + * + * This test is non-exhaustive, and there may be false-negatives: during the + * execution of a contract's constructor, its address will be reported as + * not containing a contract. + * + * > It is unsafe to assume that an address for which this function returns + * false is an externally-owned account (EOA) and not a contract. */ function isContract(address account) internal view returns (bool) { + // This method relies in extcodesize, which returns 0 for contracts in + // construction, since the code is only stored at the end of the + // constructor execution. + uint256 size; - // XXX Currently there is no better way to check if there is a contract in an address - // than to check the size of the code at that address. - // See https://ethereum.stackexchange.com/a/14016/36603 - // for more details about how this works. - // TODO Check this again before the Serenity release, because all addresses will be - // contracts then. // 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 index 1713faf1c..cbc59a1e2 100644 --- a/contracts/utils/Arrays.sol +++ b/contracts/utils/Arrays.sol @@ -2,21 +2,18 @@ pragma solidity ^0.5.0; import "../math/Math.sol"; - /** - * @title Arrays - * @dev Utility library of inline array functions + * @dev Collection of functions related to array types. */ library Arrays { - /** - * @dev Upper bound search function which is kind of binary search algorithm. It searches sorted - * array to find index of the element value. If element is found then returns its index otherwise - * it returns index of first element which is greater 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 found. - * @return The calculated index value. Returns 0 for empty array. + /** + * @dev Searches a sorted `array` and returns the first index that contains + * a value greater or equal to `element`. If no such index exists (i.e. all + * values in the array are stictly less than `element`), the array length is + * returned. Time complexity O(log n). + * + * `array` is expected to be sorted in ascending order, and to contain no + * repeated elements. */ function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) { if (array.length == 0) { diff --git a/contracts/utils/README.md b/contracts/utils/README.md new file mode 100644 index 000000000..38d0a8d8c --- /dev/null +++ b/contracts/utils/README.md @@ -0,0 +1,11 @@ +--- +title: Utilities +sections: + - title: Contracts + contracts: + - Address + - Arrays + - ReentrancyGuard +--- + +Miscellaneous contracts containing utility functions, often related to working with different data types. diff --git a/contracts/utils/ReentrancyGuard.sol b/contracts/utils/ReentrancyGuard.sol index b7d2cb43f..115d3de9f 100644 --- a/contracts/utils/ReentrancyGuard.sol +++ b/contracts/utils/ReentrancyGuard.sol @@ -1,10 +1,16 @@ pragma solidity ^0.5.0; /** - * @title Helps contracts guard against reentrancy attacks. - * @author Remco Bloemen , Eenae - * @dev If you mark a function `nonReentrant`, you should also - * mark it `external`. + * @dev Contract module that helps prevent reentrant calls to a function. + * + * Inheriting from `ReentrancyGuard` will make the `nonReentrant` modifier + * available, which can be aplied to functions to make sure there are no nested + * (reentrant) calls to them. + * + * Note that because there is a single `nonReentrant` guard, functions marked as + * `nonReentrant` may not call one another. This can be worked around by making + * those functions `private`, and then adding `external` `nonReentrant` entry + * points to them. */ contract ReentrancyGuard { /// @dev counter to allow mutex lock with only one SSTORE operation diff --git a/docs/learn-about-access-control.md b/docs/access-control.md similarity index 60% rename from docs/learn-about-access-control.md rename to docs/access-control.md index 9115e8b07..237fe2027 100644 --- a/docs/learn-about-access-control.md +++ b/docs/access-control.md @@ -1,6 +1,6 @@ --- -id: learn-about-access-control -title: Learn About Access Control +id: access-control +title: Access Control --- Access control—that is, "who is allowed to do this thing"—is incredibly important in the world of smart contracts. The access control of your contract governs who can mint tokens, who can vote on proposals, who can [`selfdestruct()`](https://blog.zeppelin.solutions/on-the-parity-wallet-multisig-hack-405a8c12e8f7) the contract, and more, so it's very important to understand how you implement it. @@ -9,7 +9,7 @@ Access control—that is, "who is allowed to do this thing"—is incredibly impo The most common and basic form of access control is the concept of _ownership_: there's one account that is the `owner` and can do administrative tasks on contracts. This approach is perfectly reasonable for contracts that only have a single administrative user. -OpenZeppelin provides [contracts/ownership/Ownable.sol](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/ownership/Ownable.sol) for implementing ownership in your contracts. +OpenZeppelin provides [`Ownable`](api/ownership#ownable) for implementing ownership in your contracts. ```solidity import "openzeppelin-solidity/contracts/ownership/Ownable.sol"; @@ -31,11 +31,11 @@ contract MyContract is Ownable { } ``` -By default, the `owner` of an `Ownable` contract is the `msg.sender` of the contract creation transaction, which is usually exactly what you want. +By default, the [`owner`](api/ownership#Ownable.owner()) of an `Ownable` contract is the `msg.sender` of the contract creation transaction, which is usually exactly what you want. Ownable also lets you: -+ `transferOwnership(address newOwner)` to transfer ownership from one account to another -+ `renounceOwnership()` to remove the owner altogether, useful for decentralizing control of your contract. **⚠ Warning!** Removing the owner altogether will mean that administrative tasks that are protected by `onlyOwner` will no longer be callable! ++ [`transferOwnership`](api/ownership#Ownable.transferOwnership(address)) to transfer ownership from one account to another ++ [`renounceOwnership`](api/ownership#Ownable.renounceOwnership()) to remove the owner altogether, useful for decentralizing control of your contract. **⚠ Warning!** Removing the owner altogether will mean that administrative tasks that are protected by `onlyOwner` will no longer be callable! Note that any contract that supports sending transactions can also be the owner of a contract; the only requirement is that the owner has an Ethereum address, so it could be a Gnosis Multisig or Gnosis Safe, an Aragon DAO, an ERC725/uPort identity contract, or a totally custom contract that _you_ create. @@ -44,17 +44,17 @@ In this way you can use _composability_ to add additional layers of access contr ### Examples in OpenZeppelin -You'll notice that none of the OpenZeppelin contracts use Ownable, though! This is because there are more flexible ways of providing access control that are more in-line with our reusable contract philosophy. For most contracts, We'll use `Roles` to govern who can do what. There are some cases, though—like with `Escrow`—where there's a direct relationship between contracts. In those cases, we'll use [`Secondary`](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/ownership/Secondary.sol) to create a "secondary" contract that allows a "primary" contract to manage it. +You'll notice that none of the OpenZeppelin contracts use `Ownable`, though! This is because there are more flexible ways of providing access control that are more in-line with our reusable contract philosophy. For most contracts, We'll use `Roles` to govern who can do what. There are some cases, though—like with [`Escrow`](localhost:3000/api/payment#escrow)—where there's a direct relationship between contracts. In those cases, we'll use [`Secondary`](api/ownership#secondary) to create a "secondary" contract that allows a "primary" contract to manage it. Let's learn about Role-Based Access Control! -## Role-Based Access Control & Roles.sol +## Roles & Role-Based Access Control An alternative to single-concern `Ownable` is role based access control (RBAC), which, instead of keeping track of a single entity with "admin" level privileges, keeps track of multiple different entities with a variety of roles that inform the contract about what they can do. -For example, a `MintableToken` could have a `minter` role that decides who can mint tokens (which could be assigned to a Crowdsale). It could also have a `namer` role that allows changing the name or symbol of the token (for whatever reason). RBAC gives you much more flexibility over who can do what and is generally recommended for applications that need more configurability. If you're experienced with web development, the vast majority of access control systems are role-based: some users are normal users, some are moderators, and some can be company employee admins. +For example, a [`MintableToken`](api/token/ERC20#erc20mintable) could have a `minter` role that decides who can mint tokens (which could be assigned to a [`Crowdsale`](api/crowdsale#crowdsale)). It could also have a `namer` role that allows changing the name or symbol of the token (for whatever reason). RBAC gives you much more flexibility over who can do what and is generally recommended for applications that need more configurability. If you're experienced with web development, the vast majority of access control systems are role-based: some users are normal users, some are moderators, and some can be company employee admins. -OpenZeppelin provides [contracts/access/Roles.sol](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/access/Roles.sol) for implementing role-based access control. +OpenZeppelin provides [`Roles`](api/access#roles) for implementing role-based access control. Here's an example of using `Roles` in our token example above, we'll use it to implement a token that can be minted by `Minters` and renamed by `Namers`: diff --git a/docs/learn-about-crowdsales.md b/docs/crowdsales.md similarity index 75% rename from docs/learn-about-crowdsales.md rename to docs/crowdsales.md index 4bcbb0128..eaf0645f2 100644 --- a/docs/learn-about-crowdsales.md +++ b/docs/crowdsales.md @@ -1,6 +1,6 @@ --- -id: learn-about-crowdsales -title: Learn About Crowdsales +id: crowdsales +title: Crowdsales --- Crowdsales are a popular use for Ethereum; they let you allocate tokens to network participants in various ways, mostly in exchange for Ether. They come in a variety of shapes and flavors, so let's go over the various types available in OpenZeppelin and how to use them. @@ -20,7 +20,7 @@ Crowdsales have a bunch of different properties, but here are some important one - Does distribution of funds happen in real-time or after the crowdsale? - Can participants receive a refund if the goal is not met? -To manage all of the different combinations and flavors of crowdsales, OpenZeppelin provides a highly configurable [`Crowdsale.sol`](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/crowdsale/Crowdsale.sol) base contract that can be combined with various other functionalities to construct a bespoke crowdsale. +To manage all of the different combinations and flavors of crowdsales, OpenZeppelin provides a highly configurable [`Crowdsale`](api/crowdsale#crowdsale) base contract that can be combined with various other functionalities to construct a bespoke crowdsale. ## Crowdsale Rate @@ -60,9 +60,9 @@ One more for practice: if I want to issue "1 TKN for every dollar (USD) in Ether One of the first decisions you have to make is "how do I get these tokens to users?". This is usually done in one of three ways: -- (default) — The Crowdsale contract owns tokens and simply transfers tokens from its own ownership to users that purchase them. -- [MintedCrowdsale](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/crowdsale/emission/MintedCrowdsale.sol) — The Crowdsale mints tokens when a purchase is made. -- [AllowanceCrowdsale](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/crowdsale/emission/AllowanceCrowdsale.sol) — The Crowdsale is granted an allowance to another wallet (like a Multisig) that already owns the tokens to be sold in the crowdsale. +- (default) — The `Crowdsale` contract owns tokens and simply transfers tokens from its own ownership to users that purchase them. +- [`MintedCrowdsale`](api/crowdsale#mintedcrowdsale) — The `Crowdsale` mints tokens when a purchase is made. +- [`AllowanceCrowdsale`](api/crowdsale#allowancecrowdsale) — The `Crowdsale` is granted an allowance to another wallet (like a Multisig) that already owns the tokens to be sold in the crowdsale. ### Default Emission @@ -84,7 +84,7 @@ new Crowdsale( ### Minted Crowdsale -To use a `MintedCrowdsale`, your token must also be a `ERC20Mintable` token that the crowdsale has permission to mint from. This can look like: +To use a [`MintedCrowdsale`](api/crowdsale#mintedcrowdsale), your token must also be a [`ERC20Mintable`](api/token/ERC20#erc20mintable) token that the crowdsale has permission to mint from. This can look like: ```solidity contract MyToken is ERC20, ERC20Mintable { @@ -128,7 +128,7 @@ contract MyCrowdsaleDeployer { ### AllowanceCrowdsale -Use an `AllowanceCrowdsale` to send tokens from another wallet to the participants of the crowdsale. In order for this to work, the source wallet must give the crowdsale an allowance via the ERC20 `approve(...)` method. +Use an [`AllowanceCrowdsale`](api/crowdsale#allowancecrowdsale) to send tokens from another wallet to the participants of the crowdsale. In order for this to work, the source wallet must give the crowdsale an allowance via the ERC20 [`approve`](api/token/ERC20#IERC20.approve(address,uint256)) method. ```solidity contract MyCrowdsale is AllowanceCrowdsale, Crowdsale { @@ -157,10 +157,10 @@ IERC20(tokenAddress).approve(CROWDALE_ADDRESS, SOME_TOKEN_AMOUNT); There are a bunch of different validation requirements that your crowdsale might be a part of: -- [CappedCrowdsale](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/crowdsale/validation/CappedCrowdsale.sol) — adds a cap to your crowdsale, invalidating any purchases that would exceed that cap -- [IndividuallyCappedCrowdsale](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/crowdsale/validation/IndividuallyCappedCrowdsale.sol) — caps an individual's contributions. -- [WhitelistedCrowdsale](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/crowdsale/validation/WhitelistedCrowdsale.sol) — only allow whitelisted participants to purchase tokens. this is useful for putting your KYC / AML whitelist on-chain! -- [TimedCrowdsale](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/crowdsale/validation/TimedCrowdsale.sol) — adds an `openingTime` and `closingTime` to your crowdsale +- [`CappedCrowdsale`](api/crowdsale#cappedcrowdsale) — adds a cap to your crowdsale, invalidating any purchases that would exceed that cap +- [`IndividuallyCappedCrowdsale`](api/crowdsale#individuallycappedcrowdsale) — caps an individual's contributions. +- [`WhitelistCrowdsale`](api/crowdsale#whitelistcrowdsale) — only allow whitelisted participants to purchase tokens. this is useful for putting your KYC / AML whitelist on-chain! +- [`TimedCrowdsale`](api/crowdsale#timedcrowdsale) — adds an [`openingTime`](api/crowdsale#TimedCrowdsale.openingTime()) and [`closingTime`](api/crowdsale#TimedCrowdsale.closingTime()) to your crowdsale Simply mix and match these crowdsale flavors to your heart's content: @@ -197,7 +197,7 @@ OpenZeppelin is here to make that easy! ### PostDeliveryCrowdsale -The [PostDeliveryCrowdsale](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/crowdsale/distribution/PostDeliveryCrowdsale.sol), as its name implies, distributes tokens after the crowdsale has finished, letting users call `withdrawTokens()` in order to claim the tokens they've purchased. +The [`PostDeliveryCrowdsale`](api/crowdsale#postdeliverycrowdsale), as its name implies, distributes tokens after the crowdsale has finished, letting users call [`withdrawTokens`](api/crowdsale#PostDeliveryCrowdsale.withdrawTokens(address)) in order to claim the tokens they've purchased. ```solidity contract MyCrowdsale is PostDeliveryCrowdsale, TimedCrowdsale, Crowdsale { @@ -222,7 +222,7 @@ contract MyCrowdsale is PostDeliveryCrowdsale, TimedCrowdsale, Crowdsale { ### RefundableCrowdsale -The [RefundableCrowdsale](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/crowdsale/distribution/RefundableCrowdsale.sol) offers to refund users if a minimum goal is not reached. If the goal is not reached, the users can `claimRefund()` to get their Ether back. +The [`RefundableCrowdsale`](api/crowdsale#refundablecrowdsale) offers to refund users if a minimum goal is not reached. If the goal is not reached, the users can [`claimRefund`](api/crowdsale#RefundableCrowdsale.claimRefund(address%20payable)) to get their Ether back. ```solidity diff --git a/docs/get-started.md b/docs/get-started.md index 16d631b77..4e6efab9f 100644 --- a/docs/get-started.md +++ b/docs/get-started.md @@ -3,7 +3,7 @@ id: get-started title: Get Started --- -OpenZeppelin can be installed directly into your existing node.js project with `npm install openzeppelin-solidity`. We will use [Truffle](https://github.com/ConsenSys/truffle), an Ethereum development environment, to get started. +OpenZeppelin can be installed directly into your existing node.js project with `npm install openzeppelin-solidity`. We will use [Truffle](https://github.com/trufflesuite/truffle), an Ethereum development environment, to get started. Please install Truffle and initialize your project: @@ -33,10 +33,10 @@ contract MyContract is Ownable { After installing OpenZeppelin, check out the rest of the guides in the sidebar to learn about the different contracts that OpenZeppelin provides and how to use them. -- [Learn About Access Control](learn-about-access-control) -- [Learn About Crowdsales](learn-about-crowdsales) -- [Learn About Tokens](learn-about-tokens) -- [Learn About Utilities](learn-about-utilities) +- [Learn About Access Control](access-control) +- [Learn About Crowdsales](crowdsales) +- [Learn About Tokens](tokens) +- [Learn About Utilities](utilities) You may also want to take a look at the guides on our blog, which cover several common use cases and good practices: https://blog.zeppelin.solutions/guides/home. diff --git a/docs/learn-about-utilities.md b/docs/learn-about-utilities.md deleted file mode 100644 index a62646fb5..000000000 --- a/docs/learn-about-utilities.md +++ /dev/null @@ -1,94 +0,0 @@ ---- -id: learn-about-utilities -title: Learn About Utilities ---- - -OpenZeppelin provides a ton of useful utilities that you can use in your project. Here are some of the more popular ones: - -## Cryptography - -- [ECDSA.sol](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/cryptography/ECDSA.sol) — provides functions for recovering and managing Ethereum account ECDSA signatures: - - to use it, declare: `using ECDSA for bytes32;` - - signatures are tightly packed, 65 byte `bytes` that look like `{v (1)} {r (32)} {s (32)}` - - this is the default from `web3.eth.sign` so you probably don't need to worry about this format - - recover the signer using `myDataHash.recover(signature)` - - if you are using `eth_personalSign`, the signer will hash your data and then add the prefix `\x19Ethereum Signed Message:\n`, so if you're attempting to recover the signer of an Ethereum signed message hash, you'll want to use `toEthSignedMessageHash` - - -Use these functions in combination to verify that a user has signed some information on-chain: - -```solidity -keccack256( - abi.encodePacked( - someData, - moreData - ) -) -.toEthSignedMessageHash() -.recover(signature) -``` - -- [MerkleProof.sol](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/cryptography/MerkleProof.sol) — provides `verify(...)` for verifying merkle proofs. - - -## Introspection - -In Solidity, it's frequently helpful to know whether or not a contract supports an interface you'd like to use. ERC165 is a standard that helps do runtime interface detection. OpenZeppelin provides some helpers, both for implementing ERC165 in your contracts and querying other contracts: - -- [IERC165](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/introspection/IERC165.sol) — this is the ERC165 interface that defines `supportsInterface(...)`. When implementing ERC165, you'll conform to this interface. -- [ERC165](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/introspection/ERC165.sol) — inherit this contract if you'd like to support interface detection using a lookup table in contract storage. You can register interfaces using `_registerInterface(bytes4)`: check out example usage as part of the ERC721 implementation. -- [ERC165Checker](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/introspection/ERC165Checker.sol) — ERC165Checker simplifies the process of checking whether or not a contract supports an interface you care about. - - include with `using ERC165Checker for address;` - - `myAddress.supportsInterface(bytes4)` - - `myAddress.supportsInterfaces(bytes4[])` - - -```solidity -contract MyContract { - using ERC165Checker for address; - - bytes4 private InterfaceId_ERC721 = 0x80ac58cd; - - /** - * @dev transfer an ERC721 token from this contract to someone else - */ - function transferERC721( - address token, - address to, - uint256 tokenId - ) - public - { - require(token.supportsInterface(InterfaceId_ERC721), "IS_NOT_721_TOKEN"); - IERC721(token).transferFrom(address(this), to, tokenId); - } -} -``` - -## Math - -The most popular math related library OpenZeppelin provides is [SafeMath](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/math/SafeMath.sol), which provides mathematical functions that protect your contract from overflows and underflows. - -Include the contract with `using SafeMath for uint256;` and then call the functions: - -- `myNumber.add(otherNumber)` -- `myNumber.sub(otherNumber)` -- `myNumber.div(otherNumber)` -- `myNumber.mul(otherNumber)` -- `myNumber.mod(otherNumber)` - -Easy! - -## Payment - -Want to split some payments between multiple people? Maybe you have an app that sends 30% of art purchases to the original creator and 70% of the profits to the current owner; you can build that with [`PaymentSplitter`](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/payment/PaymentSplitter.sol)!. - -In solidity, there are some security concerns with blindly sending money to accounts, since it allows them to execute arbitrary code. You can read up on these security concerns in the [Ethereum Smart Contract Best Practices](https://consensys.github.io/smart-contract-best-practices/) website. One of the ways to fix reentrancy and stalling problems is, instead of immediately sending Ether to accounts that need it, you can use [`PullPayment`](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/payment/PullPayment.sol), which offers an `asyncSend` function for sending money to something and requesting that they `withdraw()` it later. - -If you want to Escrow some funds, check out [`Escrow`](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/payment/escrow/Escrow.sol) and [`ConditionalEscrow`](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/payment/escrow/ConditionalEscrow.sol) for governing the release of some escrowed Ether. - -### Misc - -Want to check if an address is a contract? Use [`Address`](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/utils/Address.sol) and `Address#isContract()`. - -Want to keep track of some numbers that increment by 1 every time you want another one? Check out [`Counter`](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/v2.1.2/contracts/drafts/Counter.sol). This is especially useful for creating incremental ERC721 tokenIds like we did in the last section. diff --git a/docs/sidebar.json b/docs/sidebar.json index e9f2f3c21..ab70d762d 100644 --- a/docs/sidebar.json +++ b/docs/sidebar.json @@ -3,10 +3,10 @@ "get-started" ], "Guides": [ - "learn-about-access-control", - "learn-about-crowdsales", - "learn-about-tokens", - "learn-about-utilities" + "access-control", + "crowdsales", + "tokens", + "utilities" ], "API Reference": [ { diff --git a/docs/learn-about-tokens.md b/docs/tokens.md similarity index 58% rename from docs/learn-about-tokens.md rename to docs/tokens.md index 65674a6cd..d2a0dcad8 100644 --- a/docs/learn-about-tokens.md +++ b/docs/tokens.md @@ -1,6 +1,6 @@ --- -id: learn-about-tokens -title: Learn About Tokens +id: tokens +title: Tokens --- Ah, the "token": the world's most powerful and most misused tool. In this section we'll learn to harness the power of native units of account for good and world peace! @@ -21,22 +21,22 @@ An ERC20 token is a contract that keeps track of a `mapping(address => uint256)` OpenZeppelin provides a few different ERC20-related contracts. Here are the core contracts you'll almost definitely be using: -- [IERC20](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/token/ERC20/IERC20.sol) — defines the interface that all ERC20 token implementations should conform to -- [ERC20](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/token/ERC20/ERC20.sol) — the base implementation of the ERC20 interface -- [ERC20Detailed](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/token/ERC20/ERC20Detailed.sol) — the `name()`, `symbol()`, and `decimals()` getters are optional in the original standard, so `ERC20Detailed` adds that information to your token. +- [`IERC20`](api/token/ERC20#ierc20) — defines the interface that all ERC20 token implementations should conform to +- [`ERC20`](api/token/ERC20#erc20) — the base implementation of the ERC20 interface +- [`ERC20Detailed`](api/token/ERC20#erc20detailed) — the [`name()`](api/token/ERC20#ERC20Detailed.name()), [`symbol()`](api/token/ERC20#ERC20Detailed.symbol()), and [`decimals()`](api/token/ERC20#ERC20Detailed.decimals()) getters are optional in the original standard, so `ERC20Detailed` adds that information to your token. After that, OpenZeppelin provides a few extra properties that you may want depending on your use-case: -- [ERC20Mintable](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/token/ERC20/ERC20Mintable.sol) — `ERC20Mintable` allows users with the [`MinterRole`](/api/docs/learn-about-access-control.html) to call the `mint()` function and mint tokens to users. Minting can also be finished, locking the `mint()` function's behavior. -- [ERC20Burnable](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/token/ERC20/ERC20Burnable.sol) — if your token can be burned (aka, it can be destroyed), include this one -- [ERC20Capped](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/token/ERC20/ERC20Capped.sol) — `ERC20Capped` is a type of `ERC20Mintable` that enforces a maximum cap on tokens; this is really useful if you want to ensure network participants that there will always be a maximum number of tokens, and is useful for making sure that multiple different minting methods don't accidentally create more tokens than you expected. -- [ERC20Pausable](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/token/ERC20/ERC20Pausable.sol) — `ERC20Pausable` allows anyone with the Pauser role to pause the token, freezing transfers to and from users. This is useful if you want to stop trades until the end of a crowdsale, or if you want to have an emergency switch for freezing your tokens in the event of a large bug. Note that there are inherent decentralization tradeoffs when using a pausable token; users may not expect that their unstoppable money can be frozen by a single address! +- [`ERC20Mintable`](api/token/ERC20#erc20mintable) — `ERC20Mintable` allows users with the [`MinterRole`](access-control) to call the [`mint()`](api/token/ERC20#ERC20Mintable.mint(address,uint256)) function and mint tokens to users. +- [`ERC20Burnable`](api/token/ERC20#erc20burnable) — if your token can be burned (aka, it can be destroyed), include this one. +- [`ERC20Capped`](api/token/ERC20#erc20capped) — `ERC20Capped` is a type of `ERC20Mintable` that enforces a maximum cap on tokens; this is really useful if you want to ensure network participants that there will always be a maximum number of tokens, and is useful for making sure that multiple different minting methods don't accidentally create more tokens than you expected. +- [`ERC20Pausable`](api/token/ERC20#erc20pausable) — `ERC20Pausable` allows anyone with the Pauser role to pause the token, freezing transfers to and from users. This is useful if you want to stop trades until the end of a crowdsale, or if you want to have an emergency switch for freezing your tokens in the event of a large bug. Note that there are inherent decentralization tradeoffs when using a pausable token; users may not expect that their unstoppable money can be frozen by a single address! Finally, if you're working with ERC20 tokens, OpenZeppelin provides some utility contracts: -- [SafeERC20](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/token/ERC20/SafeERC20.sol) — provides `safeTransfer`, `safeTransferFrom`, and `safeApprove` that are helpful wrappers around the normal ERC20 functions. Using `SafeERC20` forces transfers and approvals to succeed, or the entire transaction is reverted. -- [TokenTimelock](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/token/ERC20/TokenTimelock.sol) — is an escrow contract for ERC20 tokens that will release some tokens after a specified timeout. This is useful for simple vesting schedules like "advisors get all of their tokens after 1 year". For a better vesting schedule, though, see [`TokenVesting`](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/drafts/TokenVesting.sol) +- [`SafeERC20`](api/token/ERC20#safeerc20) — provides [`safeTransfer`](api/token/ERC20#SafeERC20.safeTransfer(contract%20IERC20,address,uint256)), [`safeTransferFrom`](api/token/ERC20#SafeERC20.safeTransferFrom(contract%20IERC20,address,address,uint256)), and [`safeApprove`](api/token/ERC20#SafeERC20.safeApprove(contract%20IERC20,address,uint256)) that are helpful wrappers around the normal ERC20 functions. Using `SafeERC20` forces transfers and approvals to succeed, or the entire transaction is reverted. +- [`TokenTimelock`](api/token/ERC20#tokentimelock) — is an escrow contract for ERC20 tokens that will release some tokens after a specified timeout. This is useful for simple vesting schedules like "advisors get all of their tokens after 1 year". For a better vesting schedule, though, see [`TokenVesting`](api/drafts#tokenvesting) ### Constructing a Nice ERC20 Token @@ -79,11 +79,11 @@ We've discussed how you can make a _fungible_ token using ERC20, but what if not Let's see what contracts OpenZeppelin provides for helping us work with ERC721: -- The `IERC721`, `IERC721Metadata`, `IERC721Enumerable` interfaces are part of the [IERC721.sol](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/token/ERC721/IERC721.sol) file, which document the interfaces. -- [ERC721](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/token/ERC721/ERC721.sol) — is the full implementation of ERC721, and the contract you'll most likely be inheriting from. -- [IERC721Receiver](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/token/ERC721/IERC721Receiver.sol) — in some cases, it's beneficial to be 100% certain that a contract knows how to handle ERC721 tokens (imagine sending an in-game item to an exchange address that can't send it back!). When using `safeTransferFrom()`, the contract checks to see that the receiver is an `IERC721Receiver`, which implies that it knows how to handle ERC721 tokens. If you're writing a contract that accepts 721 tokens, you'll want to implement this interface. -- [ERC721Mintable](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/token/ERC721/ERC721Mintable.sol) — like the ERC20 version, ERC721Mintable allows addresses with the `Minter` role to mint tokens. -- [ERC721Pausable](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/token/ERC721/ERC721Pausable.sol) — like the ERC20 version, ERC721Pausable allows addresses with the `Pauser` role to freeze transfers of tokens. +- The [`IERC721`](api/token/ERC721#ierc721), [`IERC721Metadata`](api/token/ERC721#ierc721metadata), [`IERC721Enumerable`](api/token/ERC721#ierc721enumerable) contracts document the interfaces. +- [`ERC721`](api/token/ERC721#erc721) — is the full implementation of ERC721, and the contract you'll most likely be inheriting from. +- [`IERC721Receiver`](api/token/ERC721#ierc721receiver) — in some cases, it's beneficial to be 100% certain that a contract knows how to handle ERC721 tokens (imagine sending an in-game item to an exchange address that can't send it back!). When using [`safeTransferFrom()`](api/token/ERC721#ERC721.safeTransferFrom(address,address,uint256)), the contract checks to see that the receiver is an `IERC721Receiver`, which implies that it knows how to handle ERC721 tokens. If you're writing a contract that accepts ERC721 tokens, you'll want to implement this interface. +- [`ERC721Mintable`](api/token/ERC721#erc721mintable) — like the ERC20 version, `ERC721Mintable` allows addresses with the `Minter` role to mint tokens. +- [`ERC721Pausable`](api/token/ERC721#erc721pausable) — like the ERC20 version, `ERC721Pausable` allows addresses with the `Pauser` role to freeze transfers of tokens. We'll use these contracts to tokenize the time of our dogsitters: when a dogsitter wants to sell an hour of their time to watch a dog, they can mint an ERC721 token that represents that hour slot and then sell this token on an exchange. Then they'll go to the owner's house at the right time to watch their doggos. diff --git a/docs/utilities.md b/docs/utilities.md new file mode 100644 index 000000000..ff0d246c6 --- /dev/null +++ b/docs/utilities.md @@ -0,0 +1,94 @@ +--- +id: utilities +title: Utilities +--- + +OpenZeppelin provides a ton of useful utilities that you can use in your project. Here are some of the more popular ones: + +## Cryptography + +- [`ECDSA`](api/cryptography#ecdsa) — provides functions for recovering and managing Ethereum account ECDSA signatures: + - to use it, declare: `using ECDSA for bytes32;` + - signatures are tightly packed, 65 byte `bytes` that look like `{v (1)} {r (32)} {s (32)}` + - this is the default from `web3.eth.sign` so you probably don't need to worry about this format + - recover the signer using [`myDataHash.recover(signature)`](api/cryptography#ECDSA.recover(bytes32,bytes)) + - if you are using `eth_personalSign`, the signer will hash your data and then add the prefix `\x19Ethereum Signed Message:\n`, so if you're attempting to recover the signer of an Ethereum signed message hash, you'll want to use [`toEthSignedMessageHash`](api/cryptography#ECDSA.toEthSignedMessageHash(bytes32)) + + +Use these functions in combination to verify that a user has signed some information on-chain: + +```solidity +keccack256( + abi.encodePacked( + someData, + moreData + ) +) +.toEthSignedMessageHash() +.recover(signature) +``` + +- [`MerkleProof`](api/cryptography#merkleproof) — provides [`verify`](api/cryptography#MerkleProof.verify(bytes32[],bytes32,bytes32)) for verifying merkle proofs. + + +## Introspection + +In Solidity, it's frequently helpful to know whether or not a contract supports an interface you'd like to use. ERC165 is a standard that helps do runtime interface detection. OpenZeppelin provides some helpers, both for implementing ERC165 in your contracts and querying other contracts: + +- [`IERC165`](api/introspection#ierc165) — this is the ERC165 interface that defines [`supportsInterface`](api/introspection#IERC165.supportsInterface(bytes4)). When implementing ERC165, you'll conform to this interface. +- [`ERC165`](api/introspection#erc165) — inherit this contract if you'd like to support interface detection using a lookup table in contract storage. You can register interfaces using [`_registerInterface(bytes4)`](api/introspection#ERC165._registerInterface(bytes4)): check out example usage as part of the ERC721 implementation. +- [`ERC165Checker`](api/introspection#erc165checker) — ERC165Checker simplifies the process of checking whether or not a contract supports an interface you care about. + - include with `using ERC165Checker for address;` + - [`myAddress._supportsInterface(bytes4)`](api/introspection#ERC165Checker._supportsInterface(address,bytes4)) + - [`myAddress._supportsAllInterfaces(bytes4[])`](api/introspection#ERC165Checker._supportsAllInterfaces(address,bytes4[])) + + +```solidity +contract MyContract { + using ERC165Checker for address; + + bytes4 private InterfaceId_ERC721 = 0x80ac58cd; + + /** + * @dev transfer an ERC721 token from this contract to someone else + */ + function transferERC721( + address token, + address to, + uint256 tokenId + ) + public + { + require(token.supportsInterface(InterfaceId_ERC721), "IS_NOT_721_TOKEN"); + IERC721(token).transferFrom(address(this), to, tokenId); + } +} +``` + +## Math + +The most popular math related library OpenZeppelin provides is [`SafeMath`](api/math#safemath), which provides mathematical functions that protect your contract from overflows and underflows. + +Include the contract with `using SafeMath for uint256;` and then call the functions: + +- `myNumber.add(otherNumber)` +- `myNumber.sub(otherNumber)` +- `myNumber.div(otherNumber)` +- `myNumber.mul(otherNumber)` +- `myNumber.mod(otherNumber)` + +Easy! + +## Payment + +Want to split some payments between multiple people? Maybe you have an app that sends 30% of art purchases to the original creator and 70% of the profits to the current owner; you can build that with [`PaymentSplitter`](api/payment#paymentsplitter)! + +In solidity, there are some security concerns with blindly sending money to accounts, since it allows them to execute arbitrary code. You can read up on these security concerns in the [Ethereum Smart Contract Best Practices](https://consensys.github.io/smart-contract-best-practices/) website. One of the ways to fix reentrancy and stalling problems is, instead of immediately sending Ether to accounts that need it, you can use [`PullPayment`](api/payment#pullpayment), which offers an [`_asyncTransfer`](api/payment#PullPayment._asyncTransfer(address,uint256)) function for sending money to something and requesting that they [`withdrawPayments()`](api/payment#PullPayment.withdrawPayments(address%20payable)) it later. + +If you want to Escrow some funds, check out [`Escrow`](api/payment#escrow) and [`ConditionalEscrow`](api/payment#conditionalescrow) for governing the release of some escrowed Ether. + +### Misc + +Want to check if an address is a contract? Use [`Address`](api/utils#address) and [`Address#isContract()`](api/utils#Address.isContract(address)). + +Want to keep track of some numbers that increment by 1 every time you want another one? Check out [`Counter`](api/drafts#counter). This is especially useful for creating incremental ERC721 `tokenId`s like we did in the last section. diff --git a/package-lock.json b/package-lock.json index 27fd702e1..f6b32bfc9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,18 +14,18 @@ } }, "@babel/core": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.4.3.tgz", - "integrity": "sha512-oDpASqKFlbspQfzAE7yaeTmdljSH2ADIvBlb0RwbStltTuWa0+7CCI1fYVINNv9saHPa1W7oaKeuNuKj+RQCvA==", + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.4.5.tgz", + "integrity": "sha512-OvjIh6aqXtlsA8ujtGKfC7LYWksYSX8yQcM8Ay3LuvVeQ63lcOKgoZWVqcpFwkd29aYU9rVx7jxhfhiEDV9MZA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@babel/generator": "^7.4.0", - "@babel/helpers": "^7.4.3", - "@babel/parser": "^7.4.3", - "@babel/template": "^7.4.0", - "@babel/traverse": "^7.4.3", - "@babel/types": "^7.4.0", + "@babel/generator": "^7.4.4", + "@babel/helpers": "^7.4.4", + "@babel/parser": "^7.4.5", + "@babel/template": "^7.4.4", + "@babel/traverse": "^7.4.5", + "@babel/types": "^7.4.4", "convert-source-map": "^1.1.0", "debug": "^4.1.0", "json5": "^2.1.0", @@ -35,6 +35,52 @@ "source-map": "^0.5.0" }, "dependencies": { + "@babel/generator": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.4.4.tgz", + "integrity": "sha512-53UOLK6TVNqKxf7RUh8NE851EHRxOOeVXKbK2bivdb+iziMyk03Sr4eaE9OELCbyZAAafAKPDwF2TPUES5QbxQ==", + "dev": true, + "requires": { + "@babel/types": "^7.4.4", + "jsesc": "^2.5.1", + "lodash": "^4.17.11", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + } + }, + "@babel/helpers": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.4.4.tgz", + "integrity": "sha512-igczbR/0SeuPR8RFfC7tGrbdTbFL3QTvH6D+Z6zNxnTe//GyqmtHmDkzrqDmyZ3eSwPqB/LhyKoU5DXsp+Vp2A==", + "dev": true, + "requires": { + "@babel/template": "^7.4.4", + "@babel/traverse": "^7.4.4", + "@babel/types": "^7.4.4" + } + }, + "@babel/template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz", + "integrity": "sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.4.4", + "@babel/types": "^7.4.4" + } + }, + "@babel/types": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz", + "integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.11", + "to-fast-properties": "^2.0.0" + } + }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", @@ -295,17 +341,6 @@ "@babel/types": "^7.2.0" } }, - "@babel/helpers": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.4.3.tgz", - "integrity": "sha512-BMh7X0oZqb36CfyhvtbSmcWc3GXocfxv3yNsAEuM0l+fAqSO22rQrUpijr3oE/10jCTrB6/0b9kzmG4VetCj8Q==", - "dev": true, - "requires": { - "@babel/template": "^7.4.0", - "@babel/traverse": "^7.4.3", - "@babel/types": "^7.4.0" - } - }, "@babel/highlight": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", @@ -363,9 +398,9 @@ } }, "@babel/parser": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.3.tgz", - "integrity": "sha512-gxpEUhTS1sGA63EGQGuA+WESPR/6tz6ng7tSHFCmaTJK/cGK8y37cBTspX+U2xCAue2IQVvF6Z0oigmjwD8YGQ==", + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.5.tgz", + "integrity": "sha512-9mUqkL1FF5T7f0WDFfAoDdiMVPWsdD1gZYzSnaXsxUCUqzuch/8of9G3VUSNiZmMBoRxT3neyVsqeiL/ZPcjew==", "dev": true }, "@babel/plugin-proposal-async-generator-functions": { @@ -657,21 +692,12 @@ } }, "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.4.2.tgz", - "integrity": "sha512-NsAuliSwkL3WO2dzWTOL1oZJHm0TM8ZY8ZSxk2ANyKkt5SQlToGA4pzctmq1BEjoacurdwZ3xp2dCQWJkME0gQ==", - "dev": true, - "requires": { - "regexp-tree": "^0.1.0" - } - }, - "@babel/plugin-transform-new-target": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.4.0.tgz", - "integrity": "sha512-6ZKNgMQmQmrEX/ncuCwnnw1yVGoaOW5KpxNhoWI7pCQdA0uZ0HqHGqenCUIENAnxRjy2WwNQ30gfGdIgqJXXqw==", + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.4.5.tgz", + "integrity": "sha512-z7+2IsWafTBbjNsOxU/Iv5CvTJlr5w4+HGu1HovKYTtgJ362f7kBcQglkfmlspKKZ3bgrbSGvLfNx++ZJgCWsg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.0.0" + "regexp-tree": "^0.1.6" } }, "@babel/plugin-transform-object-super": { @@ -745,12 +771,12 @@ } }, "@babel/plugin-transform-regenerator": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.4.3.tgz", - "integrity": "sha512-kEzotPuOpv6/iSlHroCDydPkKYw7tiJGKlmYp6iJn4a6C/+b2FdttlJsLKYxolYHgotTJ5G5UY5h0qey5ka3+A==", + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.4.5.tgz", + "integrity": "sha512-gBKRh5qAaCWntnd09S8QC7r3auLCqq5DI6O0DlfoyDjslSBVqBibrMdsqO+Uhmx3+BlOmE/Kw1HFxmGbv0N9dA==", "dev": true, "requires": { - "regenerator-transform": "^0.13.4" + "regenerator-transform": "^0.14.0" } }, "@babel/plugin-transform-reserved-words": { @@ -809,17 +835,6 @@ "@babel/helper-plugin-utils": "^7.0.0" } }, - "@babel/plugin-transform-unicode-regex": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.4.3.tgz", - "integrity": "sha512-lnSNgkVjL8EMtnE8eSS7t2ku8qvKH3eqNf/IwIfnSPUqzgqYmRwzdsQWv4mNQAN9Nuo6Gz1Y0a4CSmdpu1Pp6g==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-regex": "^7.4.3", - "regexpu-core": "^4.5.4" - } - }, "@babel/polyfill": { "version": "7.4.3", "resolved": "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.4.3.tgz", @@ -831,61 +846,101 @@ } }, "@babel/preset-env": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.4.3.tgz", - "integrity": "sha512-FYbZdV12yHdJU5Z70cEg0f6lvtpZ8jFSDakTm7WXeJbLXh4R0ztGEu/SW7G1nJ2ZvKwDhz8YrbA84eYyprmGqw==", + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.4.5.tgz", + "integrity": "sha512-f2yNVXM+FsR5V8UwcFeIHzHWgnhXg3NpRmy0ADvALpnhB0SLbCvrCRr4BLOUYbQNLS+Z0Yer46x9dJXpXewI7w==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.0.0", "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-proposal-async-generator-functions": "^7.2.0", "@babel/plugin-proposal-json-strings": "^7.2.0", - "@babel/plugin-proposal-object-rest-spread": "^7.4.3", + "@babel/plugin-proposal-object-rest-spread": "^7.4.4", "@babel/plugin-proposal-optional-catch-binding": "^7.2.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", "@babel/plugin-syntax-async-generators": "^7.2.0", "@babel/plugin-syntax-json-strings": "^7.2.0", "@babel/plugin-syntax-object-rest-spread": "^7.2.0", "@babel/plugin-syntax-optional-catch-binding": "^7.2.0", "@babel/plugin-transform-arrow-functions": "^7.2.0", - "@babel/plugin-transform-async-to-generator": "^7.4.0", + "@babel/plugin-transform-async-to-generator": "^7.4.4", "@babel/plugin-transform-block-scoped-functions": "^7.2.0", - "@babel/plugin-transform-block-scoping": "^7.4.0", - "@babel/plugin-transform-classes": "^7.4.3", + "@babel/plugin-transform-block-scoping": "^7.4.4", + "@babel/plugin-transform-classes": "^7.4.4", "@babel/plugin-transform-computed-properties": "^7.2.0", - "@babel/plugin-transform-destructuring": "^7.4.3", - "@babel/plugin-transform-dotall-regex": "^7.4.3", + "@babel/plugin-transform-destructuring": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", "@babel/plugin-transform-duplicate-keys": "^7.2.0", "@babel/plugin-transform-exponentiation-operator": "^7.2.0", - "@babel/plugin-transform-for-of": "^7.4.3", - "@babel/plugin-transform-function-name": "^7.4.3", + "@babel/plugin-transform-for-of": "^7.4.4", + "@babel/plugin-transform-function-name": "^7.4.4", "@babel/plugin-transform-literals": "^7.2.0", "@babel/plugin-transform-member-expression-literals": "^7.2.0", "@babel/plugin-transform-modules-amd": "^7.2.0", - "@babel/plugin-transform-modules-commonjs": "^7.4.3", - "@babel/plugin-transform-modules-systemjs": "^7.4.0", + "@babel/plugin-transform-modules-commonjs": "^7.4.4", + "@babel/plugin-transform-modules-systemjs": "^7.4.4", "@babel/plugin-transform-modules-umd": "^7.2.0", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.4.2", - "@babel/plugin-transform-new-target": "^7.4.0", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.4.5", + "@babel/plugin-transform-new-target": "^7.4.4", "@babel/plugin-transform-object-super": "^7.2.0", - "@babel/plugin-transform-parameters": "^7.4.3", + "@babel/plugin-transform-parameters": "^7.4.4", "@babel/plugin-transform-property-literals": "^7.2.0", - "@babel/plugin-transform-regenerator": "^7.4.3", + "@babel/plugin-transform-regenerator": "^7.4.5", "@babel/plugin-transform-reserved-words": "^7.2.0", "@babel/plugin-transform-shorthand-properties": "^7.2.0", "@babel/plugin-transform-spread": "^7.2.0", "@babel/plugin-transform-sticky-regex": "^7.2.0", - "@babel/plugin-transform-template-literals": "^7.2.0", + "@babel/plugin-transform-template-literals": "^7.4.4", "@babel/plugin-transform-typeof-symbol": "^7.2.0", - "@babel/plugin-transform-unicode-regex": "^7.4.3", - "@babel/types": "^7.4.0", - "browserslist": "^4.5.2", - "core-js-compat": "^3.0.0", + "@babel/plugin-transform-unicode-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "browserslist": "^4.6.0", + "core-js-compat": "^3.1.1", "invariant": "^2.2.2", "js-levenshtein": "^1.1.3", "semver": "^5.5.0" }, "dependencies": { + "@babel/helper-regex": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.4.4.tgz", + "integrity": "sha512-Y5nuB/kESmR3tKjU8Nkn1wMGEx1tjJX076HBMeL3XLQCu6vA/YRzuTW0bbb+qRnXvQGn+d6Rx953yffl8vEy7Q==", + "dev": true, + "requires": { + "lodash": "^4.17.11" + } + }, + "@babel/plugin-transform-new-target": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.4.4.tgz", + "integrity": "sha512-r1z3T2DNGQwwe2vPGZMBNjioT2scgWzK9BCnDEh+46z8EEwXBq24uRzd65I7pjtugzPSj921aM15RpESgzsSuA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.4.4.tgz", + "integrity": "sha512-il+/XdNw01i93+M9J9u4T7/e/Ue/vWfNZE4IRUQjplu2Mqb/AFTDimkw2tdEdSH50wuQXZAbXSql0UphQke+vA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.4.4", + "regexpu-core": "^4.5.4" + } + }, + "@babel/types": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz", + "integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.11", + "to-fast-properties": "^2.0.0" + } + }, "semver": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", @@ -922,9 +977,9 @@ }, "dependencies": { "core-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.0.1.tgz", - "integrity": "sha512-sco40rF+2KlE0ROMvydjkrVMMG1vYilP2ALoRXcYR4obqbYIuV3Bg+51GEDW+HF8n7NRA+iaA4qD0nD9lo9mew==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.1.2.tgz", + "integrity": "sha512-3poRGjbu56leCtZCZCzCgQ7GcKOflDFnjWIepaPFUsM0IXUBrne10sl3aa2Bkcz3+FjRdIxBe9dAMhIJmEnQNA==", "dev": true } } @@ -948,22 +1003,42 @@ } }, "@babel/traverse": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.3.tgz", - "integrity": "sha512-HmA01qrtaCwwJWpSKpA948cBvU5BrmviAief/b3AVw936DtcdsTexlbyzNuDnthwhOQ37xshn7hvQaEQk7ISYQ==", + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.5.tgz", + "integrity": "sha512-Vc+qjynwkjRmIFGxy0KYoPj4FdVDxLej89kMHFsWScq999uX+pwcX4v9mWRjW0KcAYTPAuVQl2LKP1wEVLsp+A==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@babel/generator": "^7.4.0", + "@babel/generator": "^7.4.4", "@babel/helper-function-name": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.4.0", - "@babel/parser": "^7.4.3", - "@babel/types": "^7.4.0", + "@babel/helper-split-export-declaration": "^7.4.4", + "@babel/parser": "^7.4.5", + "@babel/types": "^7.4.4", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.11" }, "dependencies": { + "@babel/helper-split-export-declaration": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", + "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", + "dev": true, + "requires": { + "@babel/types": "^7.4.4" + } + }, + "@babel/types": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz", + "integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.11", + "to-fast-properties": "^2.0.0" + } + }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", @@ -1024,9 +1099,9 @@ } }, "@types/node": { - "version": "11.13.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-11.13.5.tgz", - "integrity": "sha512-/OMMBnjVtDuwX1tg2pkYVSqRIDSmNTnvVvmvP/2xiMAAWf4a5+JozrApCrO4WCAILmXVxfNoQ3E+0HJbNpFVGg==", + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.2.tgz", + "integrity": "sha512-5tabW/i+9mhrfEOUcLDu2xBPsHJ+X5Orqy9FKpale3SjDA17j5AEpYq5vfy3oAeAHGcvANRCO3NV3d2D6q3NiA==", "dev": true }, "@types/q": { @@ -1117,6 +1192,48 @@ "dev": true, "optional": true }, + "ansi-align": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", + "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", + "dev": true, + "requires": { + "string-width": "^2.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 + }, + "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 + }, + "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" + } + } + } + }, "ansi-colors": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", @@ -1168,6 +1285,130 @@ "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=", "dev": true }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "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", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "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" + } + } + } + }, + "fill-range": { + "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", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "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" + } + } + } + }, + "is-number": { + "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" + }, + "dependencies": { + "kind-of": { + "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" + } + } + } + }, + "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", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "to-regex-range": { + "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" + } + } + } + }, "app-module-path": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/app-module-path/-/app-module-path-2.2.0.tgz", @@ -1328,6 +1569,12 @@ "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", "dev": true }, + "async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", + "dev": true + }, "async-limiter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", @@ -1656,22 +1903,11 @@ } } }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } + "import-lazy": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-3.1.0.tgz", + "integrity": "sha512-8/gvXvX2JMn0F+CDlSC4l6kOmVaLOO3XLkksI7CI3Ud95KDYJuYur2b9P/PUt/i/pDAMd/DulQsNbbbmRRsDIQ==", + "dev": true }, "p-cancelable": { "version": "0.4.1", @@ -1697,6 +1933,12 @@ "p-finally": "^1.0.0" } }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, "prepend-http": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", @@ -1714,6 +1956,12 @@ } } }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true + }, "bindings": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.1.tgz", @@ -1863,6 +2111,83 @@ "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", "dev": true }, + "boxen": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", + "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", + "dev": true, + "requires": { + "ansi-align": "^2.0.0", + "camelcase": "^4.0.0", + "chalk": "^2.0.1", + "cli-boxes": "^1.0.0", + "string-width": "^2.0.0", + "term-size": "^1.2.0", + "widest-line": "^2.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 + }, + "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" + } + }, + "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 + }, + "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" + } + } + } + }, "brace-expansion": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", @@ -1975,14 +2300,14 @@ } }, "browserslist": { - "version": "4.5.5", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.5.5.tgz", - "integrity": "sha512-0QFO1r/2c792Ohkit5XI8Cm8pDtZxgNl2H6HU4mHrpYz7314pEYcsAVVatM0l/YmxPnEzh9VygXouj4gkFUTKA==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.6.0.tgz", + "integrity": "sha512-Jk0YFwXBuMOOol8n6FhgkDzn3mY9PYLYGk29zybF05SbRTsMgPqmTNeQQhOghCxq5oFqAXE3u4sYddr4C0uRhg==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30000960", - "electron-to-chromium": "^1.3.124", - "node-releases": "^1.1.14" + "caniuse-lite": "^1.0.30000967", + "electron-to-chromium": "^1.3.133", + "node-releases": "^1.1.19" } }, "buffer": { @@ -2247,15 +2572,21 @@ } }, "caniuse-db": { - "version": "1.0.30000962", - "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000962.tgz", - "integrity": "sha512-zkAkM+FSotCJZxdBDHoMhUWGUJzJjyWTTt4h33w3VFM1pirqxRHGgGIjireWkdYZQVRSYScNANixGtGycIFhmg==", + "version": "1.0.30000971", + "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000971.tgz", + "integrity": "sha512-ubSZfYXO2KMYtCVmDez82mjodeZa+mBYWAnBMAmFBPAn4C2PY4SD0eC/diYQD4Rj1K+WNdp0vr0JDtm0SQ6GNg==", "dev": true }, "caniuse-lite": { - "version": "1.0.30000962", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000962.tgz", - "integrity": "sha512-WXYsW38HK+6eaj5IZR16Rn91TGhU3OhbwjKZvJ4HN/XBIABLKfbij9Mnd3pM0VEwZSlltWjoWg3I8FQ0DGgNOA==", + "version": "1.0.30000971", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000971.tgz", + "integrity": "sha512-TQFYFhRS0O5rdsmSbF1Wn+16latXYsQJat66f7S7lizXW1PVpWJeZw9wqqVLIjuxDRz7s7xRUj13QCfd8hKn6g==", + "dev": true + }, + "capture-stack-trace": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz", + "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==", "dev": true }, "caseless": { @@ -2369,6 +2700,101 @@ } } }, + "chokidar": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.6.tgz", + "integrity": "sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + }, + "dependencies": { + "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", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + } + }, + "extend-shallow": { + "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" + } + }, + "fill-range": { + "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", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + } + }, + "is-number": { + "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" + } + }, + "kind-of": { + "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" + } + }, + "to-regex-range": { + "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" + } + } + } + }, + "ci-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", + "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", + "dev": true + }, "cipher-base": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", @@ -2423,6 +2849,12 @@ "integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==", "dev": true }, + "cli-boxes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", + "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=", + "dev": true + }, "cli-cursor": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", @@ -2669,2658 +3101,3533 @@ "typedarray": "^0.0.6" } }, - "config-chain": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz", - "integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==", - "dev": true, - "requires": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" - } - }, - "console-stream": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/console-stream/-/console-stream-0.1.1.tgz", - "integrity": "sha1-oJX+B7IEZZVfL6/Si11yvM2UnUQ=", - "dev": true - }, - "contains-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", - "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", - "dev": true - }, - "content-disposition": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=", - "dev": true - }, - "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 - }, - "continuable-cache": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/continuable-cache/-/continuable-cache-0.3.1.tgz", - "integrity": "sha1-vXJ6f67XfnH/OYWskzUakSczrQ8=", - "dev": true - }, - "convert-source-map": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", - "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", - "dev": true - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", - "dev": true - }, - "cookiejar": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", - "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==", - "dev": true - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-js": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.5.tgz", - "integrity": "sha512-klh/kDpwX8hryYL14M9w/xei6vrv6sE8gTHDG7/T/+SEovB/G4ejwcfE/CBzO6Edsu+OETZMZ3wcX/EjUkrl5A==", - "dev": true - }, - "core-js-compat": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.0.1.tgz", - "integrity": "sha512-2pC3e+Ht/1/gD7Sim/sqzvRplMiRnFQVlPpDVaHtY9l7zZP7knamr3VRD6NyGfHd84MrDC0tAM9ulNxYMW0T3g==", + "concurrently": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-4.1.0.tgz", + "integrity": "sha512-pwzXCE7qtOB346LyO9eFWpkFJVO3JQZ/qU/feGeaAHiX1M3Rw3zgXKc5cZ8vSH5DGygkjzLFDzA/pwoQDkRNGg==", "dev": true, "requires": { - "browserslist": "^4.5.4", - "core-js": "3.0.1", - "core-js-pure": "3.0.1", - "semver": "^6.0.0" + "chalk": "^2.4.1", + "date-fns": "^1.23.0", + "lodash": "^4.17.10", + "read-pkg": "^4.0.1", + "rxjs": "^6.3.3", + "spawn-command": "^0.0.2-1", + "supports-color": "^4.5.0", + "tree-kill": "^1.1.0", + "yargs": "^12.0.1" }, "dependencies": { - "core-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.0.1.tgz", - "integrity": "sha512-sco40rF+2KlE0ROMvydjkrVMMG1vYilP2ALoRXcYR4obqbYIuV3Bg+51GEDW+HF8n7NRA+iaA4qD0nD9lo9mew==", + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, - "semver": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.0.0.tgz", - "integrity": "sha512-0UewU+9rFapKFnlbirLi3byoOuhrSsli/z/ihNnvM24vgF+8sNBiI1LZPBSH9wJKUwaUbw+s3hToDLCXkrghrQ==", + "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" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "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" + }, + "dependencies": { + "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" + } + } + } + }, + "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" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", + "dev": 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 + }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "dev": true, + "requires": { + "invert-kv": "^2.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "mem": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", + "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "dev": true, + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "p-limit": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "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-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "read-pkg": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-4.0.1.tgz", + "integrity": "sha1-ljYlN48+HE1IyFhytabsfV0JMjc=", + "dev": true, + "requires": { + "normalize-package-data": "^2.3.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0" + } + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": 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, + "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": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "^2.0.0" + }, + "dependencies": { + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + } + } + }, + "yargs": { + "version": "12.0.5", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", + "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", + "dev": true, + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.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 || ^4.0.0", + "yargs-parser": "^11.1.1" + } + }, + "yargs-parser": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", + "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "config-chain": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz", + "integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==", + "dev": true, + "requires": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "configstore": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", + "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", + "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" + } + }, + "console-stream": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/console-stream/-/console-stream-0.1.1.tgz", + "integrity": "sha1-oJX+B7IEZZVfL6/Si11yvM2UnUQ=", + "dev": true + }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, + "content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=", + "dev": true + }, + "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 + }, + "continuable-cache": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/continuable-cache/-/continuable-cache-0.3.1.tgz", + "integrity": "sha1-vXJ6f67XfnH/OYWskzUakSczrQ8=", + "dev": true + }, + "convert-source-map": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", + "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", + "dev": true + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "dev": true + }, + "cookiejar": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", + "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==", + "dev": true + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "core-js": { + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.8.tgz", + "integrity": "sha512-RWlREFU74TEkdXzyl1bka66O3kYp8jeTXrvJZDzVVMH8AiHUSOFpL1yfhQJ+wHocAm1m+4971W1PPzfLuCv1vg==", + "dev": true + }, + "core-js-compat": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.1.2.tgz", + "integrity": "sha512-X0Ch5f6itrHxhg5HSJucX6nNLNAGr+jq+biBh6nPGc3YAWz2a8p/ZIZY8cUkDzSRNG54omAuu3hoEF8qZbu/6Q==", + "dev": true, + "requires": { + "browserslist": "^4.6.0", + "core-js-pure": "3.1.2", + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.1.0.tgz", + "integrity": "sha512-kCqEOOHoBcFs/2Ccuk4Xarm/KiWRSLEX9CAZF8xkJ6ZPlIoTZ8V5f7J16vYLJqDbR7KrxTJpR2lqjIEm2Qx9cQ==", + "dev": true + } + } + }, + "core-js-pure": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.1.2.tgz", + "integrity": "sha512-5ckIdBF26B3ldK9PM177y2ZcATP2oweam9RskHSoqfZCrJ2As6wVg8zJ1zTriFsZf6clj/N1ThDFRGaomMsh9w==", + "dev": true + }, + "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 + }, + "cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, + "coveralls": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.1.tgz", + "integrity": "sha512-FAzXwiDOYLGDWH+zgoIA+8GbWv50hlx+kpEJyvzLKOdnIBv9uWoVl4DhqGgyUHpiRjAlF8KYZSipWXYtllWH6Q==", + "dev": true, + "requires": { + "js-yaml": "^3.6.1", + "lcov-parse": "^0.0.10", + "log-driver": "^1.2.5", + "minimist": "^1.2.0", + "request": "^2.79.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "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-error-class": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", + "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", + "dev": true, + "requires": { + "capture-stack-trace": "^1.0.0" + } + }, + "create-hash": { + "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", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "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", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "dependencies": { + "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=" + } + } + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "lru-cache": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", + "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + } + } + }, + "crowdin-cli": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/crowdin-cli/-/crowdin-cli-0.3.0.tgz", + "integrity": "sha1-6smYmm/n/qrzMJA5evwYfGe0YZE=", + "dev": true, + "requires": { + "request": "^2.53.0", + "yamljs": "^0.2.1", + "yargs": "^2.3.0" + }, + "dependencies": { + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", + "dev": true + }, + "yargs": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-2.3.0.tgz", + "integrity": "sha1-6QDIclDsXNCA22AJ/j3WMVbx1/s=", + "dev": true, + "requires": { + "wordwrap": "0.0.2" + } + } + } + }, + "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.9-1", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.1.9-1.tgz", + "integrity": "sha1-/aGedh/Ad+Af+/3G6f38WeiAbNg=", + "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-color-names": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", + "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", + "dev": true + }, + "css-select": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.0.2.tgz", + "integrity": "sha512-dSpYaDVoWaELjvZ3mS6IKZM/y2PMPa/XYoEfYNZePL4U/XgyxZNroHEHReDx/d+VgXh9VbCTtFqLkFbmeqeaRQ==", + "dev": true, + "requires": { + "boolbase": "^1.0.0", + "css-what": "^2.1.2", + "domutils": "^1.7.0", + "nth-check": "^1.0.2" + } + }, + "css-select-base-adapter": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", + "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==", + "dev": true + }, + "css-tree": { + "version": "1.0.0-alpha.28", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.28.tgz", + "integrity": "sha512-joNNW1gCp3qFFzj4St6zk+Wh/NBv0vM5YbEreZk0SD4S23S+1xBKb6cLDg2uj4P4k/GUMlIm6cKIDqIG+vdt0w==", + "dev": true, + "requires": { + "mdn-data": "~1.1.0", + "source-map": "^0.5.3" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "css-url-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/css-url-regex/-/css-url-regex-1.1.0.tgz", + "integrity": "sha1-g4NCMMyfdMRX3lnuvRVD/uuDt+w=", + "dev": true + }, + "css-what": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", + "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==", + "dev": true + }, + "cssnano": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-3.10.0.tgz", + "integrity": "sha1-Tzj2zqK5sX+gFJDyPx3GjqZcHDg=", + "dev": true, + "requires": { + "autoprefixer": "^6.3.1", + "decamelize": "^1.1.2", + "defined": "^1.0.0", + "has": "^1.0.1", + "object-assign": "^4.0.1", + "postcss": "^5.0.14", + "postcss-calc": "^5.2.0", + "postcss-colormin": "^2.1.8", + "postcss-convert-values": "^2.3.4", + "postcss-discard-comments": "^2.0.4", + "postcss-discard-duplicates": "^2.0.1", + "postcss-discard-empty": "^2.0.1", + "postcss-discard-overridden": "^0.1.1", + "postcss-discard-unused": "^2.2.1", + "postcss-filter-plugins": "^2.0.0", + "postcss-merge-idents": "^2.1.5", + "postcss-merge-longhand": "^2.0.1", + "postcss-merge-rules": "^2.0.3", + "postcss-minify-font-values": "^1.0.2", + "postcss-minify-gradients": "^1.0.1", + "postcss-minify-params": "^1.0.4", + "postcss-minify-selectors": "^2.0.4", + "postcss-normalize-charset": "^1.1.0", + "postcss-normalize-url": "^3.0.7", + "postcss-ordered-values": "^2.1.0", + "postcss-reduce-idents": "^2.2.2", + "postcss-reduce-initial": "^1.0.0", + "postcss-reduce-transforms": "^1.0.3", + "postcss-svgo": "^2.1.1", + "postcss-unique-selectors": "^2.0.2", + "postcss-value-parser": "^3.2.3", + "postcss-zindex": "^2.0.1" + }, + "dependencies": { + "autoprefixer": { + "version": "6.7.7", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-6.7.7.tgz", + "integrity": "sha1-Hb0cg1ZY41zj+ZhAmdsAWFx4IBQ=", + "dev": true, + "requires": { + "browserslist": "^1.7.6", + "caniuse-db": "^1.0.30000634", + "normalize-range": "^0.1.2", + "num2fraction": "^1.2.2", + "postcss": "^5.2.16", + "postcss-value-parser": "^3.2.3" + } + }, + "browserslist": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz", + "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", + "dev": true, + "requires": { + "caniuse-db": "^1.0.30000639", + "electron-to-chromium": "^1.2.7" + } + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "csso": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/csso/-/csso-2.3.2.tgz", + "integrity": "sha1-3dUsWHAz9J6Utx/FVWnyUuj/X4U=", + "dev": true, + "requires": { + "clap": "^1.0.9", + "source-map": "^0.5.3" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "requires": { + "array-find-index": "^1.0.1" + } + }, + "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" + } + }, + "date-fns": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz", + "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==", + "dev": true + }, + "death": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", + "integrity": "sha1-AaqcQB7dknUFFEcLgmY5DGbGcxg=", + "dev": true + }, + "debug": { + "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" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "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 + }, + "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": { + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "dev": true, + "requires": { + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true } } }, - "core-js-pure": { + "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" + }, + "dependencies": { + "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 + } + } + }, + "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" + }, + "dependencies": { + "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 + } + } + }, + "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/core-js-pure/-/core-js-pure-3.0.1.tgz", - "integrity": "sha512-mSxeQ6IghKW3MoyF4cz19GJ1cMm7761ON+WObSyLfTu/Jn3x7w4NwNFnrZxgl4MTSvYYepVLNuRtlB4loMwJ5g==", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "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==", "dev": true }, - "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=", + "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 }, - "cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "deepmerge": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", + "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==", + "dev": true + }, + "define-properties": { + "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": { - "object-assign": "^4", - "vary": "^1" + "object-keys": "^1.0.12" } }, - "coveralls": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.1.tgz", - "integrity": "sha512-FAzXwiDOYLGDWH+zgoIA+8GbWv50hlx+kpEJyvzLKOdnIBv9uWoVl4DhqGgyUHpiRjAlF8KYZSipWXYtllWH6Q==", + "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": { - "js-yaml": "^3.6.1", - "lcov-parse": "^0.0.10", - "log-driver": "^1.2.5", - "minimist": "^1.2.0", - "request": "^2.79.0" + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "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" + } + }, + "is-data-descriptor": { + "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" + } + }, + "is-descriptor": { + "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", + "kind-of": "^6.0.2" + } + } + } + }, + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", + "dev": true + }, + "del": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", + "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", + "dev": true, + "requires": { + "globby": "^5.0.0", + "is-path-cwd": "^1.0.0", + "is-path-in-cwd": "^1.0.0", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "rimraf": "^2.2.8" }, "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "pify": { + "version": "2.3.0", + "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true } } }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "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 + }, + "delegate": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz", + "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==", + "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 + }, + "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": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" } }, - "create-hash": { - "version": "1.2.0", - "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "dev": true + }, + "detect-port-alt": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", + "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==", "dev": true, "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" + "address": "^1.0.1", + "debug": "^2.6.0" } }, - "create-hmac": { - "version": "1.1.7", - "resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "diacritics-map": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/diacritics-map/-/diacritics-map-0.1.0.tgz", + "integrity": "sha1-bfwP+dAQAKLt8oZTccrDFulJd68=", + "dev": true + }, + "diff": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", + "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", + "dev": true + }, + "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": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - }, - "dependencies": { - "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=" - } + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" } }, - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "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": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "arrify": "^1.0.1", + "path-type": "^3.0.0" }, "dependencies": { - "lru-cache": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", - "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", + "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": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" + "pify": "^3.0.0" } } } }, - "crowdin-cli": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/crowdin-cli/-/crowdin-cli-0.3.0.tgz", - "integrity": "sha1-6smYmm/n/qrzMJA5evwYfGe0YZE=", + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, "requires": { - "request": "^2.53.0", - "yamljs": "^0.2.1", - "yargs": "^2.3.0" + "esutils": "^2.0.2" + } + }, + "docusaurus": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/docusaurus/-/docusaurus-1.7.2.tgz", + "integrity": "sha512-bPuEvejWaDNrsivt3G9aLX+byhfEjwu3j23c0E3Cn5KRUDkEouHwDvrWXtiWqAl05le321opkhOWGidbe0eG9Q==", + "dev": true, + "requires": { + "@babel/core": "^7.0.0", + "@babel/plugin-proposal-class-properties": "^7.0.0", + "@babel/plugin-proposal-object-rest-spread": "^7.0.0", + "@babel/polyfill": "^7.0.0", + "@babel/preset-env": "^7.0.0", + "@babel/preset-react": "^7.0.0", + "@babel/register": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.1.2", + "autoprefixer": "^9.1.5", + "babylon": "^6.17.4", + "chalk": "^2.1.0", + "classnames": "^2.2.6", + "color": "^2.0.1", + "commander": "^2.18.0", + "cross-spawn": "^6.0.5", + "crowdin-cli": "^0.3.0", + "cssnano": "^3.10.0", + "deepmerge": "^2.1.1", + "escape-string-regexp": "^1.0.5", + "express": "^4.15.3", + "feed": "^1.1.0", + "fs-extra": "^5.0.0", + "gaze": "^1.1.2", + "glob": "^7.1.3", + "highlight.js": "^9.12.0", + "imagemin": "^6.0.0", + "imagemin-gifsicle": "^6.0.1", + "imagemin-jpegtran": "^6.0.0", + "imagemin-optipng": "^6.0.0", + "imagemin-svgo": "^7.0.0", + "lodash": "^4.17.11", + "markdown-toc": "^1.2.0", + "mkdirp": "^0.5.1", + "portfinder": "^1.0.17", + "postcss": "^7.0.1", + "prismjs": "^1.15.0", + "react": "^16.5.0", + "react-dev-utils": "^5.0.2", + "react-dom": "^16.5.0", + "remarkable": "^1.7.1", + "request": "^2.87.0", + "shelljs": "^0.7.8", + "sitemap": "^1.13.0", + "tcp-port-used": "^0.1.2", + "tiny-lr": "^1.1.1", + "tree-node-cli": "^1.2.5", + "truncate-html": "^1.0.1" }, "dependencies": { - "wordwrap": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", - "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", + "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" + } + }, + "commander": { + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", + "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", + "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" + } + }, + "fs-extra": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz", + "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "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" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", "dev": true }, - "yargs": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-2.3.0.tgz", - "integrity": "sha1-6QDIclDsXNCA22AJ/j3WMVbx1/s=", + "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": { - "wordwrap": "0.0.2" + "has-flag": "^3.0.0" } } } }, - "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==", + "dom-serializer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", + "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", "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" + "domelementtype": "^1.3.0", + "entities": "^1.1.1" } }, - "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=", + "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 }, - "css-color-names": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", - "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", "dev": true }, - "css-select": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.0.2.tgz", - "integrity": "sha512-dSpYaDVoWaELjvZ3mS6IKZM/y2PMPa/XYoEfYNZePL4U/XgyxZNroHEHReDx/d+VgXh9VbCTtFqLkFbmeqeaRQ==", + "domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", "dev": true, "requires": { - "boolbase": "^1.0.0", - "css-what": "^2.1.2", - "domutils": "^1.7.0", - "nth-check": "^1.0.2" + "domelementtype": "1" } }, - "css-select-base-adapter": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", - "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==", - "dev": true - }, - "css-tree": { - "version": "1.0.0-alpha.28", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.28.tgz", - "integrity": "sha512-joNNW1gCp3qFFzj4St6zk+Wh/NBv0vM5YbEreZk0SD4S23S+1xBKb6cLDg2uj4P4k/GUMlIm6cKIDqIG+vdt0w==", + "domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", "dev": true, "requires": { - "mdn-data": "~1.1.0", - "source-map": "^0.5.3" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } + "dom-serializer": "0", + "domelementtype": "1" } }, - "css-url-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/css-url-regex/-/css-url-regex-1.1.0.tgz", - "integrity": "sha1-g4NCMMyfdMRX3lnuvRVD/uuDt+w=", - "dev": true - }, - "css-what": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", - "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==", - "dev": true - }, - "cssnano": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-3.10.0.tgz", - "integrity": "sha1-Tzj2zqK5sX+gFJDyPx3GjqZcHDg=", + "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": { - "autoprefixer": "^6.3.1", - "decamelize": "^1.1.2", - "defined": "^1.0.0", - "has": "^1.0.1", - "object-assign": "^4.0.1", - "postcss": "^5.0.14", - "postcss-calc": "^5.2.0", - "postcss-colormin": "^2.1.8", - "postcss-convert-values": "^2.3.4", - "postcss-discard-comments": "^2.0.4", - "postcss-discard-duplicates": "^2.0.1", - "postcss-discard-empty": "^2.0.1", - "postcss-discard-overridden": "^0.1.1", - "postcss-discard-unused": "^2.2.1", - "postcss-filter-plugins": "^2.0.0", - "postcss-merge-idents": "^2.1.5", - "postcss-merge-longhand": "^2.0.1", - "postcss-merge-rules": "^2.0.3", - "postcss-minify-font-values": "^1.0.2", - "postcss-minify-gradients": "^1.0.1", - "postcss-minify-params": "^1.0.4", - "postcss-minify-selectors": "^2.0.4", - "postcss-normalize-charset": "^1.1.0", - "postcss-normalize-url": "^3.0.7", - "postcss-ordered-values": "^2.1.0", - "postcss-reduce-idents": "^2.2.2", - "postcss-reduce-initial": "^1.0.0", - "postcss-reduce-transforms": "^1.0.3", - "postcss-svgo": "^2.1.1", - "postcss-unique-selectors": "^2.0.2", - "postcss-value-parser": "^3.2.3", - "postcss-zindex": "^2.0.1" - }, - "dependencies": { - "autoprefixer": { - "version": "6.7.7", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-6.7.7.tgz", - "integrity": "sha1-Hb0cg1ZY41zj+ZhAmdsAWFx4IBQ=", - "dev": true, - "requires": { - "browserslist": "^1.7.6", - "caniuse-db": "^1.0.30000634", - "normalize-range": "^0.1.2", - "num2fraction": "^1.2.2", - "postcss": "^5.2.16", - "postcss-value-parser": "^3.2.3" - } - }, - "browserslist": { - "version": "1.7.7", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz", - "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", - "dev": true, - "requires": { - "caniuse-db": "^1.0.30000639", - "electron-to-chromium": "^1.2.7" - } - }, - "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", - "dev": true - }, - "postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "js-base64": "^2.1.9", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } + "is-obj": "^1.0.0" } }, - "csso": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/csso/-/csso-2.3.2.tgz", - "integrity": "sha1-3dUsWHAz9J6Utx/FVWnyUuj/X4U=", + "download": { + "version": "6.2.5", + "resolved": "https://registry.npmjs.org/download/-/download-6.2.5.tgz", + "integrity": "sha512-DpO9K1sXAST8Cpzb7kmEhogJxymyVUd5qz/vCOSyvwtp2Klj2XcDt5YUuasgxka44SxF0q5RriKIwJmQHG2AuA==", "dev": true, "requires": { - "clap": "^1.0.9", - "source-map": "^0.5.3" + "caw": "^2.0.0", + "content-disposition": "^0.5.2", + "decompress": "^4.0.0", + "ext-name": "^5.0.0", + "file-type": "5.2.0", + "filenamify": "^2.0.0", + "get-stream": "^3.0.0", + "got": "^7.0.0", + "make-dir": "^1.0.0", + "p-event": "^1.0.0", + "pify": "^3.0.0" }, "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "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 } } }, - "currently-unhandled": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", - "dev": true, - "requires": { - "array-find-index": "^1.0.1" - } - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "drbg.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", + "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", "dev": true, "requires": { - "assert-plus": "^1.0.0" + "browserify-aes": "^1.0.6", + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4" } }, - "death": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", - "integrity": "sha1-AaqcQB7dknUFFEcLgmY5DGbGcxg=", + "duplexer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", "dev": true }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, + "ecc-jsbn": { + "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": { - "ms": "2.0.0" + "jsbn": "~0.1.0" } }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", "dev": true }, - "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=", + "electron-to-chromium": { + "version": "1.3.137", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.137.tgz", + "integrity": "sha512-kGi32g42a8vS/WnYE7ELJyejRT7hbr3UeOOu0WeuYuQ29gCpg9Lrf6RdcTQVXSt/v0bjCfnlb/EWOOsiKpTmkw==", "dev": true }, - "decompress": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.0.tgz", - "integrity": "sha1-eu3YVCflqS2s/lVnSnxQXpbQH50=", + "elliptic": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", + "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", "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": { - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" } }, - "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "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, - "requires": { - "mimic-response": "^1.0.0" - } + "optional": true }, - "decompress-tar": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", - "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true + }, + "end-of-stream": { + "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": { - "file-type": "^5.2.0", - "is-stream": "^1.1.0", - "tar-stream": "^1.5.2" - }, - "dependencies": { - "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 - } + "once": "^1.4.0" } }, - "decompress-tarbz2": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", - "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "dev": true + }, + "error": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/error/-/error-7.0.2.tgz", + "integrity": "sha1-pfdf/02ZJhJt2sDqXcOOaJFTywI=", "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 - } + "string-template": "~0.2.1", + "xtend": "~4.0.0" } }, - "decompress-targz": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", - "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", + "error-ex": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", + "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", "dev": true, "requires": { - "decompress-tar": "^4.1.1", - "file-type": "^5.2.0", - "is-stream": "^1.1.0" - }, - "dependencies": { - "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 - } + "is-arrayish": "^0.2.1" } }, - "decompress-unzip": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", - "integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=", + "es-abstract": { + "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": { - "file-type": "^3.8.0", - "get-stream": "^2.2.0", - "pify": "^2.3.0", - "yauzl": "^2.4.2" + "es-to-primitive": "^1.2.0", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-keys": "^1.0.12" }, "dependencies": { - "file-type": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", - "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=", + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "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=", + "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": { - "object-assign": "^4.0.1", - "pinkie-promise": "^2.0.0" + "function-bind": "^1.1.1" } - }, - "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", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "es-to-primitive": { + "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": { - "type-detect": "^4.0.0" + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" } }, - "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=", + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", "dev": true }, - "deepmerge": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", - "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==", + "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 }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "escodegen": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", + "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", "dev": true, "requires": { - "object-keys": "^1.0.12" + "esprima": "^2.7.1", + "estraverse": "^1.9.1", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.2.0" + }, + "dependencies": { + "estraverse": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", + "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", + "dev": true + }, + "source-map": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", + "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", + "dev": true, + "optional": true, + "requires": { + "amdefine": ">=0.0.4" + } + } } }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "eslint": { + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz", + "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==", "dev": true, "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" + "ajv": "^5.3.0", + "babel-code-frame": "^6.22.0", + "chalk": "^2.1.0", + "concat-stream": "^1.6.0", + "cross-spawn": "^5.1.0", + "debug": "^3.1.0", + "doctrine": "^2.1.0", + "eslint-scope": "^3.7.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^3.5.4", + "esquery": "^1.0.0", + "esutils": "^2.0.2", + "file-entry-cache": "^2.0.0", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.0.1", + "ignore": "^3.3.3", + "imurmurhash": "^0.1.4", + "inquirer": "^3.0.6", + "is-resolvable": "^1.0.0", + "js-yaml": "^3.9.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.4", + "minimatch": "^3.0.2", + "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": "^1.0.1", + "require-uncached": "^1.0.3", + "semver": "^5.3.0", + "strip-ansi": "^4.0.0", + "strip-json-comments": "~2.0.1", + "table": "4.0.2", + "text-table": "~0.2.0" }, "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "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": { - "kind-of": "^6.0.0" + "color-convert": "^1.9.0" } }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "dev": true, "requires": { - "kind-of": "^6.0.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "ms": "2.0.0" } - } - } - }, - "defined": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", - "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", - "dev": true - }, - "del": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", - "dev": true, - "requires": { - "globby": "^5.0.0", - "is-path-cwd": "^1.0.0", - "is-path-in-cwd": "^1.0.0", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "rimraf": "^2.2.8" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + }, + "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 + }, + "globals": { + "version": "11.7.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.7.0.tgz", + "integrity": "sha512-K8BNSPySfeShBQXsahYB/AbbWruVOTyVpgoIDnl8odPpeSfP2J5QO2oLFFdl2j7GfDCtZj2bMKar2T49itTPCg==", "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^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.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } } } }, - "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 - }, - "delegate": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz", - "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==", - "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 - }, - "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 - }, - "detect-port-alt": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", - "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==", - "dev": true, - "requires": { - "address": "^1.0.1", - "debug": "^2.6.0" - } - }, - "diacritics-map": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/diacritics-map/-/diacritics-map-0.1.0.tgz", - "integrity": "sha1-bfwP+dAQAKLt8oZTccrDFulJd68=", - "dev": true - }, - "diff": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", - "dev": true - }, - "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==", + "eslint-config-standard": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-10.2.1.tgz", + "integrity": "sha1-wGHk0GbzedwXzVYsZOgZtN1FRZE=", + "dev": true + }, + "eslint-import-resolver-node": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", + "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", "dev": true, "requires": { - "arrify": "^1.0.1", - "path-type": "^3.0.0" + "debug": "^2.6.9", + "resolve": "^1.5.0" }, "dependencies": { - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { - "pify": "^3.0.0" + "ms": "2.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 + "resolve": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", + "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", + "dev": true, + "requires": { + "path-parse": "^1.0.5" + } } } }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "eslint-module-utils": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.2.0.tgz", + "integrity": "sha1-snA2LNiLGkitMIl2zn+lTphBF0Y=", "dev": true, "requires": { - "esutils": "^2.0.2" + "debug": "^2.6.8", + "pkg-dir": "^1.0.0" } }, - "docusaurus": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/docusaurus/-/docusaurus-1.7.2.tgz", - "integrity": "sha512-bPuEvejWaDNrsivt3G9aLX+byhfEjwu3j23c0E3Cn5KRUDkEouHwDvrWXtiWqAl05le321opkhOWGidbe0eG9Q==", + "eslint-plugin-import": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.13.0.tgz", + "integrity": "sha512-t6hGKQDMIt9N8R7vLepsYXgDfeuhp6ZJSgtrLEDxonpSubyxUZHjhm6LsAaZX8q6GYVxkbT3kTsV9G5mBCFR6A==", "dev": true, "requires": { - "@babel/core": "^7.0.0", - "@babel/plugin-proposal-class-properties": "^7.0.0", - "@babel/plugin-proposal-object-rest-spread": "^7.0.0", - "@babel/polyfill": "^7.0.0", - "@babel/preset-env": "^7.0.0", - "@babel/preset-react": "^7.0.0", - "@babel/register": "^7.0.0", - "@babel/traverse": "^7.0.0", - "@babel/types": "^7.1.2", - "autoprefixer": "^9.1.5", - "babylon": "^6.17.4", - "chalk": "^2.1.0", - "classnames": "^2.2.6", - "color": "^2.0.1", - "commander": "^2.18.0", - "cross-spawn": "^6.0.5", - "crowdin-cli": "^0.3.0", - "cssnano": "^3.10.0", - "deepmerge": "^2.1.1", - "escape-string-regexp": "^1.0.5", - "express": "^4.15.3", - "feed": "^1.1.0", - "fs-extra": "^5.0.0", - "gaze": "^1.1.2", - "glob": "^7.1.3", - "highlight.js": "^9.12.0", - "imagemin": "^6.0.0", - "imagemin-gifsicle": "^6.0.1", - "imagemin-jpegtran": "^6.0.0", - "imagemin-optipng": "^6.0.0", - "imagemin-svgo": "^7.0.0", - "lodash": "^4.17.11", - "markdown-toc": "^1.2.0", - "mkdirp": "^0.5.1", - "portfinder": "^1.0.17", - "postcss": "^7.0.1", - "prismjs": "^1.15.0", - "react": "^16.5.0", - "react-dev-utils": "^5.0.2", - "react-dom": "^16.5.0", - "remarkable": "^1.7.1", - "request": "^2.87.0", - "shelljs": "^0.7.8", - "sitemap": "^1.13.0", - "tcp-port-used": "^0.1.2", - "tiny-lr": "^1.1.1", - "tree-node-cli": "^1.2.5", - "truncate-html": "^1.0.1" + "contains-path": "^0.1.0", + "debug": "^2.6.8", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.1", + "eslint-module-utils": "^2.2.0", + "has": "^1.0.1", + "lodash": "^4.17.4", + "minimatch": "^3.0.3", + "read-pkg-up": "^2.0.0", + "resolve": "^1.6.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==", + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", "dev": true, "requires": { - "color-convert": "^1.9.0" + "esutils": "^2.0.2", + "isarray": "^1.0.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==", + "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": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "locate-path": "^2.0.0" } }, - "commander": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", - "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", - "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==", + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", "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" + "graceful-fs": "^4.1.2", + "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 + } } }, - "fs-extra": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz", - "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==", + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" + "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 + } } }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", "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": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" } }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", "dev": true, "requires": { - "graceful-fs": "^4.1.6" + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" } }, - "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", - "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==", + "resolve": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", + "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "path-parse": "^1.0.5" } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true } } }, - "dom-serializer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", - "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", + "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": { - "domelementtype": "^1.3.0", - "entities": "^1.1.1" + "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", + "integrity": "sha512-xhPXrh0Vl/b7870uEbaumb2Q+LxaEcOQ3kS1jtIXanBAwpMre1l5q/l2l/hESYJGEFKuI78bp6Uw50hlpr7B+g==", + "dev": true, + "requires": { + "ignore": "^3.3.6", + "minimatch": "^3.0.4", + "resolve": "^1.3.3", + "semver": "5.3.0" + }, + "dependencies": { + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", + "dev": true + } } }, - "dom-walk": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz", - "integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg=", + "eslint-plugin-promise": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-3.8.0.tgz", + "integrity": "sha512-JiFL9UFR15NKpHyGii1ZcvmtIqa3UTwiDAGb8atSffe43qJ3+1czVGN6UtkklpcJ2DVnqvTMzEKRaJdBkAL2aQ==", "dev": true }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "eslint-plugin-standard": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-3.1.0.tgz", + "integrity": "sha512-fVcdyuKRr0EZ4fjWl3c+gp1BANFJD1+RaWa2UPYfMZ6jCtp5RG00kSaXnK/dE5sYzt4kaWJ9qdxqUfc0d9kX0w==", "dev": true }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "eslint-scope": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", + "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", "dev": true, "requires": { - "domelementtype": "1" + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" } }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "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", + "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", + "dev": true + }, + "espree": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", + "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", "dev": true, "requires": { - "dom-serializer": "0", - "domelementtype": "1" + "acorn": "^5.5.0", + "acorn-jsx": "^3.0.0" } }, - "download": { - "version": "6.2.5", - "resolved": "https://registry.npmjs.org/download/-/download-6.2.5.tgz", - "integrity": "sha512-DpO9K1sXAST8Cpzb7kmEhogJxymyVUd5qz/vCOSyvwtp2Klj2XcDt5YUuasgxka44SxF0q5RriKIwJmQHG2AuA==", + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "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": { - "caw": "^2.0.0", - "content-disposition": "^0.5.2", - "decompress": "^4.0.0", - "ext-name": "^5.0.0", - "file-type": "5.2.0", - "filenamify": "^2.0.0", - "get-stream": "^3.0.0", - "got": "^7.0.0", - "make-dir": "^1.0.0", - "p-event": "^1.0.0", - "pify": "^3.0.0" + "esprima": "^4.0.0" }, "dependencies": { - "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 - }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "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, - "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 + "optional": true } } }, - "drbg.js": { + "esquery": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", - "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", "dev": true, "requires": { - "browserify-aes": "^1.0.6", - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4" + "estraverse": "^4.0.0" } }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", "dev": true }, - "duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", "dev": true }, - "ecc-jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", - "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "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, - "optional": true, "requires": { - "jsbn": "~0.1.0" + "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-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" + } + }, + "ethereumjs-testrpc-sc": { + "version": "6.1.6", + "resolved": "https://registry.npmjs.org/ethereumjs-testrpc-sc/-/ethereumjs-testrpc-sc-6.1.6.tgz", + "integrity": "sha512-iv2qiGBFgk9mn5Nq2enX8dG5WQ7Lk+FCqpnxfPfH4Ns8KLPwttmNOy264nh3SXDJJvcQwz/XnlLteDQVILotbg==", + "dev": true, + "requires": { + "source-map-support": "^0.5.3" + } + }, + "ethereumjs-util": { + "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.6", + "keccak": "^1.0.2", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1", + "secp256k1": "^3.0.1" + } + }, + "ethers": { + "version": "4.0.27", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.27.tgz", + "integrity": "sha512-+DXZLP/tyFnXWxqr2fXLT67KlGUfLuvDkHSOtSC9TUVG9OIj6yrG5JPeXRMYo15xkOYwnjgdMKrXp5V94rtjJA==", + "dev": true, + "requires": { + "@types/node": "^10.3.2", + "aes-js": "3.0.0", + "bn.js": "^4.4.0", + "elliptic": "6.3.3", + "hash.js": "1.1.3", + "js-sha3": "0.5.7", + "scrypt-js": "2.0.4", + "setimmediate": "1.0.4", + "uuid": "2.0.1", + "xmlhttprequest": "1.8.0" + }, + "dependencies": { + "@types/node": { + "version": "10.14.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.6.tgz", + "integrity": "sha512-Fvm24+u85lGmV4hT5G++aht2C5I4Z4dYlWZIh62FAfFO/TfzXtPpoLI6I7AuBWkIFqZCnhFOoTT7RjjaIL5Fjg==", + "dev": true + }, + "elliptic": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.3.3.tgz", + "integrity": "sha1-VILZZG1UvLif19mU/J4ulWiHbj8=", + "dev": true, + "requires": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "inherits": "^2.0.1" + } + }, + "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 + }, + "uuid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", + "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=", + "dev": true + } } }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true - }, - "electron-to-chromium": { - "version": "1.3.124", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.124.tgz", - "integrity": "sha512-glecGr/kFdfeXUHOHAWvGcXrxNU+1wSO/t5B23tT1dtlvYB26GY8aHzZSWD7HqhqC800Lr+w/hQul6C5AF542w==", - "dev": true - }, - "elliptic": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", - "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", + "ethjs-abi": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/ethjs-abi/-/ethjs-abi-0.2.1.tgz", + "integrity": "sha1-4KepOn6BFjqUR3utVu3lJKtt5TM=", "dev": true, "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" + "bn.js": "4.11.6", + "js-sha3": "0.5.5", + "number-to-bn": "1.7.0" + }, + "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 + }, + "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 + } } }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "ethjs-unit": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", + "integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=", "dev": true, - "optional": true - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "dev": true + "requires": { + "bn.js": "4.11.6", + "number-to-bn": "1.7.0" + }, + "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 + } + } }, - "end-of-stream": { - "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==", + "ethjs-util": { + "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": { - "once": "^1.4.0" + "is-hex-prefixed": "1.0.0", + "strip-hex-prefix": "1.0.0" } }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "eventemitter3": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.1.1.tgz", + "integrity": "sha1-R3hr2qCHyvext15zq8XH1UAVjNA=", "dev": true }, - "error": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/error/-/error-7.0.2.tgz", - "integrity": "sha1-pfdf/02ZJhJt2sDqXcOOaJFTywI=", + "eventsource": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-0.1.6.tgz", + "integrity": "sha1-Cs7ehJ7X3RzMMsgRuxG5RNTykjI=", "dev": true, "requires": { - "string-template": "~0.2.1", - "xtend": "~4.0.0" + "original": ">=0.0.5" } }, - "error-ex": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", - "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "evp_bytestokey": { + "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": { - "is-arrayish": "^0.2.1" + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" } }, - "es-abstract": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", - "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", + "exec-buffer": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/exec-buffer/-/exec-buffer-3.2.0.tgz", + "integrity": "sha512-wsiD+2Tp6BWHoVv3B+5Dcx6E7u5zky+hUwOHjuH2hKSLR3dvRmX8fk8UD8uqQixHs4Wk6eDmiegVrMPjKj7wpA==", "dev": true, "requires": { - "es-to-primitive": "^1.2.0", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "is-callable": "^1.1.4", - "is-regex": "^1.0.4", - "object-keys": "^1.0.12" - }, - "dependencies": { - "function-bind": { - "version": "1.1.1", - "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" - } - } + "execa": "^0.7.0", + "p-finally": "^1.0.0", + "pify": "^3.0.0", + "rimraf": "^2.5.4", + "tempfile": "^2.0.0" } }, - "es-to-primitive": { - "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==", + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", "dev": true, "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" } }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true - }, - "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 - }, - "escodegen": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", - "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", + "executable": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", + "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", "dev": true, "requires": { - "esprima": "^2.7.1", - "estraverse": "^1.9.1", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.2.0" + "pify": "^2.2.0" }, "dependencies": { - "estraverse": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", - "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true - }, - "source-map": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", - "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", - "dev": true, - "optional": true, - "requires": { - "amdefine": ">=0.0.4" - } } } }, - "eslint": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz", - "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==", - "dev": true, - "requires": { - "ajv": "^5.3.0", - "babel-code-frame": "^6.22.0", - "chalk": "^2.1.0", - "concat-stream": "^1.6.0", - "cross-spawn": "^5.1.0", - "debug": "^3.1.0", - "doctrine": "^2.1.0", - "eslint-scope": "^3.7.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^3.5.4", - "esquery": "^1.0.0", - "esutils": "^2.0.2", - "file-entry-cache": "^2.0.0", - "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.0.1", - "ignore": "^3.3.3", - "imurmurhash": "^0.1.4", - "inquirer": "^3.0.6", - "is-resolvable": "^1.0.0", - "js-yaml": "^3.9.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.4", - "minimatch": "^3.0.2", - "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": "^1.0.1", - "require-uncached": "^1.0.3", - "semver": "^5.3.0", - "strip-ansi": "^4.0.0", - "strip-json-comments": "~2.0.1", - "table": "4.0.2", - "text-table": "~0.2.0" + "expand-brackets": { + "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", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.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==", + "define-property": { + "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": { - "color-convert": "^1.9.0" + "is-descriptor": "^0.1.0" } }, - "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "is-extendable": "^0.1.0" } - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + } + } + }, + "expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "dev": true, + "requires": { + "fill-range": "^2.1.0" + }, + "dependencies": { + "fill-range": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", + "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", "dev": true, "requires": { - "ms": "2.0.0" + "is-number": "^2.1.0", + "isobject": "^2.0.0", + "randomatic": "^3.0.0", + "repeat-element": "^1.1.2", + "repeat-string": "^1.5.2" } }, - "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 - }, - "globals": { - "version": "11.7.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.7.0.tgz", - "integrity": "sha512-K8BNSPySfeShBQXsahYB/AbbWruVOTyVpgoIDnl8odPpeSfP2J5QO2oLFFdl2j7GfDCtZj2bMKar2T49itTPCg==", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", "dev": true, "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "kind-of": "^3.0.2" } }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "isarray": "1.0.0" } }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "has-flag": "^3.0.0" + "is-buffer": "^1.1.5" } } } }, - "eslint-config-standard": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-10.2.1.tgz", - "integrity": "sha1-wGHk0GbzedwXzVYsZOgZtN1FRZE=", + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "express": { + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz", + "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==", + "dev": true, + "requires": { + "accepts": "~1.3.5", + "array-flatten": "1.1.1", + "body-parser": "1.18.3", + "content-disposition": "0.5.2", + "content-type": "~1.0.4", + "cookie": "0.3.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.1.1", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.4", + "qs": "6.5.2", + "range-parser": "~1.2.0", + "safe-buffer": "5.1.2", + "send": "0.16.2", + "serve-static": "1.13.2", + "setprototypeof": "1.1.0", + "statuses": "~1.4.0", + "type-is": "~1.6.16", + "utils-merge": "1.0.1", + "vary": "~1.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 + } + } + }, + "ext-list": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz", + "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==", + "dev": true, + "requires": { + "mime-db": "^1.28.0" + } + }, + "ext-name": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz", + "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==", + "dev": true, + "requires": { + "ext-list": "^2.0.0", + "sort-keys-length": "^1.0.0" + } + }, + "extend": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", "dev": true }, - "eslint-import-resolver-node": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", - "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", + "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": { - "debug": "^2.6.9", - "resolve": "^1.5.0" + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" }, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "is-extendable": { + "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" + } + } + } + }, + "external-editor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.1.0.tgz", + "integrity": "sha512-E44iT5QVOUJBKij4IIV3uvxuNlbKS38Tw1HiupxEIHPv9qtC2PrDYohbXV5U+1jnfIXttny8gUhj+oZvflFlzA==", + "dev": true, + "requires": { + "chardet": "^0.4.0", + "iconv-lite": "^0.4.17", + "tmp": "^0.0.33" + } + }, + "extglob": { + "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", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "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" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "ms": "2.0.0" + "is-extendable": "^0.1.0" } }, - "resolve": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", - "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", + "is-accessor-descriptor": { + "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": { - "path-parse": "^1.0.5" + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "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" + } + }, + "is-descriptor": { + "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", + "kind-of": "^6.0.2" } } } }, - "eslint-module-utils": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.2.0.tgz", - "integrity": "sha1-snA2LNiLGkitMIl2zn+lTphBF0Y=", + "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": { - "debug": "^2.6.8", - "pkg-dir": "^1.0.0" + "esprima-extract-comments": "^1.1.0", + "parse-code-context": "^1.0.0" } }, - "eslint-plugin-import": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.13.0.tgz", - "integrity": "sha512-t6hGKQDMIt9N8R7vLepsYXgDfeuhp6ZJSgtrLEDxonpSubyxUZHjhm6LsAaZX8q6GYVxkbT3kTsV9G5mBCFR6A==", + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "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=", + "dev": true + }, + "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.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", + "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", "dev": true, "requires": { - "contains-path": "^0.1.0", - "debug": "^2.6.8", - "doctrine": "1.5.0", - "eslint-import-resolver-node": "^0.3.1", - "eslint-module-utils": "^2.2.0", - "has": "^1.0.1", - "lodash": "^4.17.4", - "minimatch": "^3.0.3", - "read-pkg-up": "^2.0.0", - "resolve": "^1.6.0" + "@mrmlnc/readdir-enhanced": "^2.2.1", + "@nodelib/fs.stat": "^1.1.2", + "glob-parent": "^3.1.0", + "is-glob": "^4.0.0", + "merge2": "^1.2.3", + "micromatch": "^3.1.10" }, "dependencies": { - "doctrine": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "isarray": "^1.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" - } - }, - "load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" }, "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true + "extend-shallow": { + "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" + } } } }, - "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, "requires": { - "pify": "^2.0.0" + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" }, "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true + "extend-shallow": { + "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" + } } } }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "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" + } + } } }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" } }, - "resolve": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", - "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", + "to-regex-range": { + "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": { - "path-parse": "^1.0.5" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - } - } - }, - "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", - "integrity": "sha512-xhPXrh0Vl/b7870uEbaumb2Q+LxaEcOQ3kS1jtIXanBAwpMre1l5q/l2l/hESYJGEFKuI78bp6Uw50hlpr7B+g==", - "dev": true, - "requires": { - "ignore": "^3.3.6", - "minimatch": "^3.0.4", - "resolve": "^1.3.3", - "semver": "5.3.0" - }, - "dependencies": { - "semver": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", - "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", - "dev": true + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } } } }, - "eslint-plugin-promise": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-3.8.0.tgz", - "integrity": "sha512-JiFL9UFR15NKpHyGii1ZcvmtIqa3UTwiDAGb8atSffe43qJ3+1czVGN6UtkklpcJ2DVnqvTMzEKRaJdBkAL2aQ==", + "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 }, - "eslint-plugin-standard": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-3.1.0.tgz", - "integrity": "sha512-fVcdyuKRr0EZ4fjWl3c+gp1BANFJD1+RaWa2UPYfMZ6jCtp5RG00kSaXnK/dE5sYzt4kaWJ9qdxqUfc0d9kX0w==", + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, - "eslint-scope": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", - "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", + "faye-websocket": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.1.tgz", + "integrity": "sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg=", "dev": true, "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" + "websocket-driver": ">=0.5.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", - "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", - "dev": true - }, - "espree": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", - "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", + "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": { - "acorn": "^5.5.0", - "acorn-jsx": "^3.0.0" + "pend": "~1.2.0" } }, - "esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "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==", + "feed": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/feed/-/feed-1.1.1.tgz", + "integrity": "sha1-kUiXUX6U+jJ8xvc7tYWkfEqe0yE=", "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 - } + "xml": "^1.0.1" } }, - "esquery": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", - "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", "dev": true, "requires": { - "estraverse": "^4.0.0" + "escape-string-regexp": "^1.0.5" } }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", "dev": true, "requires": { - "estraverse": "^4.1.0" + "flat-cache": "^1.2.1", + "object-assign": "^4.0.1" } }, - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true - }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "file-type": { + "version": "10.11.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-10.11.0.tgz", + "integrity": "sha512-uzk64HRpUZyTGZtVuvrjP0FYxzQrBf4rojot6J65YMEbwBLB0CWm0CLojVpwpmFmxcE/lkvYICgfcGozbBq6rw==", "dev": true }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "filename-reserved-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", + "integrity": "sha1-q/c9+rc10EVECr/qLZHzieu/oik=", "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=", + "filenamify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-2.1.0.tgz", + "integrity": "sha512-ICw7NTT6RsDp2rnYKVd8Fu4cr6ITzGy3+u4vUujPkabyaz+03F24NWEX7fs5fp+kBonlaqPH8fAO2NM+SXt/JA==", "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 - } + "filename-reserved-regex": "^2.0.0", + "strip-outer": "^1.0.0", + "trim-repeated": "^1.0.0" } }, - "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" - } + "filesize": { + "version": "3.5.11", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-3.5.11.tgz", + "integrity": "sha512-ZH7loueKBoDb7yG9esn1U+fgq7BzlzW6NRi5/rMdxIZ05dj7GFD/Xc5rq2CDt5Yq86CyfSYVyx4242QQNZbx1g==", + "dev": true }, - "ethereumjs-testrpc-sc": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/ethereumjs-testrpc-sc/-/ethereumjs-testrpc-sc-6.1.6.tgz", - "integrity": "sha512-iv2qiGBFgk9mn5Nq2enX8dG5WQ7Lk+FCqpnxfPfH4Ns8KLPwttmNOy264nh3SXDJJvcQwz/XnlLteDQVILotbg==", + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, "requires": { - "source-map-support": "^0.5.3" + "to-regex-range": "^5.0.1" } }, - "ethereumjs-util": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.0.0.tgz", - "integrity": "sha512-E3yKUyl0Fs95nvTFQZe/ZSNcofhDzUsDlA5y2uoRmf1+Ec7gpGhNCsgKkZBRh7Br5op8mJcYF/jFbmjj909+nQ==", + "finalhandler": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", + "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", "dev": true, "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "ethjs-util": "^0.1.6", - "keccak": "^1.0.2", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1", - "secp256k1": "^3.0.1" + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "statuses": "~1.4.0", + "unpipe": "~1.0.0" } }, - "ethers": { - "version": "4.0.27", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.27.tgz", - "integrity": "sha512-+DXZLP/tyFnXWxqr2fXLT67KlGUfLuvDkHSOtSC9TUVG9OIj6yrG5JPeXRMYo15xkOYwnjgdMKrXp5V94rtjJA==", + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", "dev": true, "requires": { - "@types/node": "^10.3.2", - "aes-js": "3.0.0", - "bn.js": "^4.4.0", - "elliptic": "6.3.3", - "hash.js": "1.1.3", - "js-sha3": "0.5.7", - "scrypt-js": "2.0.4", - "setimmediate": "1.0.4", - "uuid": "2.0.1", - "xmlhttprequest": "1.8.0" + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" }, "dependencies": { - "@types/node": { - "version": "10.14.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.6.tgz", - "integrity": "sha512-Fvm24+u85lGmV4hT5G++aht2C5I4Z4dYlWZIh62FAfFO/TfzXtPpoLI6I7AuBWkIFqZCnhFOoTT7RjjaIL5Fjg==", - "dev": true + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } }, - "elliptic": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.3.3.tgz", - "integrity": "sha1-VILZZG1UvLif19mU/J4ulWiHbj8=", + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "p-limit": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "inherits": "^2.0.1" + "p-limit": "^2.0.0" } }, - "js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=", + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true }, - "uuid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", - "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=", + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", "dev": true } } }, - "ethjs-abi": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/ethjs-abi/-/ethjs-abi-0.2.1.tgz", - "integrity": "sha1-4KepOn6BFjqUR3utVu3lJKtt5TM=", + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "dev": true, "requires": { - "bn.js": "4.11.6", - "js-sha3": "0.5.5", - "number-to-bn": "1.7.0" - }, - "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 - }, - "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 - } + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" } }, - "ethjs-unit": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", - "integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=", + "find-versions": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-3.1.0.tgz", + "integrity": "sha512-NCTfNiVzeE/xL+roNDffGuRbrWI6atI18lTJ22vKp7rs2OhYzMK3W1dIdO2TUndH/QMcacM4d1uWwgcZcHK69Q==", "dev": true, "requires": { - "bn.js": "4.11.6", - "number-to-bn": "1.7.0" + "array-uniq": "^2.1.0", + "semver-regex": "^2.0.0" }, "dependencies": { - "bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", + "array-uniq": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-2.1.0.tgz", + "integrity": "sha512-bdHxtev7FN6+MXI1YFW0Q8mQ8dTJc2S8AMfju+ZR77pbg2yAdVyDlwkaUI7Har0LyOMRFPHrJ9lYdyjZZswdlQ==", "dev": true } } }, - "ethjs-util": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", - "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", + "flat-cache": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", + "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", "dev": true, "requires": { - "is-hex-prefixed": "1.0.0", - "strip-hex-prefix": "1.0.0" + "circular-json": "^0.3.1", + "del": "^2.0.2", + "graceful-fs": "^4.1.2", + "write": "^0.2.1" } }, - "eventemitter3": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.1.1.tgz", - "integrity": "sha1-R3hr2qCHyvext15zq8XH1UAVjNA=", + "flatten": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz", + "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=", "dev": true }, - "eventsource": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-0.1.6.tgz", - "integrity": "sha1-Cs7ehJ7X3RzMMsgRuxG5RNTykjI=", + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", "dev": true, "requires": { - "original": ">=0.0.5" + "is-callable": "^1.1.3" } }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "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": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" + "asynckit": "^0.4.0", + "combined-stream": "1.0.6", + "mime-types": "^2.1.12" } }, - "exec-buffer": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/exec-buffer/-/exec-buffer-3.2.0.tgz", - "integrity": "sha512-wsiD+2Tp6BWHoVv3B+5Dcx6E7u5zky+hUwOHjuH2hKSLR3dvRmX8fk8UD8uqQixHs4Wk6eDmiegVrMPjKj7wpA==", + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "dev": true + }, + "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": { - "execa": "^0.7.0", - "p-finally": "^1.0.0", - "pify": "^3.0.0", - "rimraf": "^2.5.4", - "tempfile": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } + "map-cache": "^0.2.2" } }, - "execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true + }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", "dev": true, "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" } }, - "executable": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", - "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", + "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": "http://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", + "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", "dev": true, "requires": { - "pify": "^2.2.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" } }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "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": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" + "any-promise": "^1.3.0", + "fs-extra": "^2.0.0", + "mz": "^2.6.0", + "thenify-all": "^1.6.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=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "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": { - "is-extendable": "^0.1.0" + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0" } } } }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", + "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", "dev": true, + "optional": true, "requires": { - "fill-range": "^2.1.0" + "nan": "^2.12.1", + "node-pre-gyp": "^0.12.0" }, "dependencies": { - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, "dev": true, + "optional": true, "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" } }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, "dev": true, + "optional": true, "requires": { - "kind-of": "^3.0.2" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "chownr": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "4.1.1", + "bundled": true, "dev": true, + "optional": true, "requires": { - "isarray": "1.0.0" + "ms": "^2.1.1" } }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "deep-extend": { + "version": "0.6.0", + "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": { - "is-buffer": "^1.1.5" + "minipass": "^2.2.1" } - } - } - }, - "expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1" - } - }, - "express": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz", - "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==", - "dev": true, - "requires": { - "accepts": "~1.3.5", - "array-flatten": "1.1.1", - "body-parser": "1.18.3", - "content-disposition": "0.5.2", - "content-type": "~1.0.4", - "cookie": "0.3.1", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.1.1", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.2", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.4", - "qs": "6.5.2", - "range-parser": "~1.2.0", - "safe-buffer": "5.1.2", - "send": "0.16.2", - "serve-static": "1.13.2", - "setprototypeof": "1.1.0", - "statuses": "~1.4.0", - "type-is": "~1.6.16", - "utils-merge": "1.0.1", - "vary": "~1.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 - } - } - }, - "ext-list": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz", - "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==", - "dev": true, - "requires": { - "mime-db": "^1.28.0" - } - }, - "ext-name": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz", - "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==", - "dev": true, - "requires": { - "ext-list": "^2.0.0", - "sort-keys-length": "^1.0.0" - } - }, - "extend": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", - "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", - "dev": true - }, - "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" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + }, + "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.3", + "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.24", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "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": { - "is-plain-object": "^2.0.4" + "once": "^1.3.0", + "wrappy": "1" } - } - } - }, - "external-editor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.1.0.tgz", - "integrity": "sha512-E44iT5QVOUJBKij4IIV3uvxuNlbKS38Tw1HiupxEIHPv9qtC2PrDYohbXV5U+1jnfIXttny8gUhj+oZvflFlzA==", - "dev": true, - "requires": { - "chardet": "^0.4.0", - "iconv-lite": "^0.4.17", - "tmp": "^0.0.33" - } - }, - "extglob": { - "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", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "bundled": true, "dev": true, + "optional": true, "requires": { - "is-descriptor": "^1.0.0" + "number-is-nan": "^1.0.0" } }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, "dev": true, + "optional": true, "requires": { - "is-extendable": "^0.1.0" + "brace-expansion": "^1.1.7" } }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true, + "optional": true + }, + "minipass": { + "version": "2.3.5", + "bundled": true, "dev": true, + "optional": true, "requires": { - "kind-of": "^6.0.0" + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" } }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "minizlib": { + "version": "1.2.1", + "bundled": true, "dev": true, + "optional": true, "requires": { - "kind-of": "^6.0.0" + "minipass": "^2.2.1" } }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "mkdirp": { + "version": "0.5.1", + "bundled": true, "dev": true, + "optional": true, "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "minimist": "0.0.8" } - } - } - }, - "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 - }, - "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=", - "dev": true - }, - "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.6", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.6.tgz", - "integrity": "sha512-0BvMaZc1k9F+MeWWMe8pL6YltFzZYcJsYU7D4JyDA6PAczaXvxqQQ/z+mDF7/4Mw01DeUc+i3CTKajnkANkV4w==", - "dev": true, - "requires": { - "@mrmlnc/readdir-enhanced": "^2.2.1", - "@nodelib/fs.stat": "^1.1.2", - "glob-parent": "^3.1.0", - "is-glob": "^4.0.0", - "merge2": "^1.2.3", - "micromatch": "^3.1.10" - }, - "dependencies": { - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + }, + "ms": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "dev": true, + "optional": true + }, + "needle": { + "version": "2.3.0", + "bundled": true, "dev": true, + "optional": true, "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "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" - } - } + "debug": "^4.1.0", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" } }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "node-pre-gyp": { + "version": "0.12.0", + "bundled": true, "dev": true, + "optional": true, "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "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" - } - } + "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" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.1", + "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, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "optional": 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" } }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "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.8", + "bundled": true, "dev": true, + "optional": true, "requires": { - "kind-of": "^3.0.2" + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" }, "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "minimist": { + "version": "1.2.0", + "bundled": true, "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } + "optional": true } } }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "readable-stream": { + "version": "2.3.6", + "bundled": true, "dev": true, + "optional": true, "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" + "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" } }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "rimraf": { + "version": "2.6.3", + "bundled": true, "dev": true, + "optional": true, "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" + "glob": "^7.1.3" } - } - } - }, - "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 - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "faye-websocket": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.1.tgz", - "integrity": "sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg=", - "dev": true, - "requires": { - "websocket-driver": ">=0.5.1" - } - }, - "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" - } - }, - "feed": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/feed/-/feed-1.1.1.tgz", - "integrity": "sha1-kUiXUX6U+jJ8xvc7tYWkfEqe0yE=", - "dev": true, - "requires": { - "xml": "^1.0.1" - } - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "file-entry-cache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", - "dev": true, - "requires": { - "flat-cache": "^1.2.1", - "object-assign": "^4.0.1" - } - }, - "file-type": { - "version": "10.11.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-10.11.0.tgz", - "integrity": "sha512-uzk64HRpUZyTGZtVuvrjP0FYxzQrBf4rojot6J65YMEbwBLB0CWm0CLojVpwpmFmxcE/lkvYICgfcGozbBq6rw==", - "dev": true - }, - "filename-reserved-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", - "integrity": "sha1-q/c9+rc10EVECr/qLZHzieu/oik=", - "dev": true - }, - "filenamify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-2.1.0.tgz", - "integrity": "sha512-ICw7NTT6RsDp2rnYKVd8Fu4cr6ITzGy3+u4vUujPkabyaz+03F24NWEX7fs5fp+kBonlaqPH8fAO2NM+SXt/JA==", - "dev": true, - "requires": { - "filename-reserved-regex": "^2.0.0", - "strip-outer": "^1.0.0", - "trim-repeated": "^1.0.0" - } - }, - "filesize": { - "version": "3.5.11", - "resolved": "https://registry.npmjs.org/filesize/-/filesize-3.5.11.tgz", - "integrity": "sha512-ZH7loueKBoDb7yG9esn1U+fgq7BzlzW6NRi5/rMdxIZ05dj7GFD/Xc5rq2CDt5Yq86CyfSYVyx4242QQNZbx1g==", - "dev": true - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "finalhandler": { - "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", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.2", - "statuses": "~1.4.0", - "unpipe": "~1.0.0" - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true, + "optional": 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.7.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, + "optional": true, "requires": { - "locate-path": "^3.0.0" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "string_decoder": { + "version": "1.1.1", + "bundled": true, "dev": true, + "optional": true, "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" + "safe-buffer": "~5.1.0" } }, - "p-limit": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", - "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "strip-ansi": { + "version": "3.0.1", + "bundled": true, "dev": true, + "optional": true, "requires": { - "p-try": "^2.0.0" + "ansi-regex": "^2.0.0" } }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.8", + "bundled": true, "dev": true, + "optional": true, "requires": { - "p-limit": "^2.0.0" + "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" } }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "wide-align": { + "version": "1.1.3", + "bundled": true, "dev": true, + "optional": true, "requires": { - "find-up": "^3.0.0" + "string-width": "^1.0.2 || 2" } - } - } - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "find-versions": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-3.1.0.tgz", - "integrity": "sha512-NCTfNiVzeE/xL+roNDffGuRbrWI6atI18lTJ22vKp7rs2OhYzMK3W1dIdO2TUndH/QMcacM4d1uWwgcZcHK69Q==", - "dev": true, - "requires": { - "array-uniq": "^2.1.0", - "semver-regex": "^2.0.0" - }, - "dependencies": { - "array-uniq": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-2.1.0.tgz", - "integrity": "sha512-bdHxtev7FN6+MXI1YFW0Q8mQ8dTJc2S8AMfju+ZR77pbg2yAdVyDlwkaUI7Har0LyOMRFPHrJ9lYdyjZZswdlQ==", - "dev": true - } - } - }, - "flat-cache": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", - "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", - "dev": true, - "requires": { - "circular-json": "^0.3.1", - "del": "^2.0.2", - "graceful-fs": "^4.1.2", - "write": "^0.2.1" - } - }, - "flatten": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz", - "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=", - "dev": true - }, - "for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "requires": { - "is-callable": "^1.1.3" - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true - }, - "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", - "mime-types": "^2.1.12" - } - }, - "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", - "dev": true - }, - "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" - } - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "dev": true - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "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": "http://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, - "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=", + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0" - } + "optional": true + }, + "yallist": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "optional": true } } }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, "fstream": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", @@ -6273,6 +7580,15 @@ "process": "~0.5.1" } }, + "global-dirs": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", + "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", + "dev": true, + "requires": { + "ini": "^1.3.4" + } + }, "global-modules": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", @@ -6726,6 +8042,12 @@ "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==", "dev": true }, + "ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", + "dev": true + }, "imagemin": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/imagemin/-/imagemin-6.1.0.tgz", @@ -6763,22 +8085,11 @@ } } }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true } } }, @@ -6942,9 +8253,9 @@ } }, "import-lazy": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-3.1.0.tgz", - "integrity": "sha512-8/gvXvX2JMn0F+CDlSC4l6kOmVaLOO3XLkksI7CI3Ud95KDYJuYur2b9P/PUt/i/pDAMd/DulQsNbbbmRRsDIQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", "dev": true }, "imurmurhash": { @@ -7094,6 +8405,14 @@ "requires": { "from2": "^2.1.1", "p-is-promise": "^1.1.0" + }, + "dependencies": { + "p-is-promise": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz", + "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=", + "dev": true + } } }, "invariant": { @@ -7149,6 +8468,15 @@ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", @@ -7170,6 +8498,15 @@ "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", "dev": true }, + "is-ci": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz", + "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", + "dev": true, + "requires": { + "ci-info": "^1.5.0" + } + }, "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", @@ -7275,6 +8612,16 @@ "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=", "dev": true }, + "is-installed-globally": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", + "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", + "dev": true, + "requires": { + "global-dirs": "^0.1.0", + "is-path-inside": "^1.0.0" + } + }, "is-jpg": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-jpg/-/is-jpg-2.0.0.tgz", @@ -7287,12 +8634,24 @@ "integrity": "sha1-q5124dtM7VHjXeDHLr7PCfc0zeg=", "dev": true }, + "is-npm": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", + "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=", + "dev": true + }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, + "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", @@ -7350,6 +8709,12 @@ "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", "dev": true }, + "is-redirect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", + "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=", + "dev": true + }, "is-regex": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", @@ -7606,6 +8971,12 @@ "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", "dev": true }, + "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 + }, "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", @@ -7723,7 +9094,16 @@ "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", "dev": true, "requires": { - "graceful-fs": "^4.1.9" + "graceful-fs": "^4.1.9" + } + }, + "latest-version": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", + "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", + "dev": true, + "requires": { + "package-json": "^4.0.0" } }, "lazy-cache": { @@ -8014,21 +9394,21 @@ } }, "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", "dev": true, "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "dependencies": { - "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", - "dev": true - } + "pify": "^3.0.0" + } + }, + "map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "dev": true, + "requires": { + "p-defer": "^1.0.0" } }, "map-cache": { @@ -8501,14 +9881,64 @@ "dev": true }, "node-releases": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.15.tgz", - "integrity": "sha512-cKV097BQaZr8LTSRUa2+oc/aX5L8UkZtPQrMSTgiJEeaW7ymTDCoRaGCoaTqk0lqnalcoSHu4wjSl0Cmj2+bMw==", + "version": "1.1.21", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.21.tgz", + "integrity": "sha512-TwnURTCjc8a+ElJUjmDqU6+12jhli1Q61xOQmdZ7ECZVBZuQpN/1UnembiIHDM1wCcfLvh5wrWXUF5H6ufX64Q==", "dev": true, "requires": { "semver": "^5.3.0" } }, + "nodemon": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.19.0.tgz", + "integrity": "sha512-NHKpb/Je0Urmwi3QPDHlYuFY9m1vaVfTsRZG5X73rY46xPj0JpNe8WhUGQdkDXQDOxrBNIU3JrcflE9Y44EcuA==", + "dev": true, + "requires": { + "chokidar": "^2.1.5", + "debug": "^3.1.0", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.0.4", + "pstree.remy": "^1.1.6", + "semver": "^5.5.0", + "supports-color": "^5.2.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.2", + "update-notifier": "^2.5.0" + }, + "dependencies": { + "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" + } + }, + "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 + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "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" + } + } + } + }, "nopt": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", @@ -8530,6 +9960,12 @@ "validate-npm-package-license": "^3.0.1" } }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, "normalize-range": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", @@ -8556,14 +9992,6 @@ "requires": { "config-chain": "^1.1.11", "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } } }, "npm-run-path": { @@ -8757,8 +10185,8 @@ } }, "openzeppelin-docsite": { - "version": "github:OpenZeppelin/openzeppelin-docsite#1a0e1a2a151445f9343cc59e15ccd57d99863f1a", - "from": "github:OpenZeppelin/openzeppelin-docsite", + "version": "github:OpenZeppelin/openzeppelin-docsite#22388b7a891a6fcdd333efef9e4f7f584ae5b826", + "from": "github:OpenZeppelin/openzeppelin-docsite#22388b7a891a6fcdd333efef9e4f7f584ae5b826", "dev": true, "requires": { "docusaurus": "1.7.2", @@ -8769,9 +10197,9 @@ }, "dependencies": { "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -8915,6 +10343,12 @@ "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==", "dev": true }, + "p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", + "dev": true + }, "p-event": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/p-event/-/p-event-1.3.0.tgz", @@ -8931,9 +10365,9 @@ "dev": true }, "p-is-promise": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz", - "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", + "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", "dev": true }, "p-limit": { @@ -8987,6 +10421,39 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, + "package-json": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", + "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", + "dev": true, + "requires": { + "got": "^6.7.1", + "registry-auth-token": "^3.0.1", + "registry-url": "^3.0.3", + "semver": "^5.1.0" + }, + "dependencies": { + "got": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", + "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", + "dev": true, + "requires": { + "create-error-class": "^3.0.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-redirect": "^1.0.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "lowercase-keys": "^1.0.0", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "unzip-response": "^2.0.1", + "url-parse-lax": "^1.0.0" + } + } + } + }, "parse-asn1": { "version": "5.1.4", "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.4.tgz", @@ -9153,9 +10620,9 @@ "dev": true }, "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true }, "pinkie": { @@ -10600,6 +12067,12 @@ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", "dev": true }, + "pstree.remy": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.6.tgz", + "integrity": "sha512-NdF35+QsqD7EgNEI5mkI/X+UwaxVEbQaz9f4IooEmMUv6ZPmlTQYGjBPJGgrlzNdjSvIy4MWMg6Q6vCgBO2K+w==", + "dev": true + }, "public-encrypt": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", @@ -10739,6 +12212,26 @@ } } }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, "react": { "version": "16.8.6", "resolved": "https://registry.npmjs.org/react/-/react-16.8.6.tgz", @@ -10783,73 +12276,189 @@ "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", "dev": true, "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + } + } + } + }, + "react-dom": { + "version": "16.8.6", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.8.6.tgz", + "integrity": "sha512-1nL7PIq9LTL3fthPqwkvr2zY7phIPjYrT0jp4HjyEQrEROnw4dG41VVwi/wfoCneoleqrNX7iAD+pXebJZwrwA==", + "dev": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.13.6" + } + }, + "react-error-overlay": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-4.0.1.tgz", + "integrity": "sha512-xXUbDAZkU08aAkjtUvldqbvI04ogv+a1XdHxvYuHPYKIVk/42BIOD0zSKTHAWV4+gDy3yGm283z2072rA2gdtw==", + "dev": true + }, + "react-is": { + "version": "16.8.6", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz", + "integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==", + "dev": true + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "requires": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "requires": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + } + }, + "readable-stream": { + "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", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.0.3", + "util-deprecate": "~1.0.1" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + }, + "dependencies": { + "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", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "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" + } + } + } + }, + "fill-range": { + "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", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "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" + } + } + } + }, + "is-number": { + "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" + }, + "dependencies": { + "kind-of": { + "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" + } + } + } + }, + "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", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "to-regex-range": { + "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" } } } }, - "react-dom": { - "version": "16.8.6", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.8.6.tgz", - "integrity": "sha512-1nL7PIq9LTL3fthPqwkvr2zY7phIPjYrT0jp4HjyEQrEROnw4dG41VVwi/wfoCneoleqrNX7iAD+pXebJZwrwA==", - "dev": true, - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2", - "scheduler": "^0.13.6" - } - }, - "react-error-overlay": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-4.0.1.tgz", - "integrity": "sha512-xXUbDAZkU08aAkjtUvldqbvI04ogv+a1XdHxvYuHPYKIVk/42BIOD0zSKTHAWV4+gDy3yGm283z2072rA2gdtw==", - "dev": true - }, - "react-is": { - "version": "16.8.6", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz", - "integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==", - "dev": true - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true, - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true, - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - } - }, - "readable-stream": { - "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", - "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.0.3", - "util-deprecate": "~1.0.1" - } - }, "rechoir": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", @@ -10932,9 +12541,9 @@ "dev": true }, "regenerate-unicode-properties": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.0.2.tgz", - "integrity": "sha512-SbA/iNrBUf6Pv2zU8Ekv1Qbhv92yxL4hiDa2siuxs4KKn4oOoMDHXjAf7+Nz9qinUQ46B1LcWEi/PhJfPWpZWQ==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz", + "integrity": "sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA==", "dev": true, "requires": { "regenerate": "^1.4.0" @@ -10947,9 +12556,9 @@ "dev": true }, "regenerator-transform": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.13.4.tgz", - "integrity": "sha512-T0QMBjK3J0MtxjPmdIMXm72Wvj2Abb0Bd4HADdfijwMdoIsyQZ6fWC7kDFhk2YinBBEMZDL7Y7wh0J1sGx3S4A==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.0.tgz", + "integrity": "sha512-rtOelq4Cawlbmq9xuMR5gdFmv7ku/sFoB7sRiywx7aq53bc52b4j6zvH7Te1Vt/X2YveDKnCGUbioieU7FEL3w==", "dev": true, "requires": { "private": "^0.1.6" @@ -10966,9 +12575,9 @@ } }, "regexp-tree": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.5.tgz", - "integrity": "sha512-nUmxvfJyAODw+0B13hj8CFVAxhe7fDEAgJgaotBu3nnR+IgGgZq59YedJP5VYTlkEfqjuK6TuRpnymKdatLZfQ==", + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.10.tgz", + "integrity": "sha512-K1qVSbcedffwuIslMwpe6vGlj+ZXRnGkvjAtFHfDZZZuEdA/h0dxljAPu9vhUo6Rrx2U2AwJ+nSQ6hK+lrP5MQ==", "dev": true }, "regexpp": { @@ -10991,6 +12600,25 @@ "unicode-match-property-value-ecmascript": "^1.1.0" } }, + "registry-auth-token": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz", + "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==", + "dev": true, + "requires": { + "rc": "^1.1.6", + "safe-buffer": "^5.0.1" + } + }, + "registry-url": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", + "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", + "dev": true, + "requires": { + "rc": "^1.0.1" + } + }, "regjsgen": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.0.tgz", @@ -11036,6 +12664,12 @@ } } }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, "repeat-element": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", @@ -11265,6 +12899,15 @@ "rx-lite": "*" } }, + "rxjs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz", + "integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, "safe-buffer": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", @@ -11412,6 +13055,15 @@ "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", "dev": true }, + "semver-diff": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", + "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", + "dev": true, + "requires": { + "semver": "^5.0.3" + } + }, "semver-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-2.0.0.tgz", @@ -12232,9 +13884,8 @@ } }, "solidity-docgen": { - "version": "0.2.0-alpha.0", - "resolved": "https://registry.npmjs.org/solidity-docgen/-/solidity-docgen-0.2.0-alpha.0.tgz", - "integrity": "sha512-Us3v9QoXI6IP4iwdUsjPlUB2w9Qd1rtUa4djDkGyKIxZxJxVkAnFxuKXIAmFl6aRGz/eKUsOZdOT2KEvVlBU2w==", + "version": "github:OpenZeppelin/solidity-docgen#03f42b5e271b1e1c1d0b814b921ecdc086055255", + "from": "github:OpenZeppelin/solidity-docgen#03f42b5e271b1e1c1d0b814b921ecdc086055255", "dev": true, "requires": { "commander": "^2.14.1", @@ -12252,16 +13903,10 @@ "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", "dev": true }, - "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 - }, "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -12272,16 +13917,6 @@ "path-is-absolute": "^1.0.0" } }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, "semver": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", @@ -12289,9 +13924,9 @@ "dev": true }, "solc": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.5.7.tgz", - "integrity": "sha512-DaYFzB3AAYjzPtgUl9LenPY2xjI3wG9k8U8T8YE/sXHVIoCirCY5MB6mhcFPgk/VyUtaWZPUCWiYS1E6RSiiqw==", + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.5.8.tgz", + "integrity": "sha512-RQ2SlwPBOBSV7ktNQJkvbiQks3t+3V9dsqD014EdstxnJzSxBuOvbt3P5QXpNPYW1DsEmF7dhOaT3JL7yEae/A==", "dev": true, "requires": { "command-exists": "^1.2.8", @@ -12442,6 +14077,12 @@ "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", "dev": true }, + "spawn-command": { + "version": "0.0.2-1", + "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", + "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=", + "dev": true + }, "spdx-correct": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", @@ -12904,6 +14545,15 @@ "uuid": "^3.0.1" } }, + "term-size": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", + "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", + "dev": true, + "requires": { + "execa": "^0.7.0" + } + }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -13055,6 +14705,26 @@ "integrity": "sha512-gVweAectJU3ebq//Ferr2JUY4WKSDe5N+z0FvjDncLGyHmIDoxgY/2Ie4qfEIDm4IS7OA6Rmdm7pdEEdMcV/xQ==", "dev": true }, + "touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "requires": { + "nopt": "~1.0.10" + }, + "dependencies": { + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "dev": true, + "requires": { + "abbrev": "1" + } + } + } + }, "tough-cookie": { "version": "2.3.4", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", @@ -13296,6 +14966,15 @@ "through": "^2.3.8" } }, + "undefsafe": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.2.tgz", + "integrity": "sha1-Il9rngM3Zj4Njnz9aG/Cg2zKznY=", + "dev": true, + "requires": { + "debug": "^2.2.0" + } + }, "underscore": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz", @@ -13383,6 +15062,15 @@ "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=", "dev": true }, + "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", @@ -13441,6 +15129,67 @@ } } }, + "unzip-response": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", + "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=", + "dev": true + }, + "upath": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz", + "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==", + "dev": true + }, + "update-notifier": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz", + "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==", + "dev": true, + "requires": { + "boxen": "^1.2.1", + "chalk": "^2.0.1", + "configstore": "^3.0.0", + "import-lazy": "^2.1.0", + "is-ci": "^1.0.10", + "is-installed-globally": "^0.1.0", + "is-npm": "^1.0.0", + "latest-version": "^3.0.0", + "semver-diff": "^2.0.0", + "xdg-basedir": "^3.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.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" + } + }, + "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" + } + } + } + }, "uri-js": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", @@ -13558,9 +15307,9 @@ "dev": true }, "vendors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.2.tgz", - "integrity": "sha512-w/hry/368nO21AN9QljsaIhb9ZiZtZARoVH5f3CsFbawdLdayCgKRPup7CggujvySMxx0I91NOyxdVENohprLQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.3.tgz", + "integrity": "sha512-fOi47nsJP5Wqefa43kyWSg80qF+Q3XA6MUkgi7Hp1HQaKDQW4cQrK2D0P7mmbFtsV1N89am55Yru/nyEwRubcw==", "dev": true }, "verror": { @@ -14082,6 +15831,48 @@ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, + "widest-line": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", + "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", + "dev": true, + "requires": { + "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 + }, + "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 + }, + "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" + } + } + } + }, "window-size": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", @@ -14119,6 +15910,17 @@ "mkdirp": "^0.5.1" } }, + "write-file-atomic": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.2.tgz", + "integrity": "sha512-s0b6vB3xIVRLWywa6X9TOMA7k9zio0TMOsl9ZnDkliA/cfJlpHXAscj0gbHVJiTdIuAYpIyqS5GW91fqm6gG5g==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, "ws": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", @@ -14130,6 +15932,12 @@ "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.5.0", "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.5.0.tgz", diff --git a/package.json b/package.json index 69501633f..bf811412f 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "homepage": "https://github.com/OpenZeppelin/zeppelin-solidity", "devDependencies": { "chai": "^4.2.0", + "concurrently": "^4.1.0", "coveralls": "^3.0.1", "eslint": "^4.19.1", "eslint-config-standard": "^10.2.1", @@ -57,11 +58,12 @@ "ganache-cli": "^6.4.1", "ganache-cli-coverage": "https://github.com/frangio/ganache-cli/releases/download/v6.4.1-coverage/ganache-cli-coverage-6.4.1.tgz", "micromatch": "^4.0.2", - "openzeppelin-docsite": "github:OpenZeppelin/openzeppelin-docsite", + "nodemon": "^1.19.0", + "openzeppelin-docsite": "github:OpenZeppelin/openzeppelin-docsite#22388b7a891a6fcdd333efef9e4f7f584ae5b826", "openzeppelin-test-helpers": "^0.3.2", "solhint": "^1.5.0", "solidity-coverage": "github:rotcivegaf/solidity-coverage#5875f5b7bc74d447f3312c9c0e9fc7814b482477", - "solidity-docgen": "^0.2.0-alpha.0", + "solidity-docgen": "github:OpenZeppelin/solidity-docgen#03f42b5e271b1e1c1d0b814b921ecdc086055255", "truffle": "^5.0.18" } } diff --git a/scripts/docsite.sh b/scripts/docsite.sh index fb390cfe3..1b6737d02 100755 --- a/scripts/docsite.sh +++ b/scripts/docsite.sh @@ -5,4 +5,11 @@ set -o errexit npm run docgen -npx openzeppelin-docsite-run "$1" + +if [ "$1" = start ]; then + npx concurrently -n docgen,docsite --no-color \ + 'nodemon -C -w contracts -e sol,md -x npm run docgen' \ + 'openzeppelin-docsite-run start' +else + npx openzeppelin-docsite-run "$1" +fi From d95f5e2e506bc6e05009533644dfefa9938e2e50 Mon Sep 17 00:00:00 2001 From: Francisco Giordano Date: Thu, 23 May 2019 18:19:45 -0300 Subject: [PATCH 22/26] lint (cherry picked from commit bd13be9174943f3fa18896df4ac269f411143c7d) --- contracts/introspection/ERC165Checker.sol | 2 +- contracts/token/ERC777/ERC777.sol | 8 ++++---- contracts/token/ERC777/IERC777Recipient.sol | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/contracts/introspection/ERC165Checker.sol b/contracts/introspection/ERC165Checker.sol index d8788c477..8653da53a 100644 --- a/contracts/introspection/ERC165Checker.sol +++ b/contracts/introspection/ERC165Checker.sol @@ -47,7 +47,7 @@ library ERC165Checker { * * See `IERC165.supportsInterface`. */ - function _supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) { + function _supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) { // query support of ERC165 itself if (!_supportsERC165(account)) { return false; diff --git a/contracts/token/ERC777/ERC777.sol b/contracts/token/ERC777/ERC777.sol index 9038e8039..1df96220a 100644 --- a/contracts/token/ERC777/ERC777.sol +++ b/contracts/token/ERC777/ERC777.sol @@ -348,7 +348,7 @@ contract ERC777 is IERC777, IERC20 { bytes memory operatorData, bool requireReceptionAck ) - private + private { require(from != address(0), "ERC777: send from the zero address"); require(to != address(0), "ERC777: send to the zero address"); @@ -375,7 +375,7 @@ contract ERC777 is IERC777, IERC20 { bytes memory data, bytes memory operatorData ) - private + private { require(from != address(0), "ERC777: burn from the zero address"); @@ -433,7 +433,7 @@ contract ERC777 is IERC777, IERC20 { bytes memory userData, bytes memory operatorData ) - private + private { address implementer = _erc1820.getInterfaceImplementer(from, TOKENS_SENDER_INTERFACE_HASH); if (implementer != address(0)) { @@ -461,7 +461,7 @@ contract ERC777 is IERC777, IERC20 { bytes memory operatorData, bool requireReceptionAck ) - private + private { address implementer = _erc1820.getInterfaceImplementer(to, TOKENS_RECIPIENT_INTERFACE_HASH); if (implementer != address(0)) { diff --git a/contracts/token/ERC777/IERC777Recipient.sol b/contracts/token/ERC777/IERC777Recipient.sol index c1d47ebae..a46b30a9f 100644 --- a/contracts/token/ERC777/IERC777Recipient.sol +++ b/contracts/token/ERC777/IERC777Recipient.sol @@ -10,7 +10,7 @@ pragma solidity ^0.5.0; * * See `IERC1820Registry` and `ERC1820Implementer`. */ - interface IERC777Recipient { +interface IERC777Recipient { /** * @dev Called by an `IERC777` token contract whenever tokens are being * moved or created into a registered account (`to`). The type of operation From c5892562033b3b13cf5656247e4df11a894f50d2 Mon Sep 17 00:00:00 2001 From: Francisco Giordano Date: Thu, 23 May 2019 19:35:20 -0300 Subject: [PATCH 23/26] fix typos --- contracts/token/ERC777/IERC777.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/token/ERC777/IERC777.sol b/contracts/token/ERC777/IERC777.sol index 6643969bd..776de1dc9 100644 --- a/contracts/token/ERC777/IERC777.sol +++ b/contracts/token/ERC777/IERC777.sol @@ -59,7 +59,7 @@ interface IERC777 { function send(address recipient, uint256 amount, bytes calldata data) external; /** - * @dev Destoys `amount` tokens from the caller's account, reducing the + * @dev Destroys `amount` tokens from the caller's account, reducing the * total supply. * * If a send hook is registered for the caller, the corresponding function @@ -114,7 +114,7 @@ interface IERC777 { * them. * * This list is immutable, but individual holders may revoke these via - *`revokeOperator`, in which case `isOperatorFor` will return false. + * `revokeOperator`, in which case `isOperatorFor` will return false. */ function defaultOperators() external view returns (address[] memory); From fd3f2421b7aea772ad1793e1213eb35de65a6dec Mon Sep 17 00:00:00 2001 From: Francisco Giordano Date: Thu, 23 May 2019 20:38:45 -0300 Subject: [PATCH 24/26] update openzeppelin-docsite dependency --- package-lock.json | 504 +++++++++++++++------------------------------- package.json | 2 +- 2 files changed, 159 insertions(+), 347 deletions(-) diff --git a/package-lock.json b/package-lock.json index f6b32bfc9..f52ddac3e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35,52 +35,6 @@ "source-map": "^0.5.0" }, "dependencies": { - "@babel/generator": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.4.4.tgz", - "integrity": "sha512-53UOLK6TVNqKxf7RUh8NE851EHRxOOeVXKbK2bivdb+iziMyk03Sr4eaE9OELCbyZAAafAKPDwF2TPUES5QbxQ==", - "dev": true, - "requires": { - "@babel/types": "^7.4.4", - "jsesc": "^2.5.1", - "lodash": "^4.17.11", - "source-map": "^0.5.0", - "trim-right": "^1.0.1" - } - }, - "@babel/helpers": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.4.4.tgz", - "integrity": "sha512-igczbR/0SeuPR8RFfC7tGrbdTbFL3QTvH6D+Z6zNxnTe//GyqmtHmDkzrqDmyZ3eSwPqB/LhyKoU5DXsp+Vp2A==", - "dev": true, - "requires": { - "@babel/template": "^7.4.4", - "@babel/traverse": "^7.4.4", - "@babel/types": "^7.4.4" - } - }, - "@babel/template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz", - "integrity": "sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.4.4", - "@babel/types": "^7.4.4" - } - }, - "@babel/types": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz", - "integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.11", - "to-fast-properties": "^2.0.0" - } - }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", @@ -105,12 +59,12 @@ } }, "@babel/generator": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.4.0.tgz", - "integrity": "sha512-/v5I+a1jhGSKLgZDcmAUZ4K/VePi43eRkUs3yePW1HB1iANOD5tqJXwGSG4BZhSksP8J9ejSlwGeTiiOFZOrXQ==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.4.4.tgz", + "integrity": "sha512-53UOLK6TVNqKxf7RUh8NE851EHRxOOeVXKbK2bivdb+iziMyk03Sr4eaE9OELCbyZAAafAKPDwF2TPUES5QbxQ==", "dev": true, "requires": { - "@babel/types": "^7.4.0", + "@babel/types": "^7.4.4", "jsesc": "^2.5.1", "lodash": "^4.17.11", "source-map": "^0.5.0", @@ -155,38 +109,38 @@ } }, "@babel/helper-call-delegate": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.4.0.tgz", - "integrity": "sha512-SdqDfbVdNQCBp3WhK2mNdDvHd3BD6qbmIc43CAyjnsfCmgHMeqgDcM3BzY2lchi7HBJGJ2CVdynLWbezaE4mmQ==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.4.4.tgz", + "integrity": "sha512-l79boDFJ8S1c5hvQvG+rc+wHw6IuH7YldmRKsYtpbawsxURu/paVy57FZMomGK22/JckepaikOkY0MoAmdyOlQ==", "dev": true, "requires": { - "@babel/helper-hoist-variables": "^7.4.0", - "@babel/traverse": "^7.4.0", - "@babel/types": "^7.4.0" + "@babel/helper-hoist-variables": "^7.4.4", + "@babel/traverse": "^7.4.4", + "@babel/types": "^7.4.4" } }, "@babel/helper-create-class-features-plugin": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.4.3.tgz", - "integrity": "sha512-UMl3TSpX11PuODYdWGrUeW6zFkdYhDn7wRLrOuNVM6f9L+S9CzmDXYyrp3MTHcwWjnzur1f/Op8A7iYZWya2Yg==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.4.4.tgz", + "integrity": "sha512-UbBHIa2qeAGgyiNR9RszVF7bUHEdgS4JAUNT8SiqrAN6YJVxlOxeLr5pBzb5kan302dejJ9nla4RyKcR1XT6XA==", "dev": true, "requires": { "@babel/helper-function-name": "^7.1.0", "@babel/helper-member-expression-to-functions": "^7.0.0", "@babel/helper-optimise-call-expression": "^7.0.0", "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.4.0", - "@babel/helper-split-export-declaration": "^7.4.0" + "@babel/helper-replace-supers": "^7.4.4", + "@babel/helper-split-export-declaration": "^7.4.4" } }, "@babel/helper-define-map": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.4.0.tgz", - "integrity": "sha512-wAhQ9HdnLIywERVcSvX40CEJwKdAa1ID4neI9NXQPDOHwwA+57DqwLiPEVy2AIyWzAk0CQ8qx4awO0VUURwLtA==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.4.4.tgz", + "integrity": "sha512-IX3Ln8gLhZpSuqHJSnTNBWGDE9kdkTEWl21A/K7PQ00tseBwbqCHTvNLHSBd9M0R5rER4h5Rsvj9vw0R5SieBg==", "dev": true, "requires": { "@babel/helper-function-name": "^7.1.0", - "@babel/types": "^7.4.0", + "@babel/types": "^7.4.4", "lodash": "^4.17.11" } }, @@ -221,12 +175,12 @@ } }, "@babel/helper-hoist-variables": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.4.0.tgz", - "integrity": "sha512-/NErCuoe/et17IlAQFKWM24qtyYYie7sFIrW/tIQXpck6vAu2hhtYYsKLBWQV+BQZMbcIYPU/QMYuTufrY4aQw==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.4.4.tgz", + "integrity": "sha512-VYk2/H/BnYbZDDg39hr3t2kKyifAm1W6zHRfhx8jGjIHpQEBv9dry7oQ2f3+J703TLu69nYdxsovl0XYfcnK4w==", "dev": true, "requires": { - "@babel/types": "^7.4.0" + "@babel/types": "^7.4.4" } }, "@babel/helper-member-expression-to-functions": { @@ -248,16 +202,16 @@ } }, "@babel/helper-module-transforms": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.4.3.tgz", - "integrity": "sha512-H88T9IySZW25anu5uqyaC1DaQre7ofM+joZtAaO2F8NBdFfupH0SZ4gKjgSFVcvtx/aAirqA9L9Clio2heYbZA==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.4.4.tgz", + "integrity": "sha512-3Z1yp8TVQf+B4ynN7WoHPKS8EkdTbgAEy0nU0rs/1Kw4pDgmvYH3rz3aI11KgxKCba2cn7N+tqzV1mY2HMN96w==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.0.0", "@babel/helper-simple-access": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.0.0", - "@babel/template": "^7.2.2", - "@babel/types": "^7.2.2", + "@babel/helper-split-export-declaration": "^7.4.4", + "@babel/template": "^7.4.4", + "@babel/types": "^7.4.4", "lodash": "^4.17.11" } }, @@ -277,9 +231,9 @@ "dev": true }, "@babel/helper-regex": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.4.3.tgz", - "integrity": "sha512-hnoq5u96pLCfgjXuj8ZLX3QQ+6nAulS+zSgi6HulUwFbEruRAKwbGLU5OvXkE14L8XW6XsQEKsIDfgthKLRAyA==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.4.4.tgz", + "integrity": "sha512-Y5nuB/kESmR3tKjU8Nkn1wMGEx1tjJX076HBMeL3XLQCu6vA/YRzuTW0bbb+qRnXvQGn+d6Rx953yffl8vEy7Q==", "dev": true, "requires": { "lodash": "^4.17.11" @@ -299,15 +253,15 @@ } }, "@babel/helper-replace-supers": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.4.0.tgz", - "integrity": "sha512-PVwCVnWWAgnal+kJ+ZSAphzyl58XrFeSKSAJRiqg5QToTsjL+Xu1f9+RJ+d+Q0aPhPfBGaYfkox66k86thxNSg==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.4.4.tgz", + "integrity": "sha512-04xGEnd+s01nY1l15EuMS1rfKktNF+1CkKmHoErDppjAAZL+IUBZpzT748x262HF7fibaQPhbvWUl5HeSt1EXg==", "dev": true, "requires": { "@babel/helper-member-expression-to-functions": "^7.0.0", "@babel/helper-optimise-call-expression": "^7.0.0", - "@babel/traverse": "^7.4.0", - "@babel/types": "^7.4.0" + "@babel/traverse": "^7.4.4", + "@babel/types": "^7.4.4" } }, "@babel/helper-simple-access": { @@ -321,12 +275,12 @@ } }, "@babel/helper-split-export-declaration": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.0.tgz", - "integrity": "sha512-7Cuc6JZiYShaZnybDmfwhY4UYHzI6rlqhWjaIqbsJGsIqPimEYy5uh3akSRLMg65LSdSEnJ8a8/bWQN6u2oMGw==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", + "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", "dev": true, "requires": { - "@babel/types": "^7.4.0" + "@babel/types": "^7.4.4" } }, "@babel/helper-wrap-function": { @@ -341,6 +295,17 @@ "@babel/types": "^7.2.0" } }, + "@babel/helpers": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.4.4.tgz", + "integrity": "sha512-igczbR/0SeuPR8RFfC7tGrbdTbFL3QTvH6D+Z6zNxnTe//GyqmtHmDkzrqDmyZ3eSwPqB/LhyKoU5DXsp+Vp2A==", + "dev": true, + "requires": { + "@babel/template": "^7.4.4", + "@babel/traverse": "^7.4.4", + "@babel/types": "^7.4.4" + } + }, "@babel/highlight": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", @@ -415,12 +380,12 @@ } }, "@babel/plugin-proposal-class-properties": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.4.0.tgz", - "integrity": "sha512-t2ECPNOXsIeK1JxJNKmgbzQtoG27KIlVE61vTqX0DKR9E9sZlVVxWUtEW9D5FlZ8b8j7SBNCHY47GgPKCKlpPg==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.4.4.tgz", + "integrity": "sha512-WjKTI8g8d5w1Bc9zgwSz2nfrsNQsXcCf9J9cdCvrJV6RF56yztwm4TmJC0MgJ9tvwO9gUA/mcYe89bLdGfiXFg==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.4.0", + "@babel/helper-create-class-features-plugin": "^7.4.4", "@babel/helper-plugin-utils": "^7.0.0" } }, @@ -435,9 +400,9 @@ } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.4.3.tgz", - "integrity": "sha512-xC//6DNSSHVjq8O2ge0dyYlhshsH4T7XdCVoxbi5HzLYWfsC5ooFlJjrXk8RcAT+hjHAK9UjBXdylzSoDK3t4g==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.4.4.tgz", + "integrity": "sha512-dMBG6cSPBbHeEBdFXeQ2QLc5gUpg4Vkaz8octD4aoW/ISO+jBOcsuxYL7bsb5WSu8RLP6boxrBIALEHgoHtO9g==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", @@ -455,13 +420,13 @@ } }, "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.4.0.tgz", - "integrity": "sha512-h/KjEZ3nK9wv1P1FSNb9G079jXrNYR0Ko+7XkOx85+gM24iZbPn0rh4vCftk+5QKY7y1uByFataBTmX7irEF1w==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.4.4.tgz", + "integrity": "sha512-j1NwnOqMG9mFUOH58JTFsA/+ZYzQLUZ/drqWUqxCYLGeu2JFZL8YrNC9hBxKmWtAuOCHPcRpgv7fhap09Fb4kA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-regex": "^7.0.0", + "@babel/helper-regex": "^7.4.4", "regexpu-core": "^4.5.4" } }, @@ -520,9 +485,9 @@ } }, "@babel/plugin-transform-async-to-generator": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.4.0.tgz", - "integrity": "sha512-EeaFdCeUULM+GPFEsf7pFcNSxM7hYjoj5fiYbyuiXobW4JhFnjAv9OWzNwHyHcKoPNpAfeRDuW6VyaXEDUBa7g==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.4.4.tgz", + "integrity": "sha512-YiqW2Li8TXmzgbXw+STsSqPBPFnGviiaSp6CYOq55X8GQ2SGVLrXB6pNid8HkqkZAzOH6knbai3snhP7v0fNwA==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.0.0", @@ -540,9 +505,9 @@ } }, "@babel/plugin-transform-block-scoping": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.4.0.tgz", - "integrity": "sha512-AWyt3k+fBXQqt2qb9r97tn3iBwFpiv9xdAiG+Gr2HpAZpuayvbL55yWrsV3MyHvXk/4vmSiedhDRl1YI2Iy5nQ==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.4.4.tgz", + "integrity": "sha512-jkTUyWZcTrwxu5DD4rWz6rDB5Cjdmgz6z7M7RLXOJyCUkFBawssDGcGh8M/0FTSB87avyJI1HsTwUXp9nKA1PA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", @@ -550,18 +515,18 @@ } }, "@babel/plugin-transform-classes": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.4.3.tgz", - "integrity": "sha512-PUaIKyFUDtG6jF5DUJOfkBdwAS/kFFV3XFk7Nn0a6vR7ZT8jYw5cGtIlat77wcnd0C6ViGqo/wyNf4ZHytF/nQ==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.4.4.tgz", + "integrity": "sha512-/e44eFLImEGIpL9qPxSRat13I5QNRgBLu2hOQJCF7VLy/otSM/sypV1+XaIw5+502RX/+6YaSAPmldk+nhHDPw==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.0.0", - "@babel/helper-define-map": "^7.4.0", + "@babel/helper-define-map": "^7.4.4", "@babel/helper-function-name": "^7.1.0", "@babel/helper-optimise-call-expression": "^7.0.0", "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.4.0", - "@babel/helper-split-export-declaration": "^7.4.0", + "@babel/helper-replace-supers": "^7.4.4", + "@babel/helper-split-export-declaration": "^7.4.4", "globals": "^11.1.0" } }, @@ -575,22 +540,22 @@ } }, "@babel/plugin-transform-destructuring": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.4.3.tgz", - "integrity": "sha512-rVTLLZpydDFDyN4qnXdzwoVpk1oaXHIvPEOkOLyr88o7oHxVc/LyrnDx+amuBWGOwUb7D1s/uLsKBNTx08htZg==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.4.4.tgz", + "integrity": "sha512-/aOx+nW0w8eHiEHm+BTERB2oJn5D127iye/SUQl7NjHy0lf+j7h4MKMMSOwdazGq9OxgiNADncE+SRJkCxjZpQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-dotall-regex": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.4.3.tgz", - "integrity": "sha512-9Arc2I0AGynzXRR/oPdSALv3k0rM38IMFyto7kOCwb5F9sLUt2Ykdo3V9yUPR+Bgr4kb6bVEyLkPEiBhzcTeoA==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.4.4.tgz", + "integrity": "sha512-P05YEhRc2h53lZDjRPk/OektxCVevFzZs2Gfjd545Wde3k+yFDbXORgl2e0xpbq8mLcKJ7Idss4fAg0zORN/zg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-regex": "^7.4.3", + "@babel/helper-regex": "^7.4.4", "regexpu-core": "^4.5.4" } }, @@ -614,18 +579,18 @@ } }, "@babel/plugin-transform-for-of": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.4.3.tgz", - "integrity": "sha512-UselcZPwVWNSURnqcfpnxtMehrb8wjXYOimlYQPBnup/Zld426YzIhNEvuRsEWVHfESIECGrxoI6L5QqzuLH5Q==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.4.4.tgz", + "integrity": "sha512-9T/5Dlr14Z9TIEXLXkt8T1DU7F24cbhwhMNUziN3hB1AXoZcdzPcTiKGRn/6iOymDqtTKWnr/BtRKN9JwbKtdQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-function-name": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.4.3.tgz", - "integrity": "sha512-uT5J/3qI/8vACBR9I1GlAuU/JqBtWdfCrynuOkrWG6nCDieZd5przB1vfP59FRHBZQ9DC2IUfqr/xKqzOD5x0A==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.4.4.tgz", + "integrity": "sha512-iU9pv7U+2jC9ANQkKeNF6DrPy4GBa4NWQtl6dHB4Pb3izX2JOEvDTFarlNsBj/63ZEzNNIAMs3Qw4fNCcSOXJA==", "dev": true, "requires": { "@babel/helper-function-name": "^7.1.0", @@ -661,23 +626,23 @@ } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.4.3.tgz", - "integrity": "sha512-sMP4JqOTbMJMimqsSZwYWsMjppD+KRyDIUVW91pd7td0dZKAvPmhCaxhOzkzLParKwgQc7bdL9UNv+rpJB0HfA==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.4.4.tgz", + "integrity": "sha512-4sfBOJt58sEo9a2BQXnZq+Q3ZTSAUXyK3E30o36BOGnJ+tvJ6YSxF0PG6kERvbeISgProodWuI9UVG3/FMY6iw==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.4.3", + "@babel/helper-module-transforms": "^7.4.4", "@babel/helper-plugin-utils": "^7.0.0", "@babel/helper-simple-access": "^7.1.0" } }, "@babel/plugin-transform-modules-systemjs": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.4.0.tgz", - "integrity": "sha512-gjPdHmqiNhVoBqus5qK60mWPp1CmYWp/tkh11mvb0rrys01HycEGD7NvvSoKXlWEfSM9TcL36CpsK8ElsADptQ==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.4.4.tgz", + "integrity": "sha512-MSiModfILQc3/oqnG7NrP1jHaSPryO6tA2kOMmAQApz5dayPxWiHqmq4sWH2xF5LcQK56LlbKByCd8Aah/OIkQ==", "dev": true, "requires": { - "@babel/helper-hoist-variables": "^7.4.0", + "@babel/helper-hoist-variables": "^7.4.4", "@babel/helper-plugin-utils": "^7.0.0" } }, @@ -700,6 +665,15 @@ "regexp-tree": "^0.1.6" } }, + "@babel/plugin-transform-new-target": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.4.4.tgz", + "integrity": "sha512-r1z3T2DNGQwwe2vPGZMBNjioT2scgWzK9BCnDEh+46z8EEwXBq24uRzd65I7pjtugzPSj921aM15RpESgzsSuA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, "@babel/plugin-transform-object-super": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.2.0.tgz", @@ -711,12 +685,12 @@ } }, "@babel/plugin-transform-parameters": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.4.3.tgz", - "integrity": "sha512-ULJYC2Vnw96/zdotCZkMGr2QVfKpIT/4/K+xWWY0MbOJyMZuk660BGkr3bEKWQrrciwz6xpmft39nA4BF7hJuA==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.4.4.tgz", + "integrity": "sha512-oMh5DUO1V63nZcu/ZVLQFqiihBGo4OpxJxR1otF50GMeCLiRx5nUdtokd+u9SuVJrvvuIh9OosRFPP4pIPnwmw==", "dev": true, "requires": { - "@babel/helper-call-delegate": "^7.4.0", + "@babel/helper-call-delegate": "^7.4.4", "@babel/helper-get-function-arity": "^7.0.0", "@babel/helper-plugin-utils": "^7.0.0" } @@ -817,9 +791,9 @@ } }, "@babel/plugin-transform-template-literals": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.2.0.tgz", - "integrity": "sha512-FkPix00J9A/XWXv4VoKJBMeSkyY9x/TqIh76wzcdfl57RJJcf8CehQ08uwfhCDNtRQYtHQKBTwKZDEyjE13Lwg==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.4.4.tgz", + "integrity": "sha512-mQrEC4TWkhLN0z8ygIvEL9ZEToPhG5K7KDW3pzGqOfIGZ28Jb0POUkeWcoz8HnHvhFy6dwAT1j8OzqN8s804+g==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.0.0", @@ -835,10 +809,21 @@ "@babel/helper-plugin-utils": "^7.0.0" } }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.4.4.tgz", + "integrity": "sha512-il+/XdNw01i93+M9J9u4T7/e/Ue/vWfNZE4IRUQjplu2Mqb/AFTDimkw2tdEdSH50wuQXZAbXSql0UphQke+vA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.4.4", + "regexpu-core": "^4.5.4" + } + }, "@babel/polyfill": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.4.3.tgz", - "integrity": "sha512-rkv8WIvJshA5Ev8iNMGgz5WZkRtgtiPexiT7w5qevGTuT7ZBfM3de9ox1y9JR5/OXb/sWGBbWlHNa7vQKqku3Q==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.4.4.tgz", + "integrity": "sha512-WlthFLfhQQhh+A2Gn5NSFl0Huxz36x86Jn+E9OW7ibK8edKPq+KLy4apM1yDpQ8kJOVi1OVjpP4vSDLdrI04dg==", "dev": true, "requires": { "core-js": "^2.6.5", @@ -901,46 +886,6 @@ "semver": "^5.5.0" }, "dependencies": { - "@babel/helper-regex": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.4.4.tgz", - "integrity": "sha512-Y5nuB/kESmR3tKjU8Nkn1wMGEx1tjJX076HBMeL3XLQCu6vA/YRzuTW0bbb+qRnXvQGn+d6Rx953yffl8vEy7Q==", - "dev": true, - "requires": { - "lodash": "^4.17.11" - } - }, - "@babel/plugin-transform-new-target": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.4.4.tgz", - "integrity": "sha512-r1z3T2DNGQwwe2vPGZMBNjioT2scgWzK9BCnDEh+46z8EEwXBq24uRzd65I7pjtugzPSj921aM15RpESgzsSuA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-unicode-regex": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.4.4.tgz", - "integrity": "sha512-il+/XdNw01i93+M9J9u4T7/e/Ue/vWfNZE4IRUQjplu2Mqb/AFTDimkw2tdEdSH50wuQXZAbXSql0UphQke+vA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-regex": "^7.4.4", - "regexpu-core": "^4.5.4" - } - }, - "@babel/types": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz", - "integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.11", - "to-fast-properties": "^2.0.0" - } - }, "semver": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", @@ -963,9 +908,9 @@ } }, "@babel/register": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.4.0.tgz", - "integrity": "sha512-ekziebXBnS/7V6xk8sBfLSSD6YZuy6P29igBtR6OL/tswKdxOV+Yqq0nzICMguVYtGRZYUCGpfGV8J9Za2iBdw==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.4.4.tgz", + "integrity": "sha512-sn51H88GRa00+ZoMqCVgOphmswG4b7mhf9VOB0LUBAieykq2GnRFerlN+JQkO/ntT7wz4jaHNSRPg9IdMPEUkA==", "dev": true, "requires": { "core-js": "^3.0.0", @@ -985,21 +930,14 @@ } }, "@babel/template": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.0.tgz", - "integrity": "sha512-SOWwxxClTTh5NdbbYZ0BmaBVzxzTh2tO/TeLTbF6MO6EzVhHTnff8CdBXx3mEtazFBoysmEM6GU/wF+SuSx4Fw==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz", + "integrity": "sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.4.0", - "@babel/types": "^7.4.0" - }, - "dependencies": { - "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=" - } + "@babel/parser": "^7.4.4", + "@babel/types": "^7.4.4" } }, "@babel/traverse": { @@ -1019,26 +957,6 @@ "lodash": "^4.17.11" }, "dependencies": { - "@babel/helper-split-export-declaration": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", - "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", - "dev": true, - "requires": { - "@babel/types": "^7.4.4" - } - }, - "@babel/types": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz", - "integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.11", - "to-fast-properties": "^2.0.0" - } - }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", @@ -1057,9 +975,9 @@ } }, "@babel/types": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.0.tgz", - "integrity": "sha512-aPvkXyU2SPOnztlgo8n9cEiXW755mgyvueUPcpStqdzoSPm0fjO0vQBjLkt3JKJW7ufikfcnMTTPsN1xaTsBPA==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz", + "integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==", "dev": true, "requires": { "esutils": "^2.0.2", @@ -2492,58 +2410,11 @@ "map-obj": "^1.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=" - }, - "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==", - "requires": { - "color-convert": "^1.9.0" - } - }, "camelcase": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", "dev": true - }, - "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5" - }, - "dependencies": { - "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=" - } - } - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "esprima": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", - "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==" - }, - "globals": { - "version": "11.7.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.7.0.tgz", - "integrity": "sha512-K8BNSPySfeShBQXsahYB/AbbWruVOTyVpgoIDnl8odPpeSfP2J5QO2oLFFdl2j7GfDCtZj2bMKar2T49itTPCg==" } } }, @@ -2992,6 +2863,7 @@ "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" } @@ -2999,7 +2871,8 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true }, "color-string": { "version": "1.5.3", @@ -7614,9 +7487,9 @@ } }, "globals": { - "version": "11.11.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.11.0.tgz", - "integrity": "sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw==", + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true }, "globby": { @@ -7706,24 +7579,6 @@ "kind-of": "^6.0.2", "section-matter": "^1.0.0", "strip-bom-string": "^1.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 - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - } } }, "growl": { @@ -8188,12 +8043,6 @@ } } }, - "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 - }, "is-svg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz", @@ -8203,16 +8052,6 @@ "html-comment-regex": "^1.1.0" } }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -9458,12 +9297,6 @@ "strip-color": "^0.1.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 - }, "extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", @@ -9486,16 +9319,6 @@ "toml": "^2.3.2" } }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, "minimist": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", @@ -9800,7 +9623,8 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true }, "mute-stream": { "version": "0.0.7", @@ -10185,8 +10009,8 @@ } }, "openzeppelin-docsite": { - "version": "github:OpenZeppelin/openzeppelin-docsite#22388b7a891a6fcdd333efef9e4f7f584ae5b826", - "from": "github:OpenZeppelin/openzeppelin-docsite#22388b7a891a6fcdd333efef9e4f7f584ae5b826", + "version": "github:OpenZeppelin/openzeppelin-docsite#ee1df82d52ad3df4337b20392627975091f8d5b3", + "from": "github:OpenZeppelin/openzeppelin-docsite#ee1df82d52ad3df4337b20392627975091f8d5b3", "dev": true, "requires": { "docusaurus": "1.7.2", @@ -10682,9 +10506,9 @@ "dev": true }, "postcss": { - "version": "7.0.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.14.tgz", - "integrity": "sha512-NsbD6XUUMZvBxtQAJuWDJeeC4QFsmWsfozWxCJPWf3M55K9iu2iMDaKqyoOdTJ1R4usBXuxlVFAIo8rZPQD4Bg==", + "version": "7.0.16", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", + "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -10836,15 +10660,11 @@ "postcss-value-parser": "^3.1.2" }, "dependencies": { - "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=" - }, "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true }, "postcss": { "version": "5.2.18", @@ -10871,14 +10691,6 @@ "dev": true, "requires": { "has-flag": "^1.0.0" - }, - "dependencies": { - "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", - "dev": true - } } } } @@ -15220,12 +15032,12 @@ "dev": true }, "url-parse": { - "version": "1.4.6", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.6.tgz", - "integrity": "sha512-/B8AD9iQ01seoXmXf9z/MjLZQIdOoYl/+gvsQF6+mpnxaTfG9P7srYaiqaDMyKkR36XMXfhqSHss5MyFAO8lew==", + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", + "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", "dev": true, "requires": { - "querystringify": "^2.0.0", + "querystringify": "^2.1.1", "requires-port": "^1.0.0" } }, diff --git a/package.json b/package.json index bf811412f..7f289aaa8 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "ganache-cli-coverage": "https://github.com/frangio/ganache-cli/releases/download/v6.4.1-coverage/ganache-cli-coverage-6.4.1.tgz", "micromatch": "^4.0.2", "nodemon": "^1.19.0", - "openzeppelin-docsite": "github:OpenZeppelin/openzeppelin-docsite#22388b7a891a6fcdd333efef9e4f7f584ae5b826", + "openzeppelin-docsite": "github:OpenZeppelin/openzeppelin-docsite#ee1df82d52ad3df4337b20392627975091f8d5b3", "openzeppelin-test-helpers": "^0.3.2", "solhint": "^1.5.0", "solidity-coverage": "github:rotcivegaf/solidity-coverage#5875f5b7bc74d447f3312c9c0e9fc7814b482477", From d957b880fa5cfa85e9aaa40e4ceebf3033547323 Mon Sep 17 00:00:00 2001 From: Francisco Giordano Date: Fri, 24 May 2019 13:21:20 -0300 Subject: [PATCH 25/26] make naming in ERC777 clearer --- contracts/token/ERC777/ERC777.sol | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/contracts/token/ERC777/ERC777.sol b/contracts/token/ERC777/ERC777.sol index 1df96220a..f857512c8 100644 --- a/contracts/token/ERC777/ERC777.sol +++ b/contracts/token/ERC777/ERC777.sol @@ -122,7 +122,7 @@ contract ERC777 is IERC777, IERC20 { } /** - * @dev Returns the amount of tokens owned by an account (`owner`). + * @dev Returns the amount of tokens owned by an account (`tokenHolder`). */ function balanceOf(address tokenHolder) public view returns (uint256) { return _balances[tokenHolder]; @@ -252,8 +252,8 @@ contract ERC777 is IERC777, IERC20 { * not have allowance, and accounts with allowance may not be operators * themselves. */ - function allowance(address owner, address spender) public view returns (uint256) { - return _allowances[owner][spender]; + function allowance(address holder, address spender) public view returns (uint256) { + return _allowances[holder][spender]; } /** @@ -262,7 +262,8 @@ contract ERC777 is IERC777, IERC20 { * Note that accounts cannot have allowance issued by their operators. */ function approve(address spender, uint256 value) external returns (bool) { - _approve(msg.sender, spender, value); + address holder = msg.sender; + _approve(holder, spender, value); return true; } @@ -275,18 +276,18 @@ contract ERC777 is IERC777, IERC20 { * * Emits `Sent` and `Transfer` events. */ - function transferFrom(address sender, address recipient, uint256 amount) external returns (bool) { + function transferFrom(address holder, address recipient, uint256 amount) external returns (bool) { require(recipient != address(0), "ERC777: transfer to the zero address"); - require(sender != address(0), "ERC777: transfer from the zero address"); + require(holder != address(0), "ERC777: transfer from the zero address"); - address operator = msg.sender; + address spender = msg.sender; - _callTokensToSend(operator, sender, recipient, amount, "", ""); + _callTokensToSend(spender, holder, recipient, amount, "", ""); - _move(operator, sender, recipient, amount, "", ""); - _approve(sender, operator, _allowances[sender][operator].sub(amount)); + _move(spender, holder, recipient, amount, "", ""); + _approve(holder, spender, _allowances[holder][spender].sub(amount)); - _callTokensReceived(operator, sender, recipient, amount, "", "", false); + _callTokensReceived(spender, holder, recipient, amount, "", "", false); return true; } @@ -406,14 +407,14 @@ contract ERC777 is IERC777, IERC20 { emit Transfer(from, to, amount); } - function _approve(address owner, address spender, uint256 value) private { + function _approve(address holder, address spender, uint256 value) private { // TODO: restore this require statement if this function becomes internal, or is called at a new callsite. It is // currently unnecessary. - //require(owner != address(0), "ERC777: approve from the zero address"); + //require(holder != address(0), "ERC777: approve from the zero address"); require(spender != address(0), "ERC777: approve to the zero address"); - _allowances[owner][spender] = value; - emit Approval(owner, spender, value); + _allowances[holder][spender] = value; + emit Approval(holder, spender, value); } /** From 132e442c1f5c857d2929fc2d5c5f08a3274a1910 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Venturo?= Date: Mon, 27 May 2019 12:17:20 -0300 Subject: [PATCH 26/26] 2.3.0 --- CHANGELOG.md | 2 +- ethpm.json | 2 +- package-lock.json | 2 +- package.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f85c53153..34fd61b2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## 2.3.0 (unreleased) +## 2.3.0 (2019-05-27) ### New features: * `ERC1820`: added support for interacting with the [ERC1820](https://eips.ethereum.org/EIPS/eip-1820) registry contract (`IERC1820Registry`), as well as base contracts that can be registered as implementers there. ([#1677](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1677)) diff --git a/ethpm.json b/ethpm.json index 4b3efbd11..f7ed6925b 100644 --- a/ethpm.json +++ b/ethpm.json @@ -1,6 +1,6 @@ { "package_name": "zeppelin", - "version": "2.3.0-rc.3", + "version": "2.3.0", "description": "Secure Smart Contract library for Solidity", "authors": [ "OpenZeppelin Community " diff --git a/package-lock.json b/package-lock.json index f52ddac3e..7cd34ece4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "openzeppelin-solidity", - "version": "2.3.0-rc.3", + "version": "2.3.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 7f289aaa8..a23a4fa15 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "openzeppelin-solidity", - "version": "2.3.0-rc.3", + "version": "2.3.0", "description": "Secure Smart Contract library for Solidity", "files": [ "build",