From a1bd53267daceaef7db2ad0654446d0515e7a5d1 Mon Sep 17 00:00:00 2001 From: Matt Rice Date: Fri, 28 Dec 2018 16:39:50 -0500 Subject: [PATCH 1/7] upgrade version --- contracts/ContractCreator.sol | 2 +- contracts/Derivative.sol | 20 ++++++++--------- contracts/Migrations.sol | 2 +- contracts/OracleInterface.sol | 2 +- contracts/OracleMock.sol | 2 +- contracts/PriceTime.sol | 2 +- contracts/Registry.sol | 2 +- contracts/Testable.sol | 2 +- contracts/TokenizedDerivative.sol | 36 +++++++++++++++---------------- contracts/Vote.sol | 30 +++++++++++++++----------- contracts/VoteInterface.sol | 8 +++---- package.json | 10 ++++----- provider/package.json | 6 +++--- trader/package.json | 6 +++--- truffle.js | 2 +- voter/package.json | 6 +++--- 16 files changed, 71 insertions(+), 67 deletions(-) diff --git a/contracts/ContractCreator.sol b/contracts/ContractCreator.sol index 14502df836..05bcf42b66 100644 --- a/contracts/ContractCreator.sol +++ b/contracts/ContractCreator.sol @@ -1,4 +1,4 @@ -pragma solidity >=0.4.24; +pragma solidity ^0.5.0; import "./Registry.sol"; diff --git a/contracts/Derivative.sol b/contracts/Derivative.sol index 0531cd8b2b..277f09a550 100644 --- a/contracts/Derivative.sol +++ b/contracts/Derivative.sol @@ -5,7 +5,7 @@ TODO: Implement tax function */ -pragma solidity >=0.4.24; +pragma solidity ^0.5.0; import "openzeppelin-solidity/contracts/math/SafeMath.sol"; import "./OracleInterface.sol"; @@ -52,7 +52,7 @@ contract Derivative { } struct ContractParty { - address accountAddress; + address payable accountAddress; int256 balance; bool hasConfirmedPrice; } @@ -76,13 +76,13 @@ contract Derivative { int256 public npv; // Net present value is measured in Wei constructor( - address _makerAddress, - address _takerAddress, + address payable _makerAddress, + address payable _takerAddress, address _oracleAddress, int256 _defaultPenalty, int256 _requiredMargin, uint expiry, - string _product, + string memory _product, uint _notional ) public payable { // Address information @@ -361,13 +361,13 @@ contract Derivative { contract SimpleDerivative is Derivative { constructor( - address _ownerAddress, - address _counterpartyAddress, + address payable _ownerAddress, + address payable _counterpartyAddress, address _oracleAddress, int256 _defaultPenalty, int256 _requiredMargin, uint expiry, - string product, + string memory product, uint notional ) public payable Derivative( _ownerAddress, @@ -397,11 +397,11 @@ contract DerivativeCreator is ContractCreator { ContractCreator(registryAddress, _oracleAddress) {} // solhint-disable-line no-empty-blocks function createDerivative( - address counterparty, + address payable counterparty, int256 defaultPenalty, int256 requiredMargin, uint expiry, - string product, + string calldata product, uint notional ) external diff --git a/contracts/Migrations.sol b/contracts/Migrations.sol index c12737ba11..f91d756c48 100644 --- a/contracts/Migrations.sol +++ b/contracts/Migrations.sol @@ -1,4 +1,4 @@ -pragma solidity >=0.4.24; +pragma solidity ^0.5.0; contract Migrations { diff --git a/contracts/OracleInterface.sol b/contracts/OracleInterface.sol index 48c122735f..1771c1a1c6 100644 --- a/contracts/OracleInterface.sol +++ b/contracts/OracleInterface.sol @@ -2,7 +2,7 @@ OracleInterface contract. The interface that contracts use to query verified and unverified price feeds. */ -pragma solidity >=0.4.24; +pragma solidity ^0.5.0; // This interface allows contracts to query verified and unverified prices from the VoteToken. diff --git a/contracts/OracleMock.sol b/contracts/OracleMock.sol index 9e7efd81f9..e3b6527393 100644 --- a/contracts/OracleMock.sol +++ b/contracts/OracleMock.sol @@ -3,7 +3,7 @@ Simple mock implementation of a Vote Token to be used by a derivative for querying price feeds. */ -pragma solidity >=0.4.24; +pragma solidity ^0.5.0; import "openzeppelin-solidity/contracts/math/SafeMath.sol"; import "openzeppelin-solidity/contracts/ownership/Ownable.sol"; diff --git a/contracts/PriceTime.sol b/contracts/PriceTime.sol index 64796d232e..3477556143 100644 --- a/contracts/PriceTime.sol +++ b/contracts/PriceTime.sol @@ -1,7 +1,7 @@ /* PriceTime Library */ -pragma solidity >=0.4.24; +pragma solidity ^0.5.0; import "openzeppelin-solidity/contracts/math/SafeMath.sol"; diff --git a/contracts/Registry.sol b/contracts/Registry.sol index cbb110fdf9..ffbe0502d1 100644 --- a/contracts/Registry.sol +++ b/contracts/Registry.sol @@ -1,4 +1,4 @@ -pragma solidity >=0.4.24; +pragma solidity ^0.5.0; import "openzeppelin-solidity/contracts/ownership/Ownable.sol"; diff --git a/contracts/Testable.sol b/contracts/Testable.sol index ad5dc433c8..ea3391088c 100644 --- a/contracts/Testable.sol +++ b/contracts/Testable.sol @@ -4,7 +4,7 @@ Base class that provides time overrides, but only if being run in test mode. */ -pragma solidity >=0.4.24; +pragma solidity ^0.5.0; import "openzeppelin-solidity/contracts/ownership/Ownable.sol"; diff --git a/contracts/TokenizedDerivative.sol b/contracts/TokenizedDerivative.sol index 7512b7938f..f9c53766ac 100644 --- a/contracts/TokenizedDerivative.sol +++ b/contracts/TokenizedDerivative.sol @@ -3,7 +3,7 @@ Implements a simplified version of tokenized Product/ETH Products. */ -pragma solidity >=0.4.24; +pragma solidity ^0.5.0; import "openzeppelin-solidity/contracts/math/SafeMath.sol"; import "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol"; @@ -71,7 +71,7 @@ contract TokenizedDerivative is ERC20 { } struct ContractParty { - address accountAddress; + address payable accountAddress; int256 balance; bool hasConfirmedPrice; uint marginRequirement; // Percentage of nav*10^18 @@ -118,7 +118,7 @@ contract TokenizedDerivative is ERC20 { uint deposit; } - Dispute public dispute; + Dispute public disputeInfo; // The information in the following struct is only valid if in the midst of a Default or Termination. struct Termination { @@ -148,13 +148,13 @@ contract TokenizedDerivative is ERC20 { } constructor( - address _providerAddress, - address _investorAddress, + address payable _providerAddress, + address payable _investorAddress, address _oracleAddress, uint _defaultPenalty, // Percentage of nav*10^18 uint _terminationFee, // Percentage of nav*10^18 uint _providerRequiredMargin, // Percentage of nav*10^18 - string _product, + string memory _product, uint _fixedYearlyFee, // Percentage of nav * 10^18 uint _disputeDeposit, // Percentage of nav * 10^18 address _returnCalculator, @@ -249,8 +249,8 @@ contract TokenizedDerivative is ERC20 { uint initialSupply = totalSupply(); - require(this.transferFrom(msg.sender, this, numTokens)); - _burn(this, numTokens); + require(this.transferFrom(msg.sender, address(this), numTokens)); + _burn(address(this), numTokens); int256 investorBalance = investor.balance; @@ -312,9 +312,9 @@ contract TokenizedDerivative is ERC20 { state = State.Disputed; endTime = lastRemarginTime; - dispute.disputedNav = nav; - dispute.disputer = msg.sender; - dispute.deposit = requiredDeposit; + disputeInfo.disputedNav = nav; + disputeInfo.disputer = msg.sender; + disputeInfo.deposit = requiredDeposit; msg.sender.transfer(refund); } @@ -343,9 +343,9 @@ contract TokenizedDerivative is ERC20 { require(startingState == State.Disputed || startingState == State.Expired || startingState == State.Defaulted); _settleVerifiedPrice(); if (startingState == State.Disputed) { - (ContractParty storage disputer, ContractParty storage notDisputer) = _whoAmI(dispute.disputer); - int256 depositValue = int256(dispute.deposit); - if (nav == dispute.disputedNav) { + (ContractParty storage disputer, ContractParty storage notDisputer) = _whoAmI(disputeInfo.disputer); + int256 depositValue = int256(disputeInfo.deposit); + if (nav == disputeInfo.disputedNav) { disputer.balance += depositValue; } else { notDisputer.balance += depositValue; @@ -539,7 +539,7 @@ contract TokenizedDerivative is ERC20 { if (state != State.Live) { didReduce = additionalAuthorizedNav != 0; additionalAuthorizedNav = 0; - return; + return didReduce; } int256 totalAuthorizedNav = currentNav + int256(additionalAuthorizedNav); @@ -630,12 +630,12 @@ contract TokenizedDerivativeCreator is ContractCreator { ContractCreator(registryAddress, _oracleAddress) {} // solhint-disable-line no-empty-blocks function createTokenizedDerivative( - address provider, - address investor, + address payable provider, + address payable investor, uint defaultPenalty, uint terminationFee, uint providerRequiredMargin, - string product, + string calldata product, uint fixedYearlyFee, uint disputeDeposit, address returnCalculator, diff --git a/contracts/Vote.sol b/contracts/Vote.sol index e9b0b0bc9b..fb6cb7b54d 100644 --- a/contracts/Vote.sol +++ b/contracts/Vote.sol @@ -8,7 +8,7 @@ * Allows users to vote yes/no on whether a price is accurate */ -pragma solidity >=0.4.24; +pragma solidity ^0.5.0; pragma experimental ABIEncoderV2; @@ -72,7 +72,7 @@ library Poll { } } - function _addProposal(Data storage self, string ipfsHash) internal { + function _addProposal(Data storage self, string memory ipfsHash) internal { uint idx = self.proposals.length++; self.proposals[idx].ipfsHash = ipfsHash; } @@ -107,7 +107,7 @@ library VotePeriod { mapping(string => bool) ipfsHashSet; } - function _proposeFeed(Data storage self, string ipfsHash) internal { + function _proposeFeed(Data storage self, string memory ipfsHash) internal { require(!self.ipfsHashSet[ipfsHash]); self.ipfsHashSet[ipfsHash] = true; self.runoffPoll._addProposal(ipfsHash); @@ -210,7 +210,7 @@ contract VoteCoin is ERC20, VoteInterface, OracleInterface, Testable { PeriodTiming[5] private periodTimings; - constructor(string _product, uint _priceInterval, bool isTest) public Testable(isTest) { + constructor(string memory _product, uint _priceInterval, bool isTest) public Testable(isTest) { _mint(msg.sender, 10000); product = _product; priceInterval = _priceInterval; @@ -269,20 +269,20 @@ contract VoteCoin is ERC20, VoteInterface, OracleInterface, Testable { _getCurrentVotePeriod()._revealVote(voteOption, salt, balanceOf(msg.sender), period); } - function proposeFeed(string ipfsHash) public { + function proposeFeed(string memory ipfsHash) public { checkTimeAndUpdateState(); require(period == VotePeriod.PeriodType.Commit || period == VotePeriod.PeriodType.Reveal); _getCurrentVotePeriod()._proposeFeed(ipfsHash); } - function addUnverifiedPrice(PriceTime.Data priceTime) public { + function addUnverifiedPrice(PriceTime.Data memory priceTime) public { PriceTime.Data[] memory priceTimes = new PriceTime.Data[](1); priceTimes[0] = priceTime; addUnverifiedPrices(priceTimes); } - function getProposals() public view returns (Proposal.Data[] proposals) { + function getProposals() public view returns (Proposal.Data[] memory proposals) { uint time = getCurrentTime(); uint computedStartTime = _getStartOfPeriod(time); @@ -307,23 +307,23 @@ contract VoteCoin is ERC20, VoteInterface, OracleInterface, Testable { } } - function getCurrentPeriodType() public view returns (string periodType) { + function getCurrentPeriodType() public view returns (string memory periodType) { uint currentTime = getCurrentTime(); return _getStringPeriodType(_getPeriodType(_getStartOfPeriod(currentTime), currentTime)); } - function getProduct() public view returns (string _product) { + function getProduct() public view returns (string memory _product) { return product; } - function getDefaultProposalPrices() public view returns (PriceTime.Data[] prices) { + function getDefaultProposalPrices() public view returns (PriceTime.Data[] memory prices) { // TODO(mrice32): we may want to subtract some time offset to ensure all unverifiedPrices being voted on are // in before the voting period starts. // Note: this will fail if the entire voting period of prices previous do not exist. VotePeriod.Data storage votePeriod = _getCurrentVotePeriod(); (uint startTime, uint endTime) = votePeriod._getPricePeriod(totalVotingDuration); if (unverifiedPrices.length == 0 || startTime < unverifiedPrices[0].time) { - return; + return prices; } uint startIndex = unverifiedPrices._getIndex(startTime, priceInterval); @@ -469,7 +469,11 @@ contract VoteCoin is ERC20, VoteInterface, OracleInterface, Testable { return timestamp.sub(epochOffset).div(totalVotingDuration).mul(totalVotingDuration).add(epochOffset); } - function _getStringPeriodType(VotePeriod.PeriodType periodType) private pure returns (string stringPeriodType) { + function _getStringPeriodType(VotePeriod.PeriodType periodType) + private + pure + returns (string memory stringPeriodType) + { if (periodType == VotePeriod.PeriodType.Commit) { return "commit"; } else if (periodType == VotePeriod.PeriodType.Reveal) { @@ -488,7 +492,7 @@ contract VoteCoin is ERC20, VoteInterface, OracleInterface, Testable { function _initPeriodTiming(uint startOffset, uint duration, VotePeriod.PeriodType periodType) private view - returns (PeriodTiming periodTiming, uint nextStartOffset) + returns (PeriodTiming memory periodTiming, uint nextStartOffset) { periodTiming.startOffset = startOffset; periodTiming.endOffset = startOffset.add(duration); diff --git a/contracts/VoteInterface.sol b/contracts/VoteInterface.sol index 965bc739a6..de468fc4ec 100644 --- a/contracts/VoteInterface.sol +++ b/contracts/VoteInterface.sol @@ -39,16 +39,16 @@ contract VoteInterface { function getCurrentCommitRevealPeriods() public view returns (Period[] memory periods); // Returns the current period type ("commit", "reveal", or "none"). - function getCurrentPeriodType() public view returns (string periodType); + function getCurrentPeriodType() public view returns (string memory periodType); // Gets the product that the price votes apply to. - function getProduct() public view returns (string product); + function getProduct() public view returns (string memory product); // Gets the runoff/alternative proposals for the current period. - function getProposals() public view returns (Proposal.Data[] proposals); + function getProposals() public view returns (Proposal.Data[] memory proposals); // Gets the default proposal (option 1 during the primary vote period) for the current period. - function getDefaultProposalPrices() public view returns (PriceTime.Data[] defaultProposal); + function getDefaultProposalPrices() public view returns (PriceTime.Data[] memory defaultProposal); // Gets the default proposal (option 1 during the primary vote period) price for a particular time during the // current period. diff --git a/package.json b/package.json index 7591d9c1c8..aac334b9c9 100644 --- a/package.json +++ b/package.json @@ -31,16 +31,16 @@ "html-webpack-plugin": "^3.2.0", "json-loader": "^0.5.7", "node-sass": "^4.9.0", - "openzeppelin-solidity": "^2.0.0-rc.1", + "openzeppelin-solidity": "^2.1.0-rc.2", "prettier": "^1.14.3", "sass-loader": "^7.0.3", - "solhint": "^1.3.0", + "solhint": "^1.5.0", "solidity-coverage": "^0.5.11", "source-map-support": "^0.5.3", "style-loader": "^0.21.0", - "truffle": "^5.0.0-beta.2", - "truffle-contract": "^4.0.0-beta.2", - "web3": "^1.0.0-beta.36", + "truffle": "^5.0.0", + "truffle-contract": "^4.0.0", + "web3": "^1.0.0-beta.37", "webpack": "^4.12.0", "webpack-cli": "^3.0.6", "webpack-dev-server": "^3.1.4" diff --git a/provider/package.json b/provider/package.json index e43444702f..e04826d110 100644 --- a/provider/package.json +++ b/provider/package.json @@ -12,9 +12,9 @@ "react-dom": "^16.5.2", "react-scripts": "1.1.5", "recharts": "^1.3.1", - "truffle": "^5.0.0-beta.2", - "truffle-contract": "^3.0.6", - "web3": "^1.0.0-beta.36" + "truffle": "^5.0.0", + "truffle-contract": "^3.0.7", + "web3": "^1.0.0-beta.37" }, "scripts": { "start": "react-scripts start", diff --git a/trader/package.json b/trader/package.json index 8a7c3aecec..12b5c87686 100644 --- a/trader/package.json +++ b/trader/package.json @@ -10,9 +10,9 @@ "react-dom": "^16.5.2", "react-scripts": "1.1.5", "recharts": "^1.3.1", - "truffle": "^5.0.0-beta.2", - "truffle-contract": "^4.0.0-beta.2", - "web3": "^1.0.0-beta.36" + "truffle": "^5.0.0", + "truffle-contract": "^4.0.0", + "web3": "^1.0.0-beta.37" }, "scripts": { "start": "react-scripts start", diff --git a/truffle.js b/truffle.js index 418bbaf1e3..8e94f6941d 100644 --- a/truffle.js +++ b/truffle.js @@ -60,7 +60,7 @@ module.exports = { }, compilers: { solc: { - version: "0.4.25" + version: "0.5.2" } } }; diff --git a/voter/package.json b/voter/package.json index 7ba5397e5d..a268839413 100644 --- a/voter/package.json +++ b/voter/package.json @@ -10,9 +10,9 @@ "react-dom": "^16.5.2", "react-scripts": "1.1.5", "recharts": "^1.3.1", - "truffle": "^5.0.0-beta.2", - "truffle-contract": "^4.0.0-beta.2", - "web3": "^1.0.0-beta.36" + "truffle": "^5.0.0", + "truffle-contract": "^4.0.0", + "web3": "^1.0.0-beta.37" }, "scripts": { "start": "react-scripts start", From 021c27ddd7da5cc608f025a9cfa7d1a5bde225d0 Mon Sep 17 00:00:00 2001 From: Matt Rice Date: Fri, 28 Dec 2018 16:46:42 -0500 Subject: [PATCH 2/7] remove fixed compiler --- truffle.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/truffle.js b/truffle.js index 8e94f6941d..670eaa26ee 100644 --- a/truffle.js +++ b/truffle.js @@ -57,10 +57,5 @@ module.exports = { gas: 6720000, gasPrice: 20000000000, } - }, - compilers: { - solc: { - version: "0.5.2" - } } }; From 7c7f4e84b7cf2eb7202fb98c1a11e3efdfd965b5 Mon Sep 17 00:00:00 2001 From: Matt Rice Date: Fri, 28 Dec 2018 17:20:47 -0500 Subject: [PATCH 3/7] WIP --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index aac334b9c9..a35016236c 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,6 @@ "ganache-cli": "^6.1.8", "js-sha256": "^0.9.0", "node-fetch": "^2.3.0", - "truffle-hdwallet-provider": "^1.0.0-web3one.2" + "truffle-hdwallet-provider": "^1.0.0-web3one.5" } } From 41ae9878b2c54ecfbdd6a2274967ab78f845af1b Mon Sep 17 00:00:00 2001 From: Matt Rice Date: Wed, 2 Jan 2019 17:25:17 -0500 Subject: [PATCH 4/7] WIP --- .circleci/config.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f30535819b..827728f359 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -6,10 +6,6 @@ jobs: working_directory: ~/protocol steps: - checkout - - restore_cache: - keys: - - v1-dependency-cache-{{ checksum "package.json" }} - - v1-dependency-cache- - run: name: Install Dependencies command: npm install --quiet From 995941cc8edde84b56f7e68d513e3438d64b76cd Mon Sep 17 00:00:00 2001 From: Matt Rice Date: Wed, 2 Jan 2019 18:41:33 -0500 Subject: [PATCH 5/7] WIP test --- .circleci/config.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 827728f359..bdafbf7e49 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -8,7 +8,7 @@ jobs: - checkout - run: name: Install Dependencies - command: npm install --quiet + command: npm install --quiet && cat node_modules/openzeppelin-solidity/package.json - save_cache: key: v1-dependency-cache-{{ checksum "package.json" }} paths: @@ -26,7 +26,7 @@ jobs: key: protocol-{{ .Environment.CIRCLE_SHA1 }} - run: name: Compile contracts - command: $(npm bin)/truffle compile + command: npm install && $(npm bin)/truffle compile - save_cache: key: protocol-completed-build-{{ .Environment.CIRCLE_SHA1 }} paths: @@ -71,7 +71,7 @@ jobs: - checkout - run: name: Install Dependencies - command: apk add make git python g++ && npm install --quiet + command: apk add make git python g++ && npm install --quiet && curl https://raw.githubusercontent.com/maxsam4/solidity-parser/solidity-0.5/build/parser.js > node_modules/solidity-parser-sc/build/parser.js - run: name: Run coverage command: npm run coverage From 45557a0d1077191e5047171a31aef336f7c0fe21 Mon Sep 17 00:00:00 2001 From: Matt Rice Date: Wed, 2 Jan 2019 18:47:44 -0500 Subject: [PATCH 6/7] WIP --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a35016236c..53b6159cd1 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "html-webpack-plugin": "^3.2.0", "json-loader": "^0.5.7", "node-sass": "^4.9.0", - "openzeppelin-solidity": "^2.1.0-rc.2", + "openzeppelin-solidity": "2.1.0-rc.2", "prettier": "^1.14.3", "sass-loader": "^7.0.3", "solhint": "^1.5.0", From d6ef750acd1a91c87d65c0652bc292aab6c0cf4e Mon Sep 17 00:00:00 2001 From: Matt Rice Date: Wed, 2 Jan 2019 18:59:56 -0500 Subject: [PATCH 7/7] WIP --- .circleci/config.yml | 8 ++++++-- package.json | 3 ++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index bdafbf7e49..d7bfb618a9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -6,9 +6,13 @@ jobs: working_directory: ~/protocol steps: - checkout + - restore_cache: + keys: + - v1-dependency-cache-{{ checksum "package.json" }} + - v1-dependency-cache- - run: name: Install Dependencies - command: npm install --quiet && cat node_modules/openzeppelin-solidity/package.json + command: npm install --quiet - save_cache: key: v1-dependency-cache-{{ checksum "package.json" }} paths: @@ -71,7 +75,7 @@ jobs: - checkout - run: name: Install Dependencies - command: apk add make git python g++ && npm install --quiet && curl https://raw.githubusercontent.com/maxsam4/solidity-parser/solidity-0.5/build/parser.js > node_modules/solidity-parser-sc/build/parser.js + command: apk add make git python g++ curl && npm install --quiet - run: name: Run coverage command: npm run coverage diff --git a/package.json b/package.json index 53b6159cd1..713125f233 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,8 @@ "scripts": { "dev": "webpack-dev-server", "prettier": "prettier --write 'test/**/*.js' 'migrations/*.js *.js'", - "coverage": "$(npm bin)/solidity-coverage" + "//": "comment on the below script - we can get rid of the curl below once solidity-parser merges PR #18", + "coverage": "curl https://raw.githubusercontent.com/maxsam4/solidity-parser/solidity-0.5/build/parser.js > node_modules/solidity-parser-sc/build/parser.js && $(npm bin)/solidity-coverage" }, "author": "UMA Team", "license": "MIT",