diff --git a/.gitignore b/.gitignore index e13c8ee0..922a7a38 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ node_modules build -dist \ No newline at end of file +dist +accounts.json +addresses.json diff --git a/README.md b/README.md index 19d2b4b4..e7b3937f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,8 @@ -# Welcome to MyBit Network +

+ + MyBit Logo + +

[![MyBit Logo](https://files.mybit.io/mybit-icon-28x28.png)](https://mybit.io/) [MyBit Developer Portal](https://developer.mybit.io/portal/) > [Contracts](https://developer.mybit.io/web) @@ -6,71 +10,344 @@ [![CircleCI](https://circleci.com/gh/MyBitFoundation/MyBit-Network.tech.svg?style=shield)](https://circleci.com/gh/MyBitFoundation/MyBit-Network.tech) [![Coverage Status](https://coveralls.io/repos/github/MyBitFoundation/MyBit-Network.tech/badge.svg)](https://coveralls.io/github/MyBitFoundation/MyBit-Network.tech) -A software development kit for building wealth management use cases on the Ethereum network. +:factory: A software development kit for the automated machine economy. -The SDK contains a local blockchain and smart-contracts for developers to run and deploy dapps that allow for the funding and distribution of virtual assets represented by ERC tokens on the Ethereum blockchain. The contracts can be combined in different ways to customize the crowdfunding and re-distribution details, or plug into a local MyBitChain to test already operating assets. + Network SDK's are a protocol that allows the creation of decentralised digital assets, funding and trading. It also enables the distribution of revenue generated by assets. These SDK's contain all the functional logic of [MyBit-Go](https://github.com/MyBitFoundation/MyBit-Go.app). -### Getting Started +* For a simple example see [Hello-Network](https://github.com/MyBitFoundation/hello-network) -### Roles +* For importing the SDK's as an NPM package see [Network.js](https://github.com/MyBitFoundation/network.js) -The tokenized asset management structure is made up of different actors who have specific incentives to participate in the creation and management of tokenized assets within the ecosystem. The assets are managed by the AssetManager, who receives a fee for his work and escrows tokens as collateral to investors. The tokens remain in escrow until the asset tokens returns sufficient income. The platform owners can choose how assets are governed, whether by asset token holders or designated ownership roles. +## Getting Started +First install dependencies using [Yarn](https://yarnpkg.com/lang/en/docs/install/#debian-stable): -AssetManagers interact with the AssetManagerEscrow, AssetManagerFunds and Crowdsale Generators contracts, while Investors interact with the Crowdsale and DividendTokens contracts. +```bash +yarn +``` -**Platform Owner\(s\)** +If successful you should see output similar to below: -The owners of the platform are in charge of deciding high level upgrades and authorization changes made in the platform. Ownership can be decided by one owner, a multi-sig, or token holders themselves. +``` +[1/4] Resolving packages... +[2/4] Fetching packages... +[3/4] Linking dependencies... +[4/4] Building fresh packages... +Done in 5.69s. +``` -**Investor** +Then get a local test blockchain running using [Ganache](https://truffleframework.com/ganache) -The investor is any user that holds asset tokens through participating in an asset crowdsale or by means of purchasing them on an exchange. +```bash +yarn blockchain +```` -**AssetManager** +In another terminal window, you can now run the tests: +``` +yarn tests +``` -The AssetManager is a user that initiates a crowdfunding period for an asset. After the funding period, the AssetManager is in charge of handling real world operations between the asset operator and the investors. The role of the AssetManager varies depending on the type of asset, but they are responsible for the asset operating properly if the conditions allow it. The AssetManager can put down tokens in escrow, which is at stake to get burned if the owners of the asset find negligence. +To see code-coverage run: +``` +yarn coverage +``` -**Operator** +## [Roles](contracts/roles) +The MYB SDK's have 4 fundamental roles: -The operator is the producer of the asset, physical or digital. They are in charge of receiving the crowdfunding funds and producing, delivering and installing the asset. AssetManagers will deal with Operators to ensure continued functioning of the asset. +* Investor `must burn MYB to participate` +* AssetManager `must burn MYB to participate` +* Operator `must be registered by owners` +* Platform Owner(s) -✏️ All contracts are written in [Solidity](https://solidity.readthedocs.io/en/v0.4.24/) version 0.4.24. +Investors can contribute ETH or Erc20 tokens to invest in new asset crowdsales. The assets are managed by the AssetManager, who receives a fee for his work and escrows tokens as collateral to investors. The Operator receives funds from the crowdsale and produces and install the asset. Platform owners can choose how assets are governed, and whether or not a contract upgrade should happen. The platform owner can be a single account or a contract governed by many accounts. -### Setup -Install dependencies. +## Setting Up The Platform +Before creating assets, certain variables and parameters have to be set: +* All contracts must be registered in ContractManager before writing to database +* All users must approve the current contract state, which changes everytime a contract is added/updated +* Users must approve ERC20Burner to burn platform tokens before using key functionality +* Platform wallet and platform token must be set +* Operators must be registered and choose which currencies they wish to accept -`yarn` +Basic functionality for these critical operations are outlined below. All contracts are found [here](contracts) -### Testing +### [Database](contracts/database) +Contracts in the SDK store all long-term data in a database contract, which allows for contracts to be upgraded without losing valuable data. The Database stores all data using a bytes32 type, which is often the keccak256 hash of the variableName, ID, address that make up that variable. -Bootstrap [Ganache](https://truffleframework.com/ganache) +Storing an unsigned integer looks like this: +```javascript + database.setUint(keccak256(abi.encodePacked("fundingDeadline", assetID)), 20000000); +``` -`yarn blockchain` +The [Database](contracts/database/Database.sol) stores this with `key = sha3("fundingDeadline", assetID)` and `value = 20000000` +```javascript +function setUint(bytes32 _key, address _value) +onlyApprovedContract +external { + uintStorage[_key] = _value; +} +``` -Run tests +### [API](contracts/database/API.sol) +The API contract can be used to easily fetch variables from the database +```javascript + function getAssetFundingDeadline(bytes32 _assetID) + public + view + returns(uint) { + uint fundingDeadline = database.uintStorage(keccak256(abi.encodePacked("fundingDeadline", _assetID))); + return fundingDeadline; + } +``` -`yarn test` +### [ContractManagement](contracts/database/ContractManager.sol) +To give a contract write access to the database, you must call `addContract(contractName, contractAddress)` from a platform owner account +```javascript + function addContract(string _name, address _contractAddress) + external + isTrue(_contractAddress != address(0)) + isTrue(bytes(_name).length != uint(0)) + anyOwner { + require(!database.boolStorage(keccak256(abi.encodePacked("contract", _contractAddress)))); + require(database.addressStorage(keccak256(abi.encodePacked("contract", _name))) == address(0)); + database.setAddress(keccak256(abi.encodePacked("contract", _name)), _contractAddress); + database.setBool(keccak256(abi.encodePacked("contract", _contractAddress)), true); + bytes32 currentState = database.bytes32Storage(keccak256(abi.encodePacked("currentState"))); + bytes32 newState = keccak256(abi.encodePacked(currentState, _contractAddress)); + database.setBytes32(keccak256(abi.encodePacked("currentState")), newState); + emit LogContractAdded(_contractAddress, _name, block.number); + } +``` -### Compiling +Everytime a contract is added or updated the contract state will change, requiring approval from users before they interact with the platform. Users can also choose to ignore future state changes. This can be done by calling the following function: + +```javascript + function setContractStatePreferences(bool _acceptCurrentState, bool _ignoreStateChanges) + external + returns (bool) { + bytes32 currentState = database.bytes32Storage(keccak256(abi.encodePacked("currentState"))); + database.setBool(keccak256(abi.encodePacked(currentState, msg.sender)), _acceptCurrentState); + database.setBool(keccak256(abi.encodePacked("ignoreStateChanges", msg.sender)), _ignoreStateChanges); + emit LogContractStatePreferenceChanged(msg.sender, _acceptCurrentState, _ignoreStateChanges); + return true; + } +``` -`yarn compile` +### [TokenBurning](contracts/access/ERC20Burner.sol) +To create new asset orders, or purchase existing asset orders, users must provably burn MYB using the [burner](contracts/access/ERC20Burner.sol). To do this each user must approve the burner contract to burn tokens by calling the MYB contract: -### Code Coverage +```javascript + function approve(address _spender, uint256 _value) public returns (bool) { + allowed[msg.sender][_spender] = _value; + emit Approval(msg.sender, _spender, _value); + return true; + } +``` -Download solidity-coverage locally +* spender in this case should be the address of the ERC20Burner contract. value should be placed high enough to avoid needing to approve the burner every use + +Tokens are burnt before the function runs due to the modifier `burnRequired` which calls `burn()` at the [burner](contracts/access/ERC20Burner.sol) contract: +```javascript + function burn(address _tokenHolder, uint _amount) + external + onlyPlatformContracts(msg.sender) + acceptedState(_tokenHolder) + returns (bool) { + require(token.burnFrom(_tokenHolder, _amount)); + emit LogMYBBurned(_tokenHolder, msg.sender, _amount); + return true; + } +``` -`npm install --save-dev solidity-coverage` +Functions that require burning: +- `CrowdsaleGeneratorETH.createAssetOrderETH()` +- `CrowdsaleETH.buyAssetOrderETH()` +- `CrowdsaleGeneratorERC20.createAssetOrderERC20()` +- `CrowdsaleERC20.buyAssetOrderERC20()` +- `AssetExchange.buyAsset()` +- `AssetExchange.createBuyOrder()` + +### [Platform-Variables](contracts/ecosystem/PlatformFunds.sol) +Before assets can be funded the platform owners must set the `platform token` and the `platform wallet` by using: + +```javascript + function setPlatformWallet(address _walletAddress) + external + onlyOwner { + database.setAddress(keccak256(abi.encodePacked("platformWallet")), _walletAddress); + emit LogPlatformWallet(_walletAddress); + } +``` +:heavy_plus_sign: + +```javascript + // @notice + function setPlatformToken(address _tokenAddress) + external + onlyOwner { + database.setAddress(keccak256(abi.encodePacked("platformToken")), _tokenAddress); + emit LogPlatformToken(_tokenAddress); + } +``` +### [Onboarding Operators](contracts/roles/Operator.sol) +The Operator must be registered and define what currencies they are willing to receive as payment. To set the operators you can call: + +```javascript +function registerOperator(address _operatorAddress, string _operatorURI) +external +onlyOwner { + require(_operatorAddress != address(0)); + bytes32 operatorID = keccak256(abi.encodePacked(_operatorURI)); + require(database.addressStorage(keccak256(abi.encodePacked("operator", operatorID))) == address(0)); + database.setAddress(keccak256(abi.encodePacked("operator", operatorID)), _operatorAddress); + database.setBytes32(keccak256(abi.encodePacked("operator", _operatorAddress)), operatorID); + emit LogOperatorRegistered(operatorID, _operatorURI); +} +``` -Run solidity-coverage +To choose which currencies the operator would like to accept they can call: -`./node_modules/.bin/solidity-coverage` +```javascript +function acceptERC20Token(bytes32 _operatorID, address _tokenAddress, bool _accept) +external +onlyOperator(_operatorID) +returns (bool) { + database.setBool(keccak256(abi.encodePacked("acceptsToken", _operatorID, _tokenAddress)), _accept); + return true; +} +``` +OR +```javascript +function acceptEther(bytes32 _operatorID, bool _accept) +external +onlyOperator(_operatorID) +returns (bool) { + database.setBool(keccak256(abi.encodePacked("acceptsEther", _operatorID)), _accept); + return true; +} +``` +:heavy_exclamation_mark: The Operator can choose to accept Ether and an unlimited number of ERC20 tokens if they want. + +## Creating Assets +To create assets you will use [CrowdsaleGeneratorETH](contracts/crowdsale/CrowdsaleGeneratorETH) or [CrowdsaleGeneratorERC20](contracts/crowdsale/CrowdsaleGeneratorERC20) + +For Ether based crowdsales you would call `createAssetOrderETH()` from the AssetManager account, effectively creating a new crowdsale +```javascript + function createAssetOrderETH(string _assetURI, bytes32 _operatorID, uint _fundingLength, uint _amountToRaise, uint _assetManagerPerc) + external + burnRequired + returns (bool) { + require(_amountToRaise > 0); + require(_assetManagerPerc < 100); + require(database.boolStorage(keccak256(abi.encodePacked("acceptsEther", _operatorID)))); + require(database.addressStorage(keccak256(abi.encodePacked("operator", _operatorID))) != address(0)); + bytes32 assetID = keccak256(abi.encodePacked(msg.sender, _amountToRaise, _operatorID, _assetURI)); + require(database.uintStorage(keccak256(abi.encodePacked("fundingDeadline", assetID))) == 0); + address assetAddress = address(new DividendToken(_assetURI, database.addressStorage(keccak256(abi.encodePacked("contract", "CrowdsaleETH"))))); // Gives this contract all new asset tokens + database.setUint(keccak256(abi.encodePacked("fundingDeadline", assetID)), now.add(_fundingLength)); + uint assetManagerFee = _amountToRaise.mul(uint(100).mul(scalingFactor).div(uint(100).sub(_assetManagerPerc)).sub(scalingFactor)).div(scalingFactor); + database.setUint(keccak256(abi.encodePacked("assetManagerFee", assetID)), assetManagerFee); + database.setUint(keccak256(abi.encodePacked("amountToRaise", assetID)), _amountToRaise); + database.setAddress(keccak256(abi.encodePacked("tokenAddress", assetID)), assetAddress); + database.setBytes32(keccak256(abi.encodePacked("assetTokenID", assetAddress)), assetID); + database.setAddress(keccak256(abi.encodePacked("assetManager", assetID)), msg.sender); + database.setAddress(keccak256(abi.encodePacked("operator", assetID)), database.addressStorage(keccak256(abi.encodePacked("operator", _operatorID)))); + emit LogAssetFundingStarted(assetID, msg.sender, _assetURI, address(assetAddress)); + return true; + } +``` -Coverage reports can be accessed at 'coverage/index.html' +## Funding Assets +To fund an asset you can use either [CrowdsaleETH](contracts/crowdsale/crowdsaleETH) or [CrowdsaleERC20](contracts/crowdsale/CrowdsaleERC20) + +For Ether based crowdsales you would call `buyAssetOrderETH()` from the investor account: +```javascript + function buyAssetOrderETH(bytes32 _assetID) + external + payable + requiresEther + validAsset(_assetID) + beforeDeadline(_assetID) + notFinalized(_assetID) + burnRequired + returns (bool) { + EtherDividendInterface assetToken = EtherDividendInterface(database.addressStorage(keccak256(abi.encodePacked("tokenAddress", _assetID)))); + uint amountToRaise = database.uintStorage(keccak256(abi.encodePacked("amountToRaise", _assetID))); + uint tokensRemaining = amountToRaise.sub(assetToken.totalSupply()); + if (msg.value >= tokensRemaining) { + // Give assetManager his portion of tokens + require(assetToken.mint(database.addressStorage(keccak256(abi.encodePacked("assetManager", _assetID))), database.uintStorage(keccak256(abi.encodePacked("assetManagerFee", _assetID))))); + require(finalizeCrowdsale(_assetID)); // delete unnecessary variables + require(assetToken.mint(msg.sender, tokensRemaining)); // Send remaining asset tokens + require(assetToken.finishMinting()); + require(payoutETH(_assetID, amountToRaise)); // 1 token = 1 wei + msg.sender.transfer(msg.value.sub(tokensRemaining)); // Return leftover WEI after cost of tokens calculated and subtracted from msg.value + } + else { + require(assetToken.mint(msg.sender, msg.value)); + } + emit LogAssetPurchased(_assetID, msg.sender, msg.value); + return true; +} +``` -### Documentation +If the funding fails you can call `refund()` , which sends all funds to the asset-token contract to be redistributed to investors + +## Distributing Revenue +By default all assets generated on the platform are able to receive payments and distribute revenue equally to token holders. It accomplishes this by keeping track of how much value (WEI/Token) is contained in each asset-token. The token contract can receive payment in it's fallback function or by calling `issueDividends()` + +Investors an withdraw income by calling `withdraw()` which updates their personal ledger: +```javascript + function withdraw() + public + updateIncomeClaimed(msg.sender) + returns (bool) { + uint amount = incomeOwed[msg.sender].div(scalingFactor); + delete incomeOwed[msg.sender]; + emit LogIncomeCollected(msg.sender, amount); + msg.sender.transfer(amount); + return true; + } +``` -```text +## In-Development +:construction: The SDK's are a work in progress and we hope to implement more features such as asset-governance, platform-governance and obfuscated asset authentication. + +### [Governance](contracts/ownership) +We are working on giving investors governance tools to vote for new AssetManagers if the need arises. Voting is based on token holdings and can be accomplished by approving a function call at a particular contract: +```javascript + function voteForExecution(address _executingContract, bytes32 _assetID, bytes4 _methodID, bytes32 _parameterHash, uint _amountToLock) + external + validAsset(_assetID) + returns (bool) { + bytes32 executionID = keccak256(abi.encodePacked(_executingContract, _assetID, _methodID, _parameterHash)); + bytes32 numVotesID = keccak256(abi.encodePacked("voteTotal", executionID)); + bytes32 investorVotesID = keccak256(abi.encodePacked("investorVotes", executionID, msg.sender)); + uint256 numVotes = database.uintStorage(numVotesID); + uint256 investorVotes = database.uintStorage(investorVotesID); + require(lockTokens(_assetID, msg.sender, _amountToLock)); + database.setUint(numVotesID, numVotes.add(_amountToLock)); + database.setUint(investorVotesID, investorVotes.add(_amountToLock)); + return true; + } +``` + +* executingContract = The address of the contract, where the function is to be called +* assetID = The ID of the asset in question +* methodID = The function signature of the funtion to be called ie. `bytes4(sha3("exampleFunction(address, uint256, bool)"))` +* parameterHash = The sha3 hash of the exact parameters to be called at that function +* amountToLock - The number of asset-tokens this investor wishes to lock towards this function call + +✏️ All contracts are written in [Solidity](https://solidity.readthedocs.io/en/v0.4.24/) version 0.4.24. + + + + + +## Documentation +Documentation is created using [Solidity-Docgen](https://github.com/OpenZeppelin/solidity-docgen) +``` cd docs/website yarn build ``` @@ -86,18 +363,7 @@ GIT_USER= \ ## Live example test-net contracts -* [InitialVariables](https://ropsten.etherscan.io/address/0x9e6606dedcf9d4960f8652abe2d624a048231841#code) -* [UserAccess](https://ropsten.etherscan.io/address/0xb14c50bb7530c71e14f28498bad1f65d10b5b3a9#code) -* [API](https://ropsten.etherscan.io/address/0x139ebd700b089f51a9dd90c0403e5326b1426f3b#code) -* [AssetCreation](https://ropsten.etherscan.io/address/0x011d426358f1982e327648506d3fdae01d054297#code) -* [FundingHub](https://ropsten.etherscan.io/address/0xb94bd7c5ca000beeff27db7cebb9c03749901f19#code) -* [MyBitToken](https://ropsten.etherscan.io/address/0xbb07c8c6e7cd15e2e6f944a5c2cac056c5476151#code) -* [TokenFaucet](https://ropsten.etherscan.io/address/0x564a7464b6ea98259aae1ad4aa8a11ca9b502cf8#code) - -#### ⚠️ Warning -This application is unstable and has not undergone any rigorous security audits. Use at your own risk. +⚠️ This application is unstable and has not undergone any rigorous security audits. Use at your own risk. MyBit Platform™ CHE-177.186.963 - - diff --git a/UpdateProcess.md b/UpdateProcess.md new file mode 100644 index 00000000..88dce6e8 --- /dev/null +++ b/UpdateProcess.md @@ -0,0 +1,151 @@ +# Process for updating git repositories and npm packages + +When contracts are added/changed we have to make the following changes to these repositories: +- MyBit-Network.tech +- MyBit-Chain.tech +- network.js +- hello-network + +## 1) Update migrations/export chain: +- Make sure any contracts that need to be deployed on the + local chain are included in *migrations/2_deploy_protocol.js*. + This includes importing the contract, setting a contract variable, + deploying it inside the chain of promises, and exporting the address + into addresses.json + +- In terminal, run: + +```bash +./export_chain ../MyBit-Chain.tech +``` +*substitute ../MyBit-Chain.tech with whataver directory the chain is in* + +- This will also push the changes to the respository if a .git file is present + +## 2) Update lib/index.js and lib/js/: +- If there are any new contracts we need to update the files that export the ABI's + for use by network.js + +- In terminal, run: + +```bash +scripts/prepare_lib.sh +``` + +- This will generate the js files and index.js that will be used in the npm package. + +## 3) Update git: +```bash +git add -u +git add contracts/. +git commit -m "New update description" +git push origin master +``` + +## 4) Publish to NPM: + - If the package is ready to be published, run the following: + +```bash +npm version patch +npm publish --access=public +``` + +## 5) Move to MyBit-Chain.tech directory, and publish to NPM: +```bash +npm version patch +npm publish --access=public +``` +*the chain should already have been pushed to the repository* + +## 6) Move to network.js, update API: +- If you want the new contracts to be exposed by the API you'll need to update + index.js. + +- First you must set up your contract artifacts. Under the section commented + as *//Setup contracts*, create your contract object, e.g.: + +```javascript +var exampleContract = contract(ContractArtifacts.Example); +``` + +- Where 'exampleContract' is the name you'll be referencing when instatiating + contracts in your functions and 'ContractArtifacts.Example' is the variable + exported by @mybit/contracts. 'ContractArtifacts' is what we call @mybit/contracts + when it is imported, and 'Example' is just the file name of the contract + without the file type ('.sol'). + +- Next you'll want to build functions that expose the contract in the API. One + option is to simply instatiate the contract and the return the object. This + will expose all the contract's functions to the end user. For example: + +```javascript +example: async () => { + return await exampleContract.at(Chain.Example()); +} +``` + +- In this example we are just instatiating the contract that exists at Chain.Example(), + which is the address that is generated in *migrations/2_deploy_protocol.js*, which + we ran at the very beginning of this guide. Since we are returning the whole + contract we can call any function inside Example.sol. So if we import network.js + into a script as 'Network' we can call our function like so: + +```javascript +example = await Network.example(); +result = await example.function(parameter); +``` + +- Alternatively, one can expose functions directly in our API. If we go back to + *network.js/index.js* we can make the following function: + +```javascript +someFunction: async (parameter) => { + instance = await exampleContract.at(Chain.Example()); + result = await instance.function(parameter); + return result; +} +``` + +- Now we can access the function directly in our scripts: + +```javascript +result = await Network.someFunction(parameter); +``` + +## 7) Update package.json and publish to NPM: +- Since we are using new npm packages, we need to update the version numbers in + package.json. You can update @mybit/contracts and @mybit/chain to the most recent + versions. + +- Update network.js to git: +```bash +git add -u +git commit -m "Added example function" +git push origin master +``` + +- Now publish on npm: +```bash +npm version patch +npm publish --access=public +``` + +## 8) Update examples in hello-network: +- If you want to show examples and use cases for the new functions you wrote + in the API, you can add them here. + +- After creating examples, update package.json to reference the newest version + of network.js. + +- Then update git: +```bash +git add . +git commit -m "New stuff" +git push origin master +``` + +- Then publish to npm: +```bash +npm version patch +npm publish --access=public +``` diff --git a/accounts.json b/accounts.json index c0ddd8c5..1954395e 100644 --- a/accounts.json +++ b/accounts.json @@ -1,12 +1,12 @@ [ - "0x34b4c0cf65a762f3042070a03425ab4bffe0170c", - "0x44067107f06443e6d125352bbf95de0c133456f8", - "0x02c4039e7d59b00e20f0f1dade6265c5a27ea715", - "0x9d01aafb060b3b76dc8e546b0550b68e8d7c529b", - "0xb220118ca37c21717fd09d9fc01fbb98d9b1f930", - "0x2fd989874137f24325474df1a3aacae508e3e2ce", - "0x6925b5a5cc617e466437a39ffb9c82a56c89e0a9", - "0xe42cd23ef408bf91042f3bb643db512c36d7a42e", - "0xee3cc3822bfeb1567ded5c507eba3a9c680988e7", - "0x20a698e36ae9bce21d5a00f87a98876a0e21af4e" + "0xeed17b217b1e0c63b1b525d8d2e59cad0546432d", + "0x0ec0e59bd4faf0a136c2ee638f3fcff19972a304", + "0xe273d3d13d69f82b8071365e110e13c0fbde0c59", + "0x4cbe9306228ff003fe5a47fe66f2e3d3162f0f37", + "0x0dcea99d96046de44f1ab2a4bf9b3e21f3ac2924", + "0x8bd581cca82af7cfff8ab46591803fe2f2061218", + "0xd6a41e3da4bdc4a27d5707b08612925347f5934f", + "0xd0702a4258c574ff15df4e65000dbb16843cbd24", + "0xc3dda1fc00ba83300b9ad2d00faa30166fabc657", + "0x45543e02e26442e6c95e3145f7d30a53b284f418" ] \ No newline at end of file diff --git a/addresses.json b/addresses.json index bcbaeeb0..de12e952 100644 --- a/addresses.json +++ b/addresses.json @@ -1,18 +1,18 @@ { - "MyBit": "0x1251954ebb35a93414c4fdd6eb572f9292f79bcf", - "ERC20Burner": "0xc263fabff96e5b4a11704478816c874fda9c4177", - "Database": "0x3f4c458f7adc3ce2300cd9fa7ab2c218d04ea18d", - "ContractManager": "0x346505e54761981543be0cd304d3c123887c6e99", - "API": "0xa12d771ffb785ad139dbe082be83259b7a0da142", - "SingleOwned": "0x5bb4c507e7a64c7db50f3a398dc80f399e9c968a", - "Pausible": "0x23ecf8d2811058b790f97fe3c307c16b8e41649e", - "AccessHierarchy": "0x24d2a3416e8b073dfc557fcf0b72cd73c4ae12c1", - "PlatformFunds": "0x6bbb45d95ddbb7a015d10257f66d13936212e64d", - "Operators": "0xbc135c1965c54aca5777aa750bf7863f23e074b3", - "AssetManagerEscrow": "0x172a12d553dd2a57a4227005972340dafcfcf14d", - "CrowdsaleETH": "0xdcf1b48d5bacfd16be0d03f68e0c748e08c79fb1", - "CrowdsaleGeneratorETH": "0x0ff213559567c2787abd8fb42ff46777fe978307", - "CrowdsaleERC20": "0xd5b03029ad72aa013cbcd5a8dd31f6a5cca04f45", - "CrowdsaleGeneratorERC20": "0xa1a8c7e4c9b1cb580428f3326dec41fc1b53391f", - "AssetExchange": "0x75fcdea05c36b0bdcbf1cd341b6cb7b846a885a3" + "MyBit": "0x82e8ed40b49fa4682d58807e99eaed6daf20b1d4", + "ERC20Burner": "0xfa3066aa522b18e0243f7c098e9c72fa85c89ae2", + "Database": "0xf3a985536aa63fcc5e0732fef35a9d6e0881682c", + "ContractManager": "0x8397e224cc3f2560d6c989bc29bb6800517d6f97", + "API": "0x94e839af9b8ec45da92d8a76e0acd1ca45b710c5", + "SingleOwned": "0x6df2e96b18b909e6127137a4a8ddf40eb259b610", + "Pausible": "0xbea6ba1b1aa691fc07a5b722bc491df03f4c280a", + "AccessHierarchy": "0xe4f4aeefd5087eababbd73bdd4c8188cbd008ebb", + "PlatformFunds": "0x7bd53d17ebee6c87d9937c8cb4fb04297cdc83c2", + "Operators": "0x54ae7cc1c7ec065a84b84ea7f9e33a14cf3d95e6", + "AssetManagerEscrow": "0x860b672a9fcb0f12c156cc9c233cfc3ed18fc202", + "CrowdsaleETH": "0x8af6ac104c639a9011b83f3baf789271e6df6198", + "CrowdsaleGeneratorETH": "0xeed31156aa0eeb2ebf473cd16faf70d2bf463137", + "CrowdsaleERC20": "0x03a685558ffd806ca2c44ab5f2ebe84688b82d57", + "CrowdsaleGeneratorERC20": "0xede40300bea9631bddbf1ab91ca286b5cd591d14", + "AssetExchange": "0x57bff4f318c5fb88e742d89627ad0b3ee62ab536" } \ No newline at end of file diff --git a/contracts/README.md b/contracts/README.md index aa42f3db..ada7a8fd 100644 --- a/contracts/README.md +++ b/contracts/README.md @@ -2,47 +2,34 @@ :wrench: Block-end developer tools -MyBit SDK allows developers to create personalized platforms which create and distribute income using tokenized assets on the Ethereum virtual machine. Using these tools front-end developers can build decentralized asset management platforms of their own using MyBit deploy scripts and API's. - ## Contract Categories -### Access - -Access is where user access is managed. KYC restrictions can be applied across the platform using KYC.sol. Requirements can be set here, restricting access to users who can probably burn platform tokens, or pay for a time-based subscription. - -### Crowdsale +### [Access](access) +Access is where user access is managed. KYC access restriction can be applied to users who can probably burn platform tokens, or pay for a time-based subscription. +### [Crowdsale](crowdsale) In the crowdsale folder you can find all the contracts involved in funding new assets. Funds can be received in either Ether or any ERC20 token the operator agrees to accept. Each base unit of the received tokens or Wei represent 1 share of the asset. The total supply of each asset is determined by the amount raised plus the Asset Managers fee. -### Database - +### [Database](database) The database folder contains all contracts that abstract storage away from the logical 'front-end' contracts. When deploying the database, you can choose to have an upgradeable platform or a non-upgradeable. Write privileges to the database are determined by the contract manager, which is managed by the owner/owners of the platform. -### Ecosystem - -The ecosystem folder contains all the non-core contracts that are used for the on-boarding of non-platform assets, asset-exchange, staking, and platform payment and token controls. Before funding assets the platform-token and the platform-wallet need to be set. - -### Interfaces +### [Ecosystem](ecosystem) +The ecosystem folder contains all the non-core contracts that are used for the on-boarding of non-platform assets, asset-exchange, staking, and platform payment and token controls. Before funding assets the platform-token and the platform-wallet need to be set. +### [Interfaces](interfaces) All interfaces that our contracts use to interact with other deployed contracts. -### Math - +### [Math](math) Math contracts are helper libraries for performing arithmetic without worrying about overflows and underflows. -### Ownership - -Contracts for controlling the platform \(such as updating or pausing contracts\) by a single account, multiple accounts or ERC20 token holders. Investors holding asset-tokens can vote to choose or fire their current Asset Manager here. - -### Roles +### [Ownership](ownership) +Contracts for controlling the platform (such as updating or pausing contracts) by a single account, multiple accounts or ERC20 token holders. Investors holding asset-tokens can vote to choose or fire their current Asset Manager here. +### [Roles](roles) Asset Managers and Operators can control their funding preferences in the roles contracts. Asset Managers fees are held here to prevent them from transferring away the tokens. -### Test - +### [Test](test) Contracts that are only used for local testing to ensure full code coverage of the platform contracts. -### Tokens - +### [Tokens](tokens) Token contracts are used to represent fungible divisible assets. Tokens representing assets can be burnable, mintable, governed, and can receive ETH or ERC20 tokens as payment. The payment is distributed to asset-token holders according to their holdings. - diff --git a/contracts/crowdsale/CrowdsaleERC20.sol b/contracts/crowdsale/CrowdsaleERC20.sol index cc01716b..3f65c26c 100644 --- a/contracts/crowdsale/CrowdsaleERC20.sol +++ b/contracts/crowdsale/CrowdsaleERC20.sol @@ -45,7 +45,6 @@ contract CrowdsaleERC20{ require(assetToken.mint(database.addressStorage(keccak256(abi.encodePacked("assetManager", _assetID))), database.uintStorage(keccak256(abi.encodePacked("assetManagerFee", _assetID))) )); require(finalizeCrowdsale(_assetID)); require(assetToken.mint(msg.sender, tokensRemaining)); // Send remaining asset tokens to investor - // Give assetManager his portion of tokens require(assetToken.finishMinting()); require(payoutERC20(_assetID, amountToRaise)); // 1 token = 1 wei } diff --git a/contracts/crowdsale/CrowdsaleGeneratorERC20.sol b/contracts/crowdsale/CrowdsaleGeneratorERC20.sol index f8ecdf3f..cd58c8e7 100644 --- a/contracts/crowdsale/CrowdsaleGeneratorERC20.sol +++ b/contracts/crowdsale/CrowdsaleGeneratorERC20.sol @@ -34,9 +34,10 @@ contract CrowdsaleGeneratorERC20 { // @param (address) _fundingToken = The ERC20 token to be used to fund the crowdsale (Operator must accept this token as payment) function createAssetOrderERC20(string _assetURI, bytes32 _operatorID, uint _fundingLength, uint _amountToRaise, uint _assetManagerPerc, address _fundingToken) external - isTrue(_assetManagerPerc < 100) - isTrue(database.boolStorage(keccak256(abi.encodePacked("acceptsToken", _operatorID, _fundingToken)))) burnRequired { + require(_amountToRaise > 0); + require(_assetManagerPerc < 100); + require(database.boolStorage(keccak256(abi.encodePacked("acceptsToken", _operatorID, _fundingToken)))); require(database.addressStorage(keccak256(abi.encodePacked("operator", _operatorID))) != address(0)); bytes32 assetID = keccak256(abi.encodePacked(msg.sender, _amountToRaise, _operatorID, _assetURI)); require(database.uintStorage(keccak256(abi.encodePacked("fundingDeadline", assetID))) == 0); @@ -58,12 +59,6 @@ contract CrowdsaleGeneratorERC20 { // Modifiers ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // @notice reverts if _conditional isn't true - modifier isTrue(bool _conditional){ - require(_conditional); - _; - } - // @notice reverts if AssetManager hasn't approved burner to burn platform token modifier burnRequired { //emit LogSig(msg.sig); diff --git a/contracts/crowdsale/CrowdsaleGeneratorETH.sol b/contracts/crowdsale/CrowdsaleGeneratorETH.sol index 2e92a9a8..87eab960 100644 --- a/contracts/crowdsale/CrowdsaleGeneratorETH.sol +++ b/contracts/crowdsale/CrowdsaleGeneratorETH.sol @@ -33,10 +33,11 @@ contract CrowdsaleGeneratorETH { // @param (uint) _assetManagerPerc = The percentage of the total revenue which is to go to the AssetManager if asset is a success function createAssetOrderETH(string _assetURI, bytes32 _operatorID, uint _fundingLength, uint _amountToRaise, uint _assetManagerPerc) external - isTrue(_assetManagerPerc < 100) - isTrue(database.boolStorage(keccak256(abi.encodePacked("acceptsEther", _operatorID)))) burnRequired returns (bool) { + require(_amountToRaise > 0); + require(_assetManagerPerc < 100); + require(database.boolStorage(keccak256(abi.encodePacked("acceptsEther", _operatorID)))); require(database.addressStorage(keccak256(abi.encodePacked("operator", _operatorID))) != address(0)); bytes32 assetID = keccak256(abi.encodePacked(msg.sender, _amountToRaise, _operatorID, _assetURI)); require(database.uintStorage(keccak256(abi.encodePacked("fundingDeadline", assetID))) == 0); @@ -47,7 +48,7 @@ contract CrowdsaleGeneratorETH { database.setUint(keccak256(abi.encodePacked("amountToRaise", assetID)), _amountToRaise); database.setAddress(keccak256(abi.encodePacked("tokenAddress", assetID)), assetAddress); database.setBytes32(keccak256(abi.encodePacked("assetTokenID", assetAddress)), assetID); - database.setAddress(keccak256(abi.encodePacked("assetManager", assetID)), msg.sender); // Make this a require() if want to enforce escrow + database.setAddress(keccak256(abi.encodePacked("assetManager", assetID)), msg.sender); database.setAddress(keccak256(abi.encodePacked("operator", assetID)), database.addressStorage(keccak256(abi.encodePacked("operator", _operatorID)))); emit LogAssetFundingStarted(assetID, msg.sender, _assetURI, address(assetAddress)); return true; @@ -57,12 +58,8 @@ contract CrowdsaleGeneratorETH { // Modifiers ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - modifier isTrue(bool _conditional){ - require(_conditional); - _; - } - + // @notice reverts if asset manager is unable to burn pp modifier burnRequired { //emit LogSig(msg.sig); require(burner.burn(msg.sender, database.uintStorage(keccak256(abi.encodePacked(msg.sig, address(this)))))); diff --git a/contracts/roles.md b/contracts/roles.md index cca90b1f..7e4d5287 100644 --- a/contracts/roles.md +++ b/contracts/roles.md @@ -11,6 +11,19 @@ THe AssetManagerFunds are where the dividends belonging to the AssetManager are The AssetManagerEscrow contract accepts MYB tokens to be held in escrow in order to align the assetManager's incentives with investors. If an asset is not distributing returns, investors can vote to burn the assetManager's MYB placed in escrow. If the asset does give ROI, the assetManager's escrow funds are returned relative to the ROI earned. If the asset is governed, the owners of the asset-tokens can vote to change the AssetManager here. ### Operators - This contract is used the platform owner to onboard new operators. An operator ID is needed for any new asset crowdsales to be created. Operators can choose if they wish to receive Ether and/or ERC20 tokens of their choosing. + +## General roles + +#### Platform Owner(s) +The owners of the platform are in charge of deciding high level upgrades and authorization changes made in the platform. Ownership can be decided by one owner, a multi-sig, or token holders themselves. + +#### Investor +The investor is any user that holds asset tokens through participating in an asset crowdsale or by means of purchasing them on an exchange. + +#### AssetManager +The AssetManager is a user that initiates a crowdfunding period for an asset. After the funding period, the AssetManager is in charge of handling real world operations between the asset operator and the investors. The role of the AssetManager varies depending on the type of asset, but they are responsible for the asset operating properly if the conditions allow it. The AssetManager can put down tokens in escrow, which is at stake to get burned if the owners of the asset find negligence. + +#### Operator +The operator is the producer of the asset, physical or digital. They are in charge of receiving the crowdfunding funds and producing, delivering and installing the asset. AssetManagers will deal with Operators to ensure continued functioning of the asset. diff --git a/contracts/roles/AssetManagerFunds.sol b/contracts/roles/AssetManagerFunds.sol index f72b910e..bfafe2f6 100644 --- a/contracts/roles/AssetManagerFunds.sol +++ b/contracts/roles/AssetManagerFunds.sol @@ -14,19 +14,25 @@ interface DToken { // @title A dividend-token holding contract that locks tokens and retrieves dividends for assetManagers // @notice This contract receives newly minted tokens and retrieves Ether or ERC20 tokens received from the asset -// @dev Tokens +// @author Kyle Dewhurst & Peter Phillips, MyBit Foundation contract AssetManagerFunds { using SafeMath for uint256; DBInterface public database; + uint256 private transactionNumber; + + // @notice constructor: initializes database constructor(address _database) public { database = DBInterface(_database); } + // @notice asset manager can withdraw his dividend fee from assets here + // @param : bytes32 _assetID = the ID of this asset on the platform function withdraw(bytes32 _assetID) external + nonReentrant returns (bool) { require(msg.sender == database.addressStorage(keccak256(abi.encodePacked("assetManager", _assetID)))); DToken token = DToken(database.addressStorage(keccak256(abi.encodePacked("tokenAddress", _assetID)))); @@ -55,8 +61,9 @@ contract AssetManagerFunds { function retrieveAssetManagerTokens(bytes32[] _assetID) external + nonReentrant returns (bool) { - require(_assetID.length < 50); + require(_assetID.length <= 42); uint[] memory payoutAmounts = new uint[](_assetID.length); address[] memory tokenAddresses = new address[](_assetID.length); uint8 numEntries; @@ -88,8 +95,9 @@ contract AssetManagerFunds { function retrieveAssetManagerETH(bytes32[] _assetID) external + nonReentrant returns (bool) { - require(_assetID.length < 50); + require(_assetID.length <= 93); uint weiOwed; for(uint8 i = 0; i < _assetID.length; i++){ require(msg.sender == database.addressStorage(keccak256(abi.encodePacked("assetManager", _assetID[i])))); @@ -106,6 +114,7 @@ contract AssetManagerFunds { return true; } + // @notice returns the index if the address is in the list, otherwise returns list length + 1 function containsAddress(address[] _addressList, address _addr) internal pure @@ -116,6 +125,15 @@ contract AssetManagerFunds { return uint8(_addressList.length + 1); } + + // @notice prevents calls from re-entering contract + modifier nonReentrant() { + transactionNumber += 1; + uint256 localCounter = transactionNumber; + _; + require(localCounter == transactionNumber); + } + function () payable public {} diff --git a/contracts/tokens/erc20/MintableToken.sol b/contracts/tokens/erc20/MintableToken.sol index c13aa107..f853b35f 100644 --- a/contracts/tokens/erc20/MintableToken.sol +++ b/contracts/tokens/erc20/MintableToken.sol @@ -10,7 +10,7 @@ import "./StandardToken.sol"; */ contract MintableToken is StandardToken { - bool internal mintingFinished; + bool public mintingFinished; address internal minter; string internal tokenURI; // A reference to a URI containing further token information diff --git a/migrations/2_deploy_protocol.js b/migrations/2_deploy_protocol.js index f43dc45c..dca9c756 100644 --- a/migrations/2_deploy_protocol.js +++ b/migrations/2_deploy_protocol.js @@ -11,6 +11,7 @@ var AccessHierarchy = artifacts.require("./access/AccessHierarchy.sol"); var PlatformFunds = artifacts.require("./ecosystem/PlatformFunds.sol"); var Operators = artifacts.require("./roles/Operators.sol"); var AssetManagerEscrow = artifacts.require("./roles/AssetManagerEscrow.sol"); +var AssetManagerFunds = artifacts.require("./roles/AssetManagerFunds.sol"); var CrowdsaleGeneratorETH = artifacts.require("./crowdsale/CrowdsaleGeneratorETH.sol"); var CrowdsaleETH = artifacts.require("./crowdsale/CrowdsaleETH.sol"); var CrowdsaleGeneratorERC20 = artifacts.require("./crowdsale/CrowdsaleGeneratorERC20.sol"); @@ -145,8 +146,14 @@ module.exports = function(deployer, network, accounts) { console.log('AssetManagerEscrow.sol: ' + escrow.address); cm.addContract('AssetManagerEscrow', escrow.address); - return CrowdsaleGeneratorETH.new(db.address); + return AssetManagerFunds.new(db.address); + + }).then(function(instance) { + var managerFunds = instance; + cm.addContract('AssetManagerFunds', managerFunds.address); + return CrowdsaleGeneratorETH.new(db.address); + }).then(function(instance) { crowdsaleGeneratorETH = instance; diff --git a/package-lock.json b/package-lock.json index 1b1eb2a2..44337e86 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,13 +1,1707 @@ { "name": "@mybit/contracts", - "version": "0.1.1", + "version": "0.1.9", "lockfileVersion": 1, "requires": true, "dependencies": { + "abbrev": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", + "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", + "dev": true + }, + "ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "requires": { + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" + } + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "async": { + "version": "1.5.2", + "resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "requires": { + "tweetnacl": "^0.14.3" + } + }, "bignumber.js": { "version": "7.2.1", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-7.2.1.tgz", "integrity": "sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ==" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" + }, + "browserify-sha3": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/browserify-sha3/-/browserify-sha3-0.0.1.tgz", + "integrity": "sha1-P/NKMAbvFcD7NWflQbkaI0ASPRE=", + "dev": true, + "requires": { + "js-sha3": "^0.3.1" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" + }, + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=" + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "combined-stream": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", + "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", + "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "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=" + }, + "coveralls": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.2.tgz", + "integrity": "sha512-Tv0LKe/MkBOilH2v7WBiTBdudg2ChfGbdXafc/s330djpF3zKOmuehTeRwjXWc7pzfj9FrDUTA7tEx6Div8NFw==", + "requires": { + "growl": "~> 1.10.0", + "js-yaml": "^3.11.0", + "lcov-parse": "^0.0.10", + "log-driver": "^1.2.7", + "minimist": "^1.2.0", + "request": "^2.85.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + } + } + }, + "crypto-js": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.1.8.tgz", + "integrity": "sha1-cV8HC/YBTyrpkqmLOSkli3E/CNU=", + "dev": true + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "death": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", + "integrity": "sha1-AaqcQB7dknUFFEcLgmY5DGbGcxg=", + "dev": true + }, + "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" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "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 + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "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=" + }, + "escodegen": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", + "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", + "dev": true, + "requires": { + "esprima": "^2.7.1", + "estraverse": "^1.9.1", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.2.0" + }, + "dependencies": { + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "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" + } + } + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "estraverse": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", + "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "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==", + "dev": true, + "requires": { + "source-map-support": "^0.5.3" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fast-deep-equal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=" + }, + "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=" + }, + "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 + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fs-extra": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", + "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", + "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.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "ganache-cli": { + "version": "6.1.8", + "resolved": "https://registry.npmjs.org/ganache-cli/-/ganache-cli-6.1.8.tgz", + "integrity": "sha512-yXzteu4SIgUL31mnpm9j+x6dpHUw0p/nsRVkcySKq0w+1vDxH9jMErP1QhZAJuTVE6ni4nfvGSNkaQx5cD3jfg==", + "requires": { + "source-map-support": "^0.5.3" + } + }, + "get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "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" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==" + }, + "handlebars": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.12.tgz", + "integrity": "sha512-RhmTekP+FZL+XNhwS1Wf+bTTZpdLougwt5pcgA1tuz6Jcx0fpH/7z0qd71RKnZHBCxIRBHfBOnio4gViPemNzA==", + "dev": true, + "requires": { + "async": "^2.5.0", + "optimist": "^0.6.1", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4" + }, + "dependencies": { + "async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", + "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "dev": true, + "requires": { + "lodash": "^4.17.10" + } + } + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.0.tgz", + "integrity": "sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==", + "requires": { + "ajv": "^5.3.0", + "har-schema": "^2.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=" + }, + "hosted-git-info": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", + "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==" + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "interpret": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", + "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=" + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "requires": { + "builtin-modules": "^1.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "istanbul": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.4.5.tgz", + "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=", + "dev": true, + "requires": { + "abbrev": "1.0.x", + "async": "1.x", + "escodegen": "1.8.x", + "esprima": "2.7.x", + "glob": "^5.0.15", + "handlebars": "^4.0.1", + "js-yaml": "3.x", + "mkdirp": "0.5.x", + "nopt": "3.x", + "once": "1.x", + "resolve": "1.1.x", + "supports-color": "^3.1.0", + "which": "^1.1.1", + "wordwrap": "^1.0.0" + }, + "dependencies": { + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true + }, + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "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 + }, + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "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" + } + } + } + }, + "js-sha3": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.3.1.tgz", + "integrity": "sha1-hhIoAhQvCChQKg0d7h2V4lO7AkM=", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "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==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "jsonfile": { + "version": "2.4.0", + "resolved": "http://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "keccakjs": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/keccakjs/-/keccakjs-0.2.1.tgz", + "integrity": "sha1-HWM6+QfvMFu/ny+mFtVsRFYd+k0=", + "dev": true, + "requires": { + "browserify-sha3": "^0.0.1", + "sha3": "^1.1.0" + } + }, + "klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "requires": { + "graceful-fs": "^4.1.9" + } + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "requires": { + "invert-kv": "^1.0.0" + } + }, + "lcov-parse": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-0.0.10.tgz", + "integrity": "sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM=" + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + } + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + }, + "lodash.assign": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", + "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=" + }, + "log-driver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", + "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==" + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=" + }, + "mime-db": { + "version": "1.36.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.36.0.tgz", + "integrity": "sha512-L+xvyD9MkoYMXb1jAmzI/lWYAxAMCPvIBSWur0PZ5nOf5euahRLVqH//FKW9mWp2lkqUgYiXPgkzfMUFi4zVDw==" + }, + "mime-types": { + "version": "2.1.20", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.20.tgz", + "integrity": "sha512-HrkrPaP9vGuWbLK1B1FfgAkbqNjIuy4eHlIYnFi7kamZyLLrGlo2mpcx0bBmNpKqBtYtAfGbodDddIgddSJC2A==", + "requires": { + "mime-db": "~1.36.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } + }, + "mocha": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", + "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", + "requires": { + "browser-stdout": "1.3.1", + "commander": "2.15.1", + "debug": "3.1.0", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.5", + "he": "1.1.1", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "supports-color": "5.4.0" + }, + "dependencies": { + "commander": { + "version": "2.15.1", + "resolved": "http://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==" + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "mustache": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/mustache/-/mustache-2.3.2.tgz", + "integrity": "sha512-KpMNwdQsYz3O/SBS1qJ/o3sqUJ5wSb8gb0pul8CO0S56b9Y2ALm8zCfsjPXsqGFfoNBkDwZuZIAjhsZI03gYVQ==" + }, + "nan": { + "version": "2.10.0", + "resolved": "http://registry.npmjs.org/nan/-/nan-2.10.0.tgz", + "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", + "dev": true + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true, + "requires": { + "abbrev": "1" + } + }, + "normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "requires": { + "hosted-git-info": "^2.1.4", + "is-builtin-module": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "dev": true, + "requires": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + }, + "dependencies": { + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "dev": true + } + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + } + }, + "original-require": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/original-require/-/original-require-1.0.1.tgz", + "integrity": "sha1-DxMEcVhM0zURxew4yNWSE/msXiA=" + }, + "os-locale": { + "version": "1.4.0", + "resolved": "http://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "requires": { + "lcid": "^1.0.0" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "requires": { + "error-ex": "^1.2.0" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "requires": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "pegjs": { + "version": "0.10.0", + "resolved": "http://registry.npmjs.org/pegjs/-/pegjs-0.10.0.tgz", + "integrity": "sha1-z4uvrm7d/0tafvsYUmnqr0YQ3b0=", + "dev": true + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "requires": { + "pinkie": "^2.0.0" + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "prop-types": { + "version": "15.6.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.2.tgz", + "integrity": "sha512-3pboPvLiWD7dkI3qf3KbUe6hKFKa52w+AE0VCqECtf+QHAKgOL37tTaNCnuX1nAAQ4ZhyP+kYVKf8rLmJ/feDQ==", + "requires": { + "loose-envify": "^1.3.1", + "object-assign": "^4.1.1" + } + }, + "psl": { + "version": "1.1.29", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz", + "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==" + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, + "react": { + "version": "16.5.2", + "resolved": "https://registry.npmjs.org/react/-/react-16.5.2.tgz", + "integrity": "sha512-FDCSVd3DjVTmbEAjUNX6FgfAmQ+ypJfHUsqUJOYNCBUp1h8lqmtC+0mXJ+JjsWx4KAVTkk1vKd1hLQPvEviSuw==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "schedule": "^0.5.0" + } + }, + "react-dom": { + "version": "16.5.2", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.5.2.tgz", + "integrity": "sha512-RC8LDw8feuZOHVgzEf7f+cxBr/DnKdqp56VU0lAs1f4UfKc4cU8wU4fTq/mgnvynLQo8OtlPC19NUFh/zjZPuA==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "schedule": "^0.5.0" + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "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=", + "requires": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "requires": { + "resolve": "^1.1.6" + } + }, + "req-cwd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-1.0.1.tgz", + "integrity": "sha1-DXOurpJm5penj3l2AZZ352rPD/8=", + "dev": true, + "requires": { + "req-from": "^1.0.1" + } + }, + "req-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/req-from/-/req-from-1.0.1.tgz", + "integrity": "sha1-v4HaUUeUfTLRO5R9wSpYrUWHNQ4=", + "dev": true, + "requires": { + "resolve-from": "^2.0.0" + } + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + }, + "require-from-string": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz", + "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=" + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" + }, + "resolve": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", + "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", + "requires": { + "path-parse": "^1.0.5" + } + }, + "resolve-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=", + "dev": true + }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "requires": { + "glob": "^7.0.5" + } + }, + "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==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "schedule": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/schedule/-/schedule-0.5.0.tgz", + "integrity": "sha512-HUcJicG5Ou8xfR//c2rPT0lPIRR09vVvN81T9fqfVgBmhERUbDEQoYKjpBxbueJnCPpSu2ujXzOnRQt6x9o/jw==", + "requires": { + "object-assign": "^4.1.1" + } + }, + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==" + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "sha3": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/sha3/-/sha3-1.2.2.tgz", + "integrity": "sha1-pmxQmN5MJbyIM27ItIF9AFvKe6k=", + "dev": true, + "requires": { + "nan": "2.10.0" + } + }, + "shelljs": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.2.tgz", + "integrity": "sha512-pRXeNrCA2Wd9itwhvLp5LZQvPJ0wU6bcjaTMywHHGX5XWhVN2nzSu7WV0q+oUY7mGK3mgSkDDzP3MgjqdyIgbQ==", + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + } + }, + "sol-explore": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/sol-explore/-/sol-explore-1.6.2.tgz", + "integrity": "sha1-Q66MQZ/TrAVqBfip0fsQIs1B7MI=", + "dev": true + }, + "solc": { + "version": "0.4.25", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.25.tgz", + "integrity": "sha512-jU1YygRVy6zatgXrLY2rRm7HW1d7a8CkkEgNJwvH2VLpWhMFsMdWcJn6kUqZwcSz/Vm+w89dy7Z/aB5p6AFTrg==", + "requires": { + "fs-extra": "^0.30.0", + "memorystream": "^0.3.1", + "require-from-string": "^1.1.0", + "semver": "^5.3.0", + "yargs": "^4.7.1" + } + }, + "solidity-coverage": { + "version": "0.5.11", + "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.5.11.tgz", + "integrity": "sha512-qikdsSi6+9XbfvwA0aI7HUVpF9fIFNqRWTw23M89GMDY+b6Gj0wWU9IngJS0fimoZIAdEp3bfChxvpfVcrUesg==", + "dev": true, + "requires": { + "death": "^1.1.0", + "ethereumjs-testrpc-sc": "6.1.6", + "istanbul": "^0.4.5", + "keccakjs": "^0.2.1", + "req-cwd": "^1.0.1", + "shelljs": "^0.7.4", + "sol-explore": "^1.6.2", + "solidity-parser-sc": "0.4.11", + "tree-kill": "^1.2.0", + "web3": "^0.18.4" + }, + "dependencies": { + "shelljs": { + "version": "0.7.8", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", + "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", + "dev": true, + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + } + } + } + }, + "solidity-docgen": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/solidity-docgen/-/solidity-docgen-0.1.0.tgz", + "integrity": "sha512-F7ufNWmlP5c5hIi66Ijv9tc+HNosyO7ijWq6pRtyBR1WqyJBH/0DJkD6QZI8HkE8p6LEXiPKxGBWbAeVT9Nu9g==", + "requires": { + "commander": "^2.14.1", + "lodash": "^4.17.5", + "mocha": "^5.0.1", + "mustache": "^2.3.0", + "react": "^16.2.0", + "react-dom": "^16.2.0", + "shelljs": "^0.8.1" + } + }, + "solidity-parser-sc": { + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/solidity-parser-sc/-/solidity-parser-sc-0.4.11.tgz", + "integrity": "sha512-1kV5iC7m3CtMDfmHaVNwz2saSGQVIuF16rIxU417Al38MVCWHMQQ5vT6cmLsNwDe60S74auobWij9vNawSeOyw==", + "dev": true, + "requires": { + "mocha": "^4.1.0", + "pegjs": "^0.10.0", + "yargs": "^4.6.0" + }, + "dependencies": { + "browser-stdout": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", + "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", + "dev": true + }, + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", + "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 + }, + "growl": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", + "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", + "dev": true + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "mocha": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", + "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", + "dev": true, + "requires": { + "browser-stdout": "1.3.0", + "commander": "2.11.0", + "debug": "3.1.0", + "diff": "3.3.1", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.3", + "he": "1.1.1", + "mkdirp": "0.5.1", + "supports-color": "4.4.0" + } + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "^2.0.0" + } + } + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "source-map-support": { + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.9.tgz", + "integrity": "sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA==", + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "spdx-correct": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.2.tgz", + "integrity": "sha512-q9hedtzyXHr5S0A1vEPoK/7l8NpfkFYTq6iCY+Pno2ZbdZR6WexZFtqeVGkGxW3TEJMN914Z55EnAGMmenlIQQ==", + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==" + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.1.tgz", + "integrity": "sha512-TfOfPcYGBB5sDuPn3deByxPhmfegAhpDYKSOXZQN81Oyrrif8ZCodOLzK3AesELnCx03kikhyDwh0pfvvQvF8w==" + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "sshpk": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.15.1.tgz", + "integrity": "sha512-mSdgNUaidk+dRU5MhYtN9zebdzF2iG0cNPWy8HG+W8y+fT1JnSkh0fzzpjOa0L7P8i1Rscz38t0h4gPcKz43xA==", + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "requires": { + "is-utf8": "^0.2.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==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + } + }, + "tree-kill": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.0.tgz", + "integrity": "sha512-DlX6dR0lOIRDFxI0mjL9IYg6OTncLm/Zt+JiBhE5OlFcAR8yc9S7FFXU9so0oda47frdM/JFsk7UjNt9vscKcg==", + "dev": true + }, + "truffle": { + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/truffle/-/truffle-4.1.14.tgz", + "integrity": "sha512-e7tTLvKP3bN9dE7MagfWyFjy4ZgoEGbeujECy1me1ENBzbj/aO/+45gs72qsL3+3IkCNNcWNOJjjrm8BYZZNNg==", + "requires": { + "mocha": "^4.1.0", + "original-require": "1.0.1", + "solc": "0.4.24" + }, + "dependencies": { + "browser-stdout": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", + "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=" + }, + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==" + }, + "diff": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", + "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==" + }, + "growl": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", + "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==" + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" + }, + "mocha": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", + "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", + "requires": { + "browser-stdout": "1.3.0", + "commander": "2.11.0", + "debug": "3.1.0", + "diff": "3.3.1", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.3", + "he": "1.1.1", + "mkdirp": "0.5.1", + "supports-color": "4.4.0" + } + }, + "solc": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.24.tgz", + "integrity": "sha512-2xd7Cf1HeVwrIb6Bu1cwY2/TaLRodrppCq3l7rhLimFQgmxptXhTC3+/wesVLpB09F1A2kZgvbMOgH7wvhFnBQ==", + "requires": { + "fs-extra": "^0.30.0", + "memorystream": "^0.3.1", + "require-from-string": "^1.1.0", + "semver": "^5.3.0", + "yargs": "^4.7.1" + } + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "requires": { + "has-flag": "^2.0.0" + } + } + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "uglify-js": { + "version": "3.4.9", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz", + "integrity": "sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q==", + "dev": true, + "optional": true, + "requires": { + "commander": "~2.17.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "commander": { + "version": "2.17.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", + "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", + "dev": true, + "optional": true + } + } + }, + "utf8": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.2.tgz", + "integrity": "sha1-H6DZJw6b6FDZsFAn9jUZv0ZFfZY=", + "dev": true + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "web3": { + "version": "0.18.4", + "resolved": "https://registry.npmjs.org/web3/-/web3-0.18.4.tgz", + "integrity": "sha1-gewXhBRUkfLqqJVbMcBgSeB8Xn0=", + "dev": true, + "requires": { + "bignumber.js": "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2", + "crypto-js": "^3.1.4", + "utf8": "^2.1.1", + "xhr2": "*", + "xmlhttprequest": "*" + }, + "dependencies": { + "bignumber.js": { + "version": "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2", + "from": "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2", + "dev": true + } + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=" + }, + "window-size": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", + "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=" + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "xhr2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/xhr2/-/xhr2-0.1.4.tgz", + "integrity": "sha1-f4dliEdxbbUCYyOBL4GMras4el8=", + "dev": true + }, + "xmlhttprequest": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", + "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=", + "dev": true + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" + }, + "yargs": { + "version": "4.8.1", + "resolved": "http://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", + "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=", + "requires": { + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "lodash.assign": "^4.0.3", + "os-locale": "^1.4.0", + "read-pkg-up": "^1.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^1.0.1", + "which-module": "^1.0.0", + "window-size": "^0.2.0", + "y18n": "^3.2.1", + "yargs-parser": "^2.4.1" + } + }, + "yargs-parser": { + "version": "2.4.1", + "resolved": "http://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz", + "integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=", + "requires": { + "camelcase": "^3.0.0", + "lodash.assign": "^4.0.6" + } } } } diff --git a/package.json b/package.json index c1636e58..fdec3397 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,8 @@ "coveralls": "^3.0.2", "ganache-cli": "^6.1.0", "request": "^2.87.0", - "solc": "^0.4.24", + "solc": "^0.4.25", + "solidity-docgen": "^0.1.0", "truffle": "^4.1.14" }, "devDependencies": { diff --git a/test/AssetGenerator.js b/test/AssetGenerator.js index a8cb83ee..d30a9de2 100644 --- a/test/AssetGenerator.js +++ b/test/AssetGenerator.js @@ -91,7 +91,7 @@ contract('Asset Generator', async() => { await burner.setFee('0x4e38c7f4', assetGen.address, 250); }); - it('Give platform burning permission', async() => { + it('Give permission to contract state', async() => { for(var i=1; i { await db.setAddress(assetManagerHash, assetManager); await db.setAddress(operatorHash, operator); }); +/* + it("Add multiple assets", async() => { + var number = 92; //We can test multiple assets to find the limit, the limit is 93 (92 + 1 from 'Generate assetID') + for(var i=0; i { //await web3.eth.sendTransaction({from:operator, to:divToken.address, value:10*ETH}); @@ -140,7 +168,7 @@ contract('AssetManagerFunds', async() => { let balanceBefore = await web3.eth.getBalance(assetManager); let amountOwed = await divToken.getAmountOwed(assetManagerFunds.address); assert.notEqual(amountOwed, 0); - let tx = await assetManagerFunds.retrieveAssetManagerETH(assetsETH, {from:assetManager}); + let tx = await assetManagerFunds.retrieveAssetManagerETH(assetsETH, {from:assetManager, gas:6721975}); //console.log(tx); let balanceAfter = await web3.eth.getBalance(assetManager); assert.equal(bn(balanceAfter).isGreaterThan(balanceBefore), true); @@ -191,7 +219,36 @@ contract('AssetManagerFunds', async() => { assert.equal(await divTokenERC20.assetIncome(), 5*ETH); assert.equal(await burnToken.balanceOf(divTokenERC20.address), 5*ETH); }); +/* + it("Add multiple assets", async() => { + var number = 41; //We can test multiple assets to find the limit, the limit is 42 (41 + 1 from 'Generate assetID') + for(var i=0; i { let balanceBefore = await burnToken.balanceOf(user1); let amountOwed = await divTokenERC20.getAmountOwed(user1); @@ -211,12 +268,11 @@ contract('AssetManagerFunds', async() => { assert.equal(await divTokenERC20.balanceOf(assetManagerFunds.address), tokenPerAccount); console.log("amount owed"); console.log(amountOwed); - let tx = await assetManagerFunds.retrieveAssetManagerTokens(assetsERC, {from:assetManager}); + let tx = await assetManagerFunds.retrieveAssetManagerTokens(assetsERC, {from:assetManager, gas:6721975}); //console.log(tx); let balanceAfter = await burnToken.balanceOf(assetManager); console.log(balanceAfter); console.log(balanceBefore); assert.equal(balanceBefore.plus(amountOwed).eq(balanceAfter), true); }); - }); diff --git a/test/ERC20Crowdsale.js b/test/ERC20Crowdsale.js index 2b7f17af..a0e5acc0 100644 --- a/test/ERC20Crowdsale.js +++ b/test/ERC20Crowdsale.js @@ -11,6 +11,7 @@ const Pausible = artifacts.require("./ownership/Pausible.sol"); const CrowdsaleGenerator = artifacts.require("./crowdsale/CrowdsaleGeneratorERC20.sol"); const Operators = artifacts.require("./roles/Operators.sol"); const Platform = artifacts.require("./ecosystem/PlatformFunds.sol"); +const API = artifacts.require("./database/API.sol"); const owner = web3.eth.accounts[0]; @@ -36,6 +37,7 @@ contract('ERC20 Crowdsale', async() => { let db; let cm; let hash; + let api; let platform; let assetManagerFee; let operators; @@ -58,6 +60,10 @@ contract('ERC20 Crowdsale', async() => { hash = await HashFunctions.new(db.address); }); + it('Deploy api contract', async() => { + api = await API.new(db.address); + }); + it('Deploy MyB token', async() => { platformToken = await BurnableToken.new('MyBit', tokenSupply); }); @@ -360,8 +366,45 @@ contract('ERC20 Crowdsale', async() => { assert.notEqual(err, undefined); }); + // start funding with 0 assetmanager fee + it('Start funding with no fee', async() => { + assetURI = 'ipfs.io/F3b285ABA9'; + assetManagerFee = 0; + let tx = await crowdsaleGen.createAssetOrderERC20(assetURI, operatorID, 100, 2*ETH, assetManagerFee, erc20.address, {from:assetManager}); + assetID = tx.logs[0].args._assetID; + assetTokenAddress = tx.logs[0].args._tokenAddress; + console.log('Token Address: ' + tokenAddress); + assetToken = await AssetToken.at(assetTokenAddress); + }); - + it('Fully fund no fee asset', async() => { + await erc20.approve(crowdsale.address, 2*ETH, {from:user1}); + let platformWalletBalance = await erc20.balanceOf(owner); + let tx = await crowdsale.buyAssetOrderERC20(assetID, 2*ETH, {from:user1}); + let user1AssetTokens = await assetToken.balanceOf(user1); + let assetTokenSupply = await assetToken.totalSupply() + assert.equal(assetTokenSupply.eq(user1AssetTokens), true); + assert.equal(user1AssetTokens, 2*ETH); + assert.equal(await assetToken.mintingFinished(), true); + assert.equal(await assetToken.balanceOf(assetManager), 0); + assert.equal(await api.crowdsaleFinalized(assetID), true); + // Check payout to platform and operator + console.log(platformWalletBalance); + console.log(await erc20.balanceOf(owner)); + // assert.equal(bn(platformWalletBalance).gt(await erc20.balanceOf(owner)), true); + }); + + it('Fail to create asset with 0 amount to raise', async() => { + let err; + assetURI = 'ipfs.io/F3b285ABCA9'; + assetManagerFee = 12; + try{ + await await crowdsaleGen.createAssetOrderERC20(assetURI, operatorID, 100, 0, assetManagerFee, erc20.address, {from:assetManager}); + } catch(e){ + err = e; + } + assert.notEqual(err, undefined); + }); /* it('Fail to destroy', async() => { diff --git a/test/EthCrowdsale.js b/test/EthCrowdsale.js index 8fb48f75..5e22b5c4 100644 --- a/test/EthCrowdsale.js +++ b/test/EthCrowdsale.js @@ -11,6 +11,7 @@ const Operators = artifacts.require("./roles/Operators.sol"); const HashFunctions = artifacts.require("./test/HashFunctions.sol"); const Pausible = artifacts.require("./ownership/Pausible.sol"); const Platform = artifacts.require("./ecosystem/PlatformFunds.sol"); +const API = artifacts.require("./database/API.sol"); const owner = web3.eth.accounts[0]; @@ -26,7 +27,7 @@ const ETH = 1000000000000000000; const scaling = 1000000000000000000000000000000000000; const tokenSupply = 180000000000000000000000000; const tokenPerAccount = 1000000000000000000000; -const assetManagerFee = 5; +let assetManagerFee = 5; contract('Ether Crowdsale', async() => { @@ -37,6 +38,7 @@ contract('Ether Crowdsale', async() => { let db; let cm; let hash; + let api; let platform; let operators; let operatorID; @@ -59,6 +61,10 @@ contract('Ether Crowdsale', async() => { await db.enableContractManagement(cm.address); }); + it('Deploy api contract', async() => { + api = await API.new(db.address); + }); + it('Deploy MyB token', async() => { platformToken = await PlatformToken.new('MyBit', tokenSupply); }); @@ -325,7 +331,103 @@ contract('Ether Crowdsale', async() => { assert.equal(bn(user3BalanceAfter).isGreaterThan(user3BalanceBefore), true); }); - // TODO: try to create asset with assetManager fee = 0 + //Start successful funding with no manager fee + it('Start funding', async() => { + assetURI = 'Free Management'; + assetManagerFee = 0; + let tx = await crowdsaleGen.createAssetOrderETH(assetURI, operatorID, 1, 2*ETH, assetManagerFee, {from:assetManager}); + //console.log(tx.logs[0].args._assetID); + assetID = tx.logs[0].args._assetID; + tokenAddress = tx.logs[0].args._tokenAddress; + token = await Token.at(tokenAddress); + }); + + it('User1 funding', async() => { + let tokenSupply = await token.totalSupply() + console.log('Token Supply: ' + tokenSupply); + let tx = await crowdsale.buyAssetOrderETH(assetID, {from:user1, value:2*ETH}); + let user1Tokens = await token.balanceOf(user1); + console.log(user1Tokens); + console.log(2*ETH); + assert.equal(user1Tokens.eq(2*ETH), true); + assert.equal(await token.mintingFinished(), true); + assert.equal(await token.balanceOf(assetManager), 0); + assert.equal(await api.crowdsaleFinalized(assetID), true); + }); + + + it('Fail funding with 100% manager fee', async() => { + assetURI = 'Free Management'; + assetManagerFee = 100; + let err; + try { let tx = await crowdsaleGen.createAssetOrderETH(assetURI, operatorID, 1, 2*ETH, assetManagerFee, {from:assetManager}); } + catch(e) { + err = e; + } + assert.notEqual(err, undefined); + }); + + //Start successful funding with 99% manager fee + it('Start funding', async() => { + assetURI = '99%managementfee.com'; + assetManagerFee = 99; + let tx = await crowdsaleGen.createAssetOrderETH(assetURI, operatorID, 10, 2*ETH, assetManagerFee, {from:assetManager}); + //console.log(tx.logs[0].args._assetID); + assetID = tx.logs[0].args._assetID; + tokenAddress = tx.logs[0].args._tokenAddress; + token = await Token.at(tokenAddress); + }); + + + it('user2 funding ', async() => { + let tx = await crowdsale.buyAssetOrderETH(assetID, {from:user2, value:2*ETH}); + let user2Tokens = await token.balanceOf(user2); + let tokenSupply = await token.totalSupply() + assert.equal(user2Tokens.eq(2*ETH), true); + assert.equal(await token.mintingFinished(), true); + assert.equal(await api.crowdsaleFinalized(assetID), true); + }); + + it('Fail asset crowdsale with 0 amount to raise', async() => { + assetURI = 'raisenothing.com'; + assetManagerFee = 42; + let err; + try{ + await crowdsaleGen.createAssetOrderETH(assetURI, operatorID, 10, 0, assetManagerFee, {from:assetManager}); + } catch(e){ + err = e; + } + assert.notEqual(err, undefined); + }); + + // amountToRaise == 1 + it('Start funding with small amount to raise', async() => { + assetURI = 'lowgoals.com'; + assetManagerFee = 50; + let tx = await crowdsaleGen.createAssetOrderETH(assetURI, operatorID, 10, 1, assetManagerFee, {from:assetManager}); + //console.log(tx.logs[0].args._assetID); + assetID = tx.logs[0].args._assetID; + tokenAddress = tx.logs[0].args._tokenAddress; + token = await Token.at(tokenAddress); + }); + + + // Note it's possible for asset-token supply to be larger than wei received due to rounding error + // This example makes 2 asset tokens, but only receives 1 WEI as it mints a token for the assetmanager + it('user3 funding 1 wei', async() => { + let balanceBefore = web3.eth.getBalance(user3); + let tx = await crowdsale.buyAssetOrderETH(assetID, {from:user3, value:2*ETH}); + let balanceAfter = web3.eth.getBalance(user3); + let user3Tokens = await token.balanceOf(user3); + let tokenSupply = await token.totalSupply() + assert.equal(user3Tokens.eq(1), true); + assert.equal(await token.balanceOf(assetManager), 1); + assert.equal(await token.mintingFinished(), true); + assert.equal(await api.crowdsaleFinalized(assetID), true); + }); + + + // TODO: try to force integer rounding it('Fail to send money to contract', async() => { let err; diff --git a/test/accounts.json b/test/accounts.json index d41cb65d..1954395e 100644 --- a/test/accounts.json +++ b/test/accounts.json @@ -1,12 +1,12 @@ [ - "0x13c1cb47836fd4875e4fb0b44627a1ed0babf0b8", - "0xf76f915ae32ad19fd4359b0d1a56328f7beef8be", - "0x0dfb69ce3123487acdd8c6e3ab2e4ce8655b6a6c", - "0xb798b6b56024329e03b211db4c47007a3005eb68", - "0x14a89c951a59131d3e61339501f4a95cf1190efd", - "0x62bcf293e78716718bb79db862dae9ad918e0069", - "0xd72eb39df4b7d974c114f152c90c1919deed3fcc", - "0xc1334b27495bd3edba0815a2b96cab50d4abc3a1", - "0xc513d4bfd54602a931ed0ac7b160c694316e7ec8", - "0x4e8eaf8efa38c6ee6dd0fb1f11def4e6b89c3415" + "0xeed17b217b1e0c63b1b525d8d2e59cad0546432d", + "0x0ec0e59bd4faf0a136c2ee638f3fcff19972a304", + "0xe273d3d13d69f82b8071365e110e13c0fbde0c59", + "0x4cbe9306228ff003fe5a47fe66f2e3d3162f0f37", + "0x0dcea99d96046de44f1ab2a4bf9b3e21f3ac2924", + "0x8bd581cca82af7cfff8ab46591803fe2f2061218", + "0xd6a41e3da4bdc4a27d5707b08612925347f5934f", + "0xd0702a4258c574ff15df4e65000dbb16843cbd24", + "0xc3dda1fc00ba83300b9ad2d00faa30166fabc657", + "0x45543e02e26442e6c95e3145f7d30a53b284f418" ] \ No newline at end of file diff --git a/test/addresses.json b/test/addresses.json index 2af7b1e8..1e9ab1ef 100644 --- a/test/addresses.json +++ b/test/addresses.json @@ -1,18 +1,18 @@ { - "MyBit": "0x5ae411b9e357844d14b294eb7b048c8354352fe5", - "ERC20Burner": "0xf005908c936489fa048b57de05e73d506e6847d9", - "Database": "0x4338b044b042abef639b7b2ee7d55ca9d80a99a8", - "ContractManager": "0x79bae86c52a8f133c557381e9414249b3c901f5c", - "API": "0x56e32cc14dfdf2487d2a9508a2604e132bf40777", - "SingleOwned": "0xee3a88b3f9fa7fdc2754a03575a8095afde95358", - "Pausible": "0xe662b9a79186ef6514231d74b2fa5c47fcadcfb3", - "AccessHierarchy": "0xda46bd6f8f08dd39b90ab4d9f2021567f682f027", - "PlatformFunds": "0xd5c1ef521a285978cfa0e03557587ef1b8a903c8", - "Operators": "0xcdb9de3fbdaa901f6527bab64a9241a3449962dc", - "BrokerEscrow": "0xbb250e9020ba67249a3b97f7cfe5707adc229a0f", - "CrowdsaleETH": "0x38ef661c39a4a2d032694e444764ce480badb7ba", - "CrowdsaleGeneratorETH": "0xa5fe63d97497530da91d45ef502cefe2b7727e14", - "CrowdsaleERC20": "0x362eb4b6cf0e7e3c7f7d9ad673e7814307065979", - "CrowdsaleGeneratorERC20": "0x644a878583340ab68ac895d0432e87ea24729e4e", - "AssetExchange": "0x27c9d6c6843e6a33d347416177cc27f252f8ac3a" -} + "MyBit": "0x23f5dcdf9c431c467de788fb14bf5caf7966f812", + "ERC20Burner": "0x5aa75318a3b08c25ceb13cc8e808b97a6e5efc67", + "Database": "0x404823e6d5e3c99d8309295c7b243f554e7bffd7", + "ContractManager": "0x0ed1e38239b493cb78f1509ff5f6c31629939ab7", + "API": "0xe5f48145db52f521375f7cb1c71b73b207ead88b", + "SingleOwned": "0x341be03c73b3788116fa061b5bdf338b10f90460", + "Pausible": "0x75830c46ea8f42ddb9b4de81e575f9bb09ba8245", + "AccessHierarchy": "0x8266ddfd5824d4e3e773c2722a7d102de4dd732d", + "PlatformFunds": "0x03824910f1b9c17fb44b40897972fbd792792ee1", + "Operators": "0x91e698c250a486d30db5e39c659ad7cbfa12ca67", + "AssetManagerEscrow": "0xb1c6598b8fa70aeadccbda89aeb4b1d3b75410d8", + "CrowdsaleETH": "0xcb25d6fe4fc09e9cc3412df95baa90fb7fee471c", + "CrowdsaleGeneratorETH": "0x661c62ace83f7fe8c96ac6e88cacd52cb156801a", + "CrowdsaleERC20": "0x2678490ccf890c681c946ef7e25cad427fa217c8", + "CrowdsaleGeneratorERC20": "0x182eda13a88499cf7652d9091fc4337bf64ac7cb", + "AssetExchange": "0xfce2dd5b092dd362c9cb9cece545676966be27d5" +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index eb3aeba7..648fb27c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -112,6 +112,11 @@ browser-stdout@1.3.0: resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f" integrity sha1-81HTKWnTL6XXpVZxVCY9korjvR8= +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + browserify-sha3@^0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/browserify-sha3/-/browserify-sha3-0.0.1.tgz#3ff34a3006ef15c0fb3567e541b91a2340123d11" @@ -177,6 +182,16 @@ commander@2.11.0: resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" integrity sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ== +commander@2.15.1: + version "2.15.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" + integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag== + +commander@^2.14.1: + version "2.19.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" + integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== + commander@~2.17.1: version "2.17.1" resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" @@ -248,6 +263,11 @@ diff@3.3.1: resolved "https://registry.yarnpkg.com/diff/-/diff-3.3.1.tgz#aa8567a6eed03c531fc89d3f711cd0e5259dec75" integrity sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww== +diff@3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== + ecc-jsbn@~0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" @@ -439,7 +459,7 @@ growl@1.10.3: resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.3.tgz#1926ba90cf3edfe2adb4927f5880bc22c66c790f" integrity sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q== -"growl@~> 1.10.0": +growl@1.10.5, "growl@~> 1.10.0": version "1.10.5" resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== @@ -478,6 +498,11 @@ has-flag@^2.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" integrity sha1-6CB68cx7MNRGzHC3NLXovhj4jVE= +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + he@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" @@ -584,6 +609,11 @@ js-sha3@^0.3.1: resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.3.1.tgz#86122802142f0828502a0d1dee1d95e253bb0243" integrity sha1-hhIoAhQvCChQKg0d7h2V4lO7AkM= +"js-tokens@^3.0.0 || ^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + js-yaml@3.x, js-yaml@^3.11.0: version "3.12.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" @@ -680,7 +710,7 @@ lodash.assign@^4.0.3, lodash.assign@^4.0.6: resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" integrity sha1-DZnzzNem0mHRm9rrkkUAXShYCOc= -lodash@^4.17.10: +lodash@^4.17.10, lodash@^4.17.5: version "4.17.11" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== @@ -690,6 +720,13 @@ log-driver@^1.2.7: resolved "https://registry.yarnpkg.com/log-driver/-/log-driver-1.2.7.tgz#63b95021f0702fedfa2c9bb0a24e7797d71871d8" integrity sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg== +loose-envify@^1.1.0, loose-envify@^1.3.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + memorystream@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" @@ -707,7 +744,7 @@ mime-types@^2.1.12, mime-types@~2.1.19: dependencies: mime-db "~1.36.0" -"minimatch@2 || 3", minimatch@^3.0.4: +"minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== @@ -752,11 +789,33 @@ mocha@^4.1.0: mkdirp "0.5.1" supports-color "4.4.0" +mocha@^5.0.1: + version "5.2.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.2.0.tgz#6d8ae508f59167f940f2b5b3c4a612ae50c90ae6" + integrity sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ== + dependencies: + browser-stdout "1.3.1" + commander "2.15.1" + debug "3.1.0" + diff "3.5.0" + escape-string-regexp "1.0.5" + glob "7.1.2" + growl "1.10.5" + he "1.1.1" + minimatch "3.0.4" + mkdirp "0.5.1" + supports-color "5.4.0" + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= +mustache@^2.3.0: + version "2.3.2" + resolved "https://registry.yarnpkg.com/mustache/-/mustache-2.3.2.tgz#a6d4d9c3f91d13359ab889a812954f9230a3d0c5" + integrity sha512-KpMNwdQsYz3O/SBS1qJ/o3sqUJ5wSb8gb0pul8CO0S56b9Y2ALm8zCfsjPXsqGFfoNBkDwZuZIAjhsZI03gYVQ== + nan@2.10.0: version "2.10.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f" @@ -789,6 +848,11 @@ oauth-sign@~0.9.0: resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== +object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + once@1.x, once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" @@ -893,6 +957,14 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= +prop-types@^15.6.2: + version "15.6.2" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.2.tgz#05d5ca77b4453e985d60fc7ff8c859094a497102" + integrity sha512-3pboPvLiWD7dkI3qf3KbUe6hKFKa52w+AE0VCqECtf+QHAKgOL37tTaNCnuX1nAAQ4ZhyP+kYVKf8rLmJ/feDQ== + dependencies: + loose-envify "^1.3.1" + object-assign "^4.1.1" + psl@^1.1.24: version "1.1.29" resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.29.tgz#60f580d360170bb722a797cc704411e6da850c67" @@ -908,6 +980,26 @@ qs@~6.5.2: resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== +react-dom@^16.2.0: + version "16.5.2" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.5.2.tgz#b69ee47aa20bab5327b2b9d7c1fe2a30f2cfa9d7" + integrity sha512-RC8LDw8feuZOHVgzEf7f+cxBr/DnKdqp56VU0lAs1f4UfKc4cU8wU4fTq/mgnvynLQo8OtlPC19NUFh/zjZPuA== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + schedule "^0.5.0" + +react@^16.2.0: + version "16.5.2" + resolved "https://registry.yarnpkg.com/react/-/react-16.5.2.tgz#19f6b444ed139baa45609eee6dc3d318b3895d42" + integrity sha512-FDCSVd3DjVTmbEAjUNX6FgfAmQ+ypJfHUsqUJOYNCBUp1h8lqmtC+0mXJ+JjsWx4KAVTkk1vKd1hLQPvEviSuw== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + schedule "^0.5.0" + read-pkg-up@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" @@ -1021,6 +1113,13 @@ safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== +schedule@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/schedule/-/schedule-0.5.0.tgz#c128fffa0b402488b08b55ae74bb9df55cc29cc8" + integrity sha512-HUcJicG5Ou8xfR//c2rPT0lPIRR09vVvN81T9fqfVgBmhERUbDEQoYKjpBxbueJnCPpSu2ujXzOnRQt6x9o/jw== + dependencies: + object-assign "^4.1.1" + "semver@2 || 3 || 4 || 5", semver@^5.3.0: version "5.5.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.1.tgz#7dfdd8814bdb7cabc7be0fb1d734cfb66c940477" @@ -1047,6 +1146,15 @@ shelljs@^0.7.4: interpret "^1.0.0" rechoir "^0.6.2" +shelljs@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.2.tgz#345b7df7763f4c2340d584abb532c5f752ca9e35" + integrity sha512-pRXeNrCA2Wd9itwhvLp5LZQvPJ0wU6bcjaTMywHHGX5XWhVN2nzSu7WV0q+oUY7mGK3mgSkDDzP3MgjqdyIgbQ== + dependencies: + glob "^7.0.0" + interpret "^1.0.0" + rechoir "^0.6.2" + sol-explore@^1.6.2: version "1.6.2" resolved "https://registry.yarnpkg.com/sol-explore/-/sol-explore-1.6.2.tgz#43ae8c419fd3ac056a05f8a9d1fb1022cd41ecc2" @@ -1063,7 +1171,7 @@ solc@0.4.24: semver "^5.3.0" yargs "^4.7.1" -solc@^0.4.24: +solc@^0.4.25: version "0.4.25" resolved "https://registry.yarnpkg.com/solc/-/solc-0.4.25.tgz#06b8321f7112d95b4b903639b1138a4d292f5faa" integrity sha512-jU1YygRVy6zatgXrLY2rRm7HW1d7a8CkkEgNJwvH2VLpWhMFsMdWcJn6kUqZwcSz/Vm+w89dy7Z/aB5p6AFTrg== @@ -1090,6 +1198,19 @@ solidity-coverage@^0.5.11: tree-kill "^1.2.0" web3 "^0.18.4" +solidity-docgen@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/solidity-docgen/-/solidity-docgen-0.1.0.tgz#f3a56ff074e8c7d832af3a3d462c3b5abf0f64cb" + integrity sha512-F7ufNWmlP5c5hIi66Ijv9tc+HNosyO7ijWq6pRtyBR1WqyJBH/0DJkD6QZI8HkE8p6LEXiPKxGBWbAeVT9Nu9g== + dependencies: + commander "^2.14.1" + lodash "^4.17.5" + mocha "^5.0.1" + mustache "^2.3.0" + react "^16.2.0" + react-dom "^16.2.0" + shelljs "^0.8.1" + solidity-parser-sc@0.4.11: version "0.4.11" resolved "https://registry.yarnpkg.com/solidity-parser-sc/-/solidity-parser-sc-0.4.11.tgz#86734c9205537007f4d6201b57176e41696ee607" @@ -1196,6 +1317,13 @@ supports-color@4.4.0: dependencies: has-flag "^2.0.0" +supports-color@5.4.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" + integrity sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w== + dependencies: + has-flag "^3.0.0" + supports-color@^3.1.0: version "3.2.3" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6"