diff --git a/.solhint.json b/.solhint.json index 1d98a203..90e686f4 100644 --- a/.solhint.json +++ b/.solhint.json @@ -5,6 +5,7 @@ "avoid-suicide": "error", "avoid-sha3": "warn", "compiler-version": ["error", "0.8.6"], - "func-visibility": ["warn", { "ignoreConstructors": true } ] + "func-visibility": ["warn", { "ignoreConstructors": true } ], + "not-rely-on-time": "off" } } diff --git a/contracts/interfaces/native/GaugeStructs.sol b/contracts/interfaces/native/GaugeStructs.sol new file mode 100644 index 00000000..17fa0805 --- /dev/null +++ b/contracts/interfaces/native/GaugeStructs.sol @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.6; + +library GaugeStructs { + struct Vote { + uint256 gaugeID; + uint256 votePowerBPS; + } + + /// @dev Struct pack into single 32-byte word + /// @param _votingContractsIndex Index for _votingContracts for last incomplete updateGaugeWeights() call. + /// @param _votersIndex Index for _voters[savedIndex_votingContracts] for last incomplete updateGaugeWeights() call. + /// @param _votesIndex Index for _votes[savedIndex_votingContracts][savedIndex_voters] for last incomplete updateGaugeWeights() call. + struct UpdateInfo { + uint80 _votingContractsIndex; // [0:80] + uint88 _votersIndex; // [80:168] + uint88 _votesIndex; // [168:256] + } + + struct Gauge { + bool active; // [0:8] + uint248 rateOnLine; // [8:256] Max value we reasonably expect is ~20% or 2e17. We only need log 2 2e17 = ~58 bits for this. + string name; + } +} \ No newline at end of file diff --git a/contracts/interfaces/native/IDepositHelper.sol b/contracts/interfaces/native/IDepositHelper.sol new file mode 100644 index 00000000..fe9b180c --- /dev/null +++ b/contracts/interfaces/native/IDepositHelper.sol @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.6; + + +/** + * @title IDepositHelper + * @author solace.fi + * @notice The process of depositing into Solace Native requires multiple steps across multiple contracts. This helper contract allows users to deposit with a single transaction. + * + * These steps are + * 1. Deposit governance token into [`UWP`](./../../native/UnderwritingPool). + * 2. Deposit [`UWP`](./../../native/UnderwritingPool) into [`UWE`](./../../native/UnderwritingEquity). + * 3. Deposit [`UWE`](./../../native/UnderwritingEquity) into an [`Underwriting Lock`](./../../native/UnderwritingLocker). + * + * These steps can be replaced with [`depositAndLock()`](#depositandlock) or [`depositIntoLock()`](#depositintolock). + */ +interface IDepositHelper { + + /*************************************** + VIEW FUNCTIONS + ***************************************/ + + /** + * @notice Address of the [underwriting pool](./../../native/UnderwritingPool). + * @return uwp The underwriting pool. + */ + function underwritingPool() external view returns (address uwp); + + /** + * @notice Address of [underwriting equity](./../../native/UnderwritingEquity). + * @return uwe The underwriting equity. + */ + function underwritingEquity() external view returns (address uwe); + + /** + * @notice Address of [underwriting locker](./../../native/UnderwritingLocker). + * @return locker The underwriting locker. + */ + function underwritingLocker() external view returns (address locker); + + /** + * @notice Calculates the amount of [`UWE`](./../../native/UnderwritingEquity) minted for an amount of a token deposited. + * The deposit token may be one of the tokens in [`UWP`](./../../native/UnderwritingPool), the [`UWP`](./../../native/UnderwritingPool) token, or the [`UWE`](./../../native/UnderwritingEquity) token. + * @param depositToken The address of the token to deposit. + * @param depositAmount The amount of the token to deposit. + * @return uweAmount The amount of [`UWE`](./../../native/UnderwritingEquity) that will be minted to the receiver. + */ + function calculateDeposit(address depositToken, uint256 depositAmount) external view returns (uint256 uweAmount); + + /*************************************** + DEPOSIT FUNCTIONS + ***************************************/ + + /** + * @notice Deposits tokens into [`UWE`](./../../native/UnderwritingEquity) and deposits [`UWE`](./../../native/UnderwritingEquity) into a new [`UWE Lock`](./../../native/UnderwritingLocker). + * @param depositToken Address of the token to deposit. + * @param depositAmount Amount of the token to deposit. + * @param lockExpiry The timestamp the lock will unlock. + * @return lockID The ID of the newly created [`UWE Lock`](./../../native/UnderwritingLocker). + */ + function depositAndLock( + address depositToken, + uint256 depositAmount, + uint256 lockExpiry + ) external returns (uint256 lockID); + + /** + * @notice Deposits tokens into [`UWE`](./../../native/UnderwritingEquity) and deposits [`UWE`](./../../native/UnderwritingEquity) into an existing [`UWE Lock`](./../../native/UnderwritingLocker). + * @param depositToken Address of the token to deposit. + * @param depositAmount Amount of the token to deposit. + * @param lockID The ID of the [`UWE Lock`](./../../native/UnderwritingLocker) to deposit into. + */ + function depositIntoLock( + address depositToken, + uint256 depositAmount, + uint256 lockID + ) external; +} diff --git a/contracts/interfaces/native/IFluxMegaOracle.sol b/contracts/interfaces/native/IFluxMegaOracle.sol new file mode 100644 index 00000000..31d7de2e --- /dev/null +++ b/contracts/interfaces/native/IFluxMegaOracle.sol @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.6; + +import "./IPriceOracle.sol"; + +/** + * @title IFluxMegaOracle + * @author solace.fi + * @notice An oracle that consumes data from [Flux](https://fluxprotocol.org) and returns it in a useable format. + * + * [Governance](/docs/protocol/governance) can add or remove price feeds via [`addPriceFeeds()`](#addpricefeeds) and [`removePriceFeeds()`](#removepricefeeds). Users can view price feeds via [`priceFeedForToken(address token)`](#pricefeedfortoken). Users can use the price feeds via [`valueOfTokens()`](#valueoftokens). Users can list price feeds via [`tokensLength()`](#tokenslength) and [`tokenByIndex()`](#tokenbyindex). + */ +interface IFluxMegaOracle is IPriceOracle { + + /*************************************** + EVENTS + ***************************************/ + + /// @notice Emitted when a price feed is added. + event PriceFeedAdded(address indexed token); + /// @notice Emitted when a price feed is removed. + event PriceFeedRemoved(address indexed token); + + /*************************************** + VIEW FUNCTIONS + ***************************************/ + + struct PriceFeedData { + address token; + address priceFeed; + uint8 tokenDecimals; + uint8 priceFeedDecimals; + } + + /** + * @notice Returns information about the price feed for a token. + * @dev Returns a zero struct if no known price feed. + * @param token The token to query price feed data of. + * @return data Information about te price feed. + */ + function priceFeedForToken(address token) external view returns (PriceFeedData memory data); + + /** + * @notice Lists the tokens in the oracle. + * @dev Enumerable `[0,tokensLength]` + * @param index The index to query. + * @return token The address of the token at that index. + */ + function tokenByIndex(uint256 index) external view returns (address token); + + /** + * @notice The number of tokens with feeds in this oracle. + * @return len The number of tokens. + */ + function tokensLength() external view returns (uint256 len); + + /*************************************** + GOVERNANCE FUNCTIONS + ***************************************/ + + /** + * @notice Adds price feeds. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param feeds The list of price feeds to add. + */ + function addPriceFeeds(PriceFeedData[] memory feeds) external; + + /** + * @notice Removes price feeds. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param tokens The list of price feeds to remove. + */ + function removePriceFeeds(address[] memory tokens) external; +} diff --git a/contracts/interfaces/native/IFluxPriceFeed.sol b/contracts/interfaces/native/IFluxPriceFeed.sol new file mode 100644 index 00000000..aca4eac2 --- /dev/null +++ b/contracts/interfaces/native/IFluxPriceFeed.sol @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.6; + + +/** + * @title Flux first-party price feed oracle + * @author fluxprotocol.org + * @notice Simple data posting on chain of a scalar value, compatible with Chainlink V2 and V3 aggregator interface + */ +interface IFluxPriceFeed { + + /** + * @notice answer from the most recent report + */ + function latestAnswer() external view returns (int256); +} diff --git a/contracts/interfaces/native/IGaugeController.sol b/contracts/interfaces/native/IGaugeController.sol new file mode 100644 index 00000000..f21ac7e7 --- /dev/null +++ b/contracts/interfaces/native/IGaugeController.sol @@ -0,0 +1,369 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.6; + +import "./GaugeStructs.sol"; + +/** + * @title GaugeController + * @author solace.fi + * @notice Stores individual votes for Solace Native gauges, and maintains current gauge weights. + * + * Current gauge weights can be obtained through [`getGaugeWeight()`](#getgaugeweight) and [`getAllGaugeWeights()`](#getallgaugeweights) + * + * Only governance can make mutator calls to GaugeController.sol. There are no unpermissioned external mutator calls in this contract. + * + * After every epoch, governance must call [`updateGaugeWeights()`](#updategaugeweights). This will process the last epoch's votes (stored in this contract). + * + * Individual voters register and manage their vote through voting contracts that conform to IGaugeVoting. + * + * Governance can [`addGauge()`](#addgauge) or [`pauseGauge()`](#pausegauge). + */ +interface IGaugeController { + + /*************************************** + CUSTOM ERRORS + ***************************************/ + + /// @notice Thrown when zero address is given as an argument. + /// @param contractName Name of contract for which zero address was incorrectly provided. + error ZeroAddressInput(string contractName); + + /// @notice Thrown when array arguments are mismatched in length; + error ArrayArgumentsLengthMismatch(); + + /// @notice Thrown if pauseGauge() is attempted on a gauge that is already paused. + /// @param gaugeID The gauge ID. + error GaugeAlreadyPaused(uint256 gaugeID); + + /// @notice Thrown if unpauseGauge() is attempted on a gauge that is already paused. + /// @param gaugeID The gauge ID. + error GaugeAlreadyUnpaused(uint256 gaugeID); + + /// @notice Thrown if unpauseGauge() is attempted on gauge ID 0. + error CannotUnpauseGaugeID0(); + + /// @notice Thrown if vote() is attempted for gauge ID 0. + error CannotVoteForGaugeID0(); + + /// @notice Thrown if updateGaugeWeights() is called after gauge weights have been successfully updated in the current epoch. + error GaugeWeightsAlreadyUpdated(); + + /// @notice Thrown when vote attempted before gauge weights have been successfully updated for this epoch. + error GaugeWeightsNotYetUpdated(); + + /// @notice Thrown when vote() is called by an address not added as a voting contract. + error NotVotingContract(); + + /// @notice Thrown when removeVotingContract attempted for address that has not previously been added as a voting contract. + error VotingContractNotAdded(); + + /// @notice Thrown when vote() is called with gaugeID that does not exist. + error GaugeIDNotExist(); + + /// @notice Thrown when vote() is called with gaugeID that is paused. + error GaugeIDPaused(); + + /// @notice Thrown when getInsurancePremium() is called and there are no tokenholders added. + error NoTokenholdersAdded(); + + /// @notice Thrown when removeTokenholder() is attempted for an address not in the tokenholder set. + error TokenholderNotPresent(); + + /// @notice Thrown when updateGaugeWeights() is called by neither governance nor updater, or governance is locked. + error NotUpdaterNorGovernance(); + + /*************************************** + EVENTS + ***************************************/ + + /// @notice Emitted when a voting contract is added. + event VotingContractAdded(address indexed votingContractAddress); + + /// @notice Emitted when a voting contract is removed. + event VotingContractRemoved(address indexed votingContractAddress); + + /// @notice Emitted when a gauge is added. + event GaugeAdded(uint256 indexed gaugeID, uint256 rateOnLine, string gaugeName); + + /// @notice Emitted when a gauge is paused. + event GaugePaused(uint256 indexed gaugeID, string gaugeName); + + /// @notice Emitted when a gauge is unpaused. + event GaugeUnpaused(uint256 indexed gaugeID, string gaugeName); + + /// @notice Emitted when leverage factor set. + event LeverageFactorSet(uint256 indexed leverageFactor); + + /// @notice Emitted when rate on line for a gauge is set. + event RateOnLineSet(uint256 indexed gaugeID, uint256 rateOnLine); + + /// @notice Emitted when address of underwriting equity token is set. + event TokenSet(address indexed token); + + /// @notice Emitted when the epoch length is set. + event EpochLengthSet(uint256 indexed weeks_); + + /// @notice Emitted when the Updater is set. + event UpdaterSet(address indexed updater); + + /// @notice Emitted when address added to tokenholder set. + event TokenholderAdded(address indexed tokenholder); + + /// @notice Emitted when address removed from tokenholder set. + event TokenholderRemoved(address indexed tokenholder); + + /// @notice Emitted when updateGaugeWeights() does an incomplete update, and run again until completion. + event IncompleteGaugeUpdate(); + + /// @notice Emitted when gauge weights are updated. + event GaugeWeightsUpdated(uint256 indexed updateTime); + + /*************************************** + GLOBAL VARIABLES + ***************************************/ + + /// @notice Underwriting equity token. + function token() external view returns (address); + + /// @notice Updater address. + function updater() external view returns (address); + + /// @notice Insurance leverage factor. + function leverageFactor() external view returns (uint256); + + /// @notice The total number of gauges that have been created. + function totalGauges() external view returns (uint256); + + /// @notice End timestamp for last epoch that all stored votes were processed. + function lastTimeGaugeWeightsUpdated() external view returns (uint256); + + /*************************************** + EXTERNAL VIEW FUNCTIONS + ***************************************/ + + /** + * @notice Get timestamp for the start of the current epoch. + * @return timestamp + */ + function getEpochStartTimestamp() external view returns (uint256 timestamp); + + /** + * @notice Get timestamp for end of the current epoch. + * @return timestamp + */ + function getEpochEndTimestamp() external view returns (uint256 timestamp); + + /** + * @notice Get current gauge weight of single gauge ID. + * @dev Gauge weights must sum to 1e18, so a weight of 1e17 == 10% weight + * @param gaugeID_ The ID of the gauge to query. + * @return weight + */ + function getGaugeWeight(uint256 gaugeID_) external view returns (uint256 weight); + + /** + * @notice Get all gauge weights. + * @dev Gauge weights must sum to 1e18, so a weight of 1e17 == 10% weight. + * @dev weights[0] will always be 0, so that weights[1] maps to the weight of gaugeID 1. + * @return weights + */ + function getAllGaugeWeights() external view returns (uint256[] memory weights); + + /** + * @notice Get number of active gauges. + * @return numActiveGauges + */ + function getNumActiveGauges() external view returns (uint256 numActiveGauges); + + /** + * @notice Get number of paused gauges. + * @return numPausedGauges + */ + function getNumPausedGauges() external view returns (uint256 numPausedGauges); + + /** + * @notice Get gauge name. + * @param gaugeID_ The ID of the gauge to query. + * @return gaugeName + */ + function getGaugeName(uint256 gaugeID_) external view returns (string calldata gaugeName); + + /** + * @notice Query whether gauge is active. + * @param gaugeID_ The ID of the gauge to query. + * @return gaugeActive True if active, false otherwise. + */ + function isGaugeActive(uint256 gaugeID_) external view returns (bool gaugeActive); + + /** + * @notice Obtain rate on line of gauge. + * @param gaugeID_ The ID of the gauge to query. + * @return rateOnLine_ Annual rate on line, 1e18 => 100%. + */ + function getRateOnLineOfGauge(uint256 gaugeID_) external view returns (uint256 rateOnLine_); + + /** + * @notice Obtain insurance capacity in $UWE terms. + * @dev Leverage * UWE capacity. + * @return insuranceCapacity Insurance capacity in $UWE. + */ + function getInsuranceCapacity() external view returns (uint256 insuranceCapacity); + + /** + * @notice Get vote power sum across all gauges. + * @return votePowerSum + */ + function getVotePowerSum() external view returns (uint256 votePowerSum); + + /** + * @notice Get all votes for a given voter and voting contract. + * @param votingContract_ Address of voting contract - must have been added via addVotingContract(). + * @param voter_ Address of voter. + * @return votes Array of Vote {gaugeID, votePowerBPS}. + */ + function getVotes(address votingContract_, address voter_) external view returns (GaugeStructs.Vote[] memory votes); + + /** + * @notice Get all voters for a given voting contract. + * @param votingContract_ Address of voting contract - must have been added via addVotingContract(). + * @return voters Array of voters + */ + function getVoters(address votingContract_) external view returns (address[] memory voters); + + /** + * @notice Get number of votes for a given voter and voting contract. + * @param votingContract_ Address of voting contract - must have been added via addVotingContract(). + * @param voter_ Address of voter. + * @return voteCount Number of votes. + */ + function getVoteCount(address votingContract_, address voter_) external view returns (uint256 voteCount); + + /** + * @notice Get number of voters for a voting contract. + * @param votingContract_ Address of voting contract - must have been added via addVotingContract(). + * @return votersCount Number of votes. + */ + function getVotersCount(address votingContract_) external view returns (uint256 votersCount); + + /** + * @notice Get current epoch length in seconds. + * @return epochLength + */ + function getEpochLength() external view returns (uint256 epochLength); + + /*************************************** + VOTING CONTRACT FUNCTIONS + ***************************************/ + + /** + * @notice Register votes. + * @dev Can only be called by voting contracts that have been added via addVotingContract(). + * @param voter_ Address of voter. + * @param gaugeID_ The ID of the voted gauge. + * @param newVotePowerBPS_ Desired vote power BPS, 0 if removing vote. + * @return oldVotePowerBPS Old votePowerBPS value, 0 if new vote. + */ + function vote(address voter_, uint256 gaugeID_, uint256 newVotePowerBPS_) external returns (uint256 oldVotePowerBPS); + + /*************************************** + GOVERNANCE FUNCTIONS + ***************************************/ + + /** + * @notice Adds a voting contract. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param votingContract_ The votingContract to add. + */ + function addVotingContract(address votingContract_) external; + + /** + * @notice Removes a voting contract. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param votingContract_ The votingContract to add. + */ + function removeVotingContract(address votingContract_) external; + + /** + * @notice Adds an insurance gauge. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param gaugeName_ Gauge name + * @param rateOnLine_ Annual rate on line (1e18 => 100%). + */ + function addGauge(string calldata gaugeName_, uint256 rateOnLine_) external; + + /** + * @notice Pauses an insurance gauge. + * @notice Paused gauges cannot have votes added or modified, and votes for a paused gauge will not be counted + * in the next updateGaugeWeights() call. + * @dev We do not include a removeGauge function as this would distort the order of the _gauges array + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param gaugeID_ ID of gauge to pause + */ + function pauseGauge(uint256 gaugeID_) external; + + /** + * @notice Unpauses an insurance gauge. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param gaugeID_ ID of gauge to pause + */ + function unpauseGauge(uint256 gaugeID_) external; + + /** + * @notice Set insurance leverage factor. + * @dev 1e18 => 100%. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param leverageFactor_ Desired leverage factor. + */ + function setLeverageFactor(uint256 leverageFactor_) external; + + /** + * @notice Set underwriting token address. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param token_ The address of the new underwriting token. + */ + function setToken(address token_) external; + + /** + * @notice Set updater address. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param updater_ The address of the new updater. + */ + function setUpdater(address updater_) external; + + /** + * @notice Set epoch length (as an integer multiple of 1 week). + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param weeks_ Integer multiple of 1 week, to set epochLength to. + */ + function setEpochLengthInWeeks(uint256 weeks_) external; + + /** + * @notice Adds address to tokenholders set - these addresses will be queried for $UWE token balance and summed to determine the Solace Native insurance capacity. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param tokenholder_ Address of new tokenholder + */ + function addTokenholder(address tokenholder_) external; + + /** + * @notice Removes an address from the tokenholder set - these addresses will be queried for $UWE token balance and summed to determine the Solace Native insurance capacity. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param tokenholder_ Address of new tokenholder. + */ + function removeTokenholder(address tokenholder_) external; + + /** + * @notice Set annual rate-on-line for selected gaugeIDs + * @dev 1e18 => 100% + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param gaugeIDs_ Array of gaugeIDs. + * @param rateOnLines_ Array of corresponding annual rate on lines. + */ + function setRateOnLine(uint256[] calldata gaugeIDs_, uint256[] calldata rateOnLines_) external; + + /** + * @notice Updates gauge weights by processing votes for the last epoch. + * @dev Designed to be called in a while-loop with custom gas limit of 6M until `lastTimePremiumsCharged == epochStartTimestamp`. + * Can only be called by the current [**governor**](/docs/protocol/governance) or the updater role. + */ + function updateGaugeWeights() external; +} diff --git a/contracts/interfaces/native/IGaugeVoter.sol b/contracts/interfaces/native/IGaugeVoter.sol new file mode 100644 index 00000000..56327b06 --- /dev/null +++ b/contracts/interfaces/native/IGaugeVoter.sol @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.6; + +/** + * @title IGaugeVoter + * @author solace.fi + * @notice A standard interface for a contract that interacts with GaugeController.sol to register votes. + */ +interface IGaugeVoter { + /** + * @notice Get vote power for a voter. + * @param voter_ The address of the voter to query. + * @return votePower + */ + function getVotePower(address voter_) external view returns (uint256 votePower); + + /** + * @notice Cache last processed vote power for a vote ID. + * @dev Can only be called by the gaugeController contract. + * @dev For chargePremiums() calculations. + * @param voter_ Address of voter. + * @param votePower_ Vote power. + */ + function cacheLastProcessedVotePower(address voter_, uint256 votePower_) external; +} diff --git a/contracts/interfaces/native/IPriceOracle.sol b/contracts/interfaces/native/IPriceOracle.sol new file mode 100644 index 00000000..1cb1e392 --- /dev/null +++ b/contracts/interfaces/native/IPriceOracle.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.6; + +/** + * @title IPriceOracle + * @author solace.fi + * @notice Generic interface for an oracle that determines the price of tokens. + */ +interface IPriceOracle { + + /** + * @notice Given an amount of some token, calculates the value in `USD`. + * @param token The address of the token to price. + * @param amount The amount of the token to price. + * @return valueInUSD The value in `USD` with 18 decimals. + */ + function valueOfTokens(address token, uint256 amount) external view returns (uint256 valueInUSD); +} diff --git a/contracts/interfaces/native/ISolaceMegaOracle.sol b/contracts/interfaces/native/ISolaceMegaOracle.sol new file mode 100644 index 00000000..af6c1387 --- /dev/null +++ b/contracts/interfaces/native/ISolaceMegaOracle.sol @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.6; + +import "./IPriceOracle.sol"; + +/** + * @title ISolaceMegaOracle + * @author solace.fi + * @notice An oracle that consumes data from Solace updaters and returns it in a useable format. + * + * [Governance](/docs/protocol/governance) can add or remove updater bots via [`setUpdaterStatuses()`](#setupdaterstatuses). Users can view updater status via [`isUpdater()`](#isupdater). Updaters can update prices via [`transmit()`](#transmit). + * + * price feeds via [`priceFeedForToken(address token)`](#pricefeedfortoken). Users can use the price feeds via [`valueOfTokens()`](#valueoftokens). Users can list price feeds via [`tokensLength()`](#tokenslength) and [`tokenByIndex()`](#tokenbyindex). + */ +interface ISolaceMegaOracle is IPriceOracle { + + /*************************************** + EVENTS + ***************************************/ + + /// @notice Emitted when a price feed metadata is set. + event PriceFeedAdded(address indexed token); + /// @notice Emitted when a price is transmitted. + event PriceTransmitted(address indexed token, uint256 price); + /// @notice Emitted when an updater is added or removed. + event UpdaterSet(address indexed updater, bool status); + + /*************************************** + VIEW FUNCTIONS + ***************************************/ + + struct PriceFeedData { + uint256 latestPrice; + address token; + uint8 tokenDecimals; + uint8 priceFeedDecimals; + } + + /** + * @notice Returns information about the price feed for a token. + * @dev Returns a zero struct if no known price feed. + * @param token The token to query price feed data of. + * @return data Information about te price feed. + */ + function priceFeedForToken(address token) external view returns (PriceFeedData memory data); + + /** + * @notice Lists the tokens in the oracle. + * @dev Enumerable `[0,tokensLength]` + * @param index The index to query. + * @return token The address of the token at that index. + */ + function tokenByIndex(uint256 index) external view returns (address token); + + /** + * @notice The number of tokens with feeds in this oracle. + * @return len The number of tokens. + */ + function tokensLength() external view returns (uint256 len); + + /** + * @notice Returns the status of an updater. + * @param updater The account to query. + * @return status True if the account has the updater role, false otherwise. + */ + function isUpdater(address updater) external view returns (bool status); + + /*************************************** + UPDATER FUNCTIONS + ***************************************/ + + /** + * @notice Sets metadata for each token and adds it to the token enumeration. + * Can only be called by an `updater`. + * @param feeds The list of feeds to set. + */ + function addPriceFeeds(PriceFeedData[] memory feeds) external; + + /** + * @notice Sets latest price for each token. + * Can only be called by an `updater`. + * @param tokens The list of token addresses to set prices for. + * @param prices The list of prices for each token. + */ + function transmit(address[] memory tokens, uint256[] memory prices) external; + + /*************************************** + GOVERNANCE FUNCTIONS + ***************************************/ + + /** + * @notice Adds or removes updaters. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param updaters The list of updater addresses to add or remove. + * @param statuses A list of true to set as updater false otherwise. + */ + function setUpdaterStatuses(address[] memory updaters, bool[] memory statuses) external; +} diff --git a/contracts/interfaces/native/IUnderwritingEquity.sol b/contracts/interfaces/native/IUnderwritingEquity.sol new file mode 100644 index 00000000..3a30cd38 --- /dev/null +++ b/contracts/interfaces/native/IUnderwritingEquity.sol @@ -0,0 +1,152 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.6; + +import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; + + +/** + * @title IUnderwritingEquity + * @author solace.fi + * @notice Equity of the [Underwriting Pool](./../../native/UnderwritingPool) that can be used in Solace Native. + * + * Users can deposit [`UWP`](./../../native/UnderwritingPool) via [`deposit()`](#deposit) which mints `UWE`. Users can redeem `UWE` for [`UWP`](./../../native/UnderwritingPool) via [`withdraw()`](#withdraw). Note that deposits must be made via [`deposit()`](#deposit). Simply transferring [`UWP`](./../../native/UnderwritingPool) to this contract will not mint `UWE`. + * + * Solace may charge a protocol fee as a fraction of the mint amount [`issueFee()`](#issuefee). + * + * Solace may lend some of the underlying [`UWP`](./../../native/UnderwritingPool) to a lending module and borrow stables against it to pay claims via [`lend()`](#lend). + * + * [Governance](/docs/protocol/governance) can pause and unpause [`deposit()`](#deposit), [`withdraw()`](#withdraw), and [`lend()`](#lend). + */ +interface IUnderwritingEquity is IERC20Metadata { + + /*************************************** + EVENTS + ***************************************/ + + /// @notice Emitted when a deposit is made. + event DepositMade(address indexed user, uint256 uwpAmount, uint256 uweAmount); + /// @notice Emitted when a withdraw is made. + event WithdrawMade(address indexed user, uint256 uwpAmount, uint256 uweAmount); + /// @notice Emitted when uwp is loaned. + event UwpLoaned(uint256 uwpAmount, address receiver); + /// @notice Emitted when issue fee is set. + event IssueFeeSet(uint256 fee, address receiver); + /// @notice Emitted when pause is set. + event PauseSet(bool depositIsPaused, bool withdrawIsPaused, bool lendIsPaused); + /// @notice Emitted when the [`UWP`](./../../native/UnderwritingPool) contract is set. + event UwpSet(address uwp); + + /*************************************** + VIEW FUNCTIONS + ***************************************/ + + /** + * @notice Address of the [underwriting pool](./../../native/UnderwritingPool). + * @return uwp The underwriting pool. + */ + function underwritingPool() external view returns (address uwp); + + /** + * @notice The fraction of `UWE` that are charged as a protocol fee on mint. + * @return fee The fee as a fraction with 18 decimals. + */ + function issueFee() external view returns (uint256 fee); + + /** + * @notice The receiver of issue fees. + * @return receiver The receiver of the fee. + */ + function issueFeeTo() external view returns (address receiver); + + /** + * @notice Returns true if functionality of the contract is paused. + * @return depositIsPaused Returns true if depositing is paused. + * @return withdrawIsPaused Returns true if withdrawing is paused. + * @return lendIsPaused Returns true if lending is paused. + */ + function isPaused() external view returns (bool depositIsPaused, bool withdrawIsPaused, bool lendIsPaused); + + /** + * @notice Calculates the amount of `UWE` minted for an amount of [`UWP`](./../../native/UnderwritingPool) deposited. + * @param uwpAmount The amount of [`UWP`](./../../native/UnderwritingPool) to deposit. + * @return uweAmount The amount of `UWE` that will be minted to the receiver. + */ + function calculateDeposit(uint256 uwpAmount) external view returns (uint256 uweAmount); + + /** + * @notice Calculates the amount of [`UWP`](./../../native/UnderwritingPool) returned for an amount of `UWE` withdrawn. + * @param uweAmount The amount of `UWE` to redeem. + * @return uwpAmount The amount of [`UWP`](./../../native/UnderwritingPool) that will be returned to the receiver. + */ + function calculateWithdraw(uint256 uweAmount) external view returns (uint256 uwpAmount); + + /*************************************** + MODIFIER FUNCTIONS + ***************************************/ + + /** + * @notice Deposits [`UWP`](./../../native/UnderwritingPool) into `UWE`. + * @param uwpAmount The amount of [`UWP`](./../../native/UnderwritingPool) to deposit. + * @param receiver The address to send newly minted `UWE` to. + * @return uweAmount The amount of `UWE` minted. + */ + function deposit(uint256 uwpAmount, address receiver) external returns (uint256 uweAmount); + + /** + * @notice Redeems some `UWE` for [`UWP`](./../../native/UnderwritingPool). + * @param uweAmount The amount of `UWE` to burn. + * @param receiver The address to receive [`UWP`](./../../native/UnderwritingPool). + * @return uwpAmount The amount of [`UWP`](./../../native/UnderwritingPool) received. + */ + function withdraw(uint256 uweAmount, address receiver) external returns (uint256 uwpAmount); + + /** + * @notice Burns some `UWE` from `msg.sender`. + * @param uweAmount The amount of `UWE` to burn. + */ + function burn(uint256 uweAmount) external; + + /*************************************** + GOVERNANCE FUNCTIONS + ***************************************/ + + /** + * @notice Rescues misplaced tokens. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param tokens The list of tokens to rescue. + * @param receiver The receiver of the tokens. + */ + function rescueTokens(address[] memory tokens, address receiver) external; + + /** + * @notice Lends out [`UWP`](./../../native/UnderwritingPool) to pay claims. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param uwpAmount The amount of [`UWP`](./../../native/UnderwritingPool) to lend. + * @param receiver The receiver of [`UWP`](./../../native/UnderwritingPool). + */ + function lend(uint256 uwpAmount, address receiver) external; + + /** + * @notice Sets the issue fee and receiver. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param fee The fee as a fraction with 18 decimals. + * @param receiver The receiver of the fee. + */ + function setIssueFee(uint256 fee, address receiver) external; + + /** + * @notice Pauses or unpauses contract functionality. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param depositIsPaused True to pause deposit, false to unpause. + * @param withdrawIsPaused True to pause withdraw, false to unpause. + * @param lendIsPaused True to pause lend, false to unpause. + */ + function setPause(bool depositIsPaused, bool withdrawIsPaused, bool lendIsPaused) external; + + /** + * @notice Upgrades the [`UWP`](./../../native/UnderwritingPool) contract. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param uwp_ The address of the new [`UWP`](./../../native/UnderwritingPool). + */ + function setUwp(address uwp_) external; +} diff --git a/contracts/interfaces/native/IUnderwritingLockListener.sol b/contracts/interfaces/native/IUnderwritingLockListener.sol new file mode 100644 index 00000000..459fa258 --- /dev/null +++ b/contracts/interfaces/native/IUnderwritingLockListener.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.6; + +import "./IUnderwritingLocker.sol"; + +/** + * @title IUnderwritingLockListener + * @author solace.fi + * @notice A standard interface for notifying a contract about an action in another contract. + */ +interface IUnderwritingLockListener { + /** + * @notice Called when an action is performed on a lock. + * @dev Called on transfer, mint, burn, and update. + * Either the owner will change or the lock will change, not both. + * @param lockID_ The ID of the lock that was altered. + * @param oldOwner_ The old owner of the lock. + * @param newOwner_ The new owner of the lock. + * @param oldLock_ The old lock data. + * @param newLock_ The new lock data. + */ + function registerLockEvent(uint256 lockID_, address oldOwner_, address newOwner_, Lock memory oldLock_, Lock memory newLock_) external; +} diff --git a/contracts/interfaces/native/IUnderwritingLockVoting.sol b/contracts/interfaces/native/IUnderwritingLockVoting.sol new file mode 100644 index 00000000..f3b04f61 --- /dev/null +++ b/contracts/interfaces/native/IUnderwritingLockVoting.sol @@ -0,0 +1,297 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.6; + +import "./IGaugeVoter.sol"; +import "./GaugeStructs.sol"; + +/** + * @title IUnderwritingLockVoting + * @author solace.fi + * @notice Enables individual votes in Solace Native insurance gauges for owners of [`UnderwritingLocker`](./UnderwritingLocker). + * + * Any address owning an underwriting lock can vote and will have a votePower that can be viewed with [`getVotePower()`](#getVotePower) + * An address' vote power is the sum of the vote power of its owned locks. + * A lock's vote power scales linearly with locked amount, and through a sqrt formula with lock duration + * Users cannot view the vote power of an individual lock through this contract, only the total vote power of an address. + * This is an intentional design choice to abstract locks away from address-based voting. + * + * Voters can set a delegate who can vote on their behalf via [`setDelegate()`](#setDelegate). + * + * To cast a vote, either the voter or their delegate can call [`vote()`](#vote) or [`voteMultiple()`](#voteMultiple). + * Votes can be cast among existing gaugeIDs (set in GaugeController.sol), and voters/delegates can set a custom proportion + * of their total voting power for different gauges. + * Voting power proportion is measured in bps, and total used voting power bps for a voter cannot exceed 10000. + * + * Votes are saved, so a vote today will count as the voter's vote for all future epochs until the voter modifies their votes. + * + * After each epoch (one-week) has passed, voting is frozen until governance has processed all the votes. + * This is a two-step process: + * GaugeController.updateGaugeWeights() - this will aggregate individual votes and update gauge weights accordingly + * [`chargePremiums()`](#chargepremiums) - this will charge premiums for every vote. There is a voting premium + * to be paid every epoch, this gets sent to the revenue router. + */ +interface IUnderwritingLockVoting is IGaugeVoter { + + /*************************************** + CUSTOM ERRORS + ***************************************/ + + /// @notice Thrown when zero address is given as an argument. + /// @param contractName Name of contract for which zero address was incorrectly provided. + error ZeroAddressInput(string contractName); + + /// @notice Thrown when array arguments are mismatched in length (and need to have the same length); + error ArrayArgumentsLengthMismatch(); + + /// @notice Thrown when setDelegate() attempted for a non-owner. + error NotOwner(); + + /// @notice Thrown when vote is attempted before last epoch's premiums have been successfully charged. + error LastEpochPremiumsNotCharged(); + + /// @notice Thrown when vote() attempted by a non-owner or non-delegate. + error NotOwnerNorDelegate(); + + /// @notice Thrown when vote is attempted for voter with no underwriting locks. + error VoterHasNoLocks(); + + /// @notice Thrown if attempt to vote with single vote having votePowerBPS > 10000. + error SingleVotePowerBPSOver10000(); + + /// @notice Thrown if attempt to vote with total votePowerBPS > 10000. + error TotalVotePowerBPSOver10000(); + + /// @notice Thrown when non-gaugeController attempts to call setLastRecordedVotePower(). + error NotGaugeController(); + + /// @notice Thrown when chargePremiums is attempted before the last epoch's votes have been successfully processed through gaugeController.updateGaugeWeights(). + error GaugeWeightsNotYetUpdated(); + + /// @notice Thrown when chargePremiums() attempted when all premiums have been charged for the last epoch. + /// @param epochTime Timestamp of endtime for epoch already processed. + error LastEpochPremiumsAlreadyProcessed(uint256 epochTime); + + /// @notice Thrown when chargePremiums() is called by neither governance nor updater, or governance is locked. + error NotUpdaterNorGovernance(); + + /*************************************** + EVENTS + ***************************************/ + + /// @notice Emitted when a delegate is set for a voter. + event DelegateSet(address indexed voter, address indexed delegate); + + /// @notice Emitted when the Registry is set. + event RegistrySet(address indexed registry); + + /// @notice Emitted when the Updater is set. + event UpdaterSet(address indexed updater); + + /// @notice Emitted when the Bribe Controller is set. + event BribeControllerSet(address indexed bribeController); + + /// @notice Emitted when a vote is added. + event VoteAdded(address indexed voter, uint256 indexed gaugeID, uint256 votePowerBPS); + + /// @notice Emitted when a vote is added. + event VoteChanged(address indexed voter, uint256 indexed gaugeID, uint256 newVotePowerBPS, uint256 oldVotePowerBPS); + + /// @notice Emitted when a vote is removed. + event VoteRemoved(address indexed voter, uint256 indexed gaugeID); + + /// @notice Emitted when chargePremiums was partially completed and needs to be called again. + event IncompletePremiumsCharge(); + + /// @notice Emitted when premiums for all stored votes have been processed in an epoch. + event AllPremiumsCharged(uint256 indexed epochTimestamp); + + /*************************************** + GLOBAL VARIABLES + ***************************************/ + + /// @notice Revenue router address ($UWE voting fees will be transferred here). + function revenueRouter() external view returns (address); + + /// @notice Address of [`UnderwritingLocker`](./UnderwritingLocker) + function underwritingLocker() external view returns (address); + + /// @notice Address of [`GaugeController`](./GaugeController). + function gaugeController() external view returns (address); + + /// @notice Address of [`BribeController`](./BribeController). + function bribeController() external view returns (address); + + /// @notice Registry address + function registry() external view returns (address); + + /// @notice Updater address. + function updater() external view returns (address); + + /** + * @notice End timestamp for last epoch that premiums were charged for all stored votes. + * @return timestamp_ + */ + function lastTimePremiumsCharged() external view returns (uint256 timestamp_); + + /** + * @notice Get delegate for a given voter. + * @param voter_ The address of the voter to query for. + * @return delegate Zero address if no lock delegate. + */ + function delegateOf(address voter_) external view returns (address delegate); + + /** + * @notice voter => used voting power percentage (max of 10000 BPS) + * @param voter_ The address of the voter to query for. + * @return usedVotePowerBPS Total usedVotePowerBPS. + */ + function usedVotePowerBPSOf(address voter_) external view returns (uint256 usedVotePowerBPS); + + /*************************************** + EXTERNAL VIEW FUNCTIONS + ***************************************/ + + /** + * @notice Get all current votes for a voter. + * @param voter_ Address of voter to query for. + * @return votes Array of Vote{gaugeID, votePowerBPS}. + */ + function getVotes(address voter_) external view returns (GaugeStructs.Vote[] memory votes); + + /** + * @notice Get timestamp for the start of the current epoch. + * @return timestamp + */ + function getEpochStartTimestamp() external view returns (uint256 timestamp); + + /** + * @notice Get timestamp for end of the current epoch. + * @return timestamp + */ + function getEpochEndTimestamp() external view returns (uint256 timestamp); + + /** + * @notice Query whether voting is currently open. + * @return True if voting is open for this epoch, false otherwise. + */ + function isVotingOpen() external view returns (bool); + + /** + * @notice Get array of voters who have delegated their vote to a given address. + * @param delegate_ Address to query array of voting delegators for. + * @return votingDelegators Array of voting delegators. + */ + function getVotingDelegatorsOf(address delegate_) external view returns (address[] memory votingDelegators); + + /** + * @notice Get last processed vote power for given voter. + * @param voter_ Address of voter to query for. + * @return lastProcessedVotePower + */ + function getLastProcessedVotePowerOf(address voter_) external view returns (uint256 lastProcessedVotePower); + + /*************************************** + EXTERNAL MUTATOR FUNCTIONS + ***************************************/ + + /** + * @notice Register a single vote for a gauge. Can either add or change a vote. + * @notice Can also remove a vote (votePowerBPS_ == 0), the difference with removeVote() is that + * vote() will revert if the voter has no locks (no locks => no right to vote, but may have votes from + * locks that have since been burned). + * @notice GaugeController.updateGaugeWeights() will remove voters with no voting power, however voters can + * preemptively 'clean' the system. + * @notice Votes are frozen after the end of every epoch, and resumed when all stored votes have been processed. + * Can only be called by the voter or vote delegate. + * @param voter_ The voter address. + * @param gaugeID_ The ID of the gauge to vote for. + * @param votePowerBPS_ Vote power BPS to assign to this vote + */ + function vote(address voter_, uint256 gaugeID_, uint256 votePowerBPS_) external; + + /** + * @notice Register multiple gauge votes. + * Can only be called by the voter or vote delegate. + * @param voter_ The voter address. + * @param gaugeIDs_ Array of gauge IDs to vote for. + * @param votePowerBPSs_ Array of corresponding vote power BPS values. + */ + function voteMultiple(address voter_, uint256[] memory gaugeIDs_, uint256[] memory votePowerBPSs_) external; + + /** + * @notice Register a single voting configuration for multiple voters. + * Can only be called by the voter or vote delegate. + * @param voters_ Array of voters. + * @param gaugeIDs_ Array of gauge IDs to vote for. + * @param votePowerBPSs_ Array of corresponding vote power BPS values. + */ + function voteForMultipleVoters(address[] calldata voters_, uint256[] memory gaugeIDs_, uint256[] memory votePowerBPSs_) external; + + /** + * @notice Removes a vote. + * @notice Votes cannot be removed while voting is frozen. + * Can only be called by the voter or vote delegate. + * @param voter_ The voter address. + * @param gaugeID_ The ID of the gauge to remove vote for. + */ + function removeVote(address voter_, uint256 gaugeID_) external; + + /** + * @notice Remove multiple gauge votes. + * @notice Votes cannot be removed while voting is frozen. + * Can only be called by the voter or vote delegate. + * @param voter_ The voter address. + * @param gaugeIDs_ Array of gauge IDs to remove votes for. + */ + function removeVoteMultiple(address voter_, uint256[] memory gaugeIDs_) external; + + /** + * @notice Remove gauge votes for multiple voters. + * @notice Votes cannot be removed while voting is frozen. + * Can only be called by the voter or vote delegate. + * @param voters_ Array of voter addresses. + * @param gaugeIDs_ Array of gauge IDs to remove votes for. + */ + function removeVotesForMultipleVoters(address[] calldata voters_, uint256[] memory gaugeIDs_) external; + + /** + * @notice Set the voting delegate for the caller. + * To remove a delegate, the delegate can be set to the ZERO_ADDRESS - 0x0000000000000000000000000000000000000000. + * @param delegate_ Address of intended delegate + */ + function setDelegate(address delegate_) external; + + /*************************************** + GOVERNANCE FUNCTIONS + ***************************************/ + + /** + * @notice Sets the [`Registry`](./Registry) contract address. + * @dev Requires 'uwe', 'revenueRouter' and 'underwritingLocker' addresses to be set in the Registry. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param registry_ The address of `Registry` contract. + */ + function setRegistry(address registry_) external; + + /** + * @notice Set updater address. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param updater_ The address of the new updater. + */ + function setUpdater(address updater_) external; + + /** + * @notice Sets bribeController as per `bribeController` address stored in Registry. + * @dev We do not set this in constructor, because we expect BribeController.sol to be deployed after this contract. + * Can only be called by the current [**governor**](/docs/protocol/governance). + */ + function setBribeController() external; + + /** + * @notice Charge premiums for votes. + * @dev Designed to be called in a while-loop with the condition being `lastTimePremiumsCharged != epochStartTimestamp` and using the maximum custom gas limit. + * @dev Requires GaugeController.updateGaugeWeights() to be run to completion for the last epoch. + * Can only be called by the current [**governor**](/docs/protocol/governance). + */ + function chargePremiums() external; +} diff --git a/contracts/interfaces/native/IUnderwritingLocker.sol b/contracts/interfaces/native/IUnderwritingLocker.sol new file mode 100644 index 00000000..236a31fc --- /dev/null +++ b/contracts/interfaces/native/IUnderwritingLocker.sol @@ -0,0 +1,395 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.6; + +import "./../utils/IERC721Enhanced.sol"; + +/// @dev Defining Lock struct outside of the interface body causes this struct to be visible to contracts that import, but do not inherit, this file. If we otherwise define this struct in the interface body, it is only visible to contracts that both import and inherit this file. +struct Lock { + uint256 amount; + uint256 end; +} + +/** + * @title IUnderwritingLocker + * @author solace.fi + * @notice Having an underwriting lock is a requirement to vote on Solace Native insurance gauges. + * To create an underwriting lock, $UWE must be locked for a minimum of 6 months. + * + * Locks are ERC721s and can be viewed with [`locks()`](#locks). + * Each lock has an `amount` of locked $UWE, and an `end` timestamp. + * Locks have a maximum duration of four years. + * + * Users can create locks via [`createLock()`](#createlock) or [`createLockSigned()`](#createlocksigned). + * Users can deposit more $UWE into a lock via [`increaseAmount()`](#increaseamount), [`increaseAmountSigned()`] (#increaseamountsigned) or [`increaseAmountMultiple()`](#increaseamountmultiple). + * Users can extend a lock via [`extendLock()`](#extendlock) or [`extendLockMultiple()`](#extendlockmultiple). + * Users can withdraw from a lock via [`withdraw()`](#withdraw), [`withdrawInPart()`](#withdrawinpart), [`withdrawMultiple()`](#withdrawmultiple) or [`withdrawInPartMultiple()`](#withdrawinpartmultiple). + * + * Users and contracts may create a lock for another address. + * Users and contracts may deposit into a lock that they do not own. + * A portion (set by the funding rate) of withdraws will be burned. This is to incentivize longer staking periods - withdrawing later than other users will yield more tokens than withdrawing earlier. + * Early withdrawls will incur an additional burn, which will increase with longer remaining lock duration. + * + * Any time a lock is minted, burned or otherwise modified it will notify the listener contracts. + */ +// solhint-disable-next-line contract-name-camelcase +interface IUnderwritingLocker is IERC721Enhanced { + + /*************************************** + CUSTOM ERRORS + ***************************************/ + + /// @notice Thrown when array arguments are mismatched in length (and need to have the same length); + error ArrayArgumentsLengthMismatch(); + + /// @notice Thrown when zero address is given as an argument. + /// @param contractName Name of contract for which zero address was incorrectly provided. + error ZeroAddressInput(string contractName); + + /// @notice Thrown when extend or withdraw is attempted by a party that is not the owner nor approved for a lock. + error NotOwnerNorApproved(); + + /// @notice Thrown when create lock is attempted with 0 deposit. + error CannotCreateEmptyLock(); + + /// @notice Thrown when a user attempts to create a new lock, when they already have MAX_NUM_LOCKS locks. + error CreatedMaxLocks(); + + /// @notice Thrown when createLock is attempted with lock duration < 6 months. + error LockTimeTooShort(); + + /// @notice Thrown when createLock or extendLock is attempted with lock duration > 4 years. + error LockTimeTooLong(); + + /// @notice Thrown when extendLock is attempted to shorten the lock duration. + error LockTimeNotExtended(); + + /// @notice Thrown when a withdraw is attempted for an `amount` that exceeds the lock balance. + error ExcessWithdraw(); + + /// @notice Thrown when funding rate is set above 100% + error FundingRateAboveOne(); + + /// @notice Emitted when chargePremium() is not called by the voting contract. + error NotVotingContract(); + + /*************************************** + EVENTS + ***************************************/ + + /// @notice Emitted when a lock is created. + event LockCreated(uint256 indexed lockID); + + /// @notice Emitted when a new deposit is made into an existing lock. + event LockIncreased(uint256 indexed lockID, uint256 newTotalAmount, uint256 depositAmount); + + /// @notice Emitted when a new deposit is made into an existing lock. + event LockExtended(uint256 indexed lockID, uint256 newEndTimestamp); + + /// @notice Emitted when a lock is updated. + event LockUpdated(uint256 indexed lockID, uint256 amount, uint256 end); + + /// @notice Emitted when a lock is withdrawn from. + event Withdrawal(uint256 indexed lockID, uint256 requestedWithdrawAmount, uint256 actualWithdrawAmount, uint256 burnAmount); + + /// @notice Emitted when an early withdraw is made. + event EarlyWithdrawal(uint256 indexed lockID, uint256 requestedWithdrawAmount, uint256 actualWithdrawAmount, uint256 burnAmount); + + /// @notice Emitted when a listener is added. + event LockListenerAdded(address indexed listener); + + /// @notice Emitted when a listener is removed. + event LockListenerRemoved(address indexed listener); + + /// @notice Emitted when the registry is set. + event RegistrySet(address indexed registry); + + /// @notice Emitted when voting contract has been set + event VotingContractSet(address indexed votingContract); + + /// @notice Emitted when funding rate is set. + event FundingRateSet(uint256 indexed fundingRate); + + /*************************************** + GLOBAL VARIABLES + ***************************************/ + + /// @notice Token locked in the underwriting lock. + function token() external view returns (address); + + /// @notice Registry address + function registry() external view returns (address); + + /// @notice UnderwriterLockVoting.sol address. + function votingContract() external view returns (address); + + /// @notice The total number of locks that have been created. + function totalNumLocks() external view returns (uint256); + + /// @notice Funding rate - amount that will be charged and burned from a regular withdraw. + /// @dev Value of 1e18 => 100%. + function fundingRate() external view returns (uint256); + + /// @notice The minimum lock duration that a new lock must be created with. + function MIN_LOCK_DURATION() external view returns (uint256); + + /// @notice The maximum time into the future that a lock can expire. + function MAX_LOCK_DURATION() external view returns (uint256); + + /// @notice The maximum number of locks one user can create. + function MAX_NUM_LOCKS() external view returns (uint256); + + /*************************************** + EXTERNAL VIEW FUNCTIONS + ***************************************/ + + /** + * @notice Get `amount` and `end` values for a lockID. + * @param lockID_ The ID of the lock to query. + * @return lock_ Lock {uint256 amount, uint256 end}. + */ + function locks(uint256 lockID_) external view returns (Lock memory lock_); + + + /** + * @notice Determines if the lock is currently locked. + * @param lockID_ The ID of the lock to query. + * @return locked True if the lock is locked, false if unlocked. + */ + function isLocked(uint256 lockID_) external view returns (bool locked); + + /** + * @notice Determines the time left until the lock unlocks. + * @param lockID_ The ID of the lock to query. + * @return time The time left in seconds, 0 if unlocked. + */ + function timeLeft(uint256 lockID_) external view returns (uint256 time); + + /** + * @notice Returns the total token amount that the user has staked in underwriting locks. + * @param account_ The account to query. + * @return balance The user's total staked token amount. + */ + function totalStakedBalance(address account_) external view returns (uint256 balance); + + /** + * @notice The list of contracts that are listening to lock updates. + * @return listeners_ The list as an array. + */ + function getLockListeners() external view returns (address[] memory listeners_); + + /** + * @notice Computes amount of token that will be transferred to the user on full withdraw. + * @param lockID_ The ID of the lock to query. + * @return withdrawAmount Token amount that will be withdrawn. + */ + function getWithdrawAmount(uint256 lockID_) external view returns (uint256 withdrawAmount); + + /** + * @notice Computes amount of token that will be transferred to the user on partial withdraw. + * @param lockID_ The ID of the lock to query. + * @param amount_ The requested amount to withdraw. + * @return withdrawAmount Token amount that will be withdrawn. + */ + function getWithdrawInPartAmount(uint256 lockID_, uint256 amount_) external view returns (uint256 withdrawAmount); + + /** + * @notice Computes amount of token that will be burned on full withdraw. + * @param lockID_ The ID of the lock to query. + * @return burnAmount Token amount that will be burned on withdraw. + */ + function getBurnOnWithdrawAmount(uint256 lockID_) external view returns (uint256 burnAmount); + + /** + * @notice Computes amount of token that will be burned on partial withdraw. + * @param lockID_ The ID of the lock to query. + * @param amount_ The requested amount to withdraw. + * @return burnAmount Token amount that will be burned on withdraw. + */ + function getBurnOnWithdrawInPartAmount(uint256 lockID_, uint256 amount_) external view returns (uint256 burnAmount); + + /** + * @notice Gets multiplier (applied for voting boost, and for early withdrawals). + * @param lockID_ The ID of the lock to query. + * @return multiplier 1e18 => 1x multiplier, 2e18 => 2x multiplier. + */ + function getLockMultiplier(uint256 lockID_) external view returns (uint256 multiplier); + + /** + * @notice Gets all active lockIDs for a user. + * @param user_ The address of user to query. + * @return lockIDs Array of active lockIDs. + */ + function getAllLockIDsOf(address user_) external view returns (uint256[] memory lockIDs); + + /*************************************** + EXTERNAL MUTATOR FUNCTIONS + ***************************************/ + + /** + * @notice Deposit token to create a new lock. + * @dev Token is transferred from msg.sender, assumes its already approved. + * @param recipient_ The account that will receive the lock. + * @param amount_ The amount of token to deposit. + * @param end_ The timestamp the lock will unlock. + * @return lockID The ID of the newly created lock. + */ + function createLock(address recipient_, uint256 amount_, uint256 end_) external returns (uint256 lockID); + + /** + * @notice Deposit token to create a new lock. + * @dev Token is transferred from msg.sender using ERC20Permit. + * @dev recipient = msg.sender. + * @param amount_ The amount of token to deposit. + * @param end_ The timestamp the lock will unlock. + * @param deadline_ Time the transaction must go through before. + * @param v secp256k1 signature + * @param r secp256k1 signature + * @param s secp256k1 signature + * @return lockID The ID of the newly created lock. + */ + function createLockSigned(uint256 amount_, uint256 end_, uint256 deadline_, uint8 v, bytes32 r, bytes32 s) external returns (uint256 lockID); + + /** + * @notice Deposit token to increase the value of an existing lock. + * @dev Token is transferred from msg.sender, assumes its already approved. + * @dev Anyone (not just the lock owner) can call increaseAmount() and deposit to an existing lock. + * @param lockID_ The ID of the lock to update. + * @param amount_ The amount of token to deposit. + */ + function increaseAmount(uint256 lockID_, uint256 amount_) external; + + /** + * @notice Deposit token to increase the value of multiple existing locks. + * @dev Token is transferred from msg.sender, assumes its already approved. + * @dev If a lockID does not exist, the corresponding amount will be refunded to msg.sender. + * @dev Anyone (not just the lock owner) can call increaseAmountMultiple() and deposit to existing locks. + * @param lockIDs_ Array of lock IDs to update. + * @param amounts_ Array of token amounts to deposit. + */ + function increaseAmountMultiple(uint256[] calldata lockIDs_, uint256[] calldata amounts_) external; + + /** + * @notice Deposit token to increase the value of an existing lock. + * @dev Token is transferred from msg.sender using ERC20Permit. + * @dev Anyone (not just the lock owner) can call increaseAmount() and deposit to an existing lock. + * @param lockID_ The ID of the lock to update. + * @param amount_ The amount of token to deposit. + * @param deadline_ Time the transaction must go through before. + * @param v secp256k1 signature + * @param r secp256k1 signature + * @param s secp256k1 signature + */ + function increaseAmountSigned(uint256 lockID_, uint256 amount_, uint256 deadline_, uint8 v, bytes32 r, bytes32 s) external; + + /** + * @notice Extend a lock's duration. + * @dev Can only be called by the lock owner or approved. + * @param lockID_ The ID of the lock to update. + * @param end_ The new time for the lock to unlock. + */ + function extendLock(uint256 lockID_, uint256 end_) external; + + /** + * @notice Extend multiple locks' duration. + * @dev Can only be called by the lock owner or approved. + * @dev If non-existing lockIDs are entered, these will be skipped. + * @param lockIDs_ Array of lock IDs to update. + * @param ends_ Array of new unlock times. + */ + function extendLockMultiple(uint256[] calldata lockIDs_, uint256[] calldata ends_) external; + + /** + * @notice Withdraw from a lock in full. + * @dev Can only be called by the lock owner or approved. + * @dev If called before `end` timestamp, will incur additional burn amount. + * @param lockID_ The ID of the lock to withdraw from. + * @param recipient_ The user to receive the lock's token. + */ + function withdraw(uint256 lockID_, address recipient_) external; + + /** + * @notice Withdraw from a lock in part. + * @dev Can only be called by the lock owner or approved. + * @dev If called before `end` timestamp, will incur additional burn amount. + * @param lockID_ The ID of the lock to withdraw from. + * @param amount_ The amount of token to withdraw. + * @param recipient_ The user to receive the lock's token. + */ + function withdrawInPart(uint256 lockID_, uint256 amount_, address recipient_) external; + + /** + * @notice Withdraw from multiple locks in full. + * @dev Can only be called by the lock owner or approved. + * @dev If called before `end` timestamp, will incur additional burn amount. + * @param lockIDs_ The ID of the locks to withdraw from. + * @param recipient_ The user to receive the lock's token. + */ + function withdrawMultiple(uint256[] calldata lockIDs_, address recipient_) external; + + /** + * @notice Withdraw from multiple locks in part. + * @dev Can only be called by the lock owner or approved. + * @dev If called before `end` timestamp, will incur additional burn amount. + * @param lockIDs_ The ID of the locks to withdraw from. + * @param amounts_ Array of token amounts to withdraw + * @param recipient_ The user to receive the lock's token. + */ + function withdrawInPartMultiple(uint256[] calldata lockIDs_, uint256[] calldata amounts_ ,address recipient_) external; + + /*************************************** + VOTING CONTRACT FUNCTIONS + ***************************************/ + + /** + * @notice Perform accounting for voting premiums to be charged by UnderwritingLockVoting.chargePremiums(). + * @dev Can only be called by votingContract set in the registry. + * @param lockID_ The ID of the lock to charge premium. + * @param premium_ Amount of tokens to charge as premium. + */ + function chargePremium(uint256 lockID_, uint256 premium_) external; + + /*************************************** + GOVERNANCE FUNCTIONS + ***************************************/ + + /** + * @notice Adds a listener. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param listener_ The listener to add. + */ + function addLockListener(address listener_) external; + + /** + * @notice Removes a listener. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param listener_ The listener to remove. + */ + function removeLockListener(address listener_) external; + + /** + * @notice Sets the base URI for computing `tokenURI`. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param baseURI_ The new base URI. + */ + function setBaseURI(string memory baseURI_) external; + + /** + * @notice Sets the [`Registry`](./Registry) contract address. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param registry_ The address of `Registry` contract. + */ + function setRegistry(address registry_) external; + + /** + * @notice Sets votingContract and enable safeTransferFrom call by `underwritingLockVoting` address stored in Registry. + * Can only be called by the current [**governor**](/docs/protocol/governance). + */ + function setVotingContract() external; + + /** + * @notice Sets fundingRate. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param fundingRate_ Desired funding rate, 1e18 => 100% + */ + function setFundingRate(uint256 fundingRate_) external; +} diff --git a/contracts/interfaces/native/IUnderwritingPool.sol b/contracts/interfaces/native/IUnderwritingPool.sol new file mode 100644 index 00000000..53b99a4f --- /dev/null +++ b/contracts/interfaces/native/IUnderwritingPool.sol @@ -0,0 +1,191 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.6; + +import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; + + +/** + * @title IUnderwritingPool + * @author solace.fi + * @notice The underwriting pool of Solace Native. + * + * In Solace Native risk is backed by a basket of assets known as the underwriting pool (UWP). Shares of the pool are known as `UWP` and are represented as an ERC20 token. [Governance](/docs/protocol/governance) can add or remove tokens from the basket and set their parameters (min and max in USD, price oracle) via [`addTokensToPool()`](#addtokenstopool) and [`removeTokensFromPool()`](#removetokensfrompool). + * + * Users can view tokens in the pool via [`tokensLength()`](#tokenslength), [`tokenData(address token)`](#tokendata), and [`tokenList(uint256 index)`](#tokenlist). + * + * Anyone can mint `UWP` by calling [`issue()`](#issue) and depositing any of the tokens in the pool. Note that + * - You will not be credited `UWP` for raw transferring tokens to this contract. Use [`issue()`](#issue) instead. + * - You do not need to deposit all of the tokens in the pool. Most users will deposit a single token. + * - To manage risk, each token has a corresponding `min` and `max` measured in USD. Deposits must keep the pool within these bounds. + * - Solace may charge a protocol fee as a fraction of the mint amount [`issueFee()`](#issuefee). + * + * Anyone can redeem their `UWP` for tokens in the pool by calling [`redeem()`](#redeem). You will receive a fair portion of all assets in the pool. + * + * [Governance](/docs/protocol/governance) can pause and unpause [`issue()`](#issue). The other functions cannot be paused. + */ +interface IUnderwritingPool is IERC20Metadata { + + /*************************************** + EVENTS + ***************************************/ + + /// @notice Emitted when a token is added to the pool. + event TokenAdded(address indexed token); + /// @notice Emitted when a token is removed from the pool. + event TokenRemoved(address indexed token); + /// @notice Emitted when uwp is issued. + event IssueMade(address user, uint256 amount); + /// @notice Emitted when uwp is redeemed. + event RedeemMade(address user, uint256 amount); + /// @notice Emitted when issue fee is set. + event IssueFeeSet(uint256 fee, address receiver); + /// @notice Emitted when pause is set. + event PauseSet(bool issueIsPaused); + + /*************************************** + VIEW FUNCTIONS + ***************************************/ + + struct TokenData { + address token; + address oracle; + uint256 min; + uint256 max; + } + + /** + * @notice The number of tokens in the pool. + * @return length The number of tokens in the pool. + */ + function tokensLength() external view returns (uint256 length); + + /** + * @notice Information about a token in the pool. + * @param token The address of the token to query. + * @return data Information about the token. + */ + function tokenData(address token) external view returns (TokenData memory data); + + /** + * @notice The list of tokens in the pool. + * @dev Iterable `[0, tokensLength)`. + * @param index The index of the list to query. + * @return data Information about the token. + */ + function tokenList(uint256 index) external view returns (TokenData memory data); + + /** + * @notice The fraction of `UWP` that are charged as a protocol fee on mint. + * @return fee The fee as a fraction with 18 decimals. + */ + function issueFee() external view returns (uint256 fee); + + /** + * @notice The receiver of issue fees. + * @return receiver The receiver of the fee. + */ + function issueFeeTo() external view returns (address receiver); + + /** + * @notice Returns true if issue is paused. + * @return paused Returns true if issue is paused. + */ + function isPaused() external view returns (bool paused); + + /** + * @notice Calculates the value of all assets in the pool in `USD`. + * @return valueInUSD The value of the pool in `USD` with 18 decimals. + */ + function valueOfPool() external view returns (uint256 valueInUSD); + + /** + * @notice Calculates the value of an amount of `UWP` shares in `USD`. + * @param shares The amount of shares to query. + * @return valueInUSD The value of the shares in `USD` with 18 decimals. + */ + function valueOfShares(uint256 shares) external view returns (uint256 valueInUSD); + + /** + * @notice Calculates the value of a holders `UWP` shares in `USD`. + * @param holder The holder to query. + * @return valueInUSD The value of the users shares in `USD` with 18 decimals. + */ + function valueOfHolder(address holder) external view returns (uint256 valueInUSD); + + /** + * @notice Determines the amount of tokens that would be minted for a given deposit. + * @param depositTokens The list of tokens to deposit. + * @param depositAmounts The amount of each token to deposit. + * @return amount The amount of `UWP` minted. + */ + function calculateIssue(address[] memory depositTokens, uint256[] memory depositAmounts) external view returns (uint256 amount); + + /** + * @notice Determines the amount of underlying tokens that would be received for an amount of `UWP`. + * @param amount The amount of `UWP` to burn. + * @return amounts The amount of each token received. + */ + function calculateRedeem(uint256 amount) external view returns (uint256[] memory amounts); + + /*************************************** + MODIFIER FUNCTIONS + ***************************************/ + + /** + * @notice Deposits one or more tokens into the pool. + * @param depositTokens The list of tokens to deposit. + * @param depositAmounts The amount of each token to deposit. + * @param receiver The address to send newly minted `UWP` to. + * @return amount The amount of `UWP` minted. + */ + function issue(address[] memory depositTokens, uint256[] memory depositAmounts, address receiver) external returns (uint256 amount); + + /** + * @notice Redeems some `UWP` for some of the tokens in the pool. + * @param amount The amount of `UWP` to burn. + * @param receiver The address to receive underlying tokens. + * @return amounts The amount of each token received. + */ + function redeem(uint256 amount, address receiver) external returns (uint256[] memory amounts); + + /*************************************** + GOVERNANCE FUNCTIONS + ***************************************/ + + /** + * @notice Adds tokens to the pool. If the token is already in the pool, sets its oracle, min, and max. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param tokens The list of tokens to add. + */ + function addTokensToPool(TokenData[] memory tokens) external; + + /** + * @notice Removes tokens from the pool. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param tokens The list of tokens to remove. + */ + function removeTokensFromPool(address[] memory tokens) external; + + /** + * @notice Rescues misplaced tokens. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param tokens The list of tokens to rescue. + * @param receiver The receiver of the tokens. + */ + function rescueTokens(address[] memory tokens, address receiver) external; + + /** + * @notice Sets the issue fee and receiver. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param fee The fee as a fraction with 18 decimals. + * @param receiver The receiver of the fee. + */ + function setIssueFee(uint256 fee, address receiver) external; + + /** + * @notice Pauses or unpauses issue. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param pause True to pause issue, false to unpause. + */ + function setPause(bool pause) external; +} diff --git a/contracts/mocks/MockERC20PermitWithBurn.sol b/contracts/mocks/MockERC20PermitWithBurn.sol new file mode 100644 index 00000000..3ec913da --- /dev/null +++ b/contracts/mocks/MockERC20PermitWithBurn.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: Unlicense +pragma solidity 0.8.6; + +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol"; +import "./MockERC20Permit.sol"; + +/** + * @title Mock ERC-20 Permit + * @author solace.fi + * @notice Mock ERC-20 is a mock ERC-20 with the permit() function. + */ +contract MockERC20PermitWithBurn is MockERC20Permit { + /** + * @notice Constructs the Mock Token contract. + * @param name The name of the token. + * @param symbol The symbol of the token. + * @param supply The amount of supply for the token. + * @param decimals_ The amount of decimals in the token. + */ + constructor( + string memory name, + string memory symbol, + uint256 supply, + uint8 decimals_ + ) MockERC20Permit(name, symbol, supply, decimals_) {} + + function burn(uint256 amount_) external { + _burn(msg.sender, amount_); + } +} diff --git a/contracts/mocks/MockFluxPriceFeed.sol b/contracts/mocks/MockFluxPriceFeed.sol new file mode 100644 index 00000000..f42d4b8f --- /dev/null +++ b/contracts/mocks/MockFluxPriceFeed.sol @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.6; + +import "../utils/Governable.sol"; +import "../interfaces/native/IFluxPriceFeed.sol"; + + +/** + * @title Flux first-party price feed oracle + * @author fluxprotocol.org + * @notice Simple data posting on chain of a scalar value, compatible with Chainlink V2 and V3 aggregator interface + */ +contract MockFluxPriceFeed is IFluxPriceFeed, Governable { + + event AnswerSet(int256 answer); + + int256 internal _latestAnswer; + + // solhint-disable-next-line no-empty-blocks + constructor (address governance_) Governable(governance_) { } + + /** + * @notice answer from the most recent report + */ + function latestAnswer() external view override returns (int256) { + return _latestAnswer; + } + + function setAnswer(int256 answer) external onlyGovernance { + _latestAnswer = answer; + emit AnswerSet(answer); + } +} diff --git a/contracts/mocks/MockUnderwritingLockListener.sol b/contracts/mocks/MockUnderwritingLockListener.sol new file mode 100644 index 00000000..5068b203 --- /dev/null +++ b/contracts/mocks/MockUnderwritingLockListener.sol @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +pragma solidity 0.8.6; + +import "./../interfaces/native/IUnderwritingLockListener.sol"; + +/** + * @title MockUnderwritingLockListener + * @author solace.fi + * @notice Mock listener for testing UnderwritingLock. + */ +contract MockUnderwritingLockListener is IUnderwritingLockListener { + + event Updated(uint256 blocknum, address caller, uint256 lockID); + + struct LastUpdate { + uint256 blocknum; + address caller; + uint256 lockID; + address oldOwner; + address newOwner; + Lock oldLock; + Lock newLock; + } + + LastUpdate public lastUpdate; + + /** + * @notice Called when an action is performed on a lock. + * @dev Called on transfer, mint, burn, and update. + * Either the owner will change or the lock will change, not both. + * @param lockID_ The ID of the lock that was altered. + * @param oldOwner_ The old owner of the lock. + * @param newOwner_ The new owner of the lock. + * @param oldLock_ The old lock data. + * @param newLock_ The new lock data. + */ + function registerLockEvent(uint256 lockID_, address oldOwner_, address newOwner_, Lock memory oldLock_, Lock memory newLock_) external override { + lastUpdate = LastUpdate({ + blocknum: block.number, + caller: msg.sender, + lockID: lockID_, + oldOwner: oldOwner_, + newOwner: newOwner_, + oldLock: oldLock_, + newLock: newLock_ + }); + emit Updated(block.number, msg.sender, lockID_); + } +} diff --git a/contracts/native/DepositHelper.sol b/contracts/native/DepositHelper.sol new file mode 100644 index 00000000..8506027c --- /dev/null +++ b/contracts/native/DepositHelper.sol @@ -0,0 +1,179 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.6; + +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; +import "./../interfaces/native/IUnderwritingPool.sol"; +import "./../interfaces/native/IUnderwritingEquity.sol"; +import "./../interfaces/native/IUnderwritingLocker.sol"; +import "./../interfaces/native/IDepositHelper.sol"; + + +/** + * @title DepositHelper + * @author solace.fi + * @notice The process of depositing into Solace Native requires multiple steps across multiple contracts. This helper contract allows users to deposit with a single transaction. + * + * These steps are + * 1. Deposit governance token into [`UWP`](./UnderwritingPool). + * 2. Deposit [`UWP`](./UnderwritingPool) into [`UWE`](./UnderwritingEquity). + * 3. Deposit [`UWE`](./UnderwritingEquity) into an [`Underwriting Lock`](./UnderwritingLocker). + * + * These steps can be replaced with [`depositAndLock()`](#depositandlock) or [`depositIntoLock()`](#depositintolock). + */ +contract DepositHelper is IDepositHelper, ReentrancyGuard { + + /*************************************** + STATE VARIABLES + ***************************************/ + + address internal _uwe; + address internal _locker; + + constructor(address uwe_, address locker_) { + require(uwe_ != address(0x0), "zero address uwe"); + require(locker_ != address(0x0), "zero address locker"); + _uwe = uwe_; + _locker = locker_; + IERC20(uwe_).approve(locker_, type(uint256).max); + } + + /*************************************** + VIEW FUNCTIONS + ***************************************/ + + /** + * @notice Address of the [underwriting pool](./UnderwritingPool). + * @return uwp The underwriting pool. + */ + function underwritingPool() external view override returns (address uwp) { + return IUnderwritingEquity(_uwe).underwritingPool(); + } + + /** + * @notice Address of [underwriting equity](./UnderwritingEquity). + * @return uwe The underwriting equity. + */ + function underwritingEquity() external view override returns (address uwe) { + return _uwe; + } + + /** + * @notice Address of [underwriting locker](./UnderwritingLocker). + * @return locker The underwriting locker. + */ + function underwritingLocker() external view override returns (address locker) { + return _locker; + } + + /** + * @notice Calculates the amount of [`UWE`](./UnderwritingEquity) minted for an amount of a token deposited. + * The deposit token may be one of the tokens in [`UWP`](./UnderwritingPool), the [`UWP`](./UnderwritingPool) token, or the [`UWE`](./UnderwritingEquity) token. + * @param depositToken The address of the token to deposit. + * @param depositAmount The amount of the token to deposit. + * @return uweAmount The amount of [`UWE`](./UnderwritingEquity) that will be minted to the receiver. + */ + function calculateDeposit(address depositToken, uint256 depositAmount) external view override returns (uint256 uweAmount) { + address uwe_ = _uwe; + address uwp_ = IUnderwritingEquity(uwe_).underwritingPool(); + uint256 amount = depositAmount; + // if deposit token is not uwp nor uwe + // likely token is member of set + if(depositToken != uwp_ && depositToken != uwe_) { + // deposit token into set, receive uwp. reverts if token not in set + address[] memory tokens = new address[](1); + uint256[] memory amounts = new uint256[](1); + tokens[0] = depositToken; + amounts[0] = depositAmount; + amount = IUnderwritingPool(uwp_).calculateIssue(tokens, amounts); + } + // if deposit token is not uwe + if(depositToken != uwe_) { + // deposit uwp into uwe + amount = IUnderwritingEquity(uwe_).calculateDeposit(amount); + } + return amount; + } + + /*************************************** + DEPOSIT FUNCTIONS + ***************************************/ + + /** + * @notice Deposits tokens into [`UWE`](./UnderwritingEquity) and deposits [`UWE`](./UnderwritingEquity) into a new [`UWE Lock`](./UnderwritingLocker). + * @param depositToken Address of the token to deposit. + * @param depositAmount Amount of the token to deposit. + * @param lockExpiry The timestamp the lock will unlock. + * @return lockID The ID of the newly created [`UWE Lock`](./UnderwritingLocker). + */ + function depositAndLock( + address depositToken, + uint256 depositAmount, + uint256 lockExpiry + ) external override nonReentrant returns (uint256 lockID) { + // pull tokens from msg.sender, convert to uwe + uint256 uweAmount = _tokenToUwe(depositToken, depositAmount); + // deposit uwe into new lock + lockID = IUnderwritingLocker(_locker).createLock(msg.sender, uweAmount, lockExpiry); + return lockID; + } + + /** + * @notice Deposits tokens into [`UWE`](./UnderwritingEquity) and deposits [`UWE`](./UnderwritingEquity) into an existing [`UWE Lock`](./UnderwritingLocker). + * @param depositToken Address of the token to deposit. + * @param depositAmount Amount of the token to deposit. + * @param lockID The ID of the [`UWE Lock`](./UnderwritingLocker) to deposit into. + */ + function depositIntoLock( + address depositToken, + uint256 depositAmount, + uint256 lockID + ) external override nonReentrant { + // pull tokens from msg.sender, convert to uwe + uint256 uweAmount = _tokenToUwe(depositToken, depositAmount); + // deposit uwe into existing lock + IUnderwritingLocker(_locker).increaseAmount(lockID, uweAmount); + } + + /*************************************** + INTERNAL FUNCTIONS + ***************************************/ + + /** + * @notice Given a deposit token and amount, pulls the token from `msg.sender` and converts it to an amount of [`UWE`](./UnderwritingEquity). + * @param depositToken Address of the token to deposit. + * @param depositAmount Amount of the token to deposit. + * @return uweAmount Amount of [`UWE`](./UnderwritingEquity) that was minted. + */ + function _tokenToUwe( + address depositToken, + uint256 depositAmount + ) internal returns (uint256 uweAmount) { + address uwe_ = _uwe; + address uwp_ = IUnderwritingEquity(uwe_).underwritingPool(); + uint256 amount = depositAmount; + IERC20 tkn = IERC20(depositToken); + // pull tokens from msg.sender + SafeERC20.safeTransferFrom(tkn, msg.sender, address(this), amount); + // if deposit token is not uwp nor uwe + // likely token is member of set + if(depositToken != uwp_ && depositToken != uwe_) { + // deposit token into set, receive uwp. reverts if token not in set + if(tkn.allowance(address(this), uwp_) < amount) tkn.approve(uwp_, type(uint256).max); + address[] memory tokens = new address[](1); + uint256[] memory amounts = new uint256[](1); + tokens[0] = depositToken; + amounts[0] = depositAmount; + amount = IUnderwritingPool(uwp_).issue(tokens, amounts, address(this)); + } + // if deposit token is not uwe + if(depositToken != uwe_) { + // deposit uwp into uwe + IERC20 uwp2 = IERC20(uwp_); + if(uwp2.allowance(address(this), uwe_) < amount) uwp2.approve(uwe_, type(uint256).max); + amount = IUnderwritingEquity(uwe_).deposit(amount, address(this)); + } + return amount; + } +} diff --git a/contracts/native/FluxMegaOracle.sol b/contracts/native/FluxMegaOracle.sol new file mode 100644 index 00000000..02ab8396 --- /dev/null +++ b/contracts/native/FluxMegaOracle.sol @@ -0,0 +1,147 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.6; + +import "../utils/Governable.sol"; +import "../interfaces/native/IFluxPriceFeed.sol"; +import "../interfaces/native/IFluxMegaOracle.sol"; + + +/** + * @title FluxMegaOracle + * @author solace.fi + * @notice An oracle that consumes data from [Flux](https://fluxprotocol.org) and returns it in a useable format. + * + * [Governance](/docs/protocol/governance) can add or remove price feeds via [`addPriceFeeds()`](#addpricefeeds) and [`removePriceFeeds()`](#removepricefeeds). Users can view price feeds via [`priceFeedForToken(address token)`](#pricefeedfortoken). Users can use the price feeds via [`valueOfTokens()`](#valueoftokens). Users can list price feeds via [`tokensLength()`](#tokenslength) and [`tokenByIndex()`](#tokenbyindex). + */ +contract FluxMegaOracle is IFluxMegaOracle, Governable { + + /*************************************** + STATE VARIABLES + ***************************************/ + + // token => data + mapping(address => PriceFeedData) internal _priceFeeds; + // index => token + mapping(uint256 => address) internal _indexToToken; + // token => index+1 + mapping(address => uint256) internal _tokenToIndex; + // number of tokens known + uint256 internal _tokensLength; + + /** + * @notice Constructs the `FluxMegaOracle` contract. + * @param governance_ The address of the governor. + */ + // solhint-disable-next-line no-empty-blocks + constructor (address governance_) Governable(governance_) { } + + /*************************************** + VIEW FUNCTIONS + ***************************************/ + + /** + * @notice Returns information about the price feed for a token. + * @dev Returns a zero struct if no known price feed. + * @param token The token to query price feed data of. + * @return data Information about te price feed. + */ + function priceFeedForToken(address token) external view override returns (PriceFeedData memory data) { + return _priceFeeds[token]; + } + + /** + * @notice Lists the tokens in the oracle. + * @dev Enumerable `[0,tokensLength]` + * @param index The index to query. + * @return token The address of the token at that index. + */ + function tokenByIndex(uint256 index) external view override returns (address token) { + require(index < _tokensLength, "index out of bounds"); + return _indexToToken[index]; + } + + /** + * @notice The number of tokens with feeds in this oracle. + * @return len The number of tokens. + */ + function tokensLength() external view override returns (uint256 len) { + return _tokensLength; + } + + /** + * @notice Given an amount of some token, calculates the value in `USD`. + * @dev Returns zero if no known price feed for the token. + * @param token The address of the token to price. + * @param amount The amount of the token to price. + * @return valueInUSD The value in `USD` with 18 decimals. + */ + function valueOfTokens(address token, uint256 amount) external view override returns (uint256 valueInUSD) { + PriceFeedData memory feed = _priceFeeds[token]; + if(feed.priceFeed == address(0x0)) return 0; + int256 answer = IFluxPriceFeed(feed.priceFeed).latestAnswer(); + require(answer >= 0, "negative price"); + return (amount * uint256(answer) * 1 ether) / (10 ** (feed.tokenDecimals + feed.priceFeedDecimals)); + } + + /*************************************** + GOVERNANCE FUNCTIONS + ***************************************/ + + /** + * @notice Adds price feeds. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param feeds The list of price feeds to add. + */ + function addPriceFeeds(PriceFeedData[] memory feeds) external override onlyGovernance { + uint256 stLen = _tokensLength; + uint256 stLen0 = stLen; + for(uint256 i = 0; i < feeds.length; i++) { + // add to feed mapping + PriceFeedData memory feed = feeds[i]; + address token = feed.token; + _priceFeeds[token] = feed; + // add to token enumeration + if(_tokenToIndex[token] == 0) { + uint256 index = stLen++; // autoincrement from 0 + _indexToToken[index] = token; + _tokenToIndex[token] = index + 1; + } + emit PriceFeedAdded(token); + } + if(stLen != stLen0) _tokensLength = stLen; + } + + /** + * @notice Removes price feeds. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param tokens The list of price feeds to remove. + */ + function removePriceFeeds(address[] memory tokens) external override onlyGovernance { + uint256 stLen = _tokensLength; + uint256 stLen0 = stLen; + for(uint256 i = 0; i < tokens.length; i++) { + address token = tokens[i]; + delete _priceFeeds[token]; + uint256 stIndex = _tokenToIndex[token]; + // token was not in pool anyways. skip + if(stIndex == 0) continue; + // token was at end of list. simple pop + if(stIndex == stLen) { + stLen--; + delete _tokenToIndex[token]; + delete _indexToToken[stIndex-1]; + } + // token was not at end of list. remove and shuffle + else { + stLen--; + address otherToken = _indexToToken[stLen]; + _indexToToken[stIndex-1] = otherToken; + delete _indexToToken[stLen]; + _tokenToIndex[otherToken] = stIndex; + delete _tokenToIndex[token]; + } + emit PriceFeedRemoved(token); + } + if(stLen != stLen0) _tokensLength = stLen; + } +} diff --git a/contracts/native/GaugeController.sol b/contracts/native/GaugeController.sol new file mode 100644 index 00000000..07d55343 --- /dev/null +++ b/contracts/native/GaugeController.sol @@ -0,0 +1,666 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.6; + +import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; +import "./../utils/EnumerableMapS.sol"; +import "./../utils/Governable.sol"; +import "./../utils/SafeCastS.sol"; +import "./../interfaces/native/IGaugeVoter.sol"; +import "./../interfaces/native/IGaugeController.sol"; + +/** + * @title GaugeController + * @author solace.fi + * @notice Stores individual votes for Solace Native gauges, and maintains current gauge weights. + * + * Current gauge weights can be obtained through [`getGaugeWeight()`](#getgaugeweight) and [`getAllGaugeWeights()`](#getallgaugeweights) + * + * Only governance can make mutator calls to GaugeController.sol. There are no unpermissioned external mutator calls in this contract. + * + * After every epoch, governance must call [`updateGaugeWeights()`](#updategaugeweights). This will process the last epoch's votes (stored in this contract). + * + * Individual voters register and manage their vote through voting contracts that conform to IGaugeVoting. + * + * Governance can [`addGauge()`](#addgauge) or [`pauseGauge()`](#pausegauge). + */ +// solhint-disable-next-line contract-name-camelcase +contract GaugeController is + IGaugeController, + ReentrancyGuard, + Governable + { + using EnumerableSet for EnumerableSet.AddressSet; + using EnumerableMapS for EnumerableMapS.UintToUintMap; + + /*************************************** + GLOBAL PUBLIC VARIABLES + ***************************************/ + + /// @notice Underwriting equity token + address public override token; + + /// @notice Updater address. + /// @dev Second address that can call updateGaugeWeights (in addition to governance). + address public override updater; + + /// @notice Insurance leverage factor. + /// @dev 1e18 => 100%. + uint256 public override leverageFactor; + + /// @notice The total number of gauges that have been created. + uint256 public override totalGauges; + + /// @notice End timestamp for last epoch that all stored votes were processed. + uint256 public override lastTimeGaugeWeightsUpdated; + + /*************************************** + GLOBAL INTERNAL VARIABLES + ***************************************/ + + uint256 constant internal WEEK = 604800; + + /// @notice The total number of paused gauges. + uint256 internal _pausedGaugesCount; + + /// @notice gaugeID => total vote power from last time the gauge weights were updated. + mapping(uint256 => uint256) internal _votePowerOfGauge; + + /// @notice Array of Gauge {string name, bool active} + GaugeStructs.Gauge[] internal _gauges; + + /// @notice Set of addresses from which getInsuranceCapacity() will tally UWE supply from. + EnumerableSet.AddressSet internal _tokenholders; + + /// @notice Set of voting contracts conforming to IGaugeVoting.sol interface that can call [`vote()`](#vote). + EnumerableSet.AddressSet internal _votingContracts; + + /// @notice votingContract => voters. + mapping(address => EnumerableSet.AddressSet) internal _voters; + + /// @notice votingContract => voter => gaugeID => votePowerBPS + mapping(address => mapping(address => EnumerableMapS.UintToUintMap)) internal _votes; + + /// @notice Dynamic array of dead voters to remove. + address[] internal _votersToRemove; + + /// @notice State of last [`updateGaugeWeights()`](#updategaugeweights) call. + GaugeStructs.UpdateInfo internal _updateInfo; + + /// @notice Epoch length, default is 1 week. + uint256 internal _epochLength; + + /*************************************** + CONSTRUCTOR + ***************************************/ + + /** + * @notice Constructs the UnderwritingLocker contract. + * @param governance_ The address of the [governor](/docs/protocol/governance). + * @param token_ The address of the underwriting equity token. + */ + constructor(address governance_, address token_) + Governable(governance_) + { + if (token_ == address(0x0)) revert ZeroAddressInput("token"); + token = token_; + leverageFactor = 1e18; // Default 1x leverage. + // Pre-fill slot 0 of _gauges, ensure gaugeID 1 maps to _gauges[1] + _gauges.push(GaugeStructs.Gauge(false, 0, "")); + _clearUpdateInfo(); + _epochLength = WEEK; + } + + /*************************************** + INTERNAL VIEW FUNCTIONS + ***************************************/ + + /** + * @notice Get timestamp for the start of the current epoch. + * @return timestamp + */ + function _getEpochStartTimestamp() internal view returns (uint256 timestamp) { + return ( (block.timestamp / _epochLength) * _epochLength ); + } + + /** + * @notice Get timestamp for end of the current epoch. + * @return timestamp + */ + function _getEpochEndTimestamp() internal view returns (uint256 timestamp) { + return ( (block.timestamp / _epochLength) * _epochLength ) + _epochLength; + } + + /** + * @notice Get vote power sum across all gauges. + * @return votePowerSum + */ + function _getVotePowerSum() internal view returns (uint256 votePowerSum) { + for(uint256 i = 1; i < totalGauges + 1; i++) { + if (_gauges[i].active) { + votePowerSum += _votePowerOfGauge[i]; + } + } + } + + /** + * @notice Get current gauge weight for a single gauge ID. + * @dev Gauge weights must sum to 1e18, so a weight of 1e17 == 10% weight. + * @param gaugeID_ The ID of the gauge to query. + * @return weight + */ + function _getGaugeWeight(uint256 gaugeID_) internal view returns (uint256 weight) { + if (!_gauges[gaugeID_].active) return 0; + uint256 votePowerSum = _getVotePowerSum(); + if (votePowerSum == 0) return 0; // Avoid divide by 0 error + else {return 1e18 * _votePowerOfGauge[gaugeID_] / votePowerSum;} + } + + /** + * @notice Get all gauge weights. + * @dev Gauge weights must sum to 1e18, so a weight of 1e17 == 10% weight. + * @dev weights[0] will always be 0, so that weights[1] maps to the weight of gaugeID 1. + * @return weights + */ + function _getAllGaugeWeights() internal view returns (uint256[] memory weights) { + weights = new uint[](totalGauges + 1); + weights[0] = 0; + uint256 votePowerSum = _getVotePowerSum(); + + for(uint256 i = 1; i < totalGauges + 1; i++) { + if (votePowerSum > 0 && _gauges[i].active) { + weights[i] = (1e18 * _votePowerOfGauge[i] / votePowerSum); + } else { + weights[i] = 0; + } + } + } + + /** + * @notice Query whether msg.sender is either the governance or updater role. + * @return True if msg.sender is either governor or updater roler, and contract govenance is not locked, false otherwise. + */ + function _isUpdaterOrGovernance() internal view returns (bool) { + return ( !this.governanceIsLocked() && ( msg.sender == updater || msg.sender == this.governance() )); + } + + /*************************************** + EXTERNAL VIEW FUNCTIONS + ***************************************/ + + /** + * @notice Get timestamp for the start of the current epoch. + * @return timestamp + */ + function getEpochStartTimestamp() external view override returns (uint256 timestamp) { + return _getEpochStartTimestamp(); + } + + /** + * @notice Get timestamp for end of the current epoch. + * @return timestamp + */ + function getEpochEndTimestamp() external view override returns (uint256 timestamp) { + return _getEpochEndTimestamp(); + } + + /** + * @notice Get current gauge weight of single gauge ID. + * @dev Gauge weights must sum to 1e18, so a weight of 1e17 == 10% weight. + * @param gaugeID_ The ID of the gauge to query. + * @return weight + */ + function getGaugeWeight(uint256 gaugeID_) external view override returns (uint256 weight) { + return _getGaugeWeight(gaugeID_); + } + + /** + * @notice Get all gauge weights. + * @dev Gauge weights must sum to 1e18, so a weight of 1e17 == 10% weight. + * @dev weights[0] will always be 0, so that weights[1] maps to the weight of gaugeID 1. + * @return weights + */ + function getAllGaugeWeights() external view override returns (uint256[] memory weights) { + return _getAllGaugeWeights(); + } + + /** + * @notice Get number of active gauges. + * @return numActiveGauges + */ + function getNumActiveGauges() external view override returns (uint256 numActiveGauges) { + return (totalGauges - _pausedGaugesCount); + } + + /** + * @notice Get number of paused gauges. + * @return numPausedGauges + */ + function getNumPausedGauges() external view override returns (uint256 numPausedGauges) { + return _pausedGaugesCount; + } + + /** + * @notice Get gauge name. + * @param gaugeID_ The ID of the gauge to query. + * @return gaugeName + */ + function getGaugeName(uint256 gaugeID_) external view override returns (string memory gaugeName) { + return _gauges[gaugeID_].name; + } + + /** + * @notice Query whether gauge is active. + * @param gaugeID_ The ID of the gauge to query. + * @return gaugeActive True if active, false otherwise. + */ + function isGaugeActive(uint256 gaugeID_) external view override returns (bool gaugeActive) { + return _gauges[gaugeID_].active; + } + + /** + * @notice Obtain rate on line of gauge. + * @param gaugeID_ The ID of the gauge to query. + * @return rateOnLine_ Annual rate on line, 1e18 => 100%. + */ + function getRateOnLineOfGauge(uint256 gaugeID_) external view override returns (uint256 rateOnLine_) { + return _gauges[gaugeID_].rateOnLine; + } + + /** + * @notice Obtain insurance capacity in $UWE terms. + * @dev Leverage * UWE capacity + * @return insuranceCapacity Insurance capacity in $UWE. + */ + function getInsuranceCapacity() external view override returns (uint256 insuranceCapacity) { + uint256 numTokenholders = _tokenholders.length(); + if (numTokenholders == 0) revert NoTokenholdersAdded(); + uint256 tokenBalance; + for (uint256 i = 0; i < numTokenholders; i++) { + tokenBalance += IERC20(token).balanceOf(_tokenholders.at(i)); + } + return (leverageFactor * tokenBalance / 1e18); + } + + /** + * @notice Get vote power sum for all gauges. + * @return votePowerSum + */ + function getVotePowerSum() external view override returns (uint256 votePowerSum) { + return _getVotePowerSum(); + } + + /** + * @notice Get all votes for a given voter and voting contract. + * @param votingContract_ Address of voting contract - must have been added via addVotingContract(). + * @param voter_ Address of voter. + * @return votes Array of Vote {gaugeID, votePowerBPS} + */ + function getVotes(address votingContract_, address voter_) external view override returns (GaugeStructs.Vote[] memory votes) { + if ( !_votingContracts.contains(votingContract_) || !_voters[votingContract_].contains(voter_) ) { + votes = new GaugeStructs.Vote[](0); + } else { + uint256 voteCount = _votes[votingContract_][voter_].length(); + votes = new GaugeStructs.Vote[](voteCount); + for (uint256 i = 0; i < voteCount; i++) { + (uint256 gaugeID, uint256 votingPowerBPS) = _votes[votingContract_][voter_].at(i); + votes[i] = GaugeStructs.Vote(gaugeID, votingPowerBPS); + } + } + } + + /** + * @notice Get all voters for a given voting contract. + * @param votingContract_ Address of voting contract - must have been added via addVotingContract(). + * @return voters Array of voters. + */ + function getVoters(address votingContract_) external view override returns (address[] memory voters) { + if ( !_votingContracts.contains(votingContract_) ) { + voters = new address[](0); + } else { + uint256 votersCount = _voters[votingContract_].length(); + voters = new address[](votersCount); + for (uint256 i = 0; i < votersCount; i++) { + voters[i] = _voters[votingContract_].at(i); + } + } + } + + /** + * @notice Get number of votes for a given voter and voting contract. + * @param votingContract_ Address of voting contract - must have been added via addVotingContract(). + * @param voter_ Address of voter. + * @return voteCount Number of votes. + */ + function getVoteCount(address votingContract_, address voter_) external view override returns (uint256 voteCount) { + if ( !_votingContracts.contains(votingContract_) || !_voters[votingContract_].contains(voter_) ) { + return 0; + } else { + return _votes[votingContract_][voter_].length(); + } + } + + /** + * @notice Get number of voters for a voting contract. + * @param votingContract_ Address of voting contract - must have been added via addVotingContract(). + * @return votersCount Number of votes. + */ + function getVotersCount(address votingContract_) external view override returns (uint256 votersCount) { + if ( !_votingContracts.contains(votingContract_) ) { + return 0; + } else { + return _voters[votingContract_].length(); + } + } + + /*************************************** + INTERNAL MUTATOR FUNCTIONS + ***************************************/ + + /** + * @notice Internal mutator function to add, modify or remove vote + * @param votingContract_ Address of voting contract - must have been added via addVotingContract(). + * @param voter_ Address of voter. + * @param gaugeID_ ID of gauge to add, modify or remove vote for. + * @param newVotePowerBPS_ New votePowerBPS value. + * @return oldVotePowerBPS Old votePowerBPS value. + */ + function _vote(address votingContract_, address voter_, uint256 gaugeID_, uint256 newVotePowerBPS_) internal returns (uint256 oldVotePowerBPS) { + // Check if need to add new voter. + // Use `newVotePowerBPS_ > 0` to short circuit and avoid SLOAD for removing vote operations. + if ( newVotePowerBPS_ > 0 && !_voters[votingContract_].contains(voter_) ) { + _voters[votingContract_].add(voter_); + } + + // If adding new vote + if ( newVotePowerBPS_ > 0 && !_votes[votingContract_][voter_].contains(gaugeID_) ) { + _votes[votingContract_][voter_].set(gaugeID_, newVotePowerBPS_); + return 0; + // Else if removing vote + } else if (newVotePowerBPS_ == 0) { + oldVotePowerBPS = _votes[votingContract_][voter_].get(gaugeID_); + _votes[votingContract_][voter_].remove(gaugeID_); + // Check if need to remove voter + if ( _votes[votingContract_][voter_].length() == 0 ) {_voters[votingContract_].remove(voter_);} + return oldVotePowerBPS; + // Else modify vote + } else { + oldVotePowerBPS = _votes[votingContract_][voter_].get(gaugeID_); + _votes[votingContract_][voter_].set(gaugeID_, newVotePowerBPS_); + return oldVotePowerBPS; + } + } + + /*************************************** + VOTING CONTRACT FUNCTIONS + ***************************************/ + + /** + * @notice Register votes. + * @dev Can only be called by voting contracts that have been added via addVotingContract(). + * @param voter_ Address of voter. + * @param gaugeID_ The ID of the voted gauge. + * @param newVotePowerBPS_ Desired vote power BPS, 0 if removing vote. + * @return oldVotePowerBPS Old votePowerBPS value, 0 if new vote. + */ + function vote(address voter_, uint256 gaugeID_, uint256 newVotePowerBPS_) external override returns (uint256 oldVotePowerBPS) { + if (gaugeID_ == 0) revert CannotVoteForGaugeID0(); + if (_getEpochStartTimestamp() != lastTimeGaugeWeightsUpdated) revert GaugeWeightsNotYetUpdated(); + if (gaugeID_ + 1 > _gauges.length) revert GaugeIDNotExist(); + if (!_votingContracts.contains(msg.sender)) revert NotVotingContract(); + // Can remove votes while gauge paused + if (newVotePowerBPS_ > 0 && !_gauges[gaugeID_].active) revert GaugeIDPaused(); + return _vote(msg.sender, voter_, gaugeID_, newVotePowerBPS_); + } + + /*************************************** + GOVERNANCE FUNCTIONS + ***************************************/ + + /** + * @notice Adds a voting contract + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param votingContract_ The votingContract to add. + */ + function addVotingContract(address votingContract_) external override onlyGovernance { + _votingContracts.add(votingContract_); + emit VotingContractAdded(votingContract_); + } + + /** + * @notice Removes a voting contract + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param votingContract_ The votingContract to add. + */ + function removeVotingContract(address votingContract_) external override onlyGovernance { + if (!_votingContracts.contains(votingContract_)) revert VotingContractNotAdded(); + _votingContracts.remove(votingContract_); + emit VotingContractRemoved(votingContract_); + } + + /** + * @notice Adds an insurance gauge + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param gaugeName_ Gauge name. + * @param rateOnLine_ Annual rate on line (1e18 => 100%) + */ + function addGauge(string calldata gaugeName_, uint256 rateOnLine_) external override onlyGovernance { + uint256 gaugeID = ++totalGauges; + GaugeStructs.Gauge memory newGauge = GaugeStructs.Gauge(true, SafeCastS.toUint248(rateOnLine_), gaugeName_); + _gauges.push(newGauge); + assert(_gauges.length - 1 == totalGauges); // Uphold invariant, should not be violated. -1 because we already added _gauges[0] in constructor. + emit GaugeAdded(gaugeID, rateOnLine_, gaugeName_); + } + + /** + * @notice Pauses an insurance gauge + * @notice Paused gauges cannot have votes added or modified, and votes for a paused gauge will not be counted + * in the next updateGaugeWeights() call. + * @dev We do not include a removeGauge function as this would distort the order of the _gauges array + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param gaugeID_ ID of gauge to pause + */ + function pauseGauge(uint256 gaugeID_) external override onlyGovernance { + if(_gauges[gaugeID_].active == false) revert GaugeAlreadyPaused({gaugeID: gaugeID_}); + _pausedGaugesCount += 1; + _gauges[gaugeID_].active = false; + emit GaugePaused(gaugeID_, _gauges[gaugeID_].name); + } + + /** + * @notice Unpauses an insurance gauge. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param gaugeID_ ID of gauge to pause. + */ + function unpauseGauge(uint256 gaugeID_) external override onlyGovernance { + if(_gauges[gaugeID_].active == true) revert GaugeAlreadyUnpaused({gaugeID: gaugeID_}); + if(gaugeID_ == 0) revert CannotUnpauseGaugeID0(); // We do not permit gaugeID 0 to be active, and hence do not permit anyone to vote for it. + _pausedGaugesCount -= 1; + _gauges[gaugeID_].active = true; + emit GaugeUnpaused(gaugeID_, _gauges[gaugeID_].name); + } + + /** + * @notice Set insurance leverage factor. + * @dev 1e18 => 100% + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param leverageFactor_ Desired leverage factor. + */ + function setLeverageFactor(uint256 leverageFactor_) external override onlyGovernance { + leverageFactor = leverageFactor_; + emit LeverageFactorSet(leverageFactor_); + } + + /** + * @notice Set underwriting token address. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param token_ The address of the new underwriting token + */ + function setToken(address token_) external override onlyGovernance { + token = token_; + emit TokenSet(token_); + } + + /** + * @notice Set updater address. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param updater_ The address of the new updater. + */ + function setUpdater(address updater_) external override onlyGovernance { + updater = updater_; + emit UpdaterSet(updater_); + } + + /** + * @notice Set epoch length (as an integer multiple of 1 week). + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param weeks_ Integer multiple of 1 week, to set epochLength to. + */ + function setEpochLengthInWeeks(uint256 weeks_) external override onlyGovernance { + _epochLength = weeks_ * WEEK; + emit EpochLengthSet(weeks_); + } + + /** + * @notice Adds address to tokenholders set - these addresses will be queried for $UWE token balance and summed to determine the Solace Native insurance capacity. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param tokenholder_ Address of new tokenholder + */ + function addTokenholder(address tokenholder_) external override onlyGovernance { + _tokenholders.add(tokenholder_); + emit TokenholderAdded(tokenholder_); + } + + /** + * @notice Removes an address from the tokenholder set - these addresses will be queried for $UWE token balance and summed to determine the Solace Native insurance capacity. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param tokenholder_ Address of new tokenholder. + */ + function removeTokenholder(address tokenholder_) external override onlyGovernance { + bool success = _tokenholders.remove(tokenholder_); + if (!success) revert TokenholderNotPresent(); + emit TokenholderRemoved(tokenholder_); + } + + /** + * @notice Set annual rate-on-line for selected gaugeIDs + * @dev 1e18 => 100% + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param gaugeIDs_ Array of gaugeIDs. + * @param rateOnLines_ Array of corresponding annual rate on lines. + */ + function setRateOnLine(uint256[] calldata gaugeIDs_, uint256[] calldata rateOnLines_) external override onlyGovernance { + if (gaugeIDs_.length != rateOnLines_.length) revert ArrayArgumentsLengthMismatch(); + for (uint256 i = 0; i < gaugeIDs_.length; i++) { + _gauges[gaugeIDs_[i]].rateOnLine = SafeCastS.toUint248(rateOnLines_[i]); + emit RateOnLineSet(gaugeIDs_[i], rateOnLines_[i]); + } + } + + /** + * @notice Updates gauge weights by processing votes for the last epoch. + * @dev Designed to be called in a while-loop with custom gas limit of 6M until `lastTimePremiumsCharged == epochStartTimestamp`. + * Can only be called by the current [**governor**](/docs/protocol/governance) or the updater role. + */ + function updateGaugeWeights() external override { + if (!_isUpdaterOrGovernance()) revert NotUpdaterNorGovernance(); + if ( _updateInfo._votesIndex == type(uint88).max ) {_resetVotePowerOfGaugeMapping();} // If first call for epoch, reset _votePowerOfGauge + uint256 epochStartTime = _getEpochStartTimestamp(); + if (lastTimeGaugeWeightsUpdated >= epochStartTime) revert GaugeWeightsAlreadyUpdated(); + uint256 numVotingContracts = _votingContracts.length(); + + // Iterate through voting contracts + // Use ternary operator to initialise loop, to avoid setting stack-too deep error from too many local variables. + for(uint256 i = _updateInfo._votingContractsIndex == type(uint80).max ? 0 : _updateInfo._votingContractsIndex; i < numVotingContracts; i++) { + address votingContract = _votingContracts.at(i); + uint256 numVoters = _voters[votingContract].length(); + + // Iterate through voters + for(uint256 j = _updateInfo._votersIndex == type(uint88).max || i != _updateInfo._votingContractsIndex ? 0 : _updateInfo._votersIndex ; j < numVoters; j++) { + if (gasleft() < 200000) {return _saveUpdateState(i, j, 0);} + address voter = _voters[votingContract].at(j); + uint256 numVotes = _votes[votingContract][voter].length(); + uint256 votePower = IGaugeVoter(votingContract).getVotePower(voter); // Expensive computation here. ~150K gas for user with max cap of 10 locks. + if (votePower == 0) { + _votersToRemove.push(voter); + continue; + } + // If votePower == 0, we don't need to cache the result because voter will be removed from _voters EnumerableSet + // => chargePremiums() will not iterate through it + IGaugeVoter(votingContract).cacheLastProcessedVotePower(voter, votePower); + + // Iterate through votes + for(uint256 k = _updateInfo._votesIndex == type(uint88).max || j != _updateInfo._votersIndex || i != _updateInfo._votingContractsIndex ? 0 : _updateInfo._votesIndex; k < numVotes; k++) { + if (gasleft() < 15000) {return _saveUpdateState(i, j, k);} + (uint256 gaugeID, uint256 votingPowerBPS) = _votes[votingContract][voter].at(k); + // Address edge case where vote placed before gauge is paused, will be counted + if (!_gauges[gaugeID].active) {continue;} + _votePowerOfGauge[gaugeID] += votePower * votingPowerBPS / 10000; + } + } + + // Remove dead voters - unbounded SSTORE loop. + while (_votersToRemove.length > 0) { + // Subtle bug, don't set _updateInfo._votesIndex to type(uint88).max or else you actually don't skip votes iteration + if (gasleft() < 15000) { + return _saveUpdateState(i, type(uint88).max - 1, type(uint88).max - 1); + } + _voters[votingContract].remove(_votersToRemove[_votersToRemove.length - 1]); + _votersToRemove.pop(); + } + } + + _adjustVotePowerOfGaugeMapping(); + _clearUpdateInfo(); + lastTimeGaugeWeightsUpdated = epochStartTime; + emit GaugeWeightsUpdated(epochStartTime); + } + + /*************************************** + updateGaugeWeights() HELPER FUNCTIONS + ***************************************/ + + /** + * @notice Save state of updating gauge weights to _updateInfo. + * @param votingContractsIndex_ Current index of _votingContracts. + * @param votersIndex_ Current index of _voters[votingContractsIndex_]. + * @param votesIndex_ Current index of _votes[votingContractsIndex_][votersIndex_] + */ + function _saveUpdateState(uint256 votingContractsIndex_, uint256 votersIndex_, uint256 votesIndex_) internal { + assembly { + let updateInfo + updateInfo := or(updateInfo, shr(176, shl(176, votingContractsIndex_))) // [0:80] => votingContractsIndex_ + updateInfo := or(updateInfo, shr(88, shl(168, votersIndex_))) // [80:168] => votersIndex_ + updateInfo := or(updateInfo, shl(168, votesIndex_)) // [168:256] => votesIndex_ + sstore(_updateInfo.slot, updateInfo) + } + emit IncompleteGaugeUpdate(); + } + + /// @notice Reset _updateInfo to starting state. + /// @dev Avoid zero-value of storage slot. + function _clearUpdateInfo() internal { + uint256 bitmap = type(uint256).max; + assembly { + sstore(_updateInfo.slot, bitmap) + } + } + + /// @notice Reset _votePowerOfGauge on first updateGaugeWeights() call for the epoch. + /// @dev Avoid zero value of storage slots + function _resetVotePowerOfGaugeMapping() internal { + for (uint256 i = 1; i < totalGauges + 1; i++) { + _votePowerOfGauge[i] = 1; + } + } + + /// @notice Adjust _votePowerOfGauge for _resetVotePowerOfGaugeMapping call() done this epoch. + function _adjustVotePowerOfGaugeMapping() internal { + for (uint256 i = 1; i < totalGauges + 1; i++) { + if ( _gauges[i].active ) { + _votePowerOfGauge[i] -= 1; + } + } + } +} diff --git a/contracts/native/SolaceMegaOracle.sol b/contracts/native/SolaceMegaOracle.sol new file mode 100644 index 00000000..31749b9a --- /dev/null +++ b/contracts/native/SolaceMegaOracle.sol @@ -0,0 +1,157 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.6; + +import "../utils/Governable.sol"; +import "../interfaces/native/ISolaceMegaOracle.sol"; + + +/** + * @title SolaceMegaOracle + * @author solace.fi + * @notice An oracle that consumes data from Solace updaters and returns it in a useable format. + * + * [Governance](/docs/protocol/governance) can add or remove updater bots via [`setUpdaterStatuses()`](#setupdaterstatuses). Users can view updater status via [`isUpdater()`](#isupdater). + */ +contract SolaceMegaOracle is ISolaceMegaOracle, Governable { + + /*************************************** + STATE VARIABLES + ***************************************/ + + // token => data + mapping(address => PriceFeedData) internal _priceFeeds; + // index => token + mapping(uint256 => address) internal _indexToToken; + // token => index+1 + mapping(address => uint256) internal _tokenToIndex; + // number of tokens known + uint256 internal _tokensLength; + + // updater => status + mapping(address => bool) internal _isUpdater; + + /** + * @notice Constructs the `SolaceMegaOracle` contract. + * @param governance_ The address of the governor. + */ + // solhint-disable-next-line no-empty-blocks + constructor (address governance_) Governable(governance_) { } + + /*************************************** + VIEW FUNCTIONS + ***************************************/ + + /** + * @notice Returns information about the price feed for a token. + * @dev Returns a zero struct if no known price feed. + * @param token The token to query price feed data of. + * @return data Information about te price feed. + */ + function priceFeedForToken(address token) external view override returns (PriceFeedData memory data) { + return _priceFeeds[token]; + } + + /** + * @notice Lists the tokens in the oracle. + * @dev Enumerable `[0,tokensLength]` + * @param index The index to query. + * @return token The address of the token at that index. + */ + function tokenByIndex(uint256 index) external view override returns (address token) { + require(index < _tokensLength, "index out of bounds"); + return _indexToToken[index]; + } + + /** + * @notice The number of tokens with feeds in this oracle. + * @return len The number of tokens. + */ + function tokensLength() external view override returns (uint256 len) { + return _tokensLength; + } + + /** + * @notice Given an amount of some token, calculates the value in `USD`. + * @dev Returns zero if no known price feed for the token. + * @param token The address of the token to price. + * @param amount The amount of the token to price. + * @return valueInUSD The value in `USD` with 18 decimals. + */ + function valueOfTokens(address token, uint256 amount) external view override returns (uint256 valueInUSD) { + PriceFeedData memory feed = _priceFeeds[token]; + return (amount * feed.latestPrice * 1 ether) / (10 ** (feed.tokenDecimals + feed.priceFeedDecimals)); + } + + /** + * @notice Returns the status of an updater. + * @param updater The account to query. + * @return status True if the account has the updater role, false otherwise. + */ + function isUpdater(address updater) external view override returns (bool status) { + return _isUpdater[updater]; + } + + /*************************************** + UPDATER FUNCTIONS + ***************************************/ + + /** + * @notice Sets metadata for each token and adds it to the token enumeration. + * Can only be called by an `updater`. + * @param feeds The list of feeds to set. + */ + function addPriceFeeds(PriceFeedData[] memory feeds) external override { + require(_isUpdater[msg.sender], "!updater"); + uint256 stLen = _tokensLength; + uint256 stLen0 = stLen; + for(uint256 i = 0; i < feeds.length; i++) { + // add to feed mapping + PriceFeedData memory feed = feeds[i]; + address token = feed.token; + _priceFeeds[token] = feed; + // add to token enumeration + if(_tokenToIndex[token] == 0) { + uint256 index = stLen++; // autoincrement from 0 + _indexToToken[index] = token; + _tokenToIndex[token] = index + 1; + } + emit PriceFeedAdded(token); + } + if(stLen != stLen0) _tokensLength = stLen; + } + + /** + * @notice Sets latest price for each token. + * Can only be called by an `updater`. + * @param tokens The list of token addresses to set prices for. + * @param prices The list of prices for each token. + */ + function transmit(address[] memory tokens, uint256[] memory prices) external override { + require(_isUpdater[msg.sender], "!updater"); + uint256 len = tokens.length; + require(len == prices.length, "length mismatch"); + for(uint256 i = 0; i < len; i++) { + _priceFeeds[tokens[i]].latestPrice = prices[i]; + emit PriceTransmitted(tokens[i], prices[i]); + } + } + + /*************************************** + GOVERNANCE FUNCTIONS + ***************************************/ + + /** + * @notice Adds or removes updaters. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param updaters The list of updater addresses to add or remove. + * @param statuses A list of true to set as updater false otherwise. + */ + function setUpdaterStatuses(address[] memory updaters, bool[] memory statuses) external override onlyGovernance { + uint256 len = updaters.length; + require(len == statuses.length, "length mismatch"); + for(uint256 i = 0; i < len; i++) { + _isUpdater[updaters[i]] = statuses[i]; + emit UpdaterSet(updaters[i], statuses[i]); + } + } +} diff --git a/contracts/native/UnderwritingEquity.sol b/contracts/native/UnderwritingEquity.sol new file mode 100644 index 00000000..ca3bb317 --- /dev/null +++ b/contracts/native/UnderwritingEquity.sol @@ -0,0 +1,272 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.6; + +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol"; +import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; +import "../utils/Governable.sol"; +import "../interfaces/native/IUnderwritingEquity.sol"; + + +/** + * @title UnderwritingEquity + * @author solace.fi + * @notice Equity of the [Underwriting Pool](./UnderwritingPool) that can be used in Solace Native. + * + * Users can deposit [`UWP`](./UnderwritingPool) via [`deposit()`](#deposit) which mints `UWE`. Users can redeem `UWE` for [`UWP`](./UnderwritingPool) via [`withdraw()`](#withdraw). Note that deposits must be made via [`deposit()`](#deposit). Simply transferring [`UWP`](./UnderwritingPool) to this contract will not mint `UWE`. + * + * Solace may charge a protocol fee as a fraction of the mint amount [`issueFee()`](#issuefee). + * + * Solace may lend some of the underlying [`UWP`](./UnderwritingPool) to a lending module and borrow stables against it to pay claims via [`lend()`](#lend). + * + * [Governance](/docs/protocol/governance) can pause and unpause [`deposit()`](#deposit), [`withdraw()`](#withdraw), and [`lend()`](#lend). + */ +contract UnderwritingEquity is IUnderwritingEquity, ERC20Permit, ReentrancyGuard, Governable { + + /*************************************** + STATE VARIABLES + ***************************************/ + + // underwriting pool token + address internal _uwp; + + // issue fee in 18 decimals. default zero + uint256 internal _issueFee; + // receiver of issue fee + address internal _issueFeeTo; + // true if deposit is paused. default false + bool internal _depositIsPaused; + // true if withdraw is paused. default false + bool internal _withdrawIsPaused; + // true if lend is paused. default false + bool internal _lendIsPaused; + + /** + * @notice Constructs the `UnderwritingEquity` contract. + * @param governance_ The address of the governor. + */ + // solhint-disable-next-line no-empty-blocks + constructor (address governance_, address uwp_) ERC20("Solace Native Underwriting Equity", "UWE") ERC20Permit("Solace Native Underwriting Equity") Governable(governance_) { + require(uwp_ != address(0x0), "zero address uwp"); + _uwp = uwp_; + } + + /*************************************** + VIEW FUNCTIONS + ***************************************/ + + /** + * @notice Address of the [`underwriting pool`](./UnderwritingPool). + * @return uwp The underwriting pool. + */ + function underwritingPool() external view override returns (address uwp) { + return _uwp; + } + + /** + * @notice The fraction of `UWE` that are charged as a protocol fee on mint. + * @return fee The fee as a fraction with 18 decimals. + */ + function issueFee() external view override returns (uint256 fee) { + return _issueFee; + } + + /** + * @notice The receiver of issue fees. + * @return receiver The receiver of the fee. + */ + function issueFeeTo() external view override returns (address receiver) { + return _issueFeeTo; + } + + /** + * @notice Returns true if functionality of the contract is paused. + * @return depositIsPaused Returns true if depositing is paused. + * @return withdrawIsPaused Returns true if withdrawing is paused. + * @return lendIsPaused Returns true if lending is paused. + */ + function isPaused() external view override returns (bool depositIsPaused, bool withdrawIsPaused, bool lendIsPaused) { + return (_depositIsPaused, _withdrawIsPaused, _lendIsPaused); + } + + /** + * @notice Calculates the amount of `UWE` minted for an amount of [`UWP`](./UnderwritingPool) deposited. + * @param uwpAmount The amount of [`UWP`](./UnderwritingPool) to deposit. + * @return uweAmount The amount of `UWE` that will be minted to the receiver. + */ + function calculateDeposit(uint256 uwpAmount) external view override returns (uint256 uweAmount) { + // get state + uint256 ts = totalSupply(); + IERC20 uwp = IERC20(_uwp); + uint256 bal = uwp.balanceOf(address(this)); + // calculate uwe amount + uweAmount = ((ts == 0 || bal == 0) + ? uwpAmount + : ((uwpAmount * ts) / bal) ); + uint256 fee = uweAmount * _issueFee / 1 ether; + if(fee > 0) { + uweAmount -= fee; + } + return uweAmount; + } + + /** + * @notice Calculates the amount of [`UWP`](./UnderwritingPool) returned for an amount of `UWE` withdrawn. + * @param uweAmount The amount of `UWE` to redeem. + * @return uwpAmount The amount of [`UWP`](./UnderwritingPool) that will be returned to the receiver. + */ + function calculateWithdraw(uint256 uweAmount) external view override returns (uint256 uwpAmount) { + // get state + uint256 ts = totalSupply(); + require(uweAmount <= ts, "withdraw amount exceeds supply"); + IERC20 uwp = IERC20(_uwp); + uint256 bal = uwp.balanceOf(address(this)); + // calculate uwp amount + uwpAmount = ((ts == 0) + ? 0 + : ((uweAmount * bal) / ts) ); + return uwpAmount; + } + + /*************************************** + MODIFIER FUNCTIONS + ***************************************/ + + /** + * @notice Deposits [`UWP`](./UnderwritingPool) into `UWE`. + * @param uwpAmount The amount of [`UWP`](./UnderwritingPool) to deposit. + * @param receiver The address to send newly minted `UWE` to. + * @return uweAmount The amount of `UWE` minted. + */ + function deposit(uint256 uwpAmount, address receiver) external override nonReentrant returns (uint256 uweAmount) { + require(!_depositIsPaused, "deposit is paused"); + // get state + uint256 ts = totalSupply(); + IERC20 uwp = IERC20(_uwp); + uint256 bal = uwp.balanceOf(address(this)); + // transfer in uwp + SafeERC20.safeTransferFrom(uwp, msg.sender, address(this), uwpAmount); + // calculate uwe amount + uweAmount = ((ts == 0 || bal == 0) + ? uwpAmount + : ((uwpAmount * ts) / bal) ); + uint256 fee = uweAmount * _issueFee / 1 ether; + if(fee > 0) { + _mint(_issueFeeTo, fee); + uweAmount -= fee; + } + // mint uwe + _mint(receiver, uweAmount); + emit DepositMade(msg.sender, uwpAmount, uweAmount); + return uweAmount; + } + + /** + * @notice Redeems some `UWE` for [`UWP`](./UnderwritingPool). + * @param uweAmount The amount of `UWE` to burn. + * @param receiver The address to receive [`UWP`](./UnderwritingPool). + * @return uwpAmount The amount of [`UWP`](./UnderwritingPool) received. + */ + function withdraw(uint256 uweAmount, address receiver) external override nonReentrant returns (uint256 uwpAmount) { + require(!_withdrawIsPaused, "withdraw is paused"); + // get state + uint256 ts = totalSupply(); + IERC20 uwp = IERC20(_uwp); + uint256 bal = uwp.balanceOf(address(this)); + // calculate uwp amount + uwpAmount = ((ts == 0) + ? 0 + : ((uweAmount * bal) / ts) ); + // burn uwe + _burn(msg.sender, uweAmount); + // transfer out uwp + SafeERC20.safeTransfer(IERC20(_uwp), receiver, uwpAmount); + emit WithdrawMade(msg.sender, uwpAmount, uweAmount); + return uwpAmount; + } + + /** + * @notice Burns some `UWE` from `msg.sender`. + * @param uweAmount The amount of `UWE` to burn. + */ + function burn(uint256 uweAmount) external override { + _burn(msg.sender, uweAmount); + } + + /*************************************** + GOVERNANCE FUNCTIONS + ***************************************/ + + /** + * @notice Rescues misplaced tokens. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param tokens The list of tokens to rescue. + * @param receiver The receiver of the tokens. + */ + function rescueTokens(address[] memory tokens, address receiver) external override onlyGovernance { + address uwp_ = _uwp; + // for each requested token + uint256 len = tokens.length; + for(uint256 index = 0; index < len; index++) { + address token = tokens[index]; + // cannot rescue valued underlying tokens + require(token != uwp_, "cannot rescue uwp"); + // send balance to receiver + IERC20 tkn = IERC20(token); + uint256 balance = tkn.balanceOf(address(this)); + SafeERC20.safeTransfer(tkn, receiver, balance); + } + } + + /** + * @notice Lends out [`UWP`](./UnderwritingPool) to pay claims. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param uwpAmount The amount of [`UWP`](./UnderwritingPool) to lend. + * @param receiver The receiver of [`UWP`](./UnderwritingPool). + */ + function lend(uint256 uwpAmount, address receiver) external override onlyGovernance { + require(!_lendIsPaused, "lend is paused"); + SafeERC20.safeTransfer(IERC20(_uwp), receiver, uwpAmount); + emit UwpLoaned(uwpAmount, receiver); + } + + /** + * @notice Sets the issue fee and receiver. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param fee The fee as a fraction with 18 decimals. + * @param receiver The receiver of the fee. + */ + function setIssueFee(uint256 fee, address receiver) external override onlyGovernance { + require(fee <= 1 ether, "invalid issue fee"); + require(fee == 0 || receiver != address(0x0), "invalid issue fee to"); + _issueFee = fee; + _issueFeeTo = receiver; + emit IssueFeeSet(fee, receiver); + } + + /** + * @notice Pauses or unpauses contract functionality. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param depositIsPaused True to pause deposit, false to unpause. + * @param withdrawIsPaused True to pause withdraw, false to unpause. + * @param lendIsPaused True to pause lend, false to unpause. + */ + function setPause(bool depositIsPaused, bool withdrawIsPaused, bool lendIsPaused) external override onlyGovernance { + _depositIsPaused = depositIsPaused; + _withdrawIsPaused = withdrawIsPaused; + _lendIsPaused = lendIsPaused; + emit PauseSet(depositIsPaused, withdrawIsPaused, lendIsPaused); + } + + /** + * @notice Upgrades the [`UWP`](./UnderwritingPool) contract. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param uwp_ The address of the new [`UWP`](./UnderwritingPool). + */ + function setUwp(address uwp_) external override onlyGovernance { + require(uwp_ != address(0x0), "zero address uwp"); + _uwp = uwp_; + emit UwpSet(uwp_); + } +} diff --git a/contracts/native/UnderwritingLockVoting.sol b/contracts/native/UnderwritingLockVoting.sol new file mode 100644 index 00000000..f2e17779 --- /dev/null +++ b/contracts/native/UnderwritingLockVoting.sol @@ -0,0 +1,587 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.6; + +import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; +import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; +import "./../utils/Governable.sol"; +import "./../interfaces/utils/IRegistry.sol"; +import "./../interfaces/native/IUnderwritingLocker.sol"; +import "./../interfaces/native/IUnderwritingLockVoting.sol"; +import "./../interfaces/native/IGaugeController.sol"; + +/** + * @title UnderwritingLockVoting + * @author solace.fi + * @notice Enables individual votes in Solace Native insurance gauges for owners of [`UnderwritingLocker`](./UnderwritingLocker). + * + * Any address owning an underwriting lock can vote and will have a votePower that can be viewed with [`getVotePower()`](#getVotePower) + * An address' vote power is the sum of the vote power of its owned locks. + * A lock's vote power scales linearly with locked amount, and through a sqrt formula with lock duration + * Users cannot view the vote power of an individual lock through this contract, only the total vote power of an address. + * This is an intentional design choice to abstract locks away from address-based voting. + * + * Voters can set a delegate who can vote on their behalf via [`setDelegate()`](#setDelegate). + * + * To cast a vote, either the voter or their delegate can call [`vote()`](#vote) or [`voteMultiple()`](#voteMultiple). + * Votes can be cast among existing gaugeIDs (set in GaugeController.sol), and voters/delegates can set a custom proportion + * of their total voting power for different gauges. + * Voting power proportion is measured in bps, and total used voting power bps for a voter cannot exceed 10000. + * + * Votes are saved, so a vote today will count as the voter's vote for all future epochs until the voter modifies their votes. + * + * After each epoch (one-week) has passed, voting is frozen until governance has processed all the votes. + * This is a two-step process: + * GaugeController.updateGaugeWeights() - this will aggregate individual votes and update gauge weights accordingly + * [`chargePremiums()`](#chargepremiums) - this will charge premiums for every vote. There is a voting premium + * to be paid every epoch, this gets sent to the revenue router. + */ +contract UnderwritingLockVoting is + IUnderwritingLockVoting, + ReentrancyGuard, + Governable + { + using EnumerableSet for EnumerableSet.AddressSet; + + /*************************************** + GLOBAL PUBLIC VARIABLES + ***************************************/ + + /// @notice Revenue router address (Voting premiums will be transferred here). + address public override revenueRouter; + + /// @notice Address of [`UnderwritingLocker`](./UnderwritingLocker). + address public override underwritingLocker; + + /// @notice Address of [`GaugeController`](./GaugeController). + address public override gaugeController; + + /// @notice Address of [`BribeController`](./BribeController). + address public override bribeController; + + /// @notice Registry address + address public override registry; + + /// @notice Updater address. + /// @dev Second address that can call chargePremiums (in addition to governance). + address public override updater; + + /// @notice End timestamp for last epoch that premiums were charged for all stored votes. + uint256 public override lastTimePremiumsCharged; + + /// @notice voter => delegate. + mapping(address => address) public override delegateOf; + + /// @notice voter => used voting power percentage (max of 10000 bps). + mapping(address => uint256) public override usedVotePowerBPSOf; + + /*************************************** + GLOBAL INTERNAL VARIABLES + ***************************************/ + + uint256 constant internal YEAR = 31536000; + + /// @notice Total premium due to the revenueRouter. + /// @dev Avoid this storage slot being 0, avoid SSTORE cost from 0 to nonzero value. + uint256 internal _totalPremiumDue; + + /// @notice voter => last processed vote power. + /// @dev Cache for getVotePower() result for most recent GaugeController.updateGaugeWeights() call. + mapping (address => uint256) internal _lastProcessedVotePowerOf; + + /// @notice State of last [`chargePremiums()`](#chargepremiums) call. + GaugeStructs.UpdateInfo internal _updateInfo; + + /// @notice delegate => voters. + mapping(address => EnumerableSet.AddressSet) internal _votingDelegatorsOf; + + /*************************************** + CONSTRUCTOR + ***************************************/ + + /** + * @notice Constructs the UnderwritingLockVoting contract. + * @dev Requires 'uwe', 'revenueRouter', 'underwritingLocker' and 'gaugeController' addresses to be set in the Registry. + * @param governance_ The address of the [governor](/docs/protocol/governance). + * @param registry_ The [`Registry`](./Registry) contract address. + */ + constructor(address governance_, address registry_) Governable(governance_) { + _setRegistry(registry_); + // Initialize as non-zero storage slots. + _totalPremiumDue = type(uint256).max; + _clearUpdateInfo(); + } + + /*************************************** + INTERNAL VIEW FUNCTIONS + ***************************************/ + + /** + * @notice Get vote power for a lock. + * @dev Need try-catch block, otherwise revert for burned lock will deadlock updateGaugeWeight() call. + * @param lockID_ The ID of the lock to query. + * @return votePower + */ + function _getVotePowerOfLock(uint256 lockID_) internal view returns (uint256 votePower) { + try IUnderwritingLocker(underwritingLocker).locks(lockID_) returns (Lock memory lock) { + return ( lock.amount * IUnderwritingLocker(underwritingLocker).getLockMultiplier(lockID_) ) / 1e18; + } catch { + return 0; + } + } + + /** + * @notice Get timestamp for the start of the current epoch. + * @return timestamp + */ + function _getEpochStartTimestamp() internal view returns (uint256 timestamp) { + return IGaugeController(gaugeController).getEpochStartTimestamp(); + } + + /** + * @notice Get timestamp for end of the current epoch. + * @return timestamp + */ + function _getEpochEndTimestamp() internal view returns (uint256 timestamp) { + return IGaugeController(gaugeController).getEpochEndTimestamp(); + } + + /** + * @notice Get end timestamp for last epoch that all stored votes were processed. + * @return timestamp + */ + function _getLastTimeGaugesUpdated() internal view returns (uint256 timestamp) { + return IGaugeController(gaugeController).lastTimeGaugeWeightsUpdated(); + } + + /** + * @notice Query whether msg.sender is either the governance or updater role. + * @return True if msg.sender is either governor or updater roler, and contract govenance is not locked, false otherwise. + */ + function _isUpdaterOrGovernance() internal view returns (bool) { + return ( !this.governanceIsLocked() && ( msg.sender == updater || msg.sender == this.governance() )); + } + + /*************************************** + EXTERNAL VIEW FUNCTIONS + ***************************************/ + + /** + * @notice Get vote power for a voter. + * @param voter_ The address of the voter to query. + * @return votePower + */ + function getVotePower(address voter_) external view override returns (uint256 votePower) { + uint256[] memory lockIDs = IUnderwritingLocker(underwritingLocker).getAllLockIDsOf(voter_); + uint256 numVoterLocks = lockIDs.length; + for (uint256 i = 0; i < numVoterLocks; i++) {votePower += _getVotePowerOfLock(lockIDs[i]);} + } + + /** + * @notice Get all current votes for a voter. + * @param voter_ Address of voter to query for. + * @return votes Array of Vote{gaugeID, votePowerBPS}. + */ + function getVotes(address voter_) external view override returns (GaugeStructs.Vote[] memory votes) { + return IGaugeController(gaugeController).getVotes(address(this), voter_); + } + + /** + * @notice Get timestamp for the start of the current epoch. + * @return timestamp + */ + function getEpochStartTimestamp() external view override returns (uint256 timestamp) { + return _getEpochStartTimestamp(); + } + + /** + * @notice Get timestamp for end of the current epoch. + * @return timestamp + */ + function getEpochEndTimestamp() external view override returns (uint256 timestamp) { + return _getEpochEndTimestamp(); + } + + /** + * @notice Query whether voting is currently open. + * @return True if voting is open for this epoch, false otherwise. + */ + function isVotingOpen() external view override returns (bool) { + uint256 epochStartTime = _getEpochStartTimestamp(); + return epochStartTime == lastTimePremiumsCharged && epochStartTime == _getLastTimeGaugesUpdated(); + } + + /** + * @notice Get array of voters who have delegated their vote to a given address. + * @param delegate_ Address to query array of voting delegators for. + * @return votingDelegators Array of voting delegators. + */ + function getVotingDelegatorsOf(address delegate_) external view override returns (address[] memory votingDelegators) { + uint256 length = _votingDelegatorsOf[delegate_].length(); + votingDelegators = new address[](length); + for (uint256 i = 0; i < length; i++) { + votingDelegators[i] = _votingDelegatorsOf[delegate_].at(i); + } + } + + /** + * @notice Get last processed vote power for given voter. + * @param voter_ Address of voter to query for. + * @return lastProcessedVotePower + */ + function getLastProcessedVotePowerOf(address voter_) external view override returns (uint256 lastProcessedVotePower) { + return _lastProcessedVotePowerOf[voter_]; + } + + /*************************************** + INTERNAL MUTATOR FUNCTIONS + ***************************************/ + + /** + * @notice Set the voting delegate for the caller. + * To remove a delegate, the delegate can be set to the ZERO_ADDRESS - 0x0000000000000000000000000000000000000000 + * @param delegate_ Address of intended delegate + */ + function _setDelegate(address delegate_) internal { + address oldDelegate = delegateOf[msg.sender]; + if (oldDelegate != address(0)) _votingDelegatorsOf[oldDelegate].remove(msg.sender); + if (delegate_ != address(0)) _votingDelegatorsOf[delegate_].add(msg.sender); + delegateOf[msg.sender] = delegate_; + emit DelegateSet(msg.sender, delegate_); + } + + /** + * @notice Sets registry and related contract addresses. + * @dev Requires 'uwe', 'revenueRouter' and 'underwritingLocker' addresses to be set in the Registry. + * @param _registry The registry address to set. + */ + function _setRegistry(address _registry) internal { + if(_registry == address(0x0)) revert ZeroAddressInput("registry"); + registry = _registry; + IRegistry reg = IRegistry(_registry); + // set revenueRouter + (, address revenueRouterAddr) = reg.tryGet("revenueRouter"); + if(revenueRouterAddr == address(0x0)) revert ZeroAddressInput("revenueRouter"); + revenueRouter = revenueRouterAddr; + // set underwritingLocker + (, address underwritingLockerAddr) = reg.tryGet("underwritingLocker"); + if(underwritingLockerAddr == address(0x0)) revert ZeroAddressInput("underwritingLocker"); + underwritingLocker = underwritingLockerAddr; + // set gaugeController + (, address gaugeControllerAddr) = reg.tryGet("gaugeController"); + if(gaugeControllerAddr == address(0x0)) revert ZeroAddressInput("gaugeController"); + gaugeController = gaugeControllerAddr; + emit RegistrySet(_registry); + } + + /** + * @notice Add, change or remove votes. + * Can only be called by the voter or their delegate. + * @param voter_ The voter address. + * @param gaugeIDs_ The array of gaugeIDs to vote for. + * @param votePowerBPSs_ The corresponding array of votePowerBPS values. Can be from 0-10000. + */ + function _vote(address voter_, uint256[] memory gaugeIDs_, uint256[] memory votePowerBPSs_) internal { + // Disable voting if votes not yet processed or premiums not yet charged for this epoch + if ( _getEpochStartTimestamp() != lastTimePremiumsCharged) revert LastEpochPremiumsNotCharged(); + if( voter_ != msg.sender && delegateOf[voter_] != msg.sender && bribeController != msg.sender) revert NotOwnerNorDelegate(); + if (gaugeIDs_.length != votePowerBPSs_.length) revert ArrayArgumentsLengthMismatch(); + + for(uint256 i = 0; i < gaugeIDs_.length; i++) { + uint256 gaugeID = gaugeIDs_[i]; + uint256 votePowerBPS = votePowerBPSs_[i]; + if (votePowerBPS > 10000) revert SingleVotePowerBPSOver10000(); + + // If remove vote + if ( votePowerBPS == 0 ) { + uint256 oldVotePowerBPS = IGaugeController(gaugeController).vote(voter_, gaugeID, votePowerBPS); + usedVotePowerBPSOf[voter_] -= oldVotePowerBPS; + emit VoteRemoved(voter_, gaugeID); + } else { + uint256 oldVotePowerBPS = IGaugeController(gaugeController).vote(voter_, gaugeID, votePowerBPS); + // Add vote + if (oldVotePowerBPS == 0) { + usedVotePowerBPSOf[voter_] += votePowerBPS; + emit VoteAdded(voter_, gaugeID, votePowerBPS); + // Else modify vote + } else { + usedVotePowerBPSOf[voter_] += votePowerBPS; + usedVotePowerBPSOf[voter_] -= oldVotePowerBPS; + emit VoteChanged(voter_, gaugeID, votePowerBPS, oldVotePowerBPS); + } + } + } + + if (usedVotePowerBPSOf[voter_] > 10000) revert TotalVotePowerBPSOver10000(); + } + + /*************************************** + EXTERNAL MUTATOR FUNCTIONS + ***************************************/ + + /** + * @notice Register a single vote for a gauge. Can either add or change a vote. + * @notice Can also remove a vote (votePowerBPS_ == 0), the difference with removeVote() is that + * vote() will revert if the voter has no locks (no locks => no right to vote, but may have votes from + * locks that have since been burned). + * @notice GaugeController.updateGaugeWeights() will remove voters with no voting power, however voters can + * preemptively 'clean' the system. + * @notice Votes are frozen after the end of every epoch, and resumed when all stored votes have been processed. + * Can only be called by the voter or vote delegate. + * @param voter_ The voter address. + * @param gaugeID_ The ID of the gauge to vote for. + * @param votePowerBPS_ Vote power BPS to assign to this vote + */ + function vote(address voter_, uint256 gaugeID_, uint256 votePowerBPS_) external override { + if ( IUnderwritingLocker(underwritingLocker).balanceOf(voter_) == 0 ) revert VoterHasNoLocks(); + uint256[] memory gaugeIDs_ = new uint256[](1); + uint256[] memory votePowerBPSs_ = new uint256[](1); + gaugeIDs_[0] = gaugeID_; + votePowerBPSs_[0] = votePowerBPS_; + _vote(voter_, gaugeIDs_, votePowerBPSs_); + } + + /** + * @notice Register multiple gauge votes. + * Can only be called by the voter or vote delegate. + * @param voter_ The voter address. + * @param gaugeIDs_ Array of gauge IDs to vote for. + * @param votePowerBPSs_ Array of corresponding vote power BPS values. + */ + function voteMultiple(address voter_, uint256[] memory gaugeIDs_, uint256[] memory votePowerBPSs_) external override { + if ( IUnderwritingLocker(underwritingLocker).balanceOf(voter_) == 0 ) revert VoterHasNoLocks(); + _vote(voter_, gaugeIDs_, votePowerBPSs_); + } + + /** + * @notice Register a single voting configuration for multiple voters. + * Can only be called by the voter or vote delegate. + * @param voters_ Array of voters. + * @param gaugeIDs_ Array of gauge IDs to vote for. + * @param votePowerBPSs_ Array of corresponding vote power BPS values. + */ + function voteForMultipleVoters(address[] calldata voters_, uint256[] memory gaugeIDs_, uint256[] memory votePowerBPSs_) external override { + uint256 length = voters_.length; + for (uint256 i = 0; i < length; i++) { + if ( IUnderwritingLocker(underwritingLocker).balanceOf(voters_[i]) == 0 ) revert VoterHasNoLocks(); + _vote(voters_[i], gaugeIDs_, votePowerBPSs_); + } + } + + /** + * @notice Removes a vote. + * @notice Votes cannot be removed while voting is frozen. + * Can only be called by the voter or vote delegate. + * @param voter_ The voter address. + * @param gaugeID_ The ID of the gauge to remove vote for. + */ + function removeVote(address voter_, uint256 gaugeID_) external override { + uint256[] memory gaugeIDs_ = new uint256[](1); + uint256[] memory votePowerBPSs_ = new uint256[](1); + gaugeIDs_[0] = gaugeID_; + votePowerBPSs_[0] = 0; + _vote(voter_, gaugeIDs_, votePowerBPSs_); + } + + /** + * @notice Remove multiple gauge votes. + * @notice Votes cannot be removed while voting is frozen. + * Can only be called by the voter or vote delegate. + * @param voter_ The voter address. + * @param gaugeIDs_ Array of gauge IDs to remove votes for. + */ + function removeVoteMultiple(address voter_, uint256[] memory gaugeIDs_) external override { + uint256[] memory votePowerBPSs_ = new uint256[](gaugeIDs_.length); + for(uint256 i = 0; i < gaugeIDs_.length; i++) {votePowerBPSs_[i] = 0;} + _vote(voter_, gaugeIDs_, votePowerBPSs_); + } + + /** + * @notice Remove gauge votes for multiple voters. + * @notice Votes cannot be removed while voting is frozen. + * Can only be called by the voter or vote delegate. + * @param voters_ Array of voter addresses. + * @param gaugeIDs_ Array of gauge IDs to remove votes for. + */ + function removeVotesForMultipleVoters(address[] calldata voters_, uint256[] memory gaugeIDs_) external override { + uint256 length = voters_.length; + uint256[] memory votePowerBPSs_ = new uint256[](gaugeIDs_.length); + for(uint256 i = 0; i < gaugeIDs_.length; i++) {votePowerBPSs_[i] = 0;} + for (uint256 i = 0; i < length; i++) { + _vote(voters_[i], gaugeIDs_, votePowerBPSs_); + } + } + + /** + * @notice Set the voting delegate for the caller. + * To remove a delegate, the delegate can be set to the ZERO_ADDRESS - 0x0000000000000000000000000000000000000000. + * @param delegate_ Address of intended delegate + */ + function setDelegate(address delegate_) external override { + _setDelegate(delegate_); + } + + /*************************************** + GAUGE CONTROLLER FUNCTIONS + ***************************************/ + + /** + * @notice Cache last processed vote power for a voter. + * @dev Can only be called by the gaugeController contract. + * @dev Assist gas efficiency of chargePremiums(). + * @param voter_ Address of voter. + * @param votePower_ Vote power. + */ + function cacheLastProcessedVotePower(address voter_, uint256 votePower_) external override { + if (msg.sender != gaugeController) revert NotGaugeController(); + _lastProcessedVotePowerOf[voter_] = votePower_; + } + + /*************************************** + GOVERNANCE FUNCTIONS + ***************************************/ + + /** + * @notice Sets the [`Registry`](./Registry) contract address. + * @dev Requires 'uwe', 'revenueRouter' and 'underwritingLocker' addresses to be set in the Registry. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param registry_ The address of `Registry` contract. + */ + function setRegistry(address registry_) external override onlyGovernance { + _setRegistry(registry_); + } + + /** + * @notice Set updater address. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param updater_ The address of the new updater. + */ + function setUpdater(address updater_) external override onlyGovernance { + updater = updater_; + emit UpdaterSet(updater_); + } + + /** + * @notice Sets bribeController as per `bribeController` address stored in Registry. + * @dev We do not set this in constructor, because we expect BribeController.sol to be deployed after this contract. + * Can only be called by the current [**governor**](/docs/protocol/governance). + */ + function setBribeController() external override onlyGovernance { + (, address bribeControllerAddr) = IRegistry(registry).tryGet("bribeController"); + if(bribeControllerAddr == address(0x0)) revert ZeroAddressInput("bribeController"); + bribeController = bribeControllerAddr; + emit BribeControllerSet(bribeControllerAddr); + } + + /** + * @notice Charge premiums for votes. + * @dev Designed to be called in a while-loop with the condition being `lastTimePremiumsCharged != epochStartTimestamp` and using the maximum custom gas limit. + * @dev Requires GaugeController.updateGaugeWeights() to be run to completion for the last epoch. + * Can only be called by the current [**governor**](/docs/protocol/governance). + */ + function chargePremiums() external override { + if (!_isUpdaterOrGovernance()) revert NotUpdaterNorGovernance(); + uint256 epochStartTimestamp = _getEpochStartTimestamp(); + if(_getLastTimeGaugesUpdated() != epochStartTimestamp) revert GaugeWeightsNotYetUpdated(); + if(lastTimePremiumsCharged == epochStartTimestamp) revert LastEpochPremiumsAlreadyProcessed({epochTime: epochStartTimestamp}); + + // Single call for universal multipliers in premium computation. + uint256 insuranceCapacity = IGaugeController(gaugeController).getInsuranceCapacity(); + uint256 votePowerSum = IGaugeController(gaugeController).getVotePowerSum(); + uint256 epochLength = IGaugeController(gaugeController).getEpochLength(); + + // Iterate through voters + address[] memory voters = IGaugeController(gaugeController).getVoters(address(this)); + for(uint256 i = _updateInfo._votersIndex == type(uint88).max ? 0 : _updateInfo._votersIndex ; i < voters.length; i++) { + // _saveUpdateState(0, i, 0); + // Short-circuit operator - need at least 30K gas for getVoteCount() call + if (gasleft() < 40000 || gasleft() < 10000 * IGaugeController(gaugeController).getVoteCount(address(this), voters[i])) { + return _saveUpdateState(0, i, 0); + } + // Unbounded loop since # of votes (gauges) unbounded + uint256 premium = _calculateVotePremium(voters[i], insuranceCapacity, votePowerSum, epochLength); // 87K gas for 10 votes + uint256[] memory lockIDs = IUnderwritingLocker(underwritingLocker).getAllLockIDsOf(voters[i]); + uint256 numLocks = lockIDs.length; + + // Iterate through locks + // Using _votesIndex as _lockIndex + // If either votesIndex slot is cleared, or we aren't on the same voter as when we last saved, start from index 0. + for(uint256 j = _updateInfo._votesIndex == type(uint88).max || i != _updateInfo._votersIndex ? 0 : _updateInfo._votesIndex; j < numLocks; j++) { + if (gasleft() < 20000) {return _saveUpdateState(0, i, j);} + // Split premium amongst each lock equally. + IUnderwritingLocker(underwritingLocker).chargePremium(lockIDs[j], premium / numLocks); + } + + _totalPremiumDue -= premium; + } + + SafeERC20.safeTransferFrom( + IERC20(IUnderwritingLocker(underwritingLocker).token()), + underwritingLocker, + revenueRouter, + type(uint256).max - _totalPremiumDue // Avoid _totalPremiumDue being zero. + ); + + _clearUpdateInfo(); + _totalPremiumDue = type(uint256).max; // Reinitialize _totalPremiumDue. + lastTimePremiumsCharged = epochStartTimestamp; + emit AllPremiumsCharged(epochStartTimestamp); + } + + /*************************************** + updateGaugeWeights() HELPER FUNCTIONS + ***************************************/ + + /** + * @notice Save state of charging premium to _updateInfo + * @param empty_ Empty index (should be 0). + * @param votersIndex_ Current index of _voters[votingContractsIndex_]. + * @param lockIndex_ Current index of _votes[votingContractsIndex_][votersIndex_] + */ + function _saveUpdateState(uint256 empty_, uint256 votersIndex_, uint256 lockIndex_) internal { + assembly { + let updateInfo + updateInfo := or(updateInfo, shr(176, shl(176, empty_))) // [0:80] => empty_ + updateInfo := or(updateInfo, shr(88, shl(168, votersIndex_))) // [80:168] => votersIndex_ + updateInfo := or(updateInfo, shl(168, lockIndex_)) // [168:256] => lockIndex_ + sstore(_updateInfo.slot, updateInfo) + } + emit IncompletePremiumsCharge(); + } + + /// @notice Reset _updateInfo to starting state. + /// @dev Avoid zero-value of storage slot. + function _clearUpdateInfo() internal { + uint256 bitmap = type(uint256).max; + assembly { + sstore(_updateInfo.slot, bitmap) + } + } + + /** + * @notice Computes voting premium for voter. + * @param voter_ Address of voter. + * @param insuranceCapacity_ Solace Native insurance capacity. + * @param votePowerSum_ Solace Native vote power sum. + * @return premium Premium for voter. + */ + function _calculateVotePremium(address voter_, uint256 insuranceCapacity_, uint256 votePowerSum_, uint256 epochLength_) internal view returns (uint256 premium) { + GaugeStructs.Vote[] memory votes = IGaugeController(gaugeController).getVotes(address(this), voter_); + uint256 voteCount = votes.length; + + if (voteCount > 0) { + uint256 accummulator; + uint256 globalNumerator = _lastProcessedVotePowerOf[voter_] * insuranceCapacity_ * epochLength_; + // rateOnLine scaled to correct fraction for week => multiply by (WEEK / YEAR) * (1 / 1e18) + // votePowerBPS scaled to correct fraction => multiply by (1 / 10000) + uint256 globalDenominator = votePowerSum_ * YEAR * 1e18 * 10000; + for (uint256 i = 0 ; i < voteCount; i++) { + accummulator += IGaugeController(gaugeController).getRateOnLineOfGauge(votes[i].gaugeID) * votes[i].votePowerBPS; + } + return accummulator * globalNumerator / globalDenominator; + } else { + return 0; + } + } +} diff --git a/contracts/native/UnderwritingLocker.sol b/contracts/native/UnderwritingLocker.sol new file mode 100644 index 00000000..9b61d7e6 --- /dev/null +++ b/contracts/native/UnderwritingLocker.sol @@ -0,0 +1,791 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.6; + +import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol"; +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; +import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; +import "@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol"; +import "./../interfaces/utils/IRegistry.sol"; +import "./../interfaces/native/IUnderwritingLockListener.sol"; +import "./../interfaces/native/IUnderwritingLocker.sol"; +import "./../interfaces/native/IUnderwritingEquity.sol"; +import "./../utils/ERC721Enhanced.sol"; +import "./../utils/Governable.sol"; + + +/** + * @title UnderwritingLocker + * @author solace.fi + * @notice Having an underwriting lock is a requirement to vote on Solace Native insurance gauges. + * To create an underwriting lock, $UWE must be locked for a minimum of 6 months. + * + * Locks are ERC721s and can be viewed with [`locks()`](#locks). + * Each lock has an `amount` of locked $UWE, and an `end` timestamp. + * Locks have a maximum duration of four years. + * + * Users can create locks via [`createLock()`](#createlock) or [`createLockSigned()`](#createlocksigned). + * Users can deposit more $UWE into a lock via [`increaseAmount()`](#increaseamount), [`increaseAmountSigned()`] (#increaseamountsigned) or [`increaseAmountMultiple()`](#increaseamountmultiple). + * Users can extend a lock via [`extendLock()`](#extendlock) or [`extendLockMultiple()`](#extendlockmultiple). + * Users can withdraw from a lock via [`withdraw()`](#withdraw), [`withdrawInPart()`](#withdrawinpart), [`withdrawMultiple()`](#withdrawmultiple) or [`withdrawInPartMultiple()`](#withdrawinpartmultiple). + * + * Users and contracts may create a lock for another address. + * Users and contracts may deposit into a lock that they do not own. + * A portion (set by the funding rate) of withdraws will be burned. This is to incentivize longer staking periods - withdrawing later than other users will yield more tokens than withdrawing earlier. + * Early withdrawls will incur an additional burn, which will increase with longer remaining lock duration. + * + * Any time a lock is minted, burned or otherwise modified it will notify the listener contracts. + * The exception to the above statement is on chargePremium() call, we do not emit an event because we do + * not want to pay for event emission fees (~2K per event) in an unbounded loop within UnderwritingLockVoting.chargePremiums(). + */ +// solhint-disable-next-line contract-name-camelcase +contract UnderwritingLocker is + IUnderwritingLocker, + ERC721Enhanced, + ReentrancyGuard, + Governable + { + using EnumerableSet for EnumerableSet.AddressSet; + + /*************************************** + GLOBAL PUBLIC VARIABLES + ***************************************/ + + /// @notice Token locked in the underwriting lock. + address public override token; + + /// @notice Registry address + address public override registry; + + /// @notice UnderwriterLockVoting.sol address + /// @dev We expect that UnderwriterLockVoting.sol will be deployed after this contract, so we do not require votingContract to be set in the registry at construction. + address public override votingContract; + + /// @notice The total number of locks that have been created. + /// @dev Difference with totalSupply is that totalNumLocks does not decrement when locks are burned. + uint256 public override totalNumLocks; + + /// @notice Funding rate - amount that will be charged and burned from a regular withdraw. + /// @dev Value of 1e18 => 100%. + uint256 public override fundingRate; + + /// @notice The minimum lock duration (six months) that a new lock must be created with. + uint256 public constant override MIN_LOCK_DURATION = (365 days) / 2; + + /// @notice The maximum time (four years) into the future that a lock can expire. + uint256 public constant override MAX_LOCK_DURATION = 4 * (365 days); + + /// @notice The maximum number of locks one user can create. + uint256 public constant override MAX_NUM_LOCKS = 10; + + /*************************************** + GLOBAL INTERNAL VARIABLES + ***************************************/ + + uint256 internal constant MONTH = 365 days / 12; + + uint256 internal constant SQRT_SIX = 2449489742; + + // lockId => Lock {uint256 amount, uint256 end} + mapping(uint256 => Lock) internal _locks; + + // Contracts that listen for lock changes + EnumerableSet.AddressSet internal _lockListeners; + + /*************************************** + CONSTRUCTOR + ***************************************/ + + /** + * @notice Construct the UnderwritingLocker contract. + * @dev Requires 'uwe' address to be set in the Registry. + * @param governance_ The address of the [governor](/docs/protocol/governance). + * @param registry_ The [`Registry`](./Registry) contract address. + */ + constructor(address governance_, address registry_) + ERC721Enhanced("Underwriting Lock", "UnderwritingLock") + Governable(governance_) + { + _setRegistry(registry_); + } + + /*************************************** + INTERNAL VIEW FUNCTIONS + ***************************************/ + + /** + * @notice For a requested withdraw amount, computes amount burned on withdraw as well as realised withdraw amount. + * @param amount_ The amount to withdraw. + * @param end_ The end timestamp of the lock. + * @return withdrawAmount Token amount that will be withdrawn. + * @return burnAmount Token amount that will be burned on withdraw. + */ + function _getWithdrawAndBurnAmount(uint256 amount_, uint256 end_) internal view returns (uint256 withdrawAmount, uint256 burnAmount) { + // solhint-disable-next-line not-rely-on-time + bool isEarlyWithdraw = block.timestamp < end_; + withdrawAmount = ( (1e18 - fundingRate) * amount_ ) / 1e18; + + if (isEarlyWithdraw) { + uint256 multiplier = _getLockMultiplier(end_); + withdrawAmount = 1e18 * withdrawAmount / (multiplier + 1e18); + } + + burnAmount = amount_ - withdrawAmount; + return (withdrawAmount, burnAmount); + } + + /** + * @notice Gets lock multiplier (applied for voting boost, and for early withdrawals) + * @param end_ End timestamp of lock. + * @return multiplier 1e18 => 1x multiplier, 2e18 => 2x multiplier + */ + function _getLockMultiplier(uint256 end_) internal view returns (uint256 multiplier) { + if (end_ < block.timestamp) {return 0;} + else { + uint256 timeLeftInMonthsScaled = 1e18 * (end_ - block.timestamp) / MONTH; + return 1e18 * _sqrt(timeLeftInMonthsScaled) / SQRT_SIX; + } + } + + // https://github.com/paulrberg/prb-math/blob/86c068e21f9ba229025a77b951bd3c4c4cf103da/contracts/PRBMath.sol#L591-L647 + // Babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method) + // https://ethereum.stackexchange.com/questions/2910/can-i-square-root-in-solidity + // Initially attempted Uniswap implementation - https://github.com/Uniswap/v2-core/blob/master/contracts/libraries/Math.sol + // However Uniswap implementation very gas inefficient - require ~30000 gas to calculate typical result + // vs this implementation which takes 700 gas to calculate same + // Burden of more difficult code well worth 40x gas efficiency, especially given that _sqrt() runs in an + // unbounded loop in GaugeController.updateGaugeWeights(). + function _sqrt(uint256 x) internal pure returns (uint256 result) { + if (x == 0) { + return 0; + } + + // Set the initial guess to the least power of two that is greater than or equal to sqrt(x). + uint256 xAux = uint256(x); + result = 1; + if (xAux >= 0x100000000000000000000000000000000) { + xAux >>= 128; + result <<= 64; + } + if (xAux >= 0x10000000000000000) { + xAux >>= 64; + result <<= 32; + } + if (xAux >= 0x100000000) { + xAux >>= 32; + result <<= 16; + } + if (xAux >= 0x10000) { + xAux >>= 16; + result <<= 8; + } + if (xAux >= 0x100) { + xAux >>= 8; + result <<= 4; + } + if (xAux >= 0x10) { + xAux >>= 4; + result <<= 2; + } + if (xAux >= 0x8) { + result <<= 1; + } + + // The operations can never overflow because the result is max 2^127 when it enters this block. + unchecked { + result = (result + x / result) >> 1; + result = (result + x / result) >> 1; + result = (result + x / result) >> 1; + result = (result + x / result) >> 1; + result = (result + x / result) >> 1; + result = (result + x / result) >> 1; + result = (result + x / result) >> 1; // Seven iterations should be enough + uint256 roundedDownResult = x / result; + return result >= roundedDownResult ? roundedDownResult : result; + } + } + + /** + * @notice Gets all active lockIDs for a user + * @param user_ The address of user to query. + * @return lockIDs Array of active lockIDs. + */ + function _getAllLockIDsOf(address user_) internal view returns (uint256[] memory lockIDs) { + uint256 userNumOfLocks = balanceOf(user_); + lockIDs = new uint256[](userNumOfLocks); + for(uint256 i = 0; i < userNumOfLocks; i++) {lockIDs[i] = tokenOfOwnerByIndex(user_, i);} + return lockIDs; + } + + /*************************************** + EXTERNAL VIEW FUNCTIONS + ***************************************/ + + /** + * @notice Get `amount` and `end` values for a lockID. + * @param lockID_ The ID of the lock to query. + * @return lock Lock {uint256 amount, uint256 end} + */ + function locks(uint256 lockID_) external view override tokenMustExist(lockID_) returns (Lock memory lock) { + return _locks[lockID_]; + } + + /** + * @notice Determines if the lock is currently locked. + * @param lockID_ The ID of the lock to query. + * @return locked True if the lock is locked, false if unlocked. + */ + function isLocked(uint256 lockID_) external view override tokenMustExist(lockID_) returns (bool locked) { + // solhint-disable-next-line not-rely-on-time + return _locks[lockID_].end > block.timestamp; + } + + /** + * @notice Determines the time left until the lock unlocks. + * @param lockID_ The ID of the lock to query. + * @return time The time left in seconds, 0 if unlocked. + */ + function timeLeft(uint256 lockID_) external view override tokenMustExist(lockID_) returns (uint256 time) { + // solhint-disable-next-line not-rely-on-time + return (_locks[lockID_].end > block.timestamp) + // solhint-disable-next-line not-rely-on-time + ? _locks[lockID_].end - block.timestamp // locked + : 0; // unlocked + } + + /** + * @notice Returns the total token amount that the user has staked in underwriting locks. + * @param account_ The account to query. + * @return balance The user's total staked token amount. + */ + function totalStakedBalance(address account_) external view override returns (uint256 balance) { + uint256 numOfLocks = balanceOf(account_); + balance = 0; + for (uint256 i = 0; i < numOfLocks; i++) { + uint256 lockID = tokenOfOwnerByIndex(account_, i); + balance += _locks[lockID].amount; + } + return balance; + } + + /** + * @notice The list of contracts that are listening to lock updates. + * @return listeners_ The list as an array. + */ + function getLockListeners() external view override returns (address[] memory listeners_) { + uint256 len = _lockListeners.length(); + listeners_ = new address[](len); + for(uint256 index = 0; index < len; index++) { + listeners_[index] = _lockListeners.at(index); + } + return listeners_; + } + + /** + * @notice Computes amount of token that will be transferred to the user on full withdraw. + * @param lockID_ The ID of the lock to query. + * @return withdrawAmount Token amount that will be withdrawn. + */ + function getWithdrawAmount(uint256 lockID_) external view override tokenMustExist(lockID_) returns (uint256 withdrawAmount) { + Lock memory lock = _locks[lockID_]; + (withdrawAmount, ) = _getWithdrawAndBurnAmount(lock.amount, lock.end); + return withdrawAmount; + } + + /** + * @notice Computes amount of token that will be transferred to the user on partial withdraw. + * @param lockID_ The ID of the lock to query. + * @param amount_ The requested amount to withdraw. + * @return withdrawAmount Token amount that will be withdrawn. + */ + function getWithdrawInPartAmount(uint256 lockID_, uint256 amount_) external view override tokenMustExist(lockID_) returns (uint256 withdrawAmount) { + (withdrawAmount, ) = _getWithdrawAndBurnAmount(amount_, _locks[lockID_].end); + return withdrawAmount; + } + + /** + * @notice Computes amount of token that will be burned on full withdraw. + * @param lockID_ The ID of the lock to query. + * @return burnAmount Token amount that will be burned on withdraw. + */ + function getBurnOnWithdrawAmount(uint256 lockID_) external view override tokenMustExist(lockID_) returns (uint256 burnAmount) { + Lock memory lock = _locks[lockID_]; + (, burnAmount) = _getWithdrawAndBurnAmount(lock.amount, lock.end); + return burnAmount; + } + + /** + * @notice Computes amount of token that will be burned on partial withdraw. + * @param lockID_ The ID of the lock to query. + * @param amount_ The requested amount to withdraw. + * @return burnAmount Token amount that will be burned on withdraw. + */ + function getBurnOnWithdrawInPartAmount(uint256 lockID_, uint256 amount_) external view override tokenMustExist(lockID_) returns (uint256 burnAmount) { + (, burnAmount) = _getWithdrawAndBurnAmount(amount_, _locks[lockID_].end); + return burnAmount; + } + + /** + * @notice Gets multiplier (applied for voting boost, and for early withdrawals). + * @param lockID_ The ID of the lock to query. + * @return multiplier 1e18 => 1x multiplier, 2e18 => 2x multiplier. + */ + function getLockMultiplier(uint256 lockID_) external view override tokenMustExist(lockID_) returns (uint256 multiplier) { + return _getLockMultiplier(_locks[lockID_].end); + } + + /** + * @notice Gets all active lockIDs for a user + * @param user_ The address of user to query. + * @return lockIDs Array of active lockIDs. + */ + function getAllLockIDsOf(address user_) external view override returns (uint256[] memory lockIDs) { + return _getAllLockIDsOf(user_); + } + + /*************************************** + INTERNAL MUTATOR FUNCTIONS + ***************************************/ + + /** + * @notice Creates a new lock. + * @param recipient_ The user that the lock will be minted to. + * @param amount_ The amount of token in the lock. + * @param end_ The end of the lock. + * @return lockID The ID of the new lock. + */ + function _createLock(address recipient_, uint256 amount_, uint256 end_) internal returns (uint256 lockID) { + if (amount_ == 0) revert CannotCreateEmptyLock(); + // solhint-disable-next-line not-rely-on-time + if(end_ < block.timestamp + MIN_LOCK_DURATION) revert LockTimeTooShort(); + // solhint-disable-next-line not-rely-on-time + if(end_ > block.timestamp + MAX_LOCK_DURATION) revert LockTimeTooLong(); + if( balanceOf(recipient_) >= MAX_NUM_LOCKS ) revert CreatedMaxLocks(); + lockID = ++totalNumLocks; + Lock memory newLock = Lock(amount_, end_); + // accounting + _locks[lockID] = newLock; + _safeMint(recipient_, lockID); + emit LockCreated(lockID); + } + + /** + * @notice Deposit token to increase the value of an existing lock. + * @dev Token is transferred from msg.sender, assumes its already approved. + * @dev Anyone (not just the lock owner) can call increaseAmount() and deposit to an existing lock. + * @param lockID_ The ID of the lock to update. + * @param amount_ The amount of token to deposit. + */ + function _increaseAmount(uint256 lockID_, uint256 amount_) internal { + uint256 newTotalAmount = _locks[lockID_].amount + amount_; + _updateLock(lockID_, newTotalAmount, _locks[lockID_].end); + emit LockIncreased(lockID_, newTotalAmount, amount_); + } + + + /** + * @notice Updates an existing lock. + * @param lockID_ The ID of the lock to update. + * @param amount_ The amount of token now in the lock. + * @param end_ The end of the lock. + */ + function _updateLock(uint256 lockID_, uint256 amount_, uint256 end_) internal { + // checks + Lock memory prevLock = _locks[lockID_]; + Lock memory newLock = Lock(amount_, end_); // end was sanitized before passed in + // accounting + _locks[lockID_] = newLock; + address owner = ownerOf(lockID_); + _notify(lockID_, owner, owner, prevLock, newLock); + emit LockUpdated(lockID_, amount_, end_); + } + + /** + * @notice Extend a lock's duration. + * @dev Can only be called by the lock owner or approved. + * @param lockID_ The ID of the lock to update. + * @param end_ The new time for the lock to unlock. + */ + function _extendLock(uint256 lockID_, uint256 end_) internal onlyOwnerOrApproved(lockID_) { + // solhint-disable-next-line not-rely-on-time + if(end_ > block.timestamp + MAX_LOCK_DURATION) revert LockTimeTooLong(); + if(_locks[lockID_].end >= end_) revert LockTimeNotExtended(); + _updateLock(lockID_, _locks[lockID_].amount, end_); + emit LockExtended(lockID_, end_); + } + + /** + * @notice Withdraws from a lock. + * @param lockID_ The ID of the lock to withdraw from. + * @param amount_ The amount of token to withdraw. + * @return withdrawAmount Amount that will be withdrawn. + * @return burnAmount Amount that will be burned. + */ + function _withdraw(uint256 lockID_, uint256 amount_) + internal + onlyOwnerOrApproved(lockID_) + returns (uint256 withdrawAmount, uint256 burnAmount) + { + // solhint-disable-next-line not-rely-on-time + bool isEarlyWithdraw = block.timestamp < _locks[lockID_].end; + (withdrawAmount, burnAmount) = _getWithdrawAndBurnAmount(amount_, _locks[lockID_].end); + + // full withdraw + if(amount_ == _locks[lockID_].amount) { + _burn(lockID_); + delete _locks[lockID_]; + // partial withdraw + } else { + Lock memory oldLock = _locks[lockID_]; + Lock memory newLock = Lock(oldLock.amount - amount_, oldLock.end); + _locks[lockID_].amount -= amount_; + address owner = ownerOf(lockID_); + _notify(lockID_, owner, owner, oldLock, newLock); + } + + if(isEarlyWithdraw) {emit EarlyWithdrawal(lockID_, amount_, withdrawAmount, burnAmount);} + else {emit Withdrawal(lockID_, amount_, withdrawAmount, burnAmount);} + return (withdrawAmount, burnAmount); + } + + /** + * @notice Hook that is called after any token transfer. This includes minting and burning. + * @param from_ The user that sends the token, or zero if minting. + * @param to_ The zero that receives the token, or zero if burning. + * @param lockID_ The ID of the token being transferred. + */ + function _afterTokenTransfer( + address from_, + address to_, + uint256 lockID_ + ) internal override { + super._afterTokenTransfer(from_, to_, lockID_); + Lock memory lock = _locks[lockID_]; + // notify listeners + if(from_ == address(0x0)) _notify(lockID_, from_, to_, Lock(0, 0), lock); // mint + else if(to_ == address(0x0)) _notify(lockID_, from_, to_, lock, Lock(0, 0)); // burn + else {_notify(lockID_, from_, to_, lock, lock);} // transfer + } + + /** + * @notice Notify the listeners of any updates. + * @dev Called on transfer, mint, burn, and update. + * Either the owner will change or the lock will change, not both. + * @param lockID_ The ID of the lock that was altered. + * @param oldOwner_ The old owner of the lock. + * @param newOwner_ The new owner of the lock. + * @param oldLock_ The old lock data. + * @param newLock_ The new lock data. + */ + function _notify(uint256 lockID_, address oldOwner_, address newOwner_, Lock memory oldLock_, Lock memory newLock_) internal { + // register action with listener + uint256 len = _lockListeners.length(); + for(uint256 i = 0; i < len; i++) { + IUnderwritingLockListener(_lockListeners.at(i)).registerLockEvent(lockID_, oldOwner_, newOwner_, oldLock_, newLock_); + } + } + + /** + * @notice Sets registry and related contract addresses. + * @dev Requires 'uwe' addresses to be set in the Registry. + * @param registry_ The registry address to set. + */ + function _setRegistry(address registry_) internal { + // set registry + if(registry_ == address(0x0)) revert ZeroAddressInput("registry"); + registry = registry_; + IRegistry reg = IRegistry(registry_); + // set token ($UWE) + (, address uweAddr) = reg.tryGet("uwe"); + if(uweAddr == address(0x0)) revert ZeroAddressInput("uwe"); + token = uweAddr; + emit RegistrySet(registry_); + } + + /*************************************** + EXTERNAL MUTATOR FUNCTIONS + ***************************************/ + + /** + * @notice Deposit token to create a new lock. + * @dev Token is transferred from msg.sender, assumes its already approved. + * @param recipient_ The account that will receive the lock. + * @param amount_ The amount of token to deposit. + * @param end_ The timestamp the lock will unlock. + * @return lockID The ID of the newly created lock. + */ + function createLock(address recipient_, uint256 amount_, uint256 end_) external override nonReentrant returns (uint256 lockID) { + // pull token + SafeERC20.safeTransferFrom(IERC20(token), msg.sender, address(this), amount_); + // accounting + return _createLock(recipient_, amount_, end_); + } + + /** + * @notice Deposit token to create a new lock. + * @dev Token is transferred from msg.sender using ERC20Permit. + * @dev recipient = msg.sender. + * @param amount_ The amount of token to deposit. + * @param end_ The timestamp the lock will unlock. + * @param deadline_ Time the transaction must go through before. + * @param v secp256k1 signature + * @param r secp256k1 signature + * @param s secp256k1 signature + * @return lockID The ID of the newly created lock. + */ + function createLockSigned(uint256 amount_, uint256 end_, uint256 deadline_, uint8 v, bytes32 r, bytes32 s) external override nonReentrant returns (uint256 lockID) { + // permit + IERC20Permit(token).permit(msg.sender, address(this), amount_, deadline_, v, r, s); + // pull token + SafeERC20.safeTransferFrom(IERC20(token), msg.sender, address(this), amount_); + // accounting + return _createLock(msg.sender, amount_, end_); + } + + /** + * @notice Deposit token to increase the value of an existing lock. + * @dev Token is transferred from msg.sender, assumes its already approved. + * @dev Anyone (not just the lock owner) can call increaseAmount() and deposit to an existing lock. + * @param lockID_ The ID of the lock to update. + * @param amount_ The amount of token to deposit. + */ + function increaseAmount(uint256 lockID_, uint256 amount_) external override nonReentrant { + // pull token + SafeERC20.safeTransferFrom(IERC20(token), msg.sender, address(this), amount_); + // accounting + _increaseAmount(lockID_, amount_); + } + + /** + * @notice Deposit token to increase the value of multiple existing locks. + * @dev Token is transferred from msg.sender, assumes its already approved. + * @dev If a lockID does not exist, the corresponding amount will be refunded to msg.sender. + * @dev Anyone (not just the lock owner) can call increaseAmountMultiple() and deposit to existing locks. + * @param lockIDs_ Array of lock IDs to update. + * @param amounts_ Array of token amounts to deposit. + */ + function increaseAmountMultiple(uint256[] calldata lockIDs_, uint256[] calldata amounts_) external override nonReentrant { + if (lockIDs_.length != amounts_.length) revert ArrayArgumentsLengthMismatch(); + uint256 totalAmount; + for (uint256 i = 0; i < lockIDs_.length; i++) { + totalAmount += amounts_[i]; + _increaseAmount(lockIDs_[i], amounts_[i]); + } + SafeERC20.safeTransferFrom(IERC20(token), msg.sender, address(this), totalAmount); + } + + /** + * @notice Deposit token to increase the value of an existing lock. + * @dev Token is transferred from msg.sender using ERC20Permit. + * @dev Anyone (not just the lock owner) can call increaseAmount() and deposit to an existing lock. + * @param lockID_ The ID of the lock to update. + * @param amount_ The amount of token to deposit. + * @param deadline_ Time the transaction must go through before. + * @param v secp256k1 signature + * @param r secp256k1 signature + * @param s secp256k1 signature + */ + function increaseAmountSigned(uint256 lockID_, uint256 amount_, uint256 deadline_, uint8 v, bytes32 r, bytes32 s) external override nonReentrant { + // permit + IERC20Permit(token).permit(msg.sender, address(this), amount_, deadline_, v, r, s); + // pull token + SafeERC20.safeTransferFrom(IERC20(token), msg.sender, address(this), amount_); + // accounting + _increaseAmount(lockID_, amount_); + } + + /** + * @notice Extend a lock's duration. + * @dev Can only be called by the lock owner or approved. + * @param lockID_ The ID of the lock to update. + * @param end_ The new time for the lock to unlock. + */ + function extendLock(uint256 lockID_, uint256 end_) external override nonReentrant { + _extendLock(lockID_, end_); + } + + /** + * @notice Extend multiple locks' duration. + * @dev Can only be called by the lock owner or approved. + * @dev If non-existing lockIDs are entered, these will be skipped. + * @param lockIDs_ Array of lock IDs to update. + * @param ends_ Array of new unlock times. + */ + function extendLockMultiple(uint256[] calldata lockIDs_, uint256[] calldata ends_) external override nonReentrant { + if (lockIDs_.length != ends_.length) revert ArrayArgumentsLengthMismatch(); + for (uint256 i = 0; i < lockIDs_.length; i++) { + _extendLock(lockIDs_[i], ends_[i]); + } + } + + /** + * @notice Withdraw from a lock in full. + * @dev Can only be called by the lock owner or approved. + * @dev If called before `end` timestamp, will incur additional burn amount. + * @param lockID_ The ID of the lock to withdraw from. + * @param recipient_ The user to receive the lock's token. + */ + function withdraw(uint256 lockID_, address recipient_) external override nonReentrant { + uint256 amount = _locks[lockID_].amount; + (uint256 withdrawAmount, uint256 burnAmount) = _withdraw(lockID_, amount); + // transfer token + IUnderwritingEquity(token).burn(burnAmount); + SafeERC20.safeTransfer(IERC20(token), recipient_, withdrawAmount); + } + + /** + * @notice Withdraw from a lock in part. + * @dev Can only be called by the lock owner or approved. + * @dev If called before `end` timestamp, will incur additional burn amount. + * @param lockID_ The ID of the lock to withdraw from. + * @param amount_ The amount of token to withdraw. + * @param recipient_ The user to receive the lock's token. + */ + function withdrawInPart(uint256 lockID_, uint256 amount_, address recipient_) external override nonReentrant { + if (amount_ > _locks[lockID_].amount) revert ExcessWithdraw(); + (uint256 withdrawAmount, uint256 burnAmount) = _withdraw(lockID_, amount_); + // transfer token + IUnderwritingEquity(token).burn(burnAmount); + SafeERC20.safeTransfer(IERC20(token), recipient_, withdrawAmount); + } + + /** + * @notice Withdraw from multiple locks in full. + * @dev Can only be called by the lock owner or approved. + * @dev If called before `end` timestamp, will incur additional burn amount. + * @param lockIDs_ The ID of the locks to withdraw from. + * @param recipient_ The user to receive the lock's token. + */ + function withdrawMultiple(uint256[] calldata lockIDs_, address recipient_) external override nonReentrant { + uint256 len = lockIDs_.length; + uint256 totalWithdrawAmount = 0; + uint256 totalBurnAmount = 0; + for(uint256 i = 0; i < len; i++) { + uint256 lockID = lockIDs_[i]; + if (!_isApprovedOrOwner(msg.sender, lockID)) revert NotOwnerNorApproved(); + uint256 singleLockAmount = _locks[lockID].amount; + (uint256 withdrawAmount, uint256 burnAmount) = _withdraw(lockID, singleLockAmount); + totalBurnAmount += burnAmount; + totalWithdrawAmount += withdrawAmount; + } + // batched token transfer + if (totalBurnAmount > 0) {IUnderwritingEquity(token).burn(totalBurnAmount);} + SafeERC20.safeTransfer(IERC20(token), recipient_, totalWithdrawAmount); + } + + /** + * @notice Withdraw from multiple locks in part. + * @dev Can only be called by the lock owner or approved. + * @dev If called before `end` timestamp, will incur additional burn amount. + * @param lockIDs_ The ID of the locks to withdraw from. + * @param amounts_ Array of token amounts to withdraw + * @param recipient_ The user to receive the lock's token. + */ + function withdrawInPartMultiple(uint256[] calldata lockIDs_, uint256[] calldata amounts_ ,address recipient_) external override nonReentrant { + if (lockIDs_.length != amounts_.length) revert ArrayArgumentsLengthMismatch(); + uint256 len = lockIDs_.length; + uint256 totalWithdrawAmount = 0; + uint256 totalBurnAmount = 0; + for(uint256 i = 0; i < len; i++) { + uint256 lockID = lockIDs_[i]; + if (!_isApprovedOrOwner(msg.sender, lockID)) revert NotOwnerNorApproved(); + uint256 singleLockAmount = amounts_[i]; + if (singleLockAmount > _locks[lockID].amount) revert ExcessWithdraw(); + (uint256 withdrawAmount, uint256 burnAmount) = _withdraw(lockID, singleLockAmount); + totalBurnAmount += burnAmount; + totalWithdrawAmount += withdrawAmount; + } + // batched token transfer + if (totalBurnAmount > 0) {IUnderwritingEquity(token).burn(totalBurnAmount);} + SafeERC20.safeTransfer(IERC20(token), recipient_, totalWithdrawAmount); + } + + /*************************************** + VOTING CONTRACT FUNCTIONS + ***************************************/ + + /** + * @notice Perform accounting for voting premiums to be charged by UnderwritingLockVoting.chargePremiums(). + * @dev Can only be called by votingContract set in the registry. + * @dev Not meant to be called directly, but via UnderwritingLockVoting.chargePremiums(). + * @dev Costs 5K gas per call to add notification functionality. This will quickly add-up in an unbounded loop so we omit it. + * @param lockID_ The ID of the lock to charge. + * @param premium_ The amount of token charged as premium. + */ + function chargePremium(uint256 lockID_, uint256 premium_) external override nonReentrant { + if (msg.sender != votingContract) revert NotVotingContract(); + if (!_exists(lockID_)) {return;} + _locks[lockID_].amount -= premium_; + } + + /*************************************** + GOVERNANCE FUNCTIONS + ***************************************/ + + /** + * @notice Adds a listener. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param listener_ The listener to add. + */ + function addLockListener(address listener_) external override onlyGovernance { + _lockListeners.add(listener_); + emit LockListenerAdded(listener_); + } + + /** + * @notice Removes a listener. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param listener_ The listener to remove. + */ + function removeLockListener(address listener_) external override onlyGovernance { + _lockListeners.remove(listener_); + emit LockListenerRemoved(listener_); + } + + /** + * @notice Sets the base URI for computing `tokenURI`. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param baseURI_ The new base URI. + */ + function setBaseURI(string memory baseURI_) external override onlyGovernance { + _setBaseURI(baseURI_); + } + + /** + * @notice Sets the [`Registry`](./Registry) contract address. + * @dev Requires 'uwe' address to be set in the Registry. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param registry_ The address of `Registry` contract. + */ + function setRegistry(address registry_) external override onlyGovernance { + _setRegistry(registry_); + } + + /** + * @notice Sets votingContract and enable safeTransferFrom call by `underwritingLockVoting` address stored in Registry. + * @dev Requirement for UnderwritingLockVoting.chargePremiums(). + * Can only be called by the current [**governor**](/docs/protocol/governance). + */ + function setVotingContract() external override onlyGovernance { + // Remove approval for old contract. + if (votingContract != address(0x0)) SafeERC20.safeApprove(IERC20(token), votingContract, 0); + // Grant approval for new contract + (, address votingContractAddr) = IRegistry(registry).tryGet("underwritingLockVoting"); + if(votingContractAddr == address(0x0)) revert ZeroAddressInput("underwritingLockVoting"); + votingContract = votingContractAddr; + SafeERC20.safeApprove(IERC20(token), votingContractAddr, type(uint256).max); + emit VotingContractSet(votingContractAddr); + } + + /** + * @notice Sets fundingRate. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param fundingRate_ Desired funding rate, 1e18 => 100% + */ + function setFundingRate(uint256 fundingRate_) external override onlyGovernance { + if (fundingRate_ > 1e18) revert FundingRateAboveOne(); + fundingRate = fundingRate_; + emit FundingRateSet(fundingRate_); + } +} diff --git a/contracts/native/UnderwritingPool.sol b/contracts/native/UnderwritingPool.sol new file mode 100644 index 00000000..b8b780be --- /dev/null +++ b/contracts/native/UnderwritingPool.sol @@ -0,0 +1,474 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.6; + +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol"; +import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; +import "../utils/Governable.sol"; +import "../interfaces/native/IPriceOracle.sol"; +import "../interfaces/native/IUnderwritingPool.sol"; + + +/** + * @title IUnderwritingPool + * @author solace.fi + * @notice The underwriting pool of Solace Native. + * + * In Solace Native risk is backed by a basket of assets known as the underwriting pool (UWP). Shares of the pool are known as `UWP` and are represented as an ERC20 token. [Governance](/docs/protocol/governance) can add or remove tokens from the basket and set their parameters (min and max in USD, price oracle) via [`addTokensToPool()`](#addtokenstopool) and [`removeTokensFromPool()`](#removetokensfrompool). + * + * Users can view tokens in the pool via [`tokensLength()`](#tokenslength), [`tokenData(address token)`](#tokendata), and [`tokenList(uint256 index)`](#tokenlist). + * + * Anyone can mint `UWP` by calling [`issue()`](#issue) and depositing any of the tokens in the pool. Note that + * - You will not be credited `UWP` for raw transferring tokens to this contract. Use [`issue()`](#issue) instead. + * - You do not need to deposit all of the tokens in the pool. Most users will deposit a single token. + * - To manage risk, each token has a corresponding `min` and `max` measured in USD. Deposits must keep the pool within these bounds. + * - Solace may charge a protocol fee as a fraction of the mint amount [`issueFee()`](#issuefee). + * + * Anyone can redeem their `UWP` for tokens in the pool by calling [`redeem()`](#redeem). You will receive a fair portion of all assets in the pool. + * + * [Governance](/docs/protocol/governance) can pause and unpause [`issue()`](#issue). The other functions cannot be paused. + */ +contract UnderwritingPool is IUnderwritingPool, ERC20Permit, ReentrancyGuard, Governable { + // dev: 'Len' and 'Index' may be prefixed with 'in' for input or 'st' for storage + + /*************************************** + STATE VARIABLES + ***************************************/ + + // amount of tokens in pool + uint256 internal _tokensLength; + + // map of index to token and oracle + mapping(uint256 => TokenData) internal _tokens; + // map of token to index+1. if mapping returns zero, token is not in pool + mapping(address => uint256) internal _tokenIndices; + + // issue fee in 18 decimals. default zero + uint256 internal _issueFee; + // receiver of issue fee + address internal _issueFeeTo; + // true if issue is paused. default false + bool internal _isPaused; + + /** + * @notice Constructs the `UnderwritingPool` contract. + * @param governance_ The address of the governor. + */ + // solhint-disable-next-line no-empty-blocks + constructor (address governance_) ERC20("Solace Native Underwriting Pool", "UWP") ERC20Permit("Solace Native Underwriting Pool") Governable(governance_) { } + + /*************************************** + VIEW FUNCTIONS + ***************************************/ + + /** + * @notice The number of tokens in the pool. + * @return length The number of tokens in the pool. + */ + function tokensLength() external view override returns (uint256 length) { + return _tokensLength; + } + + /** + * @notice Information about a token in the pool. + * @dev Returns a zero struct if token is not in the pool. + * @param token The address of the token to query. + * @return data Information about the token. + */ + function tokenData(address token) external view override returns (TokenData memory data) { + uint256 stIndex = _tokenIndices[token]; + if(stIndex == 0) return TokenData({ + token: address(0x0), + oracle: address(0x0), + min: 0, + max: 0 + }); + return _tokens[stIndex-1]; + } + + /** + * @notice The list of tokens in the pool. + * @dev Iterable `[0, tokensLength)`. + * @param index The index of the list to query. + * @return data Information about the token. + */ + function tokenList(uint256 index) external view override returns (TokenData memory data) { + require(index < _tokensLength, "index out of bounds"); + return _tokens[index]; + } + + /** + * @notice The fraction of `UWP` that are charged as a protocol fee on mint. + * @return fee The fee as a fraction with 18 decimals. + */ + function issueFee() external view override returns (uint256 fee) { + return _issueFee; + } + + /** + * @notice The receiver of issue fees. + * @return receiver The receiver of the fee. + */ + function issueFeeTo() external view override returns (address receiver) { + return _issueFeeTo; + } + + /** + * @notice Returns true if issue is paused. + * @return paused Returns true if issue is paused. + */ + function isPaused() external view override returns (bool paused) { + return _isPaused; + } + + /** + * @notice Calculates the value of all assets in the pool in `USD`. + * @return valueInUSD The value of the pool in `USD` with 18 decimals. + */ + function valueOfPool() external view override returns (uint256 valueInUSD) { + return _valueOfPool(); + } + + /** + * @notice Calculates the value of an amount of `UWP` shares in `USD`. + * @param shares The amount of shares to query. + * @return valueInUSD The value of the shares in `USD` with 18 decimals. + */ + function valueOfShares(uint256 shares) external view override returns (uint256 valueInUSD) { + if(shares == 0) return 0; + uint256 ts = totalSupply(); + require(shares <= ts, "shares exceeds supply"); + return ((_valueOfPool() * shares) / ts); + } + + /** + * @notice Calculates the value of a holders `UWP` shares in `USD`. + * @param holder The holder to query. + * @return valueInUSD The value of the users shares in `USD` with 18 decimals. + */ + function valueOfHolder(address holder) external view override returns (uint256 valueInUSD) { + uint256 bal = balanceOf(holder); + if(bal == 0) return 0; + uint256 ts = totalSupply(); + return ((_valueOfPool() * bal) / ts); + } + + /** + * @notice Determines the amount of tokens that would be minted for a given deposit. + * @param depositTokens The list of tokens to deposit. + * @param depositAmounts The amount of each token to deposit. + * @return amount The amount of `UWP` minted. + */ + function calculateIssue(address[] memory depositTokens, uint256[] memory depositAmounts) external view override returns (uint256 amount) { + // checks + uint256 inLen = depositTokens.length; + require(inLen == depositAmounts.length, "length mismatch"); + // step 1: calculate the value of the pool + uint256 poolValue = 0; + uint256 stLen = _tokensLength; + uint256[] memory tokenValues = new uint256[](stLen); + // for each token in pool + for(uint256 stIndex = 0; stIndex < stLen; stIndex++) { + // get token and oracle + TokenData storage data = _tokens[stIndex]; + address token = data.token; + address oracle = data.oracle; + // get value + uint256 balance = IERC20(token).balanceOf(address(this)); + uint256 tokenValue = IPriceOracle(oracle).valueOfTokens(token, balance); + // accumulate + tokenValues[stIndex] = tokenValue; + poolValue += tokenValue; + } + // step 2: pull tokens from msg.sender, calculate value + uint256 depositValue = 0; + // for each token to deposit + for(uint256 inIndex = 0; inIndex < inLen; inIndex++) { + address token = depositTokens[inIndex]; + uint256 stIndex = _tokenIndices[token]; + require(stIndex != 0, "token not in pool"); + stIndex--; + TokenData storage data = _tokens[stIndex]; + // pull tokens + uint256 depositAmount = depositAmounts[inIndex]; + // calculate value + address oracle = data.oracle; + uint256 tokenValue = IPriceOracle(oracle).valueOfTokens(token, depositAmount); + depositValue += tokenValue; + tokenValue += tokenValues[stIndex]; + tokenValues[stIndex] = tokenValue; + // check min, max + require(tokenValue >= data.min, "deposit too small"); + require(tokenValue <= data.max, "deposit too large"); + } + // step 3: issue + uint256 ts = totalSupply(); + uint256 mintAmount = (ts == 0 || poolValue == 0) + ? depositValue + : (ts * depositValue / poolValue); + uint256 fee = mintAmount * _issueFee / 1 ether; + if(fee > 0) { + mintAmount -= fee; + } + return mintAmount; + } + + /** + * @notice Determines the amount of underlying tokens that would be received for an amount of `UWP`. + * @param amount The amount of `UWP` to burn. + * @return amounts The amount of each token received. + */ + function calculateRedeem(uint256 amount) external view override returns (uint256[] memory amounts) { + uint256 ts = totalSupply(); + require(amount <= ts, "redeem amount exceeds supply"); + uint256 stLen = _tokensLength; + amounts = new uint256[](stLen); + // for each token in pool + for(uint256 stIndex = 0; stIndex < stLen; stIndex++) { + // get token + TokenData storage data = _tokens[stIndex]; + IERC20 token = IERC20(data.token); + // get balance + uint256 balance = token.balanceOf(address(this)); + // transfer out fair portion + uint256 amt = balance * amount / ts; + amounts[stIndex] = amt; + } + return amounts; + } + + /*************************************** + MODIFIER FUNCTIONS + ***************************************/ + + /** + * @notice Deposits one or more tokens into the pool. + * @param depositTokens The list of tokens to deposit. + * @param depositAmounts The amount of each token to deposit. + * @param receiver The address to send newly minted `UWP` to. + * @return amount The amount of `UWP` minted. + */ + function issue(address[] memory depositTokens, uint256[] memory depositAmounts, address receiver) external override nonReentrant returns (uint256 amount) { + // checks + uint256 inLen = depositTokens.length; + require(inLen == depositAmounts.length, "length mismatch"); + require(!_isPaused, "issue is paused"); + // step 1: calculate the value of the pool + uint256 poolValue = 0; + uint256 stLen = _tokensLength; + uint256[] memory tokenValues = new uint256[](stLen); + // for each token in pool + for(uint256 stIndex = 0; stIndex < stLen; stIndex++) { + // get token and oracle + TokenData storage data = _tokens[stIndex]; + address token = data.token; + address oracle = data.oracle; + // get value + uint256 balance = IERC20(token).balanceOf(address(this)); + uint256 tokenValue = IPriceOracle(oracle).valueOfTokens(token, balance); + // accumulate + tokenValues[stIndex] = tokenValue; + poolValue += tokenValue; + } + // step 2: pull tokens from msg.sender, calculate value + uint256 depositValue = 0; + // for each token to deposit + for(uint256 inIndex = 0; inIndex < inLen; inIndex++) { + address token = depositTokens[inIndex]; + uint256 stIndex = _tokenIndices[token]; + require(stIndex != 0, "token not in pool"); + stIndex--; + TokenData storage data = _tokens[stIndex]; + // pull tokens + uint256 depositAmount = depositAmounts[inIndex]; + SafeERC20.safeTransferFrom(IERC20(token), msg.sender, address(this), depositAmount); + // calculate value + address oracle = data.oracle; + uint256 tokenValue = IPriceOracle(oracle).valueOfTokens(token, depositAmount); + depositValue += tokenValue; + tokenValue += tokenValues[stIndex]; + tokenValues[stIndex] = tokenValue; + // check min, max + require(tokenValue >= data.min, "deposit too small"); + require(tokenValue <= data.max, "deposit too large"); + } + // step 3: issue + uint256 ts = totalSupply(); + uint256 mintAmount = (ts == 0 || poolValue == 0) + ? depositValue + : (ts * depositValue / poolValue); + uint256 fee = mintAmount * _issueFee / 1 ether; + if(fee > 0) { + _mint(_issueFeeTo, fee); + mintAmount -= fee; + } + _mint(receiver, mintAmount); + emit IssueMade(msg.sender, mintAmount); + return mintAmount; + } + + /** + * @notice Redeems some `UWP` for some of the tokens in the pool. + * @param amount The amount of `UWP` to burn. + * @param receiver The address to receive underlying tokens. + * @return amounts The amount of each token received. + */ + function redeem(uint256 amount, address receiver) external override nonReentrant returns (uint256[] memory amounts) { + uint256 ts = totalSupply(); + _burn(msg.sender, amount); + uint256 stLen = _tokensLength; + amounts = new uint256[](stLen); + // for each token in pool + for(uint256 stIndex = 0; stIndex < stLen; stIndex++) { + // get token + TokenData storage data = _tokens[stIndex]; + IERC20 token = IERC20(data.token); + // get balance + uint256 balance = token.balanceOf(address(this)); + // transfer out fair portion + uint256 amt = balance * amount / ts; + amounts[stIndex] = amt; + SafeERC20.safeTransfer(token, receiver, amt); + } + emit RedeemMade(msg.sender, amount); + return amounts; + } + + /*************************************** + HELPER FUNCTIONS + ***************************************/ + + /** + * @notice Calculates the value of all assets in the pool in `USD`. + * @return valueInUSD The value of the pool in `USD` with 18 decimals. + */ + function _valueOfPool() internal view returns (uint256 valueInUSD) { + valueInUSD = 0; + uint256 stLen = _tokensLength; + // for each token in pool + for(uint256 stIndex = 0; stIndex < stLen; stIndex++) { + // get token and oracle + TokenData storage data = _tokens[stIndex]; + address token = data.token; + address oracle = data.oracle; + // get value + uint256 balance = IERC20(token).balanceOf(address(this)); + uint256 tokenValue = IPriceOracle(oracle).valueOfTokens(token, balance); + // accumulate + valueInUSD += tokenValue; + } + return valueInUSD; + } + + /*************************************** + GOVERNANCE FUNCTIONS + ***************************************/ + + /** + * @notice Adds tokens to the pool. If the token is already in the pool, sets its oracle, min, and max. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param tokens The list of tokens to add. + */ + function addTokensToPool(TokenData[] memory tokens) external override onlyGovernance { + uint256 inLen = tokens.length; + uint256 stLen = _tokensLength; + uint256 stLen0 = stLen; + // for each token to add + for(uint256 inIndex = 0; inIndex < inLen; inIndex++) { + address token = tokens[inIndex].token; + uint256 stIndex = _tokenIndices[token]; + // token not in pool. add new + if(stIndex == 0) { + stIndex = stLen; + _tokens[stIndex] = tokens[inIndex]; + _tokenIndices[token] = stIndex + 1; + stLen++; + } + // token already in pool. set oracle, min, max + else { + _tokens[stIndex-1] = tokens[inIndex]; + } + emit TokenAdded(token); + } + if(stLen != stLen0) _tokensLength = stLen; + } + + /** + * @notice Removes tokens from the pool. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param tokens The list of tokens to remove. + */ + function removeTokensFromPool(address[] memory tokens) external override onlyGovernance { + uint256 inLen = tokens.length; + uint256 stLen = _tokensLength; + uint256 stLen0 = stLen; + // for each token to remove + for(uint256 inIndex = 0; inIndex < inLen; inIndex++) { + address token = tokens[inIndex]; + uint256 stIndex = _tokenIndices[token]; + // token was not in pool anyways. skip + if(stIndex == 0) continue; + // token was at end of list. simple pop + if(stIndex == stLen) { + stLen--; + delete _tokens[stLen]; + delete _tokenIndices[token]; + } + // token was not at end of list. remove and shuffle + else { + stLen--; + _tokenIndices[_tokens[stLen].token] = stIndex; + _tokens[stIndex-1] = _tokens[stLen]; + delete _tokens[stLen]; + delete _tokenIndices[token]; + } + emit TokenRemoved(token); + } + if(stLen != stLen0) _tokensLength = stLen; + } + + /** + * @notice Rescues misplaced tokens. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param tokens The list of tokens to rescue. + * @param receiver The receiver of the tokens. + */ + function rescueTokens(address[] memory tokens, address receiver) external override nonReentrant onlyGovernance { + // for each requested token + uint256 inLen = tokens.length; + for(uint256 inIndex = 0; inIndex < inLen; inIndex++) { + address token = tokens[inIndex]; + // cannot rescue valued underlying tokens + require(_tokenIndices[token] == 0, "cannot rescue that token"); + // send balance to receiver + IERC20 tkn = IERC20(token); + uint256 balance = tkn.balanceOf(address(this)); + SafeERC20.safeTransfer(tkn, receiver, balance); + } + } + + /** + * @notice Sets the issue fee and receiver. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param fee The fee as a fraction with 18 decimals. + * @param receiver The receiver of the fee. + */ + function setIssueFee(uint256 fee, address receiver) external override onlyGovernance { + require(fee <= 1 ether, "invalid issue fee"); + require(fee == 0 || receiver != address(0x0), "invalid issue fee to"); + _issueFee = fee; + _issueFeeTo = receiver; + emit IssueFeeSet(fee, receiver); + } + + /** + * @notice Pauses or unpauses issue. + * Can only be called by the current [**governor**](/docs/protocol/governance). + * @param pause True to pause issue, false to unpause. + */ + function setPause(bool pause) external override onlyGovernance { + _isPaused = pause; + emit PauseSet(pause); + } +} diff --git a/contracts/utils/EnumerableMapS.sol b/contracts/utils/EnumerableMapS.sol new file mode 100644 index 00000000..dfce77f4 --- /dev/null +++ b/contracts/utils/EnumerableMapS.sol @@ -0,0 +1,533 @@ +// ^4.7.1 of OpenZeppelin EnumerableMap.sol +// Created as local copy in Solace repo to enable use of single updated EnumerableMap.sol file while maintaining @openzeppelin dependencies at ~4.3.2. +// Initializable pattern used in Solace repo broken with ^4.7.1 + +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableMap.sol) + +pragma solidity 0.8.6; + +import "./EnumerableSetS.sol"; + +/** + * @dev Library for managing an enumerable variant of Solidity's + * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`] + * type. + * + * Maps have the following properties: + * + * - Entries are added, removed, and checked for existence in constant time + * (O(1)). + * - Entries are enumerated in O(n). No guarantees are made on the ordering. + * + * ``` + * contract Example { + * // Add the library methods + * using EnumerableMap for EnumerableMap.UintToAddressMap; + * + * // Declare a set state variable + * EnumerableMap.UintToAddressMap private myMap; + * } + * ``` + * + * The following map types are supported: + * + * - `uint256 -> address` (`UintToAddressMap`) since v3.0.0 + * - `address -> uint256` (`AddressToUintMap`) since v4.6.0 + * - `bytes32 -> bytes32` (`Bytes32ToBytes32`) since v4.6.0 + * - `uint256 -> uint256` (`UintToUintMap`) since v4.7.0 + * - `bytes32 -> uint256` (`Bytes32ToUintMap`) since v4.7.0 + * + * [WARNING] + * ==== + * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable. + * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. + * + * In order to clean an EnumerableMap, you can either remove all elements one by one or create a fresh instance using an array of EnumerableMap. + * ==== + */ +library EnumerableMapS { + using EnumerableSetS for EnumerableSetS.Bytes32Set; + + // To implement this library for multiple types with as little code + // repetition as possible, we write it in terms of a generic Map type with + // bytes32 keys and values. + // The Map implementation uses private functions, and user-facing + // implementations (such as Uint256ToAddressMap) are just wrappers around + // the underlying Map. + // This means that we can only create new EnumerableMaps for types that fit + // in bytes32. + + struct Bytes32ToBytes32Map { + // Storage of keys + EnumerableSetS.Bytes32Set _keys; + mapping(bytes32 => bytes32) _values; + } + + /** + * @dev Adds a key-value pair to a map, or updates the value for an existing + * key. O(1). + * + * Returns true if the key was added to the map, that is if it was not + * already present. + */ + function set( + Bytes32ToBytes32Map storage map, + bytes32 key, + bytes32 value + ) internal returns (bool) { + map._values[key] = value; + return map._keys.add(key); + } + + /** + * @dev Removes a key-value pair from a map. O(1). + * + * Returns true if the key was removed from the map, that is if it was present. + */ + function remove(Bytes32ToBytes32Map storage map, bytes32 key) internal returns (bool) { + delete map._values[key]; + return map._keys.remove(key); + } + + /** + * @dev Returns true if the key is in the map. O(1). + */ + function contains(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool) { + return map._keys.contains(key); + } + + /** + * @dev Returns the number of key-value pairs in the map. O(1). + */ + function length(Bytes32ToBytes32Map storage map) internal view returns (uint256) { + return map._keys.length(); + } + + /** + * @dev Returns the key-value pair stored at position `index` in the map. O(1). + * + * Note that there are no guarantees on the ordering of entries inside the + * array, and it may change when more entries are added or removed. + * + * Requirements: + * + * - `index` must be strictly less than {length}. + */ + function at(Bytes32ToBytes32Map storage map, uint256 index) internal view returns (bytes32, bytes32) { + bytes32 key = map._keys.at(index); + return (key, map._values[key]); + } + + /** + * @dev Tries to returns the value associated with `key`. O(1). + * Does not revert if `key` is not in the map. + */ + function tryGet(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool, bytes32) { + bytes32 value = map._values[key]; + if (value == bytes32(0)) { + return (contains(map, key), bytes32(0)); + } else { + return (true, value); + } + } + + /** + * @dev Returns the value associated with `key`. O(1). + * + * Requirements: + * + * - `key` must be in the map. + */ + function get(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bytes32) { + bytes32 value = map._values[key]; + require(value != 0 || contains(map, key), "EnumerableMap: nonexistent key"); + return value; + } + + /** + * @dev Same as {_get}, with a custom error message when `key` is not in the map. + * + * CAUTION: This function is deprecated because it requires allocating memory for the error + * message unnecessarily. For custom revert reasons use {_tryGet}. + */ + function get( + Bytes32ToBytes32Map storage map, + bytes32 key, + string memory errorMessage + ) internal view returns (bytes32) { + bytes32 value = map._values[key]; + require(value != 0 || contains(map, key), errorMessage); + return value; + } + + // UintToUintMap + + struct UintToUintMap { + Bytes32ToBytes32Map _inner; + } + + /** + * @dev Adds a key-value pair to a map, or updates the value for an existing + * key. O(1). + * + * Returns true if the key was added to the map, that is if it was not + * already present. + */ + function set( + UintToUintMap storage map, + uint256 key, + uint256 value + ) internal returns (bool) { + return set(map._inner, bytes32(key), bytes32(value)); + } + + /** + * @dev Removes a value from a set. O(1). + * + * Returns true if the key was removed from the map, that is if it was present. + */ + function remove(UintToUintMap storage map, uint256 key) internal returns (bool) { + return remove(map._inner, bytes32(key)); + } + + /** + * @dev Returns true if the key is in the map. O(1). + */ + function contains(UintToUintMap storage map, uint256 key) internal view returns (bool) { + return contains(map._inner, bytes32(key)); + } + + /** + * @dev Returns the number of elements in the map. O(1). + */ + function length(UintToUintMap storage map) internal view returns (uint256) { + return length(map._inner); + } + + /** + * @dev Returns the element stored at position `index` in the set. O(1). + * Note that there are no guarantees on the ordering of values inside the + * array, and it may change when more values are added or removed. + * + * Requirements: + * + * - `index` must be strictly less than {length}. + */ + function at(UintToUintMap storage map, uint256 index) internal view returns (uint256, uint256) { + (bytes32 key, bytes32 value) = at(map._inner, index); + return (uint256(key), uint256(value)); + } + + /** + * @dev Tries to returns the value associated with `key`. O(1). + * Does not revert if `key` is not in the map. + */ + function tryGet(UintToUintMap storage map, uint256 key) internal view returns (bool, uint256) { + (bool success, bytes32 value) = tryGet(map._inner, bytes32(key)); + return (success, uint256(value)); + } + + /** + * @dev Returns the value associated with `key`. O(1). + * + * Requirements: + * + * - `key` must be in the map. + */ + function get(UintToUintMap storage map, uint256 key) internal view returns (uint256) { + return uint256(get(map._inner, bytes32(key))); + } + + /** + * @dev Same as {get}, with a custom error message when `key` is not in the map. + * + * CAUTION: This function is deprecated because it requires allocating memory for the error + * message unnecessarily. For custom revert reasons use {tryGet}. + */ + function get( + UintToUintMap storage map, + uint256 key, + string memory errorMessage + ) internal view returns (uint256) { + return uint256(get(map._inner, bytes32(key), errorMessage)); + } + + // UintToAddressMap + + struct UintToAddressMap { + Bytes32ToBytes32Map _inner; + } + + /** + * @dev Adds a key-value pair to a map, or updates the value for an existing + * key. O(1). + * + * Returns true if the key was added to the map, that is if it was not + * already present. + */ + function set( + UintToAddressMap storage map, + uint256 key, + address value + ) internal returns (bool) { + return set(map._inner, bytes32(key), bytes32(uint256(uint160(value)))); + } + + /** + * @dev Removes a value from a set. O(1). + * + * Returns true if the key was removed from the map, that is if it was present. + */ + function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) { + return remove(map._inner, bytes32(key)); + } + + /** + * @dev Returns true if the key is in the map. O(1). + */ + function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) { + return contains(map._inner, bytes32(key)); + } + + /** + * @dev Returns the number of elements in the map. O(1). + */ + function length(UintToAddressMap storage map) internal view returns (uint256) { + return length(map._inner); + } + + /** + * @dev Returns the element stored at position `index` in the set. O(1). + * Note that there are no guarantees on the ordering of values inside the + * array, and it may change when more values are added or removed. + * + * Requirements: + * + * - `index` must be strictly less than {length}. + */ + function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) { + (bytes32 key, bytes32 value) = at(map._inner, index); + return (uint256(key), address(uint160(uint256(value)))); + } + + /** + * @dev Tries to returns the value associated with `key`. O(1). + * Does not revert if `key` is not in the map. + * + * _Available since v3.4._ + */ + function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) { + (bool success, bytes32 value) = tryGet(map._inner, bytes32(key)); + return (success, address(uint160(uint256(value)))); + } + + /** + * @dev Returns the value associated with `key`. O(1). + * + * Requirements: + * + * - `key` must be in the map. + */ + function get(UintToAddressMap storage map, uint256 key) internal view returns (address) { + return address(uint160(uint256(get(map._inner, bytes32(key))))); + } + + /** + * @dev Same as {get}, with a custom error message when `key` is not in the map. + * + * CAUTION: This function is deprecated because it requires allocating memory for the error + * message unnecessarily. For custom revert reasons use {tryGet}. + */ + function get( + UintToAddressMap storage map, + uint256 key, + string memory errorMessage + ) internal view returns (address) { + return address(uint160(uint256(get(map._inner, bytes32(key), errorMessage)))); + } + + // AddressToUintMap + + struct AddressToUintMap { + Bytes32ToBytes32Map _inner; + } + + /** + * @dev Adds a key-value pair to a map, or updates the value for an existing + * key. O(1). + * + * Returns true if the key was added to the map, that is if it was not + * already present. + */ + function set( + AddressToUintMap storage map, + address key, + uint256 value + ) internal returns (bool) { + return set(map._inner, bytes32(uint256(uint160(key))), bytes32(value)); + } + + /** + * @dev Removes a value from a set. O(1). + * + * Returns true if the key was removed from the map, that is if it was present. + */ + function remove(AddressToUintMap storage map, address key) internal returns (bool) { + return remove(map._inner, bytes32(uint256(uint160(key)))); + } + + /** + * @dev Returns true if the key is in the map. O(1). + */ + function contains(AddressToUintMap storage map, address key) internal view returns (bool) { + return contains(map._inner, bytes32(uint256(uint160(key)))); + } + + /** + * @dev Returns the number of elements in the map. O(1). + */ + function length(AddressToUintMap storage map) internal view returns (uint256) { + return length(map._inner); + } + + /** + * @dev Returns the element stored at position `index` in the set. O(1). + * Note that there are no guarantees on the ordering of values inside the + * array, and it may change when more values are added or removed. + * + * Requirements: + * + * - `index` must be strictly less than {length}. + */ + function at(AddressToUintMap storage map, uint256 index) internal view returns (address, uint256) { + (bytes32 key, bytes32 value) = at(map._inner, index); + return (address(uint160(uint256(key))), uint256(value)); + } + + /** + * @dev Tries to returns the value associated with `key`. O(1). + * Does not revert if `key` is not in the map. + */ + function tryGet(AddressToUintMap storage map, address key) internal view returns (bool, uint256) { + (bool success, bytes32 value) = tryGet(map._inner, bytes32(uint256(uint160(key)))); + return (success, uint256(value)); + } + + /** + * @dev Returns the value associated with `key`. O(1). + * + * Requirements: + * + * - `key` must be in the map. + */ + function get(AddressToUintMap storage map, address key) internal view returns (uint256) { + return uint256(get(map._inner, bytes32(uint256(uint160(key))))); + } + + /** + * @dev Same as {get}, with a custom error message when `key` is not in the map. + * + * CAUTION: This function is deprecated because it requires allocating memory for the error + * message unnecessarily. For custom revert reasons use {tryGet}. + */ + function get( + AddressToUintMap storage map, + address key, + string memory errorMessage + ) internal view returns (uint256) { + return uint256(get(map._inner, bytes32(uint256(uint160(key))), errorMessage)); + } + + // Bytes32ToUintMap + + struct Bytes32ToUintMap { + Bytes32ToBytes32Map _inner; + } + + /** + * @dev Adds a key-value pair to a map, or updates the value for an existing + * key. O(1). + * + * Returns true if the key was added to the map, that is if it was not + * already present. + */ + function set( + Bytes32ToUintMap storage map, + bytes32 key, + uint256 value + ) internal returns (bool) { + return set(map._inner, key, bytes32(value)); + } + + /** + * @dev Removes a value from a set. O(1). + * + * Returns true if the key was removed from the map, that is if it was present. + */ + function remove(Bytes32ToUintMap storage map, bytes32 key) internal returns (bool) { + return remove(map._inner, key); + } + + /** + * @dev Returns true if the key is in the map. O(1). + */ + function contains(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool) { + return contains(map._inner, key); + } + + /** + * @dev Returns the number of elements in the map. O(1). + */ + function length(Bytes32ToUintMap storage map) internal view returns (uint256) { + return length(map._inner); + } + + /** + * @dev Returns the element stored at position `index` in the set. O(1). + * Note that there are no guarantees on the ordering of values inside the + * array, and it may change when more values are added or removed. + * + * Requirements: + * + * - `index` must be strictly less than {length}. + */ + function at(Bytes32ToUintMap storage map, uint256 index) internal view returns (bytes32, uint256) { + (bytes32 key, bytes32 value) = at(map._inner, index); + return (key, uint256(value)); + } + + /** + * @dev Tries to returns the value associated with `key`. O(1). + * Does not revert if `key` is not in the map. + */ + function tryGet(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool, uint256) { + (bool success, bytes32 value) = tryGet(map._inner, key); + return (success, uint256(value)); + } + + /** + * @dev Returns the value associated with `key`. O(1). + * + * Requirements: + * + * - `key` must be in the map. + */ + function get(Bytes32ToUintMap storage map, bytes32 key) internal view returns (uint256) { + return uint256(get(map._inner, key)); + } + + /** + * @dev Same as {get}, with a custom error message when `key` is not in the map. + * + * CAUTION: This function is deprecated because it requires allocating memory for the error + * message unnecessarily. For custom revert reasons use {tryGet}. + */ + function get( + Bytes32ToUintMap storage map, + bytes32 key, + string memory errorMessage + ) internal view returns (uint256) { + return uint256(get(map._inner, key, errorMessage)); + } +} diff --git a/contracts/utils/EnumerableSetS.sol b/contracts/utils/EnumerableSetS.sol new file mode 100644 index 00000000..f10ed781 --- /dev/null +++ b/contracts/utils/EnumerableSetS.sol @@ -0,0 +1,370 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol) + +pragma solidity 0.8.6; + +// NOTE: this is the EnumerableSet implementation of OpenZeppelin 4.7.1 +// we copy it here because the version of OpenZeppelin that we use (4.3.2) does not include EnumerableMap.UintToUintMap + +/** + * @dev Library for managing + * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive + * types. + * + * Sets have the following properties: + * + * - Elements are added, removed, and checked for existence in constant time + * (O(1)). + * - Elements are enumerated in O(n). No guarantees are made on the ordering. + * + * ``` + * contract Example { + * // Add the library methods + * using EnumerableSet for EnumerableSet.AddressSet; + * + * // Declare a set state variable + * EnumerableSet.AddressSet private mySet; + * } + * ``` + * + * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) + * and `uint256` (`UintSet`) are supported. + * + * [WARNING] + * ==== + * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable. + * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. + * + * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet. + * ==== + */ +library EnumerableSetS { + // To implement this library for multiple types with as little code + // repetition as possible, we write it in terms of a generic Set type with + // bytes32 values. + // The Set implementation uses private functions, and user-facing + // implementations (such as AddressSet) are just wrappers around the + // underlying Set. + // This means that we can only create new EnumerableSets for types that fit + // in bytes32. + + struct Set { + // Storage of set values + bytes32[] _values; + // Position of the value in the `values` array, plus 1 because index 0 + // means a value is not in the set. + mapping(bytes32 => uint256) _indexes; + } + + /** + * @dev Add a value to a set. O(1). + * + * Returns true if the value was added to the set, that is if it was not + * already present. + */ + function _add(Set storage set, bytes32 value) private returns (bool) { + if (!_contains(set, value)) { + set._values.push(value); + // The value is stored at length-1, but we add 1 to all indexes + // and use 0 as a sentinel value + set._indexes[value] = set._values.length; + return true; + } else { + return false; + } + } + + /** + * @dev Removes a value from a set. O(1). + * + * Returns true if the value was removed from the set, that is if it was + * present. + */ + function _remove(Set storage set, bytes32 value) private returns (bool) { + // We read and store the value's index to prevent multiple reads from the same storage slot + uint256 valueIndex = set._indexes[value]; + + if (valueIndex != 0) { + // Equivalent to contains(set, value) + // To delete an element from the _values array in O(1), we swap the element to delete with the last one in + // the array, and then remove the last element (sometimes called as 'swap and pop'). + // This modifies the order of the array, as noted in {at}. + + uint256 toDeleteIndex = valueIndex - 1; + uint256 lastIndex = set._values.length - 1; + + if (lastIndex != toDeleteIndex) { + bytes32 lastValue = set._values[lastIndex]; + + // Move the last value to the index where the value to delete is + set._values[toDeleteIndex] = lastValue; + // Update the index for the moved value + set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex + } + + // Delete the slot where the moved value was stored + set._values.pop(); + + // Delete the index for the deleted slot + delete set._indexes[value]; + + return true; + } else { + return false; + } + } + + /** + * @dev Returns true if the value is in the set. O(1). + */ + function _contains(Set storage set, bytes32 value) private view returns (bool) { + return set._indexes[value] != 0; + } + + /** + * @dev Returns the number of values on the set. O(1). + */ + function _length(Set storage set) private view returns (uint256) { + return set._values.length; + } + + /** + * @dev Returns the value stored at position `index` in the set. O(1). + * + * Note that there are no guarantees on the ordering of values inside the + * array, and it may change when more values are added or removed. + * + * Requirements: + * + * - `index` must be strictly less than {length}. + */ + function _at(Set storage set, uint256 index) private view returns (bytes32) { + return set._values[index]; + } + + /** + * @dev Return the entire set in an array + * + * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed + * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that + * this function has an unbounded cost, and using it as part of a state-changing function may render the function + * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. + */ + function _values(Set storage set) private view returns (bytes32[] memory) { + return set._values; + } + + // Bytes32Set + + struct Bytes32Set { + Set _inner; + } + + /** + * @dev Add a value to a set. O(1). + * + * Returns true if the value was added to the set, that is if it was not + * already present. + */ + function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { + return _add(set._inner, value); + } + + /** + * @dev Removes a value from a set. O(1). + * + * Returns true if the value was removed from the set, that is if it was + * present. + */ + function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { + return _remove(set._inner, value); + } + + /** + * @dev Returns true if the value is in the set. O(1). + */ + function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { + return _contains(set._inner, value); + } + + /** + * @dev Returns the number of values in the set. O(1). + */ + function length(Bytes32Set storage set) internal view returns (uint256) { + return _length(set._inner); + } + + /** + * @dev Returns the value stored at position `index` in the set. O(1). + * + * Note that there are no guarantees on the ordering of values inside the + * array, and it may change when more values are added or removed. + * + * Requirements: + * + * - `index` must be strictly less than {length}. + */ + function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { + return _at(set._inner, index); + } + + /** + * @dev Return the entire set in an array + * + * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed + * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that + * this function has an unbounded cost, and using it as part of a state-changing function may render the function + * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. + */ + function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { + return _values(set._inner); + } + + // AddressSet + + struct AddressSet { + Set _inner; + } + + /** + * @dev Add a value to a set. O(1). + * + * Returns true if the value was added to the set, that is if it was not + * already present. + */ + function add(AddressSet storage set, address value) internal returns (bool) { + return _add(set._inner, bytes32(uint256(uint160(value)))); + } + + /** + * @dev Removes a value from a set. O(1). + * + * Returns true if the value was removed from the set, that is if it was + * present. + */ + function remove(AddressSet storage set, address value) internal returns (bool) { + return _remove(set._inner, bytes32(uint256(uint160(value)))); + } + + /** + * @dev Returns true if the value is in the set. O(1). + */ + function contains(AddressSet storage set, address value) internal view returns (bool) { + return _contains(set._inner, bytes32(uint256(uint160(value)))); + } + + /** + * @dev Returns the number of values in the set. O(1). + */ + function length(AddressSet storage set) internal view returns (uint256) { + return _length(set._inner); + } + + /** + * @dev Returns the value stored at position `index` in the set. O(1). + * + * Note that there are no guarantees on the ordering of values inside the + * array, and it may change when more values are added or removed. + * + * Requirements: + * + * - `index` must be strictly less than {length}. + */ + function at(AddressSet storage set, uint256 index) internal view returns (address) { + return address(uint160(uint256(_at(set._inner, index)))); + } + + /** + * @dev Return the entire set in an array + * + * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed + * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that + * this function has an unbounded cost, and using it as part of a state-changing function may render the function + * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. + */ + function values(AddressSet storage set) internal view returns (address[] memory) { + bytes32[] memory store = _values(set._inner); + address[] memory result; + + /// @solidity memory-safe-assembly + assembly { + result := store + } + + return result; + } + + // UintSet + + struct UintSet { + Set _inner; + } + + /** + * @dev Add a value to a set. O(1). + * + * Returns true if the value was added to the set, that is if it was not + * already present. + */ + function add(UintSet storage set, uint256 value) internal returns (bool) { + return _add(set._inner, bytes32(value)); + } + + /** + * @dev Removes a value from a set. O(1). + * + * Returns true if the value was removed from the set, that is if it was + * present. + */ + function remove(UintSet storage set, uint256 value) internal returns (bool) { + return _remove(set._inner, bytes32(value)); + } + + /** + * @dev Returns true if the value is in the set. O(1). + */ + function contains(UintSet storage set, uint256 value) internal view returns (bool) { + return _contains(set._inner, bytes32(value)); + } + + /** + * @dev Returns the number of values on the set. O(1). + */ + function length(UintSet storage set) internal view returns (uint256) { + return _length(set._inner); + } + + /** + * @dev Returns the value stored at position `index` in the set. O(1). + * + * Note that there are no guarantees on the ordering of values inside the + * array, and it may change when more values are added or removed. + * + * Requirements: + * + * - `index` must be strictly less than {length}. + */ + function at(UintSet storage set, uint256 index) internal view returns (uint256) { + return uint256(_at(set._inner, index)); + } + + /** + * @dev Return the entire set in an array + * + * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed + * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that + * this function has an unbounded cost, and using it as part of a state-changing function may render the function + * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. + */ + function values(UintSet storage set) internal view returns (uint256[] memory) { + bytes32[] memory store = _values(set._inner); + uint256[] memory result; + + /// @solidity memory-safe-assembly + assembly { + result := store + } + + return result; + } +} diff --git a/contracts/utils/SafeCastS.sol b/contracts/utils/SafeCastS.sol new file mode 100644 index 00000000..5efd1605 --- /dev/null +++ b/contracts/utils/SafeCastS.sol @@ -0,0 +1,1139 @@ +// ^4.7.1 of OpenZeppelin SafeCast.sol +// Created as local copy in Solace repo to enable use of single updated SafeCast.sol file while maintaining @openzeppelin dependencies at ~4.3.2. +// Initializable pattern used in Solace repo broken with ^4.7.1 + +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol) + +pragma solidity 0.8.6; + +/** + * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow + * checks. + * + * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can + * easily result in undesired exploitation or bugs, since developers usually + * assume that overflows raise errors. `SafeCast` restores this intuition by + * reverting the transaction when such an operation overflows. + * + * Using this library instead of the unchecked operations eliminates an entire + * class of bugs, so it's recommended to use it always. + * + * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing + * all math on `uint256` and `int256` and then downcasting. + */ +library SafeCastS { + /** + * @dev Returns the downcasted uint248 from uint256, reverting on + * overflow (when the input is greater than largest uint248). + * + * Counterpart to Solidity's `uint248` operator. + * + * Requirements: + * + * - input must fit into 248 bits + * + * _Available since v4.7._ + */ + function toUint248(uint256 value) internal pure returns (uint248) { + require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits"); + return uint248(value); + } + + /** + * @dev Returns the downcasted uint240 from uint256, reverting on + * overflow (when the input is greater than largest uint240). + * + * Counterpart to Solidity's `uint240` operator. + * + * Requirements: + * + * - input must fit into 240 bits + * + * _Available since v4.7._ + */ + function toUint240(uint256 value) internal pure returns (uint240) { + require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits"); + return uint240(value); + } + + /** + * @dev Returns the downcasted uint232 from uint256, reverting on + * overflow (when the input is greater than largest uint232). + * + * Counterpart to Solidity's `uint232` operator. + * + * Requirements: + * + * - input must fit into 232 bits + * + * _Available since v4.7._ + */ + function toUint232(uint256 value) internal pure returns (uint232) { + require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits"); + return uint232(value); + } + + /** + * @dev Returns the downcasted uint224 from uint256, reverting on + * overflow (when the input is greater than largest uint224). + * + * Counterpart to Solidity's `uint224` operator. + * + * Requirements: + * + * - input must fit into 224 bits + * + * _Available since v4.2._ + */ + function toUint224(uint256 value) internal pure returns (uint224) { + require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits"); + return uint224(value); + } + + /** + * @dev Returns the downcasted uint216 from uint256, reverting on + * overflow (when the input is greater than largest uint216). + * + * Counterpart to Solidity's `uint216` operator. + * + * Requirements: + * + * - input must fit into 216 bits + * + * _Available since v4.7._ + */ + function toUint216(uint256 value) internal pure returns (uint216) { + require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits"); + return uint216(value); + } + + /** + * @dev Returns the downcasted uint208 from uint256, reverting on + * overflow (when the input is greater than largest uint208). + * + * Counterpart to Solidity's `uint208` operator. + * + * Requirements: + * + * - input must fit into 208 bits + * + * _Available since v4.7._ + */ + function toUint208(uint256 value) internal pure returns (uint208) { + require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits"); + return uint208(value); + } + + /** + * @dev Returns the downcasted uint200 from uint256, reverting on + * overflow (when the input is greater than largest uint200). + * + * Counterpart to Solidity's `uint200` operator. + * + * Requirements: + * + * - input must fit into 200 bits + * + * _Available since v4.7._ + */ + function toUint200(uint256 value) internal pure returns (uint200) { + require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits"); + return uint200(value); + } + + /** + * @dev Returns the downcasted uint192 from uint256, reverting on + * overflow (when the input is greater than largest uint192). + * + * Counterpart to Solidity's `uint192` operator. + * + * Requirements: + * + * - input must fit into 192 bits + * + * _Available since v4.7._ + */ + function toUint192(uint256 value) internal pure returns (uint192) { + require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits"); + return uint192(value); + } + + /** + * @dev Returns the downcasted uint184 from uint256, reverting on + * overflow (when the input is greater than largest uint184). + * + * Counterpart to Solidity's `uint184` operator. + * + * Requirements: + * + * - input must fit into 184 bits + * + * _Available since v4.7._ + */ + function toUint184(uint256 value) internal pure returns (uint184) { + require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits"); + return uint184(value); + } + + /** + * @dev Returns the downcasted uint176 from uint256, reverting on + * overflow (when the input is greater than largest uint176). + * + * Counterpart to Solidity's `uint176` operator. + * + * Requirements: + * + * - input must fit into 176 bits + * + * _Available since v4.7._ + */ + function toUint176(uint256 value) internal pure returns (uint176) { + require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits"); + return uint176(value); + } + + /** + * @dev Returns the downcasted uint168 from uint256, reverting on + * overflow (when the input is greater than largest uint168). + * + * Counterpart to Solidity's `uint168` operator. + * + * Requirements: + * + * - input must fit into 168 bits + * + * _Available since v4.7._ + */ + function toUint168(uint256 value) internal pure returns (uint168) { + require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits"); + return uint168(value); + } + + /** + * @dev Returns the downcasted uint160 from uint256, reverting on + * overflow (when the input is greater than largest uint160). + * + * Counterpart to Solidity's `uint160` operator. + * + * Requirements: + * + * - input must fit into 160 bits + * + * _Available since v4.7._ + */ + function toUint160(uint256 value) internal pure returns (uint160) { + require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits"); + return uint160(value); + } + + /** + * @dev Returns the downcasted uint152 from uint256, reverting on + * overflow (when the input is greater than largest uint152). + * + * Counterpart to Solidity's `uint152` operator. + * + * Requirements: + * + * - input must fit into 152 bits + * + * _Available since v4.7._ + */ + function toUint152(uint256 value) internal pure returns (uint152) { + require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits"); + return uint152(value); + } + + /** + * @dev Returns the downcasted uint144 from uint256, reverting on + * overflow (when the input is greater than largest uint144). + * + * Counterpart to Solidity's `uint144` operator. + * + * Requirements: + * + * - input must fit into 144 bits + * + * _Available since v4.7._ + */ + function toUint144(uint256 value) internal pure returns (uint144) { + require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits"); + return uint144(value); + } + + /** + * @dev Returns the downcasted uint136 from uint256, reverting on + * overflow (when the input is greater than largest uint136). + * + * Counterpart to Solidity's `uint136` operator. + * + * Requirements: + * + * - input must fit into 136 bits + * + * _Available since v4.7._ + */ + function toUint136(uint256 value) internal pure returns (uint136) { + require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits"); + return uint136(value); + } + + /** + * @dev Returns the downcasted uint128 from uint256, reverting on + * overflow (when the input is greater than largest uint128). + * + * Counterpart to Solidity's `uint128` operator. + * + * Requirements: + * + * - input must fit into 128 bits + * + * _Available since v2.5._ + */ + function toUint128(uint256 value) internal pure returns (uint128) { + require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits"); + return uint128(value); + } + + /** + * @dev Returns the downcasted uint120 from uint256, reverting on + * overflow (when the input is greater than largest uint120). + * + * Counterpart to Solidity's `uint120` operator. + * + * Requirements: + * + * - input must fit into 120 bits + * + * _Available since v4.7._ + */ + function toUint120(uint256 value) internal pure returns (uint120) { + require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits"); + return uint120(value); + } + + /** + * @dev Returns the downcasted uint112 from uint256, reverting on + * overflow (when the input is greater than largest uint112). + * + * Counterpart to Solidity's `uint112` operator. + * + * Requirements: + * + * - input must fit into 112 bits + * + * _Available since v4.7._ + */ + function toUint112(uint256 value) internal pure returns (uint112) { + require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits"); + return uint112(value); + } + + /** + * @dev Returns the downcasted uint104 from uint256, reverting on + * overflow (when the input is greater than largest uint104). + * + * Counterpart to Solidity's `uint104` operator. + * + * Requirements: + * + * - input must fit into 104 bits + * + * _Available since v4.7._ + */ + function toUint104(uint256 value) internal pure returns (uint104) { + require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits"); + return uint104(value); + } + + /** + * @dev Returns the downcasted uint96 from uint256, reverting on + * overflow (when the input is greater than largest uint96). + * + * Counterpart to Solidity's `uint96` operator. + * + * Requirements: + * + * - input must fit into 96 bits + * + * _Available since v4.2._ + */ + function toUint96(uint256 value) internal pure returns (uint96) { + require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits"); + return uint96(value); + } + + /** + * @dev Returns the downcasted uint88 from uint256, reverting on + * overflow (when the input is greater than largest uint88). + * + * Counterpart to Solidity's `uint88` operator. + * + * Requirements: + * + * - input must fit into 88 bits + * + * _Available since v4.7._ + */ + function toUint88(uint256 value) internal pure returns (uint88) { + require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits"); + return uint88(value); + } + + /** + * @dev Returns the downcasted uint80 from uint256, reverting on + * overflow (when the input is greater than largest uint80). + * + * Counterpart to Solidity's `uint80` operator. + * + * Requirements: + * + * - input must fit into 80 bits + * + * _Available since v4.7._ + */ + function toUint80(uint256 value) internal pure returns (uint80) { + require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits"); + return uint80(value); + } + + /** + * @dev Returns the downcasted uint72 from uint256, reverting on + * overflow (when the input is greater than largest uint72). + * + * Counterpart to Solidity's `uint72` operator. + * + * Requirements: + * + * - input must fit into 72 bits + * + * _Available since v4.7._ + */ + function toUint72(uint256 value) internal pure returns (uint72) { + require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits"); + return uint72(value); + } + + /** + * @dev Returns the downcasted uint64 from uint256, reverting on + * overflow (when the input is greater than largest uint64). + * + * Counterpart to Solidity's `uint64` operator. + * + * Requirements: + * + * - input must fit into 64 bits + * + * _Available since v2.5._ + */ + function toUint64(uint256 value) internal pure returns (uint64) { + require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits"); + return uint64(value); + } + + /** + * @dev Returns the downcasted uint56 from uint256, reverting on + * overflow (when the input is greater than largest uint56). + * + * Counterpart to Solidity's `uint56` operator. + * + * Requirements: + * + * - input must fit into 56 bits + * + * _Available since v4.7._ + */ + function toUint56(uint256 value) internal pure returns (uint56) { + require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits"); + return uint56(value); + } + + /** + * @dev Returns the downcasted uint48 from uint256, reverting on + * overflow (when the input is greater than largest uint48). + * + * Counterpart to Solidity's `uint48` operator. + * + * Requirements: + * + * - input must fit into 48 bits + * + * _Available since v4.7._ + */ + function toUint48(uint256 value) internal pure returns (uint48) { + require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits"); + return uint48(value); + } + + /** + * @dev Returns the downcasted uint40 from uint256, reverting on + * overflow (when the input is greater than largest uint40). + * + * Counterpart to Solidity's `uint40` operator. + * + * Requirements: + * + * - input must fit into 40 bits + * + * _Available since v4.7._ + */ + function toUint40(uint256 value) internal pure returns (uint40) { + require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits"); + return uint40(value); + } + + /** + * @dev Returns the downcasted uint32 from uint256, reverting on + * overflow (when the input is greater than largest uint32). + * + * Counterpart to Solidity's `uint32` operator. + * + * Requirements: + * + * - input must fit into 32 bits + * + * _Available since v2.5._ + */ + function toUint32(uint256 value) internal pure returns (uint32) { + require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits"); + return uint32(value); + } + + /** + * @dev Returns the downcasted uint24 from uint256, reverting on + * overflow (when the input is greater than largest uint24). + * + * Counterpart to Solidity's `uint24` operator. + * + * Requirements: + * + * - input must fit into 24 bits + * + * _Available since v4.7._ + */ + function toUint24(uint256 value) internal pure returns (uint24) { + require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits"); + return uint24(value); + } + + /** + * @dev Returns the downcasted uint16 from uint256, reverting on + * overflow (when the input is greater than largest uint16). + * + * Counterpart to Solidity's `uint16` operator. + * + * Requirements: + * + * - input must fit into 16 bits + * + * _Available since v2.5._ + */ + function toUint16(uint256 value) internal pure returns (uint16) { + require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits"); + return uint16(value); + } + + /** + * @dev Returns the downcasted uint8 from uint256, reverting on + * overflow (when the input is greater than largest uint8). + * + * Counterpart to Solidity's `uint8` operator. + * + * Requirements: + * + * - input must fit into 8 bits + * + * _Available since v2.5._ + */ + function toUint8(uint256 value) internal pure returns (uint8) { + require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits"); + return uint8(value); + } + + /** + * @dev Converts a signed int256 into an unsigned uint256. + * + * Requirements: + * + * - input must be greater than or equal to 0. + * + * _Available since v3.0._ + */ + function toUint256(int256 value) internal pure returns (uint256) { + require(value >= 0, "SafeCast: value must be positive"); + return uint256(value); + } + + /** + * @dev Returns the downcasted int248 from int256, reverting on + * overflow (when the input is less than smallest int248 or + * greater than largest int248). + * + * Counterpart to Solidity's `int248` operator. + * + * Requirements: + * + * - input must fit into 248 bits + * + * _Available since v4.7._ + */ + function toInt248(int256 value) internal pure returns (int248 downcasted) { + downcasted = int248(value); + require(downcasted == value, "SafeCast: value doesn't fit in 248 bits"); + } + + /** + * @dev Returns the downcasted int240 from int256, reverting on + * overflow (when the input is less than smallest int240 or + * greater than largest int240). + * + * Counterpart to Solidity's `int240` operator. + * + * Requirements: + * + * - input must fit into 240 bits + * + * _Available since v4.7._ + */ + function toInt240(int256 value) internal pure returns (int240 downcasted) { + downcasted = int240(value); + require(downcasted == value, "SafeCast: value doesn't fit in 240 bits"); + } + + /** + * @dev Returns the downcasted int232 from int256, reverting on + * overflow (when the input is less than smallest int232 or + * greater than largest int232). + * + * Counterpart to Solidity's `int232` operator. + * + * Requirements: + * + * - input must fit into 232 bits + * + * _Available since v4.7._ + */ + function toInt232(int256 value) internal pure returns (int232 downcasted) { + downcasted = int232(value); + require(downcasted == value, "SafeCast: value doesn't fit in 232 bits"); + } + + /** + * @dev Returns the downcasted int224 from int256, reverting on + * overflow (when the input is less than smallest int224 or + * greater than largest int224). + * + * Counterpart to Solidity's `int224` operator. + * + * Requirements: + * + * - input must fit into 224 bits + * + * _Available since v4.7._ + */ + function toInt224(int256 value) internal pure returns (int224 downcasted) { + downcasted = int224(value); + require(downcasted == value, "SafeCast: value doesn't fit in 224 bits"); + } + + /** + * @dev Returns the downcasted int216 from int256, reverting on + * overflow (when the input is less than smallest int216 or + * greater than largest int216). + * + * Counterpart to Solidity's `int216` operator. + * + * Requirements: + * + * - input must fit into 216 bits + * + * _Available since v4.7._ + */ + function toInt216(int256 value) internal pure returns (int216 downcasted) { + downcasted = int216(value); + require(downcasted == value, "SafeCast: value doesn't fit in 216 bits"); + } + + /** + * @dev Returns the downcasted int208 from int256, reverting on + * overflow (when the input is less than smallest int208 or + * greater than largest int208). + * + * Counterpart to Solidity's `int208` operator. + * + * Requirements: + * + * - input must fit into 208 bits + * + * _Available since v4.7._ + */ + function toInt208(int256 value) internal pure returns (int208 downcasted) { + downcasted = int208(value); + require(downcasted == value, "SafeCast: value doesn't fit in 208 bits"); + } + + /** + * @dev Returns the downcasted int200 from int256, reverting on + * overflow (when the input is less than smallest int200 or + * greater than largest int200). + * + * Counterpart to Solidity's `int200` operator. + * + * Requirements: + * + * - input must fit into 200 bits + * + * _Available since v4.7._ + */ + function toInt200(int256 value) internal pure returns (int200 downcasted) { + downcasted = int200(value); + require(downcasted == value, "SafeCast: value doesn't fit in 200 bits"); + } + + /** + * @dev Returns the downcasted int192 from int256, reverting on + * overflow (when the input is less than smallest int192 or + * greater than largest int192). + * + * Counterpart to Solidity's `int192` operator. + * + * Requirements: + * + * - input must fit into 192 bits + * + * _Available since v4.7._ + */ + function toInt192(int256 value) internal pure returns (int192 downcasted) { + downcasted = int192(value); + require(downcasted == value, "SafeCast: value doesn't fit in 192 bits"); + } + + /** + * @dev Returns the downcasted int184 from int256, reverting on + * overflow (when the input is less than smallest int184 or + * greater than largest int184). + * + * Counterpart to Solidity's `int184` operator. + * + * Requirements: + * + * - input must fit into 184 bits + * + * _Available since v4.7._ + */ + function toInt184(int256 value) internal pure returns (int184 downcasted) { + downcasted = int184(value); + require(downcasted == value, "SafeCast: value doesn't fit in 184 bits"); + } + + /** + * @dev Returns the downcasted int176 from int256, reverting on + * overflow (when the input is less than smallest int176 or + * greater than largest int176). + * + * Counterpart to Solidity's `int176` operator. + * + * Requirements: + * + * - input must fit into 176 bits + * + * _Available since v4.7._ + */ + function toInt176(int256 value) internal pure returns (int176 downcasted) { + downcasted = int176(value); + require(downcasted == value, "SafeCast: value doesn't fit in 176 bits"); + } + + /** + * @dev Returns the downcasted int168 from int256, reverting on + * overflow (when the input is less than smallest int168 or + * greater than largest int168). + * + * Counterpart to Solidity's `int168` operator. + * + * Requirements: + * + * - input must fit into 168 bits + * + * _Available since v4.7._ + */ + function toInt168(int256 value) internal pure returns (int168 downcasted) { + downcasted = int168(value); + require(downcasted == value, "SafeCast: value doesn't fit in 168 bits"); + } + + /** + * @dev Returns the downcasted int160 from int256, reverting on + * overflow (when the input is less than smallest int160 or + * greater than largest int160). + * + * Counterpart to Solidity's `int160` operator. + * + * Requirements: + * + * - input must fit into 160 bits + * + * _Available since v4.7._ + */ + function toInt160(int256 value) internal pure returns (int160 downcasted) { + downcasted = int160(value); + require(downcasted == value, "SafeCast: value doesn't fit in 160 bits"); + } + + /** + * @dev Returns the downcasted int152 from int256, reverting on + * overflow (when the input is less than smallest int152 or + * greater than largest int152). + * + * Counterpart to Solidity's `int152` operator. + * + * Requirements: + * + * - input must fit into 152 bits + * + * _Available since v4.7._ + */ + function toInt152(int256 value) internal pure returns (int152 downcasted) { + downcasted = int152(value); + require(downcasted == value, "SafeCast: value doesn't fit in 152 bits"); + } + + /** + * @dev Returns the downcasted int144 from int256, reverting on + * overflow (when the input is less than smallest int144 or + * greater than largest int144). + * + * Counterpart to Solidity's `int144` operator. + * + * Requirements: + * + * - input must fit into 144 bits + * + * _Available since v4.7._ + */ + function toInt144(int256 value) internal pure returns (int144 downcasted) { + downcasted = int144(value); + require(downcasted == value, "SafeCast: value doesn't fit in 144 bits"); + } + + /** + * @dev Returns the downcasted int136 from int256, reverting on + * overflow (when the input is less than smallest int136 or + * greater than largest int136). + * + * Counterpart to Solidity's `int136` operator. + * + * Requirements: + * + * - input must fit into 136 bits + * + * _Available since v4.7._ + */ + function toInt136(int256 value) internal pure returns (int136 downcasted) { + downcasted = int136(value); + require(downcasted == value, "SafeCast: value doesn't fit in 136 bits"); + } + + /** + * @dev Returns the downcasted int128 from int256, reverting on + * overflow (when the input is less than smallest int128 or + * greater than largest int128). + * + * Counterpart to Solidity's `int128` operator. + * + * Requirements: + * + * - input must fit into 128 bits + * + * _Available since v3.1._ + */ + function toInt128(int256 value) internal pure returns (int128 downcasted) { + downcasted = int128(value); + require(downcasted == value, "SafeCast: value doesn't fit in 128 bits"); + } + + /** + * @dev Returns the downcasted int120 from int256, reverting on + * overflow (when the input is less than smallest int120 or + * greater than largest int120). + * + * Counterpart to Solidity's `int120` operator. + * + * Requirements: + * + * - input must fit into 120 bits + * + * _Available since v4.7._ + */ + function toInt120(int256 value) internal pure returns (int120 downcasted) { + downcasted = int120(value); + require(downcasted == value, "SafeCast: value doesn't fit in 120 bits"); + } + + /** + * @dev Returns the downcasted int112 from int256, reverting on + * overflow (when the input is less than smallest int112 or + * greater than largest int112). + * + * Counterpart to Solidity's `int112` operator. + * + * Requirements: + * + * - input must fit into 112 bits + * + * _Available since v4.7._ + */ + function toInt112(int256 value) internal pure returns (int112 downcasted) { + downcasted = int112(value); + require(downcasted == value, "SafeCast: value doesn't fit in 112 bits"); + } + + /** + * @dev Returns the downcasted int104 from int256, reverting on + * overflow (when the input is less than smallest int104 or + * greater than largest int104). + * + * Counterpart to Solidity's `int104` operator. + * + * Requirements: + * + * - input must fit into 104 bits + * + * _Available since v4.7._ + */ + function toInt104(int256 value) internal pure returns (int104 downcasted) { + downcasted = int104(value); + require(downcasted == value, "SafeCast: value doesn't fit in 104 bits"); + } + + /** + * @dev Returns the downcasted int96 from int256, reverting on + * overflow (when the input is less than smallest int96 or + * greater than largest int96). + * + * Counterpart to Solidity's `int96` operator. + * + * Requirements: + * + * - input must fit into 96 bits + * + * _Available since v4.7._ + */ + function toInt96(int256 value) internal pure returns (int96 downcasted) { + downcasted = int96(value); + require(downcasted == value, "SafeCast: value doesn't fit in 96 bits"); + } + + /** + * @dev Returns the downcasted int88 from int256, reverting on + * overflow (when the input is less than smallest int88 or + * greater than largest int88). + * + * Counterpart to Solidity's `int88` operator. + * + * Requirements: + * + * - input must fit into 88 bits + * + * _Available since v4.7._ + */ + function toInt88(int256 value) internal pure returns (int88 downcasted) { + downcasted = int88(value); + require(downcasted == value, "SafeCast: value doesn't fit in 88 bits"); + } + + /** + * @dev Returns the downcasted int80 from int256, reverting on + * overflow (when the input is less than smallest int80 or + * greater than largest int80). + * + * Counterpart to Solidity's `int80` operator. + * + * Requirements: + * + * - input must fit into 80 bits + * + * _Available since v4.7._ + */ + function toInt80(int256 value) internal pure returns (int80 downcasted) { + downcasted = int80(value); + require(downcasted == value, "SafeCast: value doesn't fit in 80 bits"); + } + + /** + * @dev Returns the downcasted int72 from int256, reverting on + * overflow (when the input is less than smallest int72 or + * greater than largest int72). + * + * Counterpart to Solidity's `int72` operator. + * + * Requirements: + * + * - input must fit into 72 bits + * + * _Available since v4.7._ + */ + function toInt72(int256 value) internal pure returns (int72 downcasted) { + downcasted = int72(value); + require(downcasted == value, "SafeCast: value doesn't fit in 72 bits"); + } + + /** + * @dev Returns the downcasted int64 from int256, reverting on + * overflow (when the input is less than smallest int64 or + * greater than largest int64). + * + * Counterpart to Solidity's `int64` operator. + * + * Requirements: + * + * - input must fit into 64 bits + * + * _Available since v3.1._ + */ + function toInt64(int256 value) internal pure returns (int64 downcasted) { + downcasted = int64(value); + require(downcasted == value, "SafeCast: value doesn't fit in 64 bits"); + } + + /** + * @dev Returns the downcasted int56 from int256, reverting on + * overflow (when the input is less than smallest int56 or + * greater than largest int56). + * + * Counterpart to Solidity's `int56` operator. + * + * Requirements: + * + * - input must fit into 56 bits + * + * _Available since v4.7._ + */ + function toInt56(int256 value) internal pure returns (int56 downcasted) { + downcasted = int56(value); + require(downcasted == value, "SafeCast: value doesn't fit in 56 bits"); + } + + /** + * @dev Returns the downcasted int48 from int256, reverting on + * overflow (when the input is less than smallest int48 or + * greater than largest int48). + * + * Counterpart to Solidity's `int48` operator. + * + * Requirements: + * + * - input must fit into 48 bits + * + * _Available since v4.7._ + */ + function toInt48(int256 value) internal pure returns (int48 downcasted) { + downcasted = int48(value); + require(downcasted == value, "SafeCast: value doesn't fit in 48 bits"); + } + + /** + * @dev Returns the downcasted int40 from int256, reverting on + * overflow (when the input is less than smallest int40 or + * greater than largest int40). + * + * Counterpart to Solidity's `int40` operator. + * + * Requirements: + * + * - input must fit into 40 bits + * + * _Available since v4.7._ + */ + function toInt40(int256 value) internal pure returns (int40 downcasted) { + downcasted = int40(value); + require(downcasted == value, "SafeCast: value doesn't fit in 40 bits"); + } + + /** + * @dev Returns the downcasted int32 from int256, reverting on + * overflow (when the input is less than smallest int32 or + * greater than largest int32). + * + * Counterpart to Solidity's `int32` operator. + * + * Requirements: + * + * - input must fit into 32 bits + * + * _Available since v3.1._ + */ + function toInt32(int256 value) internal pure returns (int32 downcasted) { + downcasted = int32(value); + require(downcasted == value, "SafeCast: value doesn't fit in 32 bits"); + } + + /** + * @dev Returns the downcasted int24 from int256, reverting on + * overflow (when the input is less than smallest int24 or + * greater than largest int24). + * + * Counterpart to Solidity's `int24` operator. + * + * Requirements: + * + * - input must fit into 24 bits + * + * _Available since v4.7._ + */ + function toInt24(int256 value) internal pure returns (int24 downcasted) { + downcasted = int24(value); + require(downcasted == value, "SafeCast: value doesn't fit in 24 bits"); + } + + /** + * @dev Returns the downcasted int16 from int256, reverting on + * overflow (when the input is less than smallest int16 or + * greater than largest int16). + * + * Counterpart to Solidity's `int16` operator. + * + * Requirements: + * + * - input must fit into 16 bits + * + * _Available since v3.1._ + */ + function toInt16(int256 value) internal pure returns (int16 downcasted) { + downcasted = int16(value); + require(downcasted == value, "SafeCast: value doesn't fit in 16 bits"); + } + + /** + * @dev Returns the downcasted int8 from int256, reverting on + * overflow (when the input is less than smallest int8 or + * greater than largest int8). + * + * Counterpart to Solidity's `int8` operator. + * + * Requirements: + * + * - input must fit into 8 bits + * + * _Available since v3.1._ + */ + function toInt8(int256 value) internal pure returns (int8 downcasted) { + downcasted = int8(value); + require(downcasted == value, "SafeCast: value doesn't fit in 8 bits"); + } + + /** + * @dev Converts an unsigned uint256 into a signed int256. + * + * Requirements: + * + * - input must be less than or equal to maxInt256. + * + * _Available since v3.0._ + */ + function toInt256(uint256 value) internal pure returns (int256) { + // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive + require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256"); + return int256(value); + } +} diff --git a/package-lock.json b/package-lock.json index 3253f948..ca0821a1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,44 +4,97 @@ "lockfileVersion": 1, "dependencies": { "@babel/code-frame": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", - "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", "dev": true, "requires": { - "@babel/highlight": "^7.12.13" + "@babel/highlight": "^7.18.6" } }, "@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz", + "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==", "dev": true }, "@babel/highlight": { - "version": "7.13.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.10.tgz", - "integrity": "sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.12.11", + "@babel/helper-validator-identifier": "^7.18.6", "chalk": "^2.0.0", "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, - "@cspotcode/source-map-consumer": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", - "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", - "dev": true + "@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "optional": true }, "@cspotcode/source-map-support": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", - "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, "requires": { - "@cspotcode/source-map-consumer": "0.8.0" + "@jridgewell/trace-mapping": "0.3.9" } }, "@ensdomains/ens": { @@ -57,33 +110,10 @@ "web3-utils": "^1.0.0-beta.31" }, "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", - "dev": true - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, "fs-extra": { "version": "0.30.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", + "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -93,25 +123,10 @@ "rimraf": "^2.2.8" } }, - "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==", - "dev": true - }, - "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=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, "jsonfile": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", "dev": true, "requires": { "graceful-fs": "^4.1.6" @@ -120,13 +135,7 @@ "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=", - "dev": true - }, - "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=", + "integrity": "sha512-H7AkJWMobeskkttHyhTVtS0fxpFLjxhbfMa6Bk3wimP7sdPRGL3EyCg3sAQenFfAe+xQ+oAc85Nmtvq0ROM83Q==", "dev": true }, "semver": { @@ -147,80 +156,6 @@ "semver": "^5.3.0", "yargs": "^4.7.1" } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^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=", - "dev": true - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - } - }, - "y18n": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", - "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", - "dev": true - }, - "yargs": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", - "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=", - "dev": true, - "requires": { - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "lodash.assign": "^4.0.3", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.1", - "which-module": "^1.0.0", - "window-size": "^0.2.0", - "y18n": "^3.2.1", - "yargs-parser": "^2.4.1" - } - }, - "yargs-parser": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz", - "integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=", - "dev": true, - "requires": { - "camelcase": "^3.0.0", - "lodash.assign": "^4.0.6" - } } } }, @@ -231,19 +166,19 @@ "dev": true }, "@ethereum-waffle/chai": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@ethereum-waffle/chai/-/chai-3.4.0.tgz", - "integrity": "sha512-GVaFKuFbFUclMkhHtQTDnWBnBQMJc/pAbfbFj/nnIK237WPLsO3KDDslA7m+MNEyTAOFrcc0CyfruAGGXAQw3g==", + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@ethereum-waffle/chai/-/chai-3.4.4.tgz", + "integrity": "sha512-/K8czydBtXXkcM9X6q29EqEkc5dN3oYenyH2a9hF7rGAApAJUpH8QBtojxOY/xQ2up5W332jqgxwp0yPiYug1g==", "dev": true, "requires": { - "@ethereum-waffle/provider": "^3.4.0", - "ethers": "^5.0.0" + "@ethereum-waffle/provider": "^3.4.4", + "ethers": "^5.5.2" } }, "@ethereum-waffle/compiler": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@ethereum-waffle/compiler/-/compiler-3.4.0.tgz", - "integrity": "sha512-a2wxGOoB9F1QFRE+Om7Cz2wn+pxM/o7a0a6cbwhaS2lECJgFzeN9xEkVrKahRkF4gEfXGcuORg4msP0Asxezlw==", + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@ethereum-waffle/compiler/-/compiler-3.4.4.tgz", + "integrity": "sha512-RUK3axJ8IkD5xpWjWoJgyHclOeEzDLQFga6gKpeGxiS/zBu+HB0W2FvsrrLalTFIaPw/CGYACRBSIxqiCqwqTQ==", "dev": true, "requires": { "@resolver-engine/imports": "^0.3.3", @@ -257,111 +192,116 @@ "solc": "^0.6.3", "ts-generator": "^0.1.1", "typechain": "^3.0.0" + }, + "dependencies": { + "fs-extra": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", + "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } + }, + "jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "solc": { + "version": "0.6.12", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.6.12.tgz", + "integrity": "sha512-Lm0Ql2G9Qc7yPP2Ba+WNmzw2jwsrd3u4PobHYlSOxaut3TtUbj9+5ZrT6f4DUpNPEoBaFUOEg9Op9C0mk7ge9g==", + "dev": true, + "requires": { + "command-exists": "^1.2.8", + "commander": "3.0.2", + "fs-extra": "^0.30.0", + "js-sha3": "0.8.0", + "memorystream": "^0.3.1", + "require-from-string": "^2.0.0", + "semver": "^5.5.0", + "tmp": "0.0.33" + } + } } }, "@ethereum-waffle/ens": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@ethereum-waffle/ens/-/ens-3.3.0.tgz", - "integrity": "sha512-zVIH/5cQnIEgJPg1aV8+ehYicpcfuAisfrtzYh1pN3UbfeqPylFBeBaIZ7xj/xYzlJjkrek/h9VfULl6EX9Aqw==", + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@ethereum-waffle/ens/-/ens-3.4.4.tgz", + "integrity": "sha512-0m4NdwWxliy3heBYva1Wr4WbJKLnwXizmy5FfSSr5PMbjI7SIGCdCB59U7/ZzY773/hY3bLnzLwvG5mggVjJWg==", "dev": true, "requires": { "@ensdomains/ens": "^0.4.4", "@ensdomains/resolver": "^0.2.4", - "ethers": "^5.0.1" + "ethers": "^5.5.2" } }, "@ethereum-waffle/mock-contract": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@ethereum-waffle/mock-contract/-/mock-contract-3.3.0.tgz", - "integrity": "sha512-apwq0d+2nQxaNwsyLkE+BNMBhZ1MKGV28BtI9WjD3QD2Ztdt1q9II4sKA4VrLTUneYSmkYbJZJxw89f+OpJGyw==", + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@ethereum-waffle/mock-contract/-/mock-contract-3.4.4.tgz", + "integrity": "sha512-Mp0iB2YNWYGUV+VMl5tjPsaXKbKo8MDH9wSJ702l9EBjdxFf/vBvnMBAC1Fub1lLtmD0JHtp1pq+mWzg/xlLnA==", "dev": true, "requires": { - "@ethersproject/abi": "^5.0.1", - "ethers": "^5.0.1" + "@ethersproject/abi": "^5.5.0", + "ethers": "^5.5.2" } }, "@ethereum-waffle/provider": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@ethereum-waffle/provider/-/provider-3.4.0.tgz", - "integrity": "sha512-QgseGzpwlzmaHXhqfdzthCGu5a6P1SBF955jQHf/rBkK1Y7gGo2ukt3rXgxgfg/O5eHqRU+r8xw5MzVyVaBscQ==", + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@ethereum-waffle/provider/-/provider-3.4.4.tgz", + "integrity": "sha512-GK8oKJAM8+PKy2nK08yDgl4A80mFuI8zBkE0C9GqTRYQqvuxIyXoLmJ5NZU9lIwyWVv5/KsoA11BgAv2jXE82g==", "dev": true, "requires": { - "@ethereum-waffle/ens": "^3.3.0", - "ethers": "^5.0.1", + "@ethereum-waffle/ens": "^3.4.4", + "ethers": "^5.5.2", "ganache-core": "^2.13.2", "patch-package": "^6.2.2", "postinstall-postinstall": "^2.1.0" } }, "@ethereumjs/block": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/block/-/block-3.6.0.tgz", - "integrity": "sha512-dqLo1LtsLG+Oelu5S5tWUDG0pah3QUwV5TJZy2cm19BXDr4ka/S9XBSgao0i09gTcuPlovlHgcs6d7EZ37urjQ==", + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@ethereumjs/block/-/block-3.6.3.tgz", + "integrity": "sha512-CegDeryc2DVKnDkg5COQrE0bJfw/p0v3GBk2W5/Dj5dOVfEmb50Ux0GLnSPypooLnfqjwFaorGuT9FokWB3GRg==", "dev": true, "requires": { - "@ethereumjs/common": "^2.6.0", - "@ethereumjs/tx": "^3.4.0", - "ethereumjs-util": "^7.1.3", - "merkle-patricia-tree": "^4.2.2" - }, - "dependencies": { - "@ethereumjs/common": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.0.tgz", - "integrity": "sha512-Cq2qS0FTu6O2VU1sgg+WyU9Ps0M6j/BEMHN+hRaECXCV/r0aI78u4N6p52QW/BDVhwWZpCdrvG8X7NJdzlpNUA==", - "dev": true, - "requires": { - "crc-32": "^1.2.0", - "ethereumjs-util": "^7.1.3" - } - }, - "@ethereumjs/tx": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.4.0.tgz", - "integrity": "sha512-WWUwg1PdjHKZZxPPo274ZuPsJCWV3SqATrEKQP1n2DrVYVP1aZIYpo/mFaA0BDoE0tIQmBeimRCEA0Lgil+yYw==", - "dev": true, - "requires": { - "@ethereumjs/common": "^2.6.0", - "ethereumjs-util": "^7.1.3" - } - } + "@ethereumjs/common": "^2.6.5", + "@ethereumjs/tx": "^3.5.2", + "ethereumjs-util": "^7.1.5", + "merkle-patricia-tree": "^4.2.4" } }, "@ethereumjs/blockchain": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/@ethereumjs/blockchain/-/blockchain-5.5.1.tgz", - "integrity": "sha512-JS2jeKxl3tlaa5oXrZ8mGoVBCz6YqsGG350XVNtHAtNZXKk7pU3rH4xzF2ru42fksMMqzFLzKh9l4EQzmNWDqA==", + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/@ethereumjs/blockchain/-/blockchain-5.5.3.tgz", + "integrity": "sha512-bi0wuNJ1gw4ByNCV56H0Z4Q7D+SxUbwyG12Wxzbvqc89PXLRNR20LBcSUZRKpN0+YCPo6m0XZL/JLio3B52LTw==", "dev": true, "requires": { - "@ethereumjs/block": "^3.6.0", - "@ethereumjs/common": "^2.6.0", + "@ethereumjs/block": "^3.6.2", + "@ethereumjs/common": "^2.6.4", "@ethereumjs/ethash": "^1.1.0", - "debug": "^2.2.0", - "ethereumjs-util": "^7.1.3", + "debug": "^4.3.3", + "ethereumjs-util": "^7.1.5", "level-mem": "^5.0.1", "lru-cache": "^5.1.1", "semaphore-async-await": "^1.5.1" }, "dependencies": { - "@ethereumjs/common": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.0.tgz", - "integrity": "sha512-Cq2qS0FTu6O2VU1sgg+WyU9Ps0M6j/BEMHN+hRaECXCV/r0aI78u4N6p52QW/BDVhwWZpCdrvG8X7NJdzlpNUA==", - "dev": true, - "requires": { - "crc-32": "^1.2.0", - "ethereumjs-util": "^7.1.3" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, "lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -371,22 +311,22 @@ "yallist": "^3.0.2" } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true } } }, "@ethereumjs/common": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.4.0.tgz", - "integrity": "sha512-UdkhFWzWcJCZVsj1O/H8/oqj/0RVYjLc1OhPjBrQdALAkQHpCp8xXI4WLnuGTADqTdJZww0NtgwG+TRPkXt27w==", + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.5.tgz", + "integrity": "sha512-lRyVQOeCDaIVtgfbowla32pzeDv2Obr8oR8Put5RdUBNRGr1VGPGQNGP6elWIpgK3YdpzqTOh4GyUGOureVeeA==", "dev": true, "requires": { "crc-32": "^1.2.0", - "ethereumjs-util": "^7.1.0" + "ethereumjs-util": "^7.1.5" } }, "@ethereumjs/ethash": { @@ -414,893 +354,438 @@ } }, "@ethereumjs/tx": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.3.0.tgz", - "integrity": "sha512-yTwEj2lVzSMgE6Hjw9Oa1DZks/nKTWM8Wn4ykDNapBPua2f4nXO3qKnni86O6lgDj5fVNRqbDsD0yy7/XNGDEA==", + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.5.2.tgz", + "integrity": "sha512-gQDNJWKrSDGu2w7w0PzVXVBNMzb7wwdDOmOqczmhNjqFxFuIbhVJDwiGEnxFNC2/b8ifcZzY7MLcluizohRzNw==", "dev": true, "requires": { - "@ethereumjs/common": "^2.4.0", - "ethereumjs-util": "^7.1.0" + "@ethereumjs/common": "^2.6.4", + "ethereumjs-util": "^7.1.5" } }, "@ethereumjs/vm": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/vm/-/vm-5.6.0.tgz", - "integrity": "sha512-J2m/OgjjiGdWF2P9bj/4LnZQ1zRoZhY8mRNVw/N3tXliGI8ai1sI1mlDPkLpeUUM4vq54gH6n0ZlSpz8U/qlYQ==", + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/@ethereumjs/vm/-/vm-5.9.3.tgz", + "integrity": "sha512-Ha04TeF8goEglr8eL7hkkYyjhzdZS0PsoRURzYlTF6I0VVId5KjKb0N7MrA8GMgheN+UeTncfTgYx52D/WhEmg==", "dev": true, "requires": { - "@ethereumjs/block": "^3.6.0", - "@ethereumjs/blockchain": "^5.5.0", - "@ethereumjs/common": "^2.6.0", - "@ethereumjs/tx": "^3.4.0", + "@ethereumjs/block": "^3.6.3", + "@ethereumjs/blockchain": "^5.5.3", + "@ethereumjs/common": "^2.6.5", + "@ethereumjs/tx": "^3.5.2", "async-eventemitter": "^0.2.4", "core-js-pure": "^3.0.1", - "debug": "^2.2.0", - "ethereumjs-util": "^7.1.3", + "debug": "^4.3.3", + "ethereumjs-util": "^7.1.5", "functional-red-black-tree": "^1.0.1", "mcl-wasm": "^0.7.1", - "merkle-patricia-tree": "^4.2.2", + "merkle-patricia-tree": "^4.2.4", "rustbn.js": "~0.2.0" - }, - "dependencies": { - "@ethereumjs/common": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.0.tgz", - "integrity": "sha512-Cq2qS0FTu6O2VU1sgg+WyU9Ps0M6j/BEMHN+hRaECXCV/r0aI78u4N6p52QW/BDVhwWZpCdrvG8X7NJdzlpNUA==", - "dev": true, - "requires": { - "crc-32": "^1.2.0", - "ethereumjs-util": "^7.1.3" - } - }, - "@ethereumjs/tx": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.4.0.tgz", - "integrity": "sha512-WWUwg1PdjHKZZxPPo274ZuPsJCWV3SqATrEKQP1n2DrVYVP1aZIYpo/mFaA0BDoE0tIQmBeimRCEA0Lgil+yYw==", - "dev": true, - "requires": { - "@ethereumjs/common": "^2.6.0", - "ethereumjs-util": "^7.1.3" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } } }, "@ethersproject/abi": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.4.0.tgz", - "integrity": "sha512-9gU2H+/yK1j2eVMdzm6xvHSnMxk8waIHQGYCZg5uvAyH0rsAzxkModzBSpbAkAuhKFEovC2S9hM4nPuLym8IZw==", - "dev": true, + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", + "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", "requires": { - "@ethersproject/address": "^5.4.0", - "@ethersproject/bignumber": "^5.4.0", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/constants": "^5.4.0", - "@ethersproject/hash": "^5.4.0", - "@ethersproject/keccak256": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/properties": "^5.4.0", - "@ethersproject/strings": "^5.4.0" + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" } }, "@ethersproject/abstract-provider": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.4.1.tgz", - "integrity": "sha512-3EedfKI3LVpjSKgAxoUaI+gB27frKsxzm+r21w9G60Ugk+3wVLQwhi1LsEJAKNV7WoZc8CIpNrATlL1QFABjtQ==", - "dev": true, + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", + "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", "requires": { - "@ethersproject/bignumber": "^5.4.0", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/networks": "^5.4.0", - "@ethersproject/properties": "^5.4.0", - "@ethersproject/transactions": "^5.4.0", - "@ethersproject/web": "^5.4.0" + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0" } }, "@ethersproject/abstract-signer": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.4.1.tgz", - "integrity": "sha512-SkkFL5HVq1k4/25dM+NWP9MILgohJCgGv5xT5AcRruGz4ILpfHeBtO/y6j+Z3UN/PAjDeb4P7E51Yh8wcGNLGA==", - "dev": true, + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", + "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", "requires": { - "@ethersproject/abstract-provider": "^5.4.0", - "@ethersproject/bignumber": "^5.4.0", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/properties": "^5.4.0" + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0" } }, "@ethersproject/address": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.4.0.tgz", - "integrity": "sha512-SD0VgOEkcACEG/C6xavlU1Hy3m5DGSXW3CUHkaaEHbAPPsgi0coP5oNPsxau8eTlZOk/bpa/hKeCNoK5IzVI2Q==", - "dev": true, + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", + "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", "requires": { - "@ethersproject/bignumber": "^5.4.0", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/keccak256": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/rlp": "^5.4.0" + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/rlp": "^5.7.0" } }, "@ethersproject/base64": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.4.0.tgz", - "integrity": "sha512-CjQw6E17QDSSC5jiM9YpF7N1aSCHmYGMt9bWD8PWv6YPMxjsys2/Q8xLrROKI3IWJ7sFfZ8B3flKDTM5wlWuZQ==", - "dev": true, + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", + "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", "requires": { - "@ethersproject/bytes": "^5.4.0" + "@ethersproject/bytes": "^5.7.0" } }, "@ethersproject/basex": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.4.0.tgz", - "integrity": "sha512-J07+QCVJ7np2bcpxydFVf/CuYo9mZ7T73Pe7KQY4c1lRlrixMeblauMxHXD0MPwFmUHZIILDNViVkykFBZylbg==", - "dev": true, + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", + "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", "requires": { - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/properties": "^5.4.0" + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/properties": "^5.7.0" } }, "@ethersproject/bignumber": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.4.1.tgz", - "integrity": "sha512-fJhdxqoQNuDOk6epfM7yD6J8Pol4NUCy1vkaGAkuujZm0+lNow//MKu1hLhRiYV4BsOHyBv5/lsTjF+7hWwhJg==", - "dev": true, + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", + "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", "requires": { - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "bn.js": "^4.11.9" + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "bn.js": "^5.2.1" } }, "@ethersproject/bytes": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.4.0.tgz", - "integrity": "sha512-H60ceqgTHbhzOj4uRc/83SCN9d+BSUnOkrr2intevqdtEMO1JFVZ1XL84OEZV+QjV36OaZYxtnt4lGmxcGsPfA==", - "dev": true, + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", + "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", "requires": { - "@ethersproject/logger": "^5.4.0" + "@ethersproject/logger": "^5.7.0" } }, "@ethersproject/constants": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.4.0.tgz", - "integrity": "sha512-tzjn6S7sj9+DIIeKTJLjK9WGN2Tj0P++Z8ONEIlZjyoTkBuODN+0VfhAyYksKi43l1Sx9tX2VlFfzjfmr5Wl3Q==", - "dev": true, + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", + "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", "requires": { - "@ethersproject/bignumber": "^5.4.0" + "@ethersproject/bignumber": "^5.7.0" } }, "@ethersproject/contracts": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.4.1.tgz", - "integrity": "sha512-m+z2ZgPy4pyR15Je//dUaymRUZq5MtDajF6GwFbGAVmKz/RF+DNIPwF0k5qEcL3wPGVqUjFg2/krlCRVTU4T5w==", - "dev": true, - "requires": { - "@ethersproject/abi": "^5.4.0", - "@ethersproject/abstract-provider": "^5.4.0", - "@ethersproject/abstract-signer": "^5.4.0", - "@ethersproject/address": "^5.4.0", - "@ethersproject/bignumber": "^5.4.0", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/constants": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/properties": "^5.4.0", - "@ethersproject/transactions": "^5.4.0" + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.7.0.tgz", + "integrity": "sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==", + "requires": { + "@ethersproject/abi": "^5.7.0", + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/transactions": "^5.7.0" } }, "@ethersproject/hardware-wallets": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hardware-wallets/-/hardware-wallets-5.5.0.tgz", - "integrity": "sha512-oZh/Ps/ohxFQdKVeMw8wpw0xZpL+ndsRlQwNE3Eki2vLeH2to14de6fNrgETZtAbAhzglH6ES9Nlx1+UuqvvYg==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hardware-wallets/-/hardware-wallets-5.7.0.tgz", + "integrity": "sha512-DjMMXIisRc8xFvEoLoYz1w7JDOYmaz/a0X9sp7Zu668RR8U1zCAyj5ow25HLRW+TCzEC5XiFetTXqS5kXonFCQ==", "requires": { "@ledgerhq/hw-app-eth": "5.27.2", "@ledgerhq/hw-transport": "5.26.0", "@ledgerhq/hw-transport-node-hid": "5.26.0", "@ledgerhq/hw-transport-u2f": "5.26.0", - "ethers": "^5.5.0" - }, - "dependencies": { - "@ethersproject/abi": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.5.0.tgz", - "integrity": "sha512-loW7I4AohP5KycATvc0MgujU6JyCHPqHdeoo9z3Nr9xEiNioxa65ccdm1+fsoJhkuhdRtfcL8cfyGamz2AxZ5w==", - "requires": { - "@ethersproject/address": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/constants": "^5.5.0", - "@ethersproject/hash": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/strings": "^5.5.0" - } - }, - "@ethersproject/abstract-provider": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.5.1.tgz", - "integrity": "sha512-m+MA/ful6eKbxpr99xUYeRvLkfnlqzrF8SZ46d/xFB1A7ZVknYc/sXJG0RcufF52Qn2jeFj1hhcoQ7IXjNKUqg==", - "requires": { - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/networks": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/transactions": "^5.5.0", - "@ethersproject/web": "^5.5.0" - } - }, - "@ethersproject/abstract-signer": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.5.0.tgz", - "integrity": "sha512-lj//7r250MXVLKI7sVarXAbZXbv9P50lgmJQGr2/is82EwEb8r7HrxsmMqAjTsztMYy7ohrIhGMIml+Gx4D3mA==", - "requires": { - "@ethersproject/abstract-provider": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0" - } - }, - "@ethersproject/address": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.5.0.tgz", - "integrity": "sha512-l4Nj0eWlTUh6ro5IbPTgbpT4wRbdH5l8CQf7icF7sb/SI3Nhd9Y9HzhonTSTi6CefI0necIw7LJqQPopPLZyWw==", - "requires": { - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/rlp": "^5.5.0" - } - }, - "@ethersproject/base64": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.5.0.tgz", - "integrity": "sha512-tdayUKhU1ljrlHzEWbStXazDpsx4eg1dBXUSI6+mHlYklOXoXF6lZvw8tnD6oVaWfnMxAgRSKROg3cVKtCcppA==", - "requires": { - "@ethersproject/bytes": "^5.5.0" - } - }, - "@ethersproject/basex": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.5.0.tgz", - "integrity": "sha512-ZIodwhHpVJ0Y3hUCfUucmxKsWQA5TMnavp5j/UOuDdzZWzJlRmuOjcTMIGgHCYuZmHt36BfiSyQPSRskPxbfaQ==", - "requires": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/properties": "^5.5.0" - } - }, - "@ethersproject/bignumber": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.5.0.tgz", - "integrity": "sha512-6Xytlwvy6Rn3U3gKEc1vP7nR92frHkv6wtVr95LFR3jREXiCPzdWxKQ1cx4JGQBXxcguAwjA8murlYN2TSiEbg==", - "requires": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "bn.js": "^4.11.9" - } - }, - "@ethersproject/bytes": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.5.0.tgz", - "integrity": "sha512-ABvc7BHWhZU9PNM/tANm/Qx4ostPGadAuQzWTr3doklZOhDlmcBqclrQe/ZXUIj3K8wC28oYeuRa+A37tX9kog==", - "requires": { - "@ethersproject/logger": "^5.5.0" - } - }, - "@ethersproject/constants": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.5.0.tgz", - "integrity": "sha512-2MsRRVChkvMWR+GyMGY4N1sAX9Mt3J9KykCsgUFd/1mwS0UH1qw+Bv9k1UJb3X3YJYFco9H20pjSlOIfCG5HYQ==", - "requires": { - "@ethersproject/bignumber": "^5.5.0" - } - }, - "@ethersproject/contracts": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.5.0.tgz", - "integrity": "sha512-2viY7NzyvJkh+Ug17v7g3/IJC8HqZBDcOjYARZLdzRxrfGlRgmYgl6xPRKVbEzy1dWKw/iv7chDcS83pg6cLxg==", - "requires": { - "@ethersproject/abi": "^5.5.0", - "@ethersproject/abstract-provider": "^5.5.0", - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/address": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/constants": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/transactions": "^5.5.0" - } - }, - "@ethersproject/hash": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.5.0.tgz", - "integrity": "sha512-dnGVpK1WtBjmnp3mUT0PlU2MpapnwWI0PibldQEq1408tQBAbZpPidkWoVVuNMOl/lISO3+4hXZWCL3YV7qzfg==", - "requires": { - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/address": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/strings": "^5.5.0" - } - }, - "@ethersproject/hdnode": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.5.0.tgz", - "integrity": "sha512-mcSOo9zeUg1L0CoJH7zmxwUG5ggQHU1UrRf8jyTYy6HxdZV+r0PBoL1bxr+JHIPXRzS6u/UW4mEn43y0tmyF8Q==", - "requires": { - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/basex": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/pbkdf2": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/sha2": "^5.5.0", - "@ethersproject/signing-key": "^5.5.0", - "@ethersproject/strings": "^5.5.0", - "@ethersproject/transactions": "^5.5.0", - "@ethersproject/wordlists": "^5.5.0" - } - }, - "@ethersproject/json-wallets": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.5.0.tgz", - "integrity": "sha512-9lA21XQnCdcS72xlBn1jfQdj2A1VUxZzOzi9UkNdnokNKke/9Ya2xA9aIK1SC3PQyBDLt4C+dfps7ULpkvKikQ==", - "requires": { - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/address": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/hdnode": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/pbkdf2": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/random": "^5.5.0", - "@ethersproject/strings": "^5.5.0", - "@ethersproject/transactions": "^5.5.0", - "aes-js": "3.0.0", - "scrypt-js": "3.0.1" - } - }, - "@ethersproject/keccak256": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.5.0.tgz", - "integrity": "sha512-5VoFCTjo2rYbBe1l2f4mccaRFN/4VQEYFwwn04aJV2h7qf4ZvI2wFxUE1XOX+snbwCLRzIeikOqtAoPwMza9kg==", - "requires": { - "@ethersproject/bytes": "^5.5.0", - "js-sha3": "0.8.0" - } - }, - "@ethersproject/logger": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.5.0.tgz", - "integrity": "sha512-rIY/6WPm7T8n3qS2vuHTUBPdXHl+rGxWxW5okDfo9J4Z0+gRRZT0msvUdIJkE4/HS29GUMziwGaaKO2bWONBrg==" - }, - "@ethersproject/networks": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.5.2.tgz", - "integrity": "sha512-NEqPxbGBfy6O3x4ZTISb90SjEDkWYDUbEeIFhJly0F7sZjoQMnj5KYzMSkMkLKZ+1fGpx00EDpHQCy6PrDupkQ==", - "requires": { - "@ethersproject/logger": "^5.5.0" - } - }, - "@ethersproject/pbkdf2": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.5.0.tgz", - "integrity": "sha512-SaDvQFvXPnz1QGpzr6/HToLifftSXGoXrbpZ6BvoZhmx4bNLHrxDe8MZisuecyOziP1aVEwzC2Hasj+86TgWVg==", - "requires": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/sha2": "^5.5.0" - } - }, - "@ethersproject/properties": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.5.0.tgz", - "integrity": "sha512-l3zRQg3JkD8EL3CPjNK5g7kMx4qSwiR60/uk5IVjd3oq1MZR5qUg40CNOoEJoX5wc3DyY5bt9EbMk86C7x0DNA==", - "requires": { - "@ethersproject/logger": "^5.5.0" - } - }, - "@ethersproject/providers": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.5.2.tgz", - "integrity": "sha512-hkbx7x/MKcRjyrO4StKXCzCpWer6s97xnm34xkfPiarhtEUVAN4TBBpamM+z66WcTt7H5B53YwbRj1n7i8pZoQ==", - "requires": { - "@ethersproject/abstract-provider": "^5.5.0", - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/address": "^5.5.0", - "@ethersproject/basex": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/constants": "^5.5.0", - "@ethersproject/hash": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/networks": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/random": "^5.5.0", - "@ethersproject/rlp": "^5.5.0", - "@ethersproject/sha2": "^5.5.0", - "@ethersproject/strings": "^5.5.0", - "@ethersproject/transactions": "^5.5.0", - "@ethersproject/web": "^5.5.0", - "bech32": "1.1.4", - "ws": "7.4.6" - } - }, - "@ethersproject/random": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.5.1.tgz", - "integrity": "sha512-YaU2dQ7DuhL5Au7KbcQLHxcRHfgyNgvFV4sQOo0HrtW3Zkrc9ctWNz8wXQ4uCSfSDsqX2vcjhroxU5RQRV0nqA==", - "requires": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0" - } - }, - "@ethersproject/rlp": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.5.0.tgz", - "integrity": "sha512-hLv8XaQ8PTI9g2RHoQGf/WSxBfTB/NudRacbzdxmst5VHAqd1sMibWG7SENzT5Dj3yZ3kJYx+WiRYEcQTAkcYA==", - "requires": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0" - } - }, - "@ethersproject/sha2": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.5.0.tgz", - "integrity": "sha512-B5UBoglbCiHamRVPLA110J+2uqsifpZaTmid2/7W5rbtYVz6gus6/hSDieIU/6gaKIDcOj12WnOdiymEUHIAOA==", - "requires": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "hash.js": "1.1.7" - } - }, - "@ethersproject/signing-key": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.5.0.tgz", - "integrity": "sha512-5VmseH7qjtNmDdZBswavhotYbWB0bOwKIlOTSlX14rKn5c11QmJwGt4GHeo7NrL/Ycl7uo9AHvEqs5xZgFBTng==", - "requires": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "bn.js": "^4.11.9", - "elliptic": "6.5.4", - "hash.js": "1.1.7" - } - }, - "@ethersproject/solidity": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.5.0.tgz", - "integrity": "sha512-9NgZs9LhGMj6aCtHXhtmFQ4AN4sth5HuFXVvAQtzmm0jpSCNOTGtrHZJAeYTh7MBjRR8brylWZxBZR9zDStXbw==", - "requires": { - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/sha2": "^5.5.0", - "@ethersproject/strings": "^5.5.0" - } - }, - "@ethersproject/strings": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.5.0.tgz", - "integrity": "sha512-9fy3TtF5LrX/wTrBaT8FGE6TDJyVjOvXynXJz5MT5azq+E6D92zuKNx7i29sWW2FjVOaWjAsiZ1ZWznuduTIIQ==", - "requires": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/constants": "^5.5.0", - "@ethersproject/logger": "^5.5.0" - } - }, - "@ethersproject/transactions": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.5.0.tgz", - "integrity": "sha512-9RZYSKX26KfzEd/1eqvv8pLauCKzDTub0Ko4LfIgaERvRuwyaNV78mJs7cpIgZaDl6RJui4o49lHwwCM0526zA==", - "requires": { - "@ethersproject/address": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/constants": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/rlp": "^5.5.0", - "@ethersproject/signing-key": "^5.5.0" - } - }, - "@ethersproject/units": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.5.0.tgz", - "integrity": "sha512-7+DpjiZk4v6wrikj+TCyWWa9dXLNU73tSTa7n0TSJDxkYbV3Yf1eRh9ToMLlZtuctNYu9RDNNy2USq3AdqSbag==", - "requires": { - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/constants": "^5.5.0", - "@ethersproject/logger": "^5.5.0" - } - }, - "@ethersproject/wallet": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.5.0.tgz", - "integrity": "sha512-Mlu13hIctSYaZmUOo7r2PhNSd8eaMPVXe1wxrz4w4FCE4tDYBywDH+bAR1Xz2ADyXGwqYMwstzTrtUVIsKDO0Q==", - "requires": { - "@ethersproject/abstract-provider": "^5.5.0", - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/address": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/hash": "^5.5.0", - "@ethersproject/hdnode": "^5.5.0", - "@ethersproject/json-wallets": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/random": "^5.5.0", - "@ethersproject/signing-key": "^5.5.0", - "@ethersproject/transactions": "^5.5.0", - "@ethersproject/wordlists": "^5.5.0" - } - }, - "@ethersproject/web": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.5.1.tgz", - "integrity": "sha512-olvLvc1CB12sREc1ROPSHTdFCdvMh0J5GSJYiQg2D0hdD4QmJDy8QYDb1CvoqD/bF1c++aeKv2sR5uduuG9dQg==", - "requires": { - "@ethersproject/base64": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/strings": "^5.5.0" - } - }, - "@ethersproject/wordlists": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.5.0.tgz", - "integrity": "sha512-bL0UTReWDiaQJJYOC9sh/XcRu/9i2jMrzf8VLRmPKx58ckSlOJiohODkECCO50dtLZHcGU6MLXQ4OOrgBwP77Q==", - "requires": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/hash": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/strings": "^5.5.0" - } - }, - "ethers": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.5.3.tgz", - "integrity": "sha512-fTT4WT8/hTe/BLwRUtl7I5zlpF3XC3P/Xwqxc5AIP2HGlH15qpmjs0Ou78az93b1rLITzXLFxoNX63B8ZbUd7g==", - "requires": { - "@ethersproject/abi": "5.5.0", - "@ethersproject/abstract-provider": "5.5.1", - "@ethersproject/abstract-signer": "5.5.0", - "@ethersproject/address": "5.5.0", - "@ethersproject/base64": "5.5.0", - "@ethersproject/basex": "5.5.0", - "@ethersproject/bignumber": "5.5.0", - "@ethersproject/bytes": "5.5.0", - "@ethersproject/constants": "5.5.0", - "@ethersproject/contracts": "5.5.0", - "@ethersproject/hash": "5.5.0", - "@ethersproject/hdnode": "5.5.0", - "@ethersproject/json-wallets": "5.5.0", - "@ethersproject/keccak256": "5.5.0", - "@ethersproject/logger": "5.5.0", - "@ethersproject/networks": "5.5.2", - "@ethersproject/pbkdf2": "5.5.0", - "@ethersproject/properties": "5.5.0", - "@ethersproject/providers": "5.5.2", - "@ethersproject/random": "5.5.1", - "@ethersproject/rlp": "5.5.0", - "@ethersproject/sha2": "5.5.0", - "@ethersproject/signing-key": "5.5.0", - "@ethersproject/solidity": "5.5.0", - "@ethersproject/strings": "5.5.0", - "@ethersproject/transactions": "5.5.0", - "@ethersproject/units": "5.5.0", - "@ethersproject/wallet": "5.5.0", - "@ethersproject/web": "5.5.1", - "@ethersproject/wordlists": "5.5.0" - } - }, - "js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" - } + "ethers": "^5.7.0" } }, "@ethersproject/hash": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.4.0.tgz", - "integrity": "sha512-xymAM9tmikKgbktOCjW60Z5sdouiIIurkZUr9oW5NOex5uwxrbsYG09kb5bMcNjlVeJD3yPivTNzViIs1GCbqA==", - "dev": true, + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", + "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", "requires": { - "@ethersproject/abstract-signer": "^5.4.0", - "@ethersproject/address": "^5.4.0", - "@ethersproject/bignumber": "^5.4.0", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/keccak256": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/properties": "^5.4.0", - "@ethersproject/strings": "^5.4.0" + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" } }, "@ethersproject/hdnode": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.4.0.tgz", - "integrity": "sha512-pKxdS0KAaeVGfZPp1KOiDLB0jba11tG6OP1u11QnYfb7pXn6IZx0xceqWRr6ygke8+Kw74IpOoSi7/DwANhy8Q==", - "dev": true, - "requires": { - "@ethersproject/abstract-signer": "^5.4.0", - "@ethersproject/basex": "^5.4.0", - "@ethersproject/bignumber": "^5.4.0", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/pbkdf2": "^5.4.0", - "@ethersproject/properties": "^5.4.0", - "@ethersproject/sha2": "^5.4.0", - "@ethersproject/signing-key": "^5.4.0", - "@ethersproject/strings": "^5.4.0", - "@ethersproject/transactions": "^5.4.0", - "@ethersproject/wordlists": "^5.4.0" + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", + "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", + "requires": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/basex": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/pbkdf2": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wordlists": "^5.7.0" } }, "@ethersproject/json-wallets": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.4.0.tgz", - "integrity": "sha512-igWcu3fx4aiczrzEHwG1xJZo9l1cFfQOWzTqwRw/xcvxTk58q4f9M7cjh51EKphMHvrJtcezJ1gf1q1AUOfEQQ==", - "dev": true, - "requires": { - "@ethersproject/abstract-signer": "^5.4.0", - "@ethersproject/address": "^5.4.0", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/hdnode": "^5.4.0", - "@ethersproject/keccak256": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/pbkdf2": "^5.4.0", - "@ethersproject/properties": "^5.4.0", - "@ethersproject/random": "^5.4.0", - "@ethersproject/strings": "^5.4.0", - "@ethersproject/transactions": "^5.4.0", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz", + "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==", + "requires": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hdnode": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/pbkdf2": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", "aes-js": "3.0.0", "scrypt-js": "3.0.1" } }, "@ethersproject/keccak256": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.4.0.tgz", - "integrity": "sha512-FBI1plWet+dPUvAzPAeHzRKiPpETQzqSUWR1wXJGHVWi4i8bOSrpC3NwpkPjgeXG7MnugVc1B42VbfnQikyC/A==", - "dev": true, + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", + "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", "requires": { - "@ethersproject/bytes": "^5.4.0", - "js-sha3": "0.5.7" + "@ethersproject/bytes": "^5.7.0", + "js-sha3": "0.8.0" } }, "@ethersproject/logger": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.4.0.tgz", - "integrity": "sha512-xYdWGGQ9P2cxBayt64d8LC8aPFJk6yWCawQi/4eJ4+oJdMMjEBMrIcIMZ9AxhwpPVmnBPrsB10PcXGmGAqgUEQ==", - "dev": true + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", + "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==" }, "@ethersproject/networks": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.4.2.tgz", - "integrity": "sha512-eekOhvJyBnuibfJnhtK46b8HimBc5+4gqpvd1/H9LEl7Q7/qhsIhM81dI9Fcnjpk3jB1aTy6bj0hz3cifhNeYw==", - "dev": true, + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.0.tgz", + "integrity": "sha512-MG6oHSQHd4ebvJrleEQQ4HhVu8Ichr0RDYEfHzsVAVjHNM+w36x9wp9r+hf1JstMXtseXDtkiVoARAG6M959AA==", "requires": { - "@ethersproject/logger": "^5.4.0" + "@ethersproject/logger": "^5.7.0" } }, "@ethersproject/pbkdf2": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.4.0.tgz", - "integrity": "sha512-x94aIv6tiA04g6BnazZSLoRXqyusawRyZWlUhKip2jvoLpzJuLb//KtMM6PEovE47pMbW+Qe1uw+68ameJjB7g==", - "dev": true, + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", + "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", "requires": { - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/sha2": "^5.4.0" + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/sha2": "^5.7.0" } }, "@ethersproject/properties": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.4.0.tgz", - "integrity": "sha512-7jczalGVRAJ+XSRvNA6D5sAwT4gavLq3OXPuV/74o3Rd2wuzSL035IMpIMgei4CYyBdialJMrTqkOnzccLHn4A==", - "dev": true, + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", + "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", "requires": { - "@ethersproject/logger": "^5.4.0" + "@ethersproject/logger": "^5.7.0" } }, "@ethersproject/providers": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.4.3.tgz", - "integrity": "sha512-VURwkaWPoUj7jq9NheNDT5Iyy64Qcyf6BOFDwVdHsmLmX/5prNjFrgSX3GHPE4z1BRrVerDxe2yayvXKFm/NNg==", - "dev": true, - "requires": { - "@ethersproject/abstract-provider": "^5.4.0", - "@ethersproject/abstract-signer": "^5.4.0", - "@ethersproject/address": "^5.4.0", - "@ethersproject/basex": "^5.4.0", - "@ethersproject/bignumber": "^5.4.0", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/constants": "^5.4.0", - "@ethersproject/hash": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/networks": "^5.4.0", - "@ethersproject/properties": "^5.4.0", - "@ethersproject/random": "^5.4.0", - "@ethersproject/rlp": "^5.4.0", - "@ethersproject/sha2": "^5.4.0", - "@ethersproject/strings": "^5.4.0", - "@ethersproject/transactions": "^5.4.0", - "@ethersproject/web": "^5.4.0", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.0.tgz", + "integrity": "sha512-+TTrrINMzZ0aXtlwO/95uhAggKm4USLm1PbeCBR/3XZ7+Oey+3pMyddzZEyRhizHpy1HXV0FRWRMI1O3EGYibA==", + "requires": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/basex": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0", "bech32": "1.1.4", "ws": "7.4.6" } }, "@ethersproject/random": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.4.0.tgz", - "integrity": "sha512-pnpWNQlf0VAZDEOVp1rsYQosmv2o0ITS/PecNw+mS2/btF8eYdspkN0vIXrCMtkX09EAh9bdk8GoXmFXM1eAKw==", - "dev": true, + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", + "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", "requires": { - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/logger": "^5.4.0" + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" } }, "@ethersproject/rlp": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.4.0.tgz", - "integrity": "sha512-0I7MZKfi+T5+G8atId9QaQKHRvvasM/kqLyAH4XxBCBchAooH2EX5rL9kYZWwcm3awYV+XC7VF6nLhfeQFKVPg==", - "dev": true, + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", + "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", "requires": { - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/logger": "^5.4.0" + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" } }, "@ethersproject/sha2": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.4.0.tgz", - "integrity": "sha512-siheo36r1WD7Cy+bDdE1BJ8y0bDtqXCOxRMzPa4bV1TGt/eTUUt03BHoJNB6reWJD8A30E/pdJ8WFkq+/uz4Gg==", - "dev": true, + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz", + "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==", "requires": { - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/logger": "^5.4.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", "hash.js": "1.1.7" } }, "@ethersproject/signing-key": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.4.0.tgz", - "integrity": "sha512-q8POUeywx6AKg2/jX9qBYZIAmKSB4ubGXdQ88l40hmATj29JnG5pp331nAWwwxPn2Qao4JpWHNZsQN+bPiSW9A==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/properties": "^5.4.0", - "bn.js": "^4.11.9", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", + "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", + "requires": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "bn.js": "^5.2.1", "elliptic": "6.5.4", "hash.js": "1.1.7" } }, "@ethersproject/solidity": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.4.0.tgz", - "integrity": "sha512-XFQTZ7wFSHOhHcV1DpcWj7VXECEiSrBuv7JErJvB9Uo+KfCdc3QtUZV+Vjh/AAaYgezUEKbCtE6Khjm44seevQ==", - "dev": true, + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", + "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", "requires": { - "@ethersproject/bignumber": "^5.4.0", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/keccak256": "^5.4.0", - "@ethersproject/sha2": "^5.4.0", - "@ethersproject/strings": "^5.4.0" + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/strings": "^5.7.0" } }, "@ethersproject/strings": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.4.0.tgz", - "integrity": "sha512-k/9DkH5UGDhv7aReXLluFG5ExurwtIpUfnDNhQA29w896Dw3i4uDTz01Quaptbks1Uj9kI8wo9tmW73wcIEaWA==", - "dev": true, + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", + "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", "requires": { - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/constants": "^5.4.0", - "@ethersproject/logger": "^5.4.0" + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" } }, "@ethersproject/transactions": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.4.0.tgz", - "integrity": "sha512-s3EjZZt7xa4BkLknJZ98QGoIza94rVjaEed0rzZ/jB9WrIuu/1+tjvYCWzVrystXtDswy7TPBeIepyXwSYa4WQ==", - "dev": true, + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz", + "integrity": "sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==", "requires": { - "@ethersproject/address": "^5.4.0", - "@ethersproject/bignumber": "^5.4.0", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/constants": "^5.4.0", - "@ethersproject/keccak256": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/properties": "^5.4.0", - "@ethersproject/rlp": "^5.4.0", - "@ethersproject/signing-key": "^5.4.0" + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0" } }, "@ethersproject/units": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.4.0.tgz", - "integrity": "sha512-Z88krX40KCp+JqPCP5oPv5p750g+uU6gopDYRTBGcDvOASh6qhiEYCRatuM/suC4S2XW9Zz90QI35MfSrTIaFg==", - "dev": true, + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", + "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", "requires": { - "@ethersproject/bignumber": "^5.4.0", - "@ethersproject/constants": "^5.4.0", - "@ethersproject/logger": "^5.4.0" + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" } }, "@ethersproject/wallet": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.4.0.tgz", - "integrity": "sha512-wU29majLjM6AjCjpat21mPPviG+EpK7wY1+jzKD0fg3ui5fgedf2zEu1RDgpfIMsfn8fJHJuzM4zXZ2+hSHaSQ==", - "dev": true, - "requires": { - "@ethersproject/abstract-provider": "^5.4.0", - "@ethersproject/abstract-signer": "^5.4.0", - "@ethersproject/address": "^5.4.0", - "@ethersproject/bignumber": "^5.4.0", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/hash": "^5.4.0", - "@ethersproject/hdnode": "^5.4.0", - "@ethersproject/json-wallets": "^5.4.0", - "@ethersproject/keccak256": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/properties": "^5.4.0", - "@ethersproject/random": "^5.4.0", - "@ethersproject/signing-key": "^5.4.0", - "@ethersproject/transactions": "^5.4.0", - "@ethersproject/wordlists": "^5.4.0" + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", + "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", + "requires": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/hdnode": "^5.7.0", + "@ethersproject/json-wallets": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wordlists": "^5.7.0" } }, "@ethersproject/web": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.4.0.tgz", - "integrity": "sha512-1bUusGmcoRLYgMn6c1BLk1tOKUIFuTg8j+6N8lYlbMpDesnle+i3pGSagGNvwjaiLo4Y5gBibwctpPRmjrh4Og==", - "dev": true, + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.0.tgz", + "integrity": "sha512-ApHcbbj+muRASVDSCl/tgxaH2LBkRMEYfLOLVa0COipx0+nlu0QKet7U2lEg0vdkh8XRSLf2nd1f1Uk9SrVSGA==", "requires": { - "@ethersproject/base64": "^5.4.0", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/properties": "^5.4.0", - "@ethersproject/strings": "^5.4.0" + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" } }, "@ethersproject/wordlists": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.4.0.tgz", - "integrity": "sha512-FemEkf6a+EBKEPxlzeVgUaVSodU7G0Na89jqKjmWMlDB0tomoU8RlEMgUvXyqtrg8N4cwpLh8nyRnm1Nay1isA==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", + "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", + "requires": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "dev": true, "requires": { - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/hash": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/properties": "^5.4.0", - "@ethersproject/strings": "^5.4.0" + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" } }, "@ledgerhq/cryptoassets": { @@ -1320,16 +805,6 @@ "@ledgerhq/logs": "^5.50.0", "rxjs": "6", "semver": "^7.3.5" - }, - "dependencies": { - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "requires": { - "lru-cache": "^6.0.0" - } - } } }, "@ledgerhq/errors": { @@ -1428,74 +903,197 @@ "resolved": "https://registry.npmjs.org/@ledgerhq/logs/-/logs-5.50.0.tgz", "integrity": "sha512-swKHYCOZUGyVt4ge0u8a7AwNcA//h4nx5wIi0sruGye1IJ5Cva0GyK9L2/WdX+kWVTKp92ZiEo1df31lrWGPgA==" }, + "@metamask/eth-sig-util": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz", + "integrity": "sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==", + "dev": true, + "requires": { + "ethereumjs-abi": "^0.6.8", + "ethereumjs-util": "^6.2.1", + "ethjs-util": "^0.1.6", + "tweetnacl": "^1.0.3", + "tweetnacl-util": "^0.15.1" + }, + "dependencies": { + "@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "ethereumjs-util": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", + "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", + "dev": true, + "requires": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", + "dev": true + } + } + }, + "@noble/hashes": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.1.2.tgz", + "integrity": "sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA==", + "dev": true + }, + "@noble/secp256k1": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.6.3.tgz", + "integrity": "sha512-T04e4iTurVy7I8Sw4+c5OSN9/RkPlo1uKxAomtxQNLq8j1uPAqnsqG1bqvY3Jv7c13gyr6dui0zmh/I3+f/JaQ==", + "dev": true + }, "@nodelib/fs.scandir": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", - "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "requires": { - "@nodelib/fs.stat": "2.0.4", + "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "@nodelib/fs.stat": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz", - "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true }, "@nodelib/fs.walk": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz", - "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, "requires": { - "@nodelib/fs.scandir": "2.1.4", + "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "@nomiclabs/hardhat-ethers": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.0.4.tgz", - "integrity": "sha512-7LMR344TkdCYkMVF9LuC9VU2NBIi84akQiwqm7OufpWaDgHbWhuanY53rk3SVAW0E4HBk5xn5wl5+bN5f+Mq5w==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.1.1.tgz", + "integrity": "sha512-Gg0IFkT/DW3vOpih4/kMjeZCLYqtfgECLeLXTs7ZDPzcK0cfoc5wKk4nq5n/izCUzdhidO/Utd6ptF9JrWwWVA==", "dev": true }, "@nomiclabs/hardhat-etherscan": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.0.3.tgz", - "integrity": "sha512-OfNtUKc/ZwzivmZnnpwWREfaYncXteKHskn3yDnz+fPBZ6wfM4GR+d5RwjREzYFWE+o5iR9ruXhWw/8fejWM9g==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.1.0.tgz", + "integrity": "sha512-JroYgfN1AlYFkQTQ3nRwFi4o8NtZF7K/qFR2dxDUgHbCtIagkUseca9L4E/D2ScUm4XT40+8PbCdqZi+XmHyQA==", "dev": true, "requires": { "@ethersproject/abi": "^5.1.2", "@ethersproject/address": "^5.0.2", "cbor": "^5.0.2", + "chalk": "^2.4.2", "debug": "^4.1.1", "fs-extra": "^7.0.1", + "lodash": "^4.17.11", "semver": "^6.3.0", - "undici": "^4.14.1" + "table": "^6.8.0", + "undici": "^5.4.0" }, "dependencies": { - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "ms": "2.1.2" + "color-convert": "^1.9.0" } }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "cbor": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/cbor/-/cbor-5.2.0.tgz", + "integrity": "sha512-5IMhi9e1QU76ppa5/ajP1BmMWZ2FHkhAhjeVKQ/EFCgYSEaeVaoGtL7cxJskf9oCCk+XjzaIdc3IuU/dbA/o2A==", + "dev": true, + "requires": { + "bignumber.js": "^9.0.1", + "nofilter": "^1.0.4" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true - } - } - }, - "@nomiclabs/hardhat-waffle": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-waffle/-/hardhat-waffle-2.0.1.tgz", - "integrity": "sha512-2YR2V5zTiztSH9n8BYWgtv3Q+EL0N5Ltm1PAr5z20uAY4SkkfylJ98CIqt18XFvxTD5x4K2wKBzddjV9ViDAZQ==", + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "nofilter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-1.0.4.tgz", + "integrity": "sha512-N8lidFp+fCz+TD51+haYdbDGrcBWwuHX40F5+z0qkUjMJ5Tp+rdSuAkMJ9N9eoolDlEVTf6u5icM+cNKkKW2mA==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@nomiclabs/hardhat-waffle": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-waffle/-/hardhat-waffle-2.0.3.tgz", + "integrity": "sha512-049PHSnI1CZq6+XTbrMbMv5NaL7cednTfPenx02k3cEh8wBMLa6ys++dBETJa6JjfwgA9nBhhHQ173LJv6k2Pg==", "dev": true, "requires": { "@types/sinon-chai": "^3.2.3", @@ -1523,77 +1121,132 @@ "@oclif/parser": "^3.8.6", "debug": "^4.1.1", "semver": "^7.3.2" + } + }, + "@oclif/config": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/@oclif/config/-/config-1.18.3.tgz", + "integrity": "sha512-sBpko86IrTscc39EvHUhL+c++81BVTsIZ3ETu/vG+cCdi0N6vb2DoahR67A9FI2CGnxRRHjnTfa3m6LulwNATA==", + "dev": true, + "requires": { + "@oclif/errors": "^1.3.5", + "@oclif/parser": "^3.8.0", + "debug": "^4.1.1", + "globby": "^11.0.1", + "is-wsl": "^2.1.1", + "tslib": "^2.3.1" }, "dependencies": { - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, "requires": { - "ms": "2.1.2" + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" } }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", + "dev": true } } }, - "@oclif/config": { - "version": "1.18.2", - "resolved": "https://registry.npmjs.org/@oclif/config/-/config-1.18.2.tgz", - "integrity": "sha512-cE3qfHWv8hGRCP31j7fIS7BfCflm/BNZ2HNqHexH+fDrdF2f1D5S8VmXWLC77ffv3oDvWyvE9AZeR0RfmHCCaA==", + "@oclif/core": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/@oclif/core/-/core-1.16.0.tgz", + "integrity": "sha512-xtqhAbjQHBcz+xQpEHJ3eJEVfRQ4zl41Yw5gw/N+D1jgaIUrHTxCY/sfTvhw93LAQo7B++ozHzSb7DISFXsQFQ==", "dev": true, "requires": { - "@oclif/errors": "^1.3.3", - "@oclif/parser": "^3.8.0", - "debug": "^4.1.1", - "globby": "^11.0.1", - "is-wsl": "^2.1.1", - "tslib": "^2.0.0" + "@oclif/linewrap": "^1.0.0", + "@oclif/screen": "^3.0.2", + "ansi-escapes": "^4.3.2", + "ansi-styles": "^4.3.0", + "cardinal": "^2.1.1", + "chalk": "^4.1.2", + "clean-stack": "^3.0.1", + "cli-progress": "^3.10.0", + "debug": "^4.3.4", + "ejs": "^3.1.6", + "fs-extra": "^9.1.0", + "get-package-type": "^0.1.0", + "globby": "^11.1.0", + "hyperlinker": "^1.0.0", + "indent-string": "^4.0.0", + "is-wsl": "^2.2.0", + "js-yaml": "^3.14.1", + "natural-orderby": "^2.0.3", + "object-treeify": "^1.1.33", + "password-prompt": "^1.1.2", + "semver": "^7.3.7", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "supports-color": "^8.1.1", + "supports-hyperlinks": "^2.2.0", + "tslib": "^2.3.1", + "widest-line": "^3.1.0", + "wrap-ansi": "^7.0.0" }, "dependencies": { - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "requires": { - "ms": "2.1.2" + "sprintf-js": "~1.0.2" } }, - "fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "clean-stack": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-3.0.1.tgz", + "integrity": "sha512-lR9wNiMRcVQjSB3a7xXGLuz4cr4wJuuXlaAEbRutGowQTmlp7R72/DOgN21e8jdwblMWl9UOJMJXarX94pzKdg==", "dev": true, "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" + "escape-string-regexp": "4.0.0" } }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", "dev": true, "requires": { - "is-glob": "^4.0.1" + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" } }, "globby": { @@ -1616,17 +1269,89 @@ "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, "tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", + "dev": true + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } } } }, @@ -1649,34 +1374,19 @@ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "clean-stack": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-3.0.1.tgz", + "integrity": "sha512-lR9wNiMRcVQjSB3a7xXGLuz4cr4wJuuXlaAEbRutGowQTmlp7R72/DOgN21e8jdwblMWl9UOJMJXarX94pzKdg==", "dev": true, "requires": { - "color-name": "~1.1.4" + "escape-string-regexp": "4.0.0" } }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, "fs-extra": { @@ -1746,56 +1456,44 @@ "wrap-ansi": "^6.2.0" }, "dependencies": { + "@oclif/config": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/@oclif/config/-/config-1.18.2.tgz", + "integrity": "sha512-cE3qfHWv8hGRCP31j7fIS7BfCflm/BNZ2HNqHexH+fDrdF2f1D5S8VmXWLC77ffv3oDvWyvE9AZeR0RfmHCCaA==", + "dev": true, + "requires": { + "@oclif/errors": "^1.3.3", + "@oclif/parser": "^3.8.0", + "debug": "^4.1.1", + "globby": "^11.0.1", + "is-wsl": "^2.1.1", + "tslib": "^2.0.0" + } + }, "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, "requires": { - "color-name": "~1.1.4" + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" } }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true }, "is-fullwidth-code-point": { @@ -1804,6 +1502,12 @@ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, "string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -1824,14 +1528,11 @@ "ansi-regex": "^5.0.1" } }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } + "tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", + "dev": true }, "wrap-ansi": { "version": "6.2.0", @@ -1853,263 +1554,66 @@ "dev": true }, "@oclif/parser": { - "version": "3.8.6", - "resolved": "https://registry.npmjs.org/@oclif/parser/-/parser-3.8.6.tgz", - "integrity": "sha512-tXb0NKgSgNxmf6baN6naK+CCwOueaFk93FG9u202U7mTBHUKsioOUlw1SG/iPi9aJM3WE4pHLXmty59pci0OEw==", + "version": "3.8.7", + "resolved": "https://registry.npmjs.org/@oclif/parser/-/parser-3.8.7.tgz", + "integrity": "sha512-b11xBmIUK+LuuwVGJpFs4LwQN2xj2cBWj2c4z1FtiXGrJ85h9xV6q+k136Hw0tGg1jQoRXuvuBnqQ7es7vO9/Q==", "dev": true, "requires": { - "@oclif/errors": "^1.2.2", + "@oclif/errors": "^1.3.5", "@oclif/linewrap": "^1.0.0", "chalk": "^4.1.0", - "tslib": "^2.0.0" + "tslib": "^2.3.1" }, "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", "dev": true } } }, "@oclif/plugin-help": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@oclif/plugin-help/-/plugin-help-3.3.1.tgz", - "integrity": "sha512-QuSiseNRJygaqAdABYFWn/H1CwIZCp9zp/PLid6yXvy6VcQV7OenEFF5XuYaCvSARe2Tg9r8Jqls5+fw1A9CbQ==", + "version": "5.1.12", + "resolved": "https://registry.npmjs.org/@oclif/plugin-help/-/plugin-help-5.1.12.tgz", + "integrity": "sha512-HvH/RubJxqCinP0vUWQLTOboT+SfjfL8h40s+PymkWaldIcXlpoRaJX50vz+SjZIs7uewZwEk8fzLqpF/BWXlg==", "dev": true, "requires": { - "@oclif/command": "^1.8.15", - "@oclif/config": "1.18.2", - "@oclif/errors": "1.3.5", - "@oclif/help": "^1.0.1", - "chalk": "^4.1.2", - "indent-string": "^4.0.0", - "lodash": "^4.17.21", - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "widest-line": "^3.1.0", - "wrap-ansi": "^6.2.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - } + "@oclif/core": "^1.3.6" } }, + "@oclif/screen": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@oclif/screen/-/screen-3.0.2.tgz", + "integrity": "sha512-S/SF/XYJeevwIgHFmVDAFRUvM3m+OjhvCAYMk78ZJQCYCQ5wS7j+LTt1ZEv2jpEEGg2tx/F6TYYWxddNAYHrFQ==", + "dev": true + }, "@openzeppelin/contracts": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.3.2.tgz", - "integrity": "sha512-AybF1cesONZStg5kWf6ao9OlqTZuPqddvprc0ky7lrUVOjXeKpmQ2Y9FK+6ygxasb+4aic4O5pneFBfwVsRRRg==" + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.3.3.tgz", + "integrity": "sha512-tDBopO1c98Yk7Cv/PZlHqrvtVjlgK5R4J6jxLwoO7qxK4xqOiZG+zSkIvGFpPZ0ikc3QOED3plgdqjgNTnBc7g==" }, "@openzeppelin/contracts-upgradeable": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.3.2.tgz", - "integrity": "sha512-i/pOaOtcqDk4UqsrOv735uYyTbn6dvfiuVu5hstsgV6c4ZKUtu88/31zT2BzkCg+3JfcwOfgg2TtRKVKKZIGkQ==" + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.3.3.tgz", + "integrity": "sha512-2ELsJkBQ0xirVQnx0utl3N+/iTPF+S0r3j0IVQIMG0HgAWreFXumY+yhGcwSV5JZ/yNNAXWR4mjIYRH/FEgu2Q==" }, "@openzeppelin/hardhat-upgrades": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/@openzeppelin/hardhat-upgrades/-/hardhat-upgrades-1.13.0.tgz", - "integrity": "sha512-0pSSUimzd4JL/mKhdNcczDGhv6ELPcI8cWWyCYjTwKoI3wL+AnRrbIQ+yrpHVpia3dAmI/+1sLOz70HvFKNzNQ==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/hardhat-upgrades/-/hardhat-upgrades-1.20.0.tgz", + "integrity": "sha512-ign7fc/ZdPe+KAYCB91619o+wlBr7sIEEt1nqLhoXAJ9f0qVuXkwAaTdLB0MTSWH85TzlUUT2fTJp1ZnZ1o4LQ==", "requires": { - "@openzeppelin/upgrades-core": "^1.11.0", - "chalk": "^4.1.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } + "@openzeppelin/upgrades-core": "^1.18.0", + "chalk": "^4.1.0", + "debug": "^4.1.1", + "proper-lockfile": "^4.1.1" } }, "@openzeppelin/upgrades-core": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@openzeppelin/upgrades-core/-/upgrades-core-1.11.0.tgz", - "integrity": "sha512-gZ5/hXpxmi/3JeURgcWshUBOIBaYwhZ/KbbHdu0VZuvF2Yg3VVRMhspA5mSR26uKrWBg6tgQQ67Shgbq+XbxqQ==", + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/upgrades-core/-/upgrades-core-1.18.0.tgz", + "integrity": "sha512-fFp5sscGC876yhq7BU595LG45yky21sZFa6cDJigluUjAyJSPoLwF7GD9bSwQMMo4jC7ii1UJBtLipUxN6PVTA==", "requires": { - "bn.js": "^5.1.2", "cbor": "^8.0.0", "chalk": "^4.1.0", "compare-versions": "^4.0.0", @@ -2117,82 +1621,6 @@ "ethereumjs-util": "^7.0.3", "proper-lockfile": "^4.1.1", "solidity-ast": "^0.4.15" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - }, - "cbor": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz", - "integrity": "sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==", - "requires": { - "nofilter": "^3.1.0" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "requires": { - "ms": "2.1.2" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "nofilter": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", - "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } } }, "@resolver-engine/core": { @@ -2204,6 +1632,17 @@ "debug": "^3.1.0", "is-url": "^1.2.4", "request": "^2.85.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } } }, "@resolver-engine/fs": { @@ -2214,6 +1653,17 @@ "requires": { "@resolver-engine/core": "^0.3.3", "debug": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } } }, "@resolver-engine/imports": { @@ -2227,6 +1677,17 @@ "hosted-git-info": "^2.6.0", "path-browserify": "^1.0.0", "url": "^0.11.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } } }, "@resolver-engine/imports-fs": { @@ -2238,6 +1699,44 @@ "@resolver-engine/fs": "^0.3.3", "@resolver-engine/imports": "^0.3.3", "debug": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "@scure/base": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz", + "integrity": "sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==", + "dev": true + }, + "@scure/bip32": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.0.tgz", + "integrity": "sha512-ftTW3kKX54YXLCxH6BB7oEEoJfoE2pIgw7MINKAs5PsS6nqKPuKk1haTF/EuHmYqG330t5GSrdmtRuHaY1a62Q==", + "dev": true, + "requires": { + "@noble/hashes": "~1.1.1", + "@noble/secp256k1": "~1.6.0", + "@scure/base": "~1.1.0" + } + }, + "@scure/bip39": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.0.tgz", + "integrity": "sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w==", + "dev": true, + "requires": { + "@noble/hashes": "~1.1.1", + "@scure/base": "~1.1.0" } }, "@sentry/core": { @@ -2328,9 +1827,9 @@ "dev": true }, "@solidity-parser/parser": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.0.tgz", - "integrity": "sha512-cX0JJRcmPtNUJpzD2K7FdA7qQsTOk1UZnFx2k7qAg9ZRvuaH5NBe5IEdBMXGlmf2+FmjhqbygJ26H8l2SV7aKQ==", + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.3.tgz", + "integrity": "sha512-29g2SZ29HtsqA58pLCtopI1P/cPy5/UAzlcAXO6T/CNJimG6yA8kx4NaseMyJULiC+TEs02Y9/yeHzClqoA0hw==", "dev": true, "requires": { "antlr4ts": "^0.5.0-alpha.4" @@ -2346,64 +1845,26 @@ } }, "@truffle/error": { - "version": "0.0.14", - "resolved": "https://registry.npmjs.org/@truffle/error/-/error-0.0.14.tgz", - "integrity": "sha512-utJx+SZYoMqk8wldQG4gCVKhV8GwMJbWY7sLXFT/D8wWZTnE2peX7URFJh/cxkjTRCO328z1s2qewkhyVsu2HA==", + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@truffle/error/-/error-0.1.1.tgz", + "integrity": "sha512-sE7c9IHIGdbK4YayH4BC8i8qMjoAOeg6nUXUDZZp8wlU21/EMpaG+CLx+KqcIPyR+GSWIW3Dm0PXkr2nlggFDA==", "dev": true }, "@truffle/interface-adapter": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/@truffle/interface-adapter/-/interface-adapter-0.5.8.tgz", - "integrity": "sha512-vvy3xpq36oLgjjy8KE9l2Jabg3WcGPOt18tIyMfTQX9MFnbHoQA2Ne2i8xsd4p6KfxIqSjAB53Q9/nScAqY0UQ==", + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/@truffle/interface-adapter/-/interface-adapter-0.5.21.tgz", + "integrity": "sha512-2ltbu3upsWS0TAQu1kLQc048XlXNmDkCzH6iebX4dg3VBB+l7oG/pu5+/kl8t+LRfzGoEMLKwOQt7vk0Vm3PNA==", "dev": true, "requires": { "bn.js": "^5.1.3", "ethers": "^4.0.32", - "web3": "1.5.3" + "web3": "1.7.4" }, "dependencies": { - "@ethersproject/abi": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz", - "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==", - "dev": true, - "requires": { - "@ethersproject/address": "^5.0.4", - "@ethersproject/bignumber": "^5.0.7", - "@ethersproject/bytes": "^5.0.4", - "@ethersproject/constants": "^5.0.4", - "@ethersproject/hash": "^5.0.4", - "@ethersproject/keccak256": "^5.0.3", - "@ethersproject/logger": "^5.0.5", - "@ethersproject/properties": "^5.0.3", - "@ethersproject/strings": "^5.0.4" - } - }, - "@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/node": { - "version": "12.20.42", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.42.tgz", - "integrity": "sha512-aI3/oo5DzyiI5R/xAhxxRzfZlWlsbbqdgxfTPkqu/Zt+23GXiJvMCyPJT4+xKSXOnLqoL8jJYMLTwvK2M3a5hw==", - "dev": true - }, - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", - "dev": true - }, - "ethers": { - "version": "4.0.49", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.49.tgz", - "integrity": "sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==", + "ethers": { + "version": "4.0.49", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.49.tgz", + "integrity": "sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==", "dev": true, "requires": { "aes-js": "3.0.0", @@ -2435,6 +1896,12 @@ "minimalistic-assert": "^1.0.0" } }, + "js-sha3": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", + "integrity": "sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==", + "dev": true + }, "scrypt-js": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz", @@ -2444,662 +1911,113 @@ "setimmediate": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz", - "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=", + "integrity": "sha512-/TjEmXQVEzdod/FFskf3o7oOAsGhHf2j1dZqRFbDzq4F3mvvxflIIi4Hd3bLQE9y/CpwqfSQam5JakI/mi3Pog==", "dev": true }, "uuid": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", - "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=", + "integrity": "sha512-nWg9+Oa3qD2CQzHIP4qKUqwNfzKn8P0LtFhotaCTFchsV7ZfDhAybeip/HZVeMIpZi9JgY1E3nUlwaCmZT1sEg==", "dev": true }, "web3": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3/-/web3-1.5.3.tgz", - "integrity": "sha512-eyBg/1K44flfv0hPjXfKvNwcUfIVDI4NX48qHQe6wd7C8nPSdbWqo9vLy6ksZIt9NLa90HjI8HsGYgnMSUxn6w==", - "dev": true, - "requires": { - "web3-bzz": "1.5.3", - "web3-core": "1.5.3", - "web3-eth": "1.5.3", - "web3-eth-personal": "1.5.3", - "web3-net": "1.5.3", - "web3-shh": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-bzz": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.5.3.tgz", - "integrity": "sha512-SlIkAqG0eS6cBS9Q2eBOTI1XFzqh83RqGJWnyrNZMDxUwsTVHL+zNnaPShVPvrWQA1Ub5b0bx1Kc5+qJVxsTJg==", - "dev": true, - "requires": { - "@types/node": "^12.12.6", - "got": "9.6.0", - "swarm-js": "^0.1.40" - } - }, - "web3-core": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.5.3.tgz", - "integrity": "sha512-ACTbu8COCu+0eUNmd9pG7Q9EVsNkAg2w3Y7SqhDr+zjTgbSHZV01jXKlapm9z+G3AN/BziV3zGwudClJ4u4xXQ==", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.5", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-requestmanager": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-core-helpers": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.5.3.tgz", - "integrity": "sha512-Ip1IjB3S8vN7Kf1PPjK41U5gskmMk6IJQlxIVuS8/1U7n/o0jC8krqtpRwiMfAgYyw3TXwBFtxSRTvJtnLyXZw==", - "dev": true, - "requires": { - "web3-eth-iban": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-core-method": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.5.3.tgz", - "integrity": "sha512-8wJrwQ2qD9ibWieF9oHXwrJsUGrv3XAtEkNeyvyNMpktNTIjxJ2jaFGQUuLiyUrMubD18XXgLk4JS6PJU4Loeg==", - "dev": true, - "requires": { - "@ethereumjs/common": "^2.4.0", - "@ethersproject/transactions": "^5.0.0-beta.135", - "web3-core-helpers": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-core-promievent": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.5.3.tgz", - "integrity": "sha512-CFfgqvk3Vk6PIAxtLLuX+pOMozxkKCY+/GdGr7weMh033mDXEPvwyVjoSRO1PqIKj668/hMGQsVoIgbyxkJ9Mg==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4" - } - }, - "web3-core-requestmanager": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.5.3.tgz", - "integrity": "sha512-9k/Bze2rs8ONix5IZR+hYdMNQv+ark2Ek2kVcrFgWO+LdLgZui/rn8FikPunjE+ub7x7pJaKCgVRbYFXjo3ZWg==", - "dev": true, - "requires": { - "util": "^0.12.0", - "web3-core-helpers": "1.5.3", - "web3-providers-http": "1.5.3", - "web3-providers-ipc": "1.5.3", - "web3-providers-ws": "1.5.3" - } - }, - "web3-core-subscriptions": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.5.3.tgz", - "integrity": "sha512-L2m9vG1iRN6thvmv/HQwO2YLhOQlmZU8dpLG6GSo9FBN14Uch868Swk0dYVr3rFSYjZ/GETevSXU+O+vhCummA==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3" - } - }, - "web3-eth": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.5.3.tgz", - "integrity": "sha512-saFurA1L23Bd7MEf7cBli6/jRdMhD4X/NaMiO2mdMMCXlPujoudlIJf+VWpRWJpsbDFdu7XJ2WHkmBYT5R3p1Q==", - "dev": true, - "requires": { - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-eth-abi": "1.5.3", - "web3-eth-accounts": "1.5.3", - "web3-eth-contract": "1.5.3", - "web3-eth-ens": "1.5.3", - "web3-eth-iban": "1.5.3", - "web3-eth-personal": "1.5.3", - "web3-net": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-eth-abi": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.5.3.tgz", - "integrity": "sha512-i/qhuFsoNrnV130CSRYX/z4SlCfSQ4mHntti5yTmmQpt70xZKYZ57BsU0R29ueSQ9/P+aQrL2t2rqkQkAloUxg==", - "dev": true, - "requires": { - "@ethersproject/abi": "5.0.7", - "web3-utils": "1.5.3" - } - }, - "web3-eth-accounts": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.5.3.tgz", - "integrity": "sha512-pdGhXgeBaEJENMvRT6W9cmji3Zz/46ugFSvmnLLw79qi5EH7XJhKISNVb41eWCrs4am5GhI67GLx5d2s2a72iw==", - "dev": true, - "requires": { - "@ethereumjs/common": "^2.3.0", - "@ethereumjs/tx": "^3.2.1", - "crypto-browserify": "3.12.0", - "eth-lib": "0.2.8", - "ethereumjs-util": "^7.0.10", - "scrypt-js": "^3.0.1", - "uuid": "3.3.2", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-utils": "1.5.3" - }, - "dependencies": { - "scrypt-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", - "dev": true - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "dev": true - } - } - }, - "web3-eth-contract": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.5.3.tgz", - "integrity": "sha512-Gdlt1L6cdHe83k7SdV6xhqCytVtOZkjD0kY/15x441AuuJ4JLubCHuqu69k2Dr3tWifHYVys/vG8QE/W16syGg==", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.5", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-eth-abi": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-eth-ens": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.5.3.tgz", - "integrity": "sha512-QmGFFtTGElg0E+3xfCIFhiUF+1imFi9eg/cdsRMUZU4F1+MZCC/ee+IAelYLfNTGsEslCqfAusliKOT9DdGGnw==", - "dev": true, - "requires": { - "content-hash": "^2.5.2", - "eth-ens-namehash": "2.0.8", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-eth-abi": "1.5.3", - "web3-eth-contract": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-eth-iban": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.5.3.tgz", - "integrity": "sha512-vMzmGqolYZvRHwP9P4Nf6G8uYM5aTLlQu2a34vz78p0KlDC+eV1th3+90Qeaupa28EG7OO0IT1F0BejiIauOPw==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "web3-utils": "1.5.3" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "web3-eth-personal": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.5.3.tgz", - "integrity": "sha512-JzibJafR7ak/Icas8uvos3BmUNrZw1vShuNR5Cxjo+vteOC8XMqz1Vr7RH65B4bmlfb3bm9xLxetUHO894+Sew==", - "dev": true, - "requires": { - "@types/node": "^12.12.6", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-net": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-net": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.5.3.tgz", - "integrity": "sha512-0W/xHIPvgVXPSdLu0iZYnpcrgNnhzHMC888uMlGP5+qMCt8VuflUZHy7tYXae9Mzsg1kxaJAS5lHVNyeNw4CoQ==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3/-/web3-1.7.4.tgz", + "integrity": "sha512-iFGK5jO32vnXM/ASaJBaI0+gVR6uHozvYdxkdhaeOCD6HIQ4iIXadbO2atVpE9oc/H8l2MovJ4LtPhG7lIBN8A==", "dev": true, "requires": { - "web3-core": "1.5.3", - "web3-core-method": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-providers-http": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.5.3.tgz", - "integrity": "sha512-5DpUyWGHtDAr2RYmBu34Fu+4gJuBAuNx2POeiJIooUtJ+Mu6pIx4XkONWH6V+Ez87tZAVAsFOkJRTYuzMr3rPw==", - "dev": true, - "requires": { - "web3-core-helpers": "1.5.3", - "xhr2-cookies": "1.1.0" - } - }, - "web3-providers-ipc": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.5.3.tgz", - "integrity": "sha512-JmeAptugVpmXI39LGxUSAymx0NOFdgpuI1hGQfIhbEAcd4sv7fhfd5D+ZU4oLHbRI8IFr4qfGU0uhR8BXhDzlg==", - "dev": true, - "requires": { - "oboe": "2.1.5", - "web3-core-helpers": "1.5.3" - } - }, - "web3-providers-ws": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.5.3.tgz", - "integrity": "sha512-6DhTw4Q7nm5CFYEUHOJM0gAb3xFx+9gWpVveg3YxJ/ybR1BUvEWo3bLgIJJtX56cYX0WyY6DS35a7f0LOI1kVg==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3", - "websocket": "^1.0.32" - } - }, - "web3-shh": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.5.3.tgz", - "integrity": "sha512-COfEXfsqoV/BkcsNLRxQqnWc1Teb8/9GxdGag5GtPC5gQC/vsN+7hYVJUwNxY9LtJPKYTij2DHHnx6UkITng+Q==", - "dev": true, - "requires": { - "web3-core": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-net": "1.5.3" + "web3-bzz": "1.7.4", + "web3-core": "1.7.4", + "web3-eth": "1.7.4", + "web3-eth-personal": "1.7.4", + "web3-net": "1.7.4", + "web3-shh": "1.7.4", + "web3-utils": "1.7.4" } }, "web3-utils": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", - "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", + "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", "dev": true, "requires": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", + "bn.js": "^5.2.1", "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", "ethjs-unit": "0.1.6", "number-to-bn": "1.7.0", "randombytes": "^2.1.0", "utf8": "3.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } } } } }, "@truffle/provider": { - "version": "0.2.42", - "resolved": "https://registry.npmjs.org/@truffle/provider/-/provider-0.2.42.tgz", - "integrity": "sha512-ZNoglPho4alYIjJR+sLTgX0x6ho7m4OAUWuJ50RAWmoEqYc4AM6htdrI+lTSoRrOHHbmgasv22a7rFPMnmDrTg==", + "version": "0.2.59", + "resolved": "https://registry.npmjs.org/@truffle/provider/-/provider-0.2.59.tgz", + "integrity": "sha512-4b79yUSZlEd7KqzaPkQiiT4aRCGaI+pXPdwJMD0olLvnZrGoNrBtRQSmnXesxBcqi6FaSDxxC+/9URG2HBPE2g==", "dev": true, "requires": { - "@truffle/error": "^0.0.14", - "@truffle/interface-adapter": "^0.5.8", - "web3": "1.5.3" + "@truffle/error": "^0.1.1", + "@truffle/interface-adapter": "^0.5.21", + "debug": "^4.3.1", + "web3": "1.7.4" }, "dependencies": { - "@ethersproject/abi": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz", - "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==", - "dev": true, - "requires": { - "@ethersproject/address": "^5.0.4", - "@ethersproject/bignumber": "^5.0.7", - "@ethersproject/bytes": "^5.0.4", - "@ethersproject/constants": "^5.0.4", - "@ethersproject/hash": "^5.0.4", - "@ethersproject/keccak256": "^5.0.3", - "@ethersproject/logger": "^5.0.5", - "@ethersproject/properties": "^5.0.3", - "@ethersproject/strings": "^5.0.4" - } - }, - "@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/node": { - "version": "12.20.42", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.42.tgz", - "integrity": "sha512-aI3/oo5DzyiI5R/xAhxxRzfZlWlsbbqdgxfTPkqu/Zt+23GXiJvMCyPJT4+xKSXOnLqoL8jJYMLTwvK2M3a5hw==", - "dev": true - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "dev": true - }, "web3": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3/-/web3-1.5.3.tgz", - "integrity": "sha512-eyBg/1K44flfv0hPjXfKvNwcUfIVDI4NX48qHQe6wd7C8nPSdbWqo9vLy6ksZIt9NLa90HjI8HsGYgnMSUxn6w==", - "dev": true, - "requires": { - "web3-bzz": "1.5.3", - "web3-core": "1.5.3", - "web3-eth": "1.5.3", - "web3-eth-personal": "1.5.3", - "web3-net": "1.5.3", - "web3-shh": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-bzz": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.5.3.tgz", - "integrity": "sha512-SlIkAqG0eS6cBS9Q2eBOTI1XFzqh83RqGJWnyrNZMDxUwsTVHL+zNnaPShVPvrWQA1Ub5b0bx1Kc5+qJVxsTJg==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3/-/web3-1.7.4.tgz", + "integrity": "sha512-iFGK5jO32vnXM/ASaJBaI0+gVR6uHozvYdxkdhaeOCD6HIQ4iIXadbO2atVpE9oc/H8l2MovJ4LtPhG7lIBN8A==", "dev": true, "requires": { - "@types/node": "^12.12.6", - "got": "9.6.0", - "swarm-js": "^0.1.40" - } - }, - "web3-core": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.5.3.tgz", - "integrity": "sha512-ACTbu8COCu+0eUNmd9pG7Q9EVsNkAg2w3Y7SqhDr+zjTgbSHZV01jXKlapm9z+G3AN/BziV3zGwudClJ4u4xXQ==", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.5", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-requestmanager": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-core-helpers": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.5.3.tgz", - "integrity": "sha512-Ip1IjB3S8vN7Kf1PPjK41U5gskmMk6IJQlxIVuS8/1U7n/o0jC8krqtpRwiMfAgYyw3TXwBFtxSRTvJtnLyXZw==", - "dev": true, - "requires": { - "web3-eth-iban": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-core-method": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.5.3.tgz", - "integrity": "sha512-8wJrwQ2qD9ibWieF9oHXwrJsUGrv3XAtEkNeyvyNMpktNTIjxJ2jaFGQUuLiyUrMubD18XXgLk4JS6PJU4Loeg==", - "dev": true, - "requires": { - "@ethereumjs/common": "^2.4.0", - "@ethersproject/transactions": "^5.0.0-beta.135", - "web3-core-helpers": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-core-promievent": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.5.3.tgz", - "integrity": "sha512-CFfgqvk3Vk6PIAxtLLuX+pOMozxkKCY+/GdGr7weMh033mDXEPvwyVjoSRO1PqIKj668/hMGQsVoIgbyxkJ9Mg==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4" - } - }, - "web3-core-requestmanager": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.5.3.tgz", - "integrity": "sha512-9k/Bze2rs8ONix5IZR+hYdMNQv+ark2Ek2kVcrFgWO+LdLgZui/rn8FikPunjE+ub7x7pJaKCgVRbYFXjo3ZWg==", - "dev": true, - "requires": { - "util": "^0.12.0", - "web3-core-helpers": "1.5.3", - "web3-providers-http": "1.5.3", - "web3-providers-ipc": "1.5.3", - "web3-providers-ws": "1.5.3" - } - }, - "web3-core-subscriptions": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.5.3.tgz", - "integrity": "sha512-L2m9vG1iRN6thvmv/HQwO2YLhOQlmZU8dpLG6GSo9FBN14Uch868Swk0dYVr3rFSYjZ/GETevSXU+O+vhCummA==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3" - } - }, - "web3-eth": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.5.3.tgz", - "integrity": "sha512-saFurA1L23Bd7MEf7cBli6/jRdMhD4X/NaMiO2mdMMCXlPujoudlIJf+VWpRWJpsbDFdu7XJ2WHkmBYT5R3p1Q==", - "dev": true, - "requires": { - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-eth-abi": "1.5.3", - "web3-eth-accounts": "1.5.3", - "web3-eth-contract": "1.5.3", - "web3-eth-ens": "1.5.3", - "web3-eth-iban": "1.5.3", - "web3-eth-personal": "1.5.3", - "web3-net": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-eth-abi": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.5.3.tgz", - "integrity": "sha512-i/qhuFsoNrnV130CSRYX/z4SlCfSQ4mHntti5yTmmQpt70xZKYZ57BsU0R29ueSQ9/P+aQrL2t2rqkQkAloUxg==", - "dev": true, - "requires": { - "@ethersproject/abi": "5.0.7", - "web3-utils": "1.5.3" + "web3-bzz": "1.7.4", + "web3-core": "1.7.4", + "web3-eth": "1.7.4", + "web3-eth-personal": "1.7.4", + "web3-net": "1.7.4", + "web3-shh": "1.7.4", + "web3-utils": "1.7.4" } }, - "web3-eth-accounts": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.5.3.tgz", - "integrity": "sha512-pdGhXgeBaEJENMvRT6W9cmji3Zz/46ugFSvmnLLw79qi5EH7XJhKISNVb41eWCrs4am5GhI67GLx5d2s2a72iw==", + "web3-utils": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", + "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", "dev": true, "requires": { - "@ethereumjs/common": "^2.3.0", - "@ethereumjs/tx": "^3.2.1", - "crypto-browserify": "3.12.0", - "eth-lib": "0.2.8", - "ethereumjs-util": "^7.0.10", - "scrypt-js": "^3.0.1", - "uuid": "3.3.2", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-eth-contract": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.5.3.tgz", - "integrity": "sha512-Gdlt1L6cdHe83k7SdV6xhqCytVtOZkjD0kY/15x441AuuJ4JLubCHuqu69k2Dr3tWifHYVys/vG8QE/W16syGg==", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.5", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-eth-abi": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-eth-ens": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.5.3.tgz", - "integrity": "sha512-QmGFFtTGElg0E+3xfCIFhiUF+1imFi9eg/cdsRMUZU4F1+MZCC/ee+IAelYLfNTGsEslCqfAusliKOT9DdGGnw==", - "dev": true, - "requires": { - "content-hash": "^2.5.2", - "eth-ens-namehash": "2.0.8", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-eth-abi": "1.5.3", - "web3-eth-contract": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-eth-iban": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.5.3.tgz", - "integrity": "sha512-vMzmGqolYZvRHwP9P4Nf6G8uYM5aTLlQu2a34vz78p0KlDC+eV1th3+90Qeaupa28EG7OO0IT1F0BejiIauOPw==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "web3-utils": "1.5.3" - } - }, - "web3-eth-personal": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.5.3.tgz", - "integrity": "sha512-JzibJafR7ak/Icas8uvos3BmUNrZw1vShuNR5Cxjo+vteOC8XMqz1Vr7RH65B4bmlfb3bm9xLxetUHO894+Sew==", - "dev": true, - "requires": { - "@types/node": "^12.12.6", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-net": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-net": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.5.3.tgz", - "integrity": "sha512-0W/xHIPvgVXPSdLu0iZYnpcrgNnhzHMC888uMlGP5+qMCt8VuflUZHy7tYXae9Mzsg1kxaJAS5lHVNyeNw4CoQ==", - "dev": true, - "requires": { - "web3-core": "1.5.3", - "web3-core-method": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-providers-http": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.5.3.tgz", - "integrity": "sha512-5DpUyWGHtDAr2RYmBu34Fu+4gJuBAuNx2POeiJIooUtJ+Mu6pIx4XkONWH6V+Ez87tZAVAsFOkJRTYuzMr3rPw==", - "dev": true, - "requires": { - "web3-core-helpers": "1.5.3", - "xhr2-cookies": "1.1.0" - } - }, - "web3-providers-ipc": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.5.3.tgz", - "integrity": "sha512-JmeAptugVpmXI39LGxUSAymx0NOFdgpuI1hGQfIhbEAcd4sv7fhfd5D+ZU4oLHbRI8IFr4qfGU0uhR8BXhDzlg==", - "dev": true, - "requires": { - "oboe": "2.1.5", - "web3-core-helpers": "1.5.3" - } - }, - "web3-providers-ws": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.5.3.tgz", - "integrity": "sha512-6DhTw4Q7nm5CFYEUHOJM0gAb3xFx+9gWpVveg3YxJ/ybR1BUvEWo3bLgIJJtX56cYX0WyY6DS35a7f0LOI1kVg==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3", - "websocket": "^1.0.32" - } - }, - "web3-shh": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.5.3.tgz", - "integrity": "sha512-COfEXfsqoV/BkcsNLRxQqnWc1Teb8/9GxdGag5GtPC5gQC/vsN+7hYVJUwNxY9LtJPKYTij2DHHnx6UkITng+Q==", - "dev": true, - "requires": { - "web3-core": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-net": "1.5.3" - } - }, - "web3-utils": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", - "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", - "ethereum-bloom-filters": "^1.0.6", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" + "bn.js": "^5.2.1", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" } } } }, "@tsconfig/node10": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", - "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", "dev": true }, "@tsconfig/node12": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", - "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", "dev": true }, "@tsconfig/node14": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", - "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", "dev": true }, "@tsconfig/node16": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", - "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", "dev": true }, "@typechain/ethers-v5": { @@ -3132,12 +2050,31 @@ "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", "requires": { "@types/node": "*" + }, + "dependencies": { + "@types/node": { + "version": "18.7.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.13.tgz", + "integrity": "sha512-46yIhxSe5xEaJZXWdIBP7GU4HDTG8/eo0qd9atdiL+lFpA03y8KS+lkTN834TWJj5767GbWv4n/P6efyTFt1Dw==" + } + } + }, + "@types/cacheable-request": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", + "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", + "dev": true, + "requires": { + "@types/http-cache-semantics": "*", + "@types/keyv": "*", + "@types/node": "*", + "@types/responselike": "*" } }, "@types/chai": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.0.tgz", - "integrity": "sha512-/ceqdqeRraGolFTcfoXNiqjyQhZzbINDngeoAq9GoHa8PPK1yNzTaxWjA6BFWp5Ua9JpXEMSS4s5i9tS0hOJtw==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.3.tgz", + "integrity": "sha512-hC7OMnszpxhZPduX+m+nrx+uFoLkWOMiR4oa/AZF3MuSETYTZmFfJAHqZEM8MVlvfG7BEUcgvtwoCTxBp6hm3g==", "dev": true }, "@types/concat-stream": { @@ -3152,7 +2089,7 @@ "@types/form-data": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", - "integrity": "sha1-yayFsqX9GENbjIXZ7LUObWyJP/g=", + "integrity": "sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==", "dev": true, "requires": { "@types/node": "*" @@ -3168,6 +2105,27 @@ "@types/node": "*" } }, + "@types/http-cache-semantics": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", + "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==", + "dev": true + }, + "@types/json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha512-3YP80IxxFJB4b5tYC2SUPwkg0XQLiu0nWvhRgEatgjf+29IcWO9X1k8xRv5DGssJ/lCrjYTjQPcobJr2yWIVuQ==", + "dev": true + }, + "@types/keyv": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/level-errors": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/level-errors/-/level-errors-3.0.0.tgz", @@ -3192,9 +2150,9 @@ "dev": true }, "@types/minimatch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.0.tgz", + "integrity": "sha512-0RJHq5FqDWo17kdHe+SMDJLfxmLaqHbWnqZ6gNKzDvStUlrmx/eKIY17+ifLS1yybo7X86aUshQMlittDOVNnw==", "dev": true }, "@types/mkdirp": { @@ -3213,18 +2171,32 @@ "dev": true }, "@types/node": { - "version": "16.4.14", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.4.14.tgz", - "integrity": "sha512-GZpnVRNtv7sHDXIFncsERt+qvj4rzAgRQtnvzk3Z7OVNtThD2dHXYCMDNc80D5mv4JE278qo8biZCwcmkbdpqw==" + "version": "16.11.56", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.56.tgz", + "integrity": "sha512-aFcUkv7EddxxOa/9f74DINReQ/celqH8DiB3fRYgVDM2Xm5QJL8sl80QKuAnGvwAsMn+H3IFA6WCrQh1CY7m1A==", + "dev": true }, "@types/node-fetch": { - "version": "2.5.10", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.10.tgz", - "integrity": "sha512-IpkX0AasN44hgEad0gEF/V6EgR5n69VEqPEgnmoM8GsIGro3PowbWs4tR6IhxUTyPLpOn+fiGG6nrQhcmoCuIQ==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.2.tgz", + "integrity": "sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==", "dev": true, "requires": { "@types/node": "*", "form-data": "^3.0.0" + }, + "dependencies": { + "form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + } } }, "@types/pbkdf2": { @@ -3233,12 +2205,19 @@ "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", "requires": { "@types/node": "*" + }, + "dependencies": { + "@types/node": { + "version": "18.7.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.13.tgz", + "integrity": "sha512-46yIhxSe5xEaJZXWdIBP7GU4HDTG8/eo0qd9atdiL+lFpA03y8KS+lkTN834TWJj5767GbWv4n/P6efyTFt1Dw==" + } } }, "@types/prettier": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.2.tgz", - "integrity": "sha512-i99hy7Ki19EqVOl77WplDrvgNugHnsSjECVR/wUrzw2TJXz1zlUfT2ngGckR6xN7yFYaijsMAqPkOLx9HgUqHg==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.0.tgz", + "integrity": "sha512-RI1L7N4JnW5gQw2spvL7Sllfuf1SaHdrZpCHiBlCXjIlufi1SMNnbu2teze3/QE67Fg2tBlH7W+mi4hVNk4p0A==", "dev": true }, "@types/qs": { @@ -3256,27 +2235,43 @@ "@types/node": "*" } }, + "@types/responselike": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", + "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/secp256k1": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==", "requires": { "@types/node": "*" + }, + "dependencies": { + "@types/node": { + "version": "18.7.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.13.tgz", + "integrity": "sha512-46yIhxSe5xEaJZXWdIBP7GU4HDTG8/eo0qd9atdiL+lFpA03y8KS+lkTN834TWJj5767GbWv4n/P6efyTFt1Dw==" + } } }, "@types/sinon": { - "version": "9.0.10", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-9.0.10.tgz", - "integrity": "sha512-/faDC0erR06wMdybwI/uR8wEKV/E83T0k4sepIpB7gXuy2gzx2xiOjmztq6a2Y6rIGJ04D+6UU0VBmWy+4HEMA==", + "version": "10.0.13", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.13.tgz", + "integrity": "sha512-UVjDqJblVNQYvVNUsj0PuYYw0ELRmgt1Nt5Vk0pT5f16ROGfcKJY8o1HVuMOJOpD727RrGB9EGvoaTQE5tgxZQ==", "dev": true, "requires": { "@types/sinonjs__fake-timers": "*" } }, "@types/sinon-chai": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.5.tgz", - "integrity": "sha512-bKQqIpew7mmIGNRlxW6Zli/QVyc3zikpGzCa797B/tRnD9OtHvZ/ts8sYXV+Ilj9u3QRaUEM8xrjgd1gwm1BpQ==", + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.8.tgz", + "integrity": "sha512-d4ImIQbT/rKMG8+AXpmcan5T2/PNeSjrYhvkwet6z0p8kzYtfgA32xzOBlbU0yqJfq+/0Ml805iFoODO0LP5/g==", "dev": true, "requires": { "@types/chai": "*", @@ -3284,15 +2279,15 @@ } }, "@types/sinonjs__fake-timers": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.2.tgz", - "integrity": "sha512-dIPoZ3g5gcx9zZEszaxLSVTvMReD3xxyyDnQUjA6IYDG9Ba2AV0otMPs+77sG9ojB4Qr2N2Vk5RnKeuA0X/0bg==", + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.2.tgz", + "integrity": "sha512-9GcLXF0/v3t80caGs5p2rRfkB+a8VBGLJZVih6CNFkx8IZ994wiKKLSRs9nuFwk1HevWs/1mnUmkApGrSGsShA==", "dev": true }, "@types/underscore": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.11.0.tgz", - "integrity": "sha512-ipNAQLgRnG0EWN1cTtfdVHp5AyTW/PAMJ1PxLN4bAKSHbusSZbj48mIHiydQpN7GgQrYqwfnvZ573OVfJm5Nzg==", + "version": "1.11.4", + "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.11.4.tgz", + "integrity": "sha512-uO4CD2ELOjw8tasUrAhvnn2W4A0ZECOvMjCivJr4gA9pGgjv+qxKWY9GLTMVEK8ej85BxQOocUyE7hImmSQYcg==", "dev": true }, "@types/web3": { @@ -3305,6 +2300,12 @@ "@types/underscore": "*" } }, + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, "@uniswap/lib": { "version": "4.0.1-alpha", "resolved": "https://registry.npmjs.org/@uniswap/lib/-/lib-4.0.1-alpha.tgz", @@ -3316,16 +2317,16 @@ "integrity": "sha512-MtybtkUPSyysqLY2U210NBDeCHX+ltHt3oADGdjqoThZaFRDKwM6k1Nb3F0A3hk5hwuQvytFWhrWHOEq6nVJ8Q==" }, "@uniswap/v3-core": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@uniswap/v3-core/-/v3-core-1.0.0.tgz", - "integrity": "sha512-kSC4djMGKMHj7sLMYVnn61k9nu+lHjMIxgg9CDQT+s2QYLoA56GbSK9Oxr+qJXzzygbkrmuY6cwgP6cW2JXPFA==" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@uniswap/v3-core/-/v3-core-1.0.1.tgz", + "integrity": "sha512-7pVk4hEm00j9tc71Y9+ssYpO6ytkeI0y7WE9P6UcmNzhxPePwyAxImuhVsTqWK9YFvzgtvzJHi64pBl4jUzKMQ==" }, "@uniswap/v3-periphery": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@uniswap/v3-periphery/-/v3-periphery-1.1.1.tgz", - "integrity": "sha512-orqD2Xy4lxVPF6pxd7ECSJY0gzEuqyeVSDHjzM86uWxOXlA4Nlh5pvI959KaS32pSOFBOVVA4XbbZywbJj+CZg==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@uniswap/v3-periphery/-/v3-periphery-1.4.1.tgz", + "integrity": "sha512-Ab0ZCKOQrQMKIcpBTezTsEhWfQjItd0TtkCG8mPhoQu+wC67nPaf4hYUhM6wGHeFUmDiYY5MpEQuokB0ENvoTg==", "requires": { - "@openzeppelin/contracts": "3.4.1-solc-0.7-2", + "@openzeppelin/contracts": "3.4.2-solc-0.7", "@uniswap/lib": "^4.0.1-alpha", "@uniswap/v2-core": "1.0.1", "@uniswap/v3-core": "1.0.0", @@ -3334,9 +2335,14 @@ }, "dependencies": { "@openzeppelin/contracts": { - "version": "3.4.1-solc-0.7-2", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-3.4.1-solc-0.7-2.tgz", - "integrity": "sha512-tAG9LWg8+M2CMu7hIsqHPaTyG4uDzjr6mhvH96LvOpLZZj6tgzTluBt+LsCf1/QaYrlis6pITvpIaIhE+iZB+Q==" + "version": "3.4.2-solc-0.7", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-3.4.2-solc-0.7.tgz", + "integrity": "sha512-W6QmqgkADuFcTLzHL8vVoNBtkwjvQRpYIAom7KiUNoLKghyx3FgH0GBjt8NRvigV1ZmMOBllvE1By1C+bi8WpA==" + }, + "@uniswap/v3-core": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@uniswap/v3-core/-/v3-core-1.0.0.tgz", + "integrity": "sha512-kSC4djMGKMHj7sLMYVnn61k9nu+lHjMIxgg9CDQT+s2QYLoA56GbSK9Oxr+qJXzzygbkrmuY6cwgP6cW2JXPFA==" } } }, @@ -3349,7 +2355,7 @@ "abbrev": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", - "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", + "integrity": "sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==", "dev": true }, "abort-controller": { @@ -3361,6 +2367,12 @@ "event-target-shim": "^5.0.0" } }, + "abortcontroller-polyfill": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.3.tgz", + "integrity": "sha512-zetDJxd89y3X99Kvo4qFx8GKlt6GsvN3UcRZHwU6iFA/0KiOmhkTVhe8oRoTBiTVPZu09x3vCra47+w8Yz1+2Q==", + "dev": true + }, "abstract-leveldown": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.3.0.tgz", @@ -3375,13 +2387,13 @@ } }, "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "dev": true, "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" + "mime-types": "~2.1.34", + "negotiator": "0.6.3" } }, "acorn": { @@ -3391,9 +2403,9 @@ "dev": true }, "acorn-jsx": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", - "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true }, "acorn-walk": { @@ -3403,9 +2415,9 @@ "dev": true }, "address": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/address/-/address-1.1.2.tgz", - "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/address/-/address-1.2.0.tgz", + "integrity": "sha512-tNEZYz5G/zYunxFm7sfhAxkXEuLj3K6BKwv6ZURlsF6yiUQ65z0Q2wZW9L5cPUl9ocofGvXOdFYbFHp0+6MOig==", "dev": true }, "adm-zip": { @@ -3417,7 +2429,7 @@ "aes-js": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0=" + "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==" }, "agent-base": { "version": "6.0.2", @@ -3426,48 +2438,41 @@ "dev": true, "requires": { "debug": "4" - }, - "dependencies": { - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } + } + }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" } }, "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", "uri-js": "^4.2.2" } }, "amdefine": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==", "dev": true, "optional": true }, "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", "dev": true }, "ansi-escapes": { @@ -3480,19 +2485,24 @@ } }, "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==" }, "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "requires": { - "color-convert": "^1.9.0" + "color-convert": "^2.0.1" } }, + "ansicolors": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", + "integrity": "sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==", + "dev": true + }, "antlr4": { "version": "4.7.1", "resolved": "https://registry.npmjs.org/antlr4/-/antlr4-4.7.1.tgz", @@ -3506,9 +2516,9 @@ "dev": true }, "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -3537,13 +2547,10 @@ "dev": true }, "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true }, "array-back": { "version": "2.0.0", @@ -3557,7 +2564,7 @@ "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", "dev": true }, "array-union": { @@ -3569,19 +2576,32 @@ "array-uniq": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", "dev": true }, + "array.prototype.reduce": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.4.tgz", + "integrity": "sha512-WnM+AjG/DvLRLo4DDl+r+SvCzYtD2Jd9oeBYMcEaI7t3fFrHY9M53/wdLcTvmZNQ70IU6Htj0emFkZ5TS+lrdw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.2", + "es-array-method-boxes-properly": "^1.0.0", + "is-string": "^1.0.7" + } + }, "asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", "dev": true }, "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", "dev": true, "requires": { "safer-buffer": "~2.1.0" @@ -3597,12 +2617,20 @@ "inherits": "^2.0.1", "minimalistic-assert": "^1.0.0", "safer-buffer": "^2.1.0" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } } }, "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", "dev": true }, "assertion-error": { @@ -3614,19 +2642,19 @@ "ast-parents": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/ast-parents/-/ast-parents-0.0.1.tgz", - "integrity": "sha1-UI/Q8F0MSHddnszaLhdEIyYejdM=", + "integrity": "sha512-XHusKxKz3zoYk1ic8Un640joHbFMhbqneyoZfoKnEGtf2ey9Uh/IdpcQplODdO/kENaMIWsD0nJm4+wX3UNLHA==", "dev": true }, "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true }, "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", "dev": true, "requires": { "lodash": "^4.17.14" @@ -3650,18 +2678,24 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true }, "available-typed-arrays": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.4.tgz", - "integrity": "sha512-SA5mXJWrId1TaQjfxUYghbqQ/hYioKmLJvPJyDuYRtXXenFNMjj4hSSt1Cf1xsuXSXrtxrVC5Ot4eU6cOtBDdA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", "dev": true }, "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=", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", "dev": true }, "aws4": { @@ -3677,35 +2711,18 @@ "requires": { "follow-redirects": "^1.14.9", "form-data": "^4.0.0" - }, - "dependencies": { - "follow-redirects": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.0.tgz", - "integrity": "sha512-aExlJShTV4qOUOL7yF1U5tvLCB0xQuudbf6toyYA0E/acBNw71mvjFTnLaRp50aQaYocMR0a/RMMBIHeZnGyjQ==" - }, - "form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - } } }, "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, "base-x": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.8.tgz", - "integrity": "sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==", + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", + "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", "requires": { "safe-buffer": "^5.0.1" } @@ -3723,18 +2740,10 @@ "bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", "dev": true, "requires": { "tweetnacl": "^0.14.3" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true - } } }, "bech32": { @@ -3743,9 +2752,9 @@ "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" }, "bignumber.js": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", - "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==" + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.0.tgz", + "integrity": "sha512-4LwHK4nfDOraBCtst+wOWIHbu1vhvAPJK8g8nROd4iuc3PSEjWif/qwbkh8jwCJz6yDBvtU4KPynETgrfh7y3A==" }, "binary-extensions": { "version": "2.2.0", @@ -3756,19 +2765,11 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "optional": true, "requires": { "file-uri-to-path": "1.0.0" } }, - "bip66": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", - "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, "bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -3794,9 +2795,9 @@ } }, "blakejs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.1.tgz", - "integrity": "sha512-bLG6PHOCZJKNshTjGRBvET0vTciwQE6zFKOKKXPDJfwFBd4Ac0yBfPZqcGvGJap50l7ktvlpFqc2jGVaUgbJgg==" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==" }, "bluebird": { "version": "3.7.2", @@ -3805,26 +2806,28 @@ "dev": true }, "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" }, "body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", + "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", "dev": true, "requires": { - "bytes": "3.1.0", + "bytes": "3.1.2", "content-type": "~1.0.4", "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" + "on-finished": "2.4.1", + "qs": "6.10.3", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" }, "dependencies": { "debug": { @@ -3836,47 +2839,19 @@ "ms": "2.0.0" } }, - "http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", - "dev": true - }, - "raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", + "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", "dev": true, "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" + "side-channel": "^1.0.4" } } } @@ -3902,7 +2877,7 @@ "brorand": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" }, "browser-stdout": { "version": "1.3.1", @@ -3954,14 +2929,6 @@ "requires": { "bn.js": "^5.0.0", "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", - "dev": true - } } }, "browserify-sign": { @@ -3981,12 +2948,6 @@ "safe-buffer": "^5.2.0" }, "dependencies": { - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", - "dev": true - }, "readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", @@ -3997,13 +2958,19 @@ "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true } } }, "bs58": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", "requires": { "base-x": "^3.0.2" } @@ -4036,27 +3003,33 @@ "buffer-to-arraybuffer": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz", - "integrity": "sha1-YGSkD6dutDxyOrqe+PbhIW0QURo=", + "integrity": "sha512-3dthu5CYiVB1DEJp61FtApNnNndTckcqe4pFcLdvHtrpG+kcyekCJKg4MRiDcFW7A6AODnXB9U4dwQiCW5kzJQ==", "dev": true }, "buffer-xor": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==" }, "bufferutil": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.3.tgz", - "integrity": "sha512-yEYTwGndELGvfXsImMBLop58eaGW+YdONi1fNjTINSY98tmMmFijBG6WXgdkfuLNt4imzQNtIE+eBp1PVpMCSw==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.6.tgz", + "integrity": "sha512-jduaYOYtnio4aIAyc6UbvPCVcgq7nYpVnucyxr6eCYg/Woad9Hf/oxxBRDnGGjPfjUm6j5O/uBWhIu4iLebFaw==", "dev": true, "requires": { - "node-gyp-build": "^4.2.0" + "node-gyp-build": "^4.3.0" } }, "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true + }, + "cacheable-lookup": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-6.1.0.tgz", + "integrity": "sha512-KJ/Dmo1lDDhmW2XDPMo+9oiy/CeqosPguPCrgcVzKyZrL6pM1gU2GmPY/xo6OQPTUaA/c0kwHuywB4E6nmT9ww==", "dev": true }, "cacheable-request": { @@ -4104,7 +3077,7 @@ "caller-callsite": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", - "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", + "integrity": "sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==", "dev": true, "requires": { "callsites": "^2.0.0" @@ -4113,7 +3086,7 @@ "caller-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", - "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", + "integrity": "sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==", "dev": true, "requires": { "caller-callsite": "^2.0.0" @@ -4122,54 +3095,61 @@ "callsites": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", + "integrity": "sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==", "dev": true }, "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==", "dev": true }, + "cardinal": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", + "integrity": "sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==", + "dev": true, + "requires": { + "ansicolors": "~0.3.2", + "redeyed": "~2.1.0" + } + }, "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", "dev": true }, "cbor": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/cbor/-/cbor-5.2.0.tgz", - "integrity": "sha512-5IMhi9e1QU76ppa5/ajP1BmMWZ2FHkhAhjeVKQ/EFCgYSEaeVaoGtL7cxJskf9oCCk+XjzaIdc3IuU/dbA/o2A==", - "dev": true, + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz", + "integrity": "sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==", "requires": { - "bignumber.js": "^9.0.1", - "nofilter": "^1.0.4" + "nofilter": "^3.1.0" } }, "chai": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", - "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", + "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", "dev": true, "requires": { "assertion-error": "^1.1.0", "check-error": "^1.0.2", "deep-eql": "^3.0.1", "get-func-name": "^2.0.0", + "loupe": "^2.3.1", "pathval": "^1.1.1", "type-detect": "^4.0.5" } }, "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, "chardet": { @@ -4181,28 +3161,28 @@ "charenc": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=", + "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", "dev": true }, "check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", "dev": true }, "chokidar": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", - "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "requires": { - "anymatch": "~3.1.1", + "anymatch": "~3.1.2", "braces": "~3.0.2", - "fsevents": "~2.3.1", - "glob-parent": "~5.1.0", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" + "readdirp": "~3.6.0" } }, "chownr": { @@ -4257,39 +3237,27 @@ "dev": true }, "clean-stack": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-3.0.1.tgz", - "integrity": "sha512-lR9wNiMRcVQjSB3a7xXGLuz4cr4wJuuXlaAEbRutGowQTmlp7R72/DOgN21e8jdwblMWl9UOJMJXarX94pzKdg==", - "dev": true, - "requires": { - "escape-string-regexp": "4.0.0" - }, - "dependencies": { - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - } - } + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true }, "cli-cursor": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==", "dev": true, "requires": { "restore-cursor": "^2.0.0" } }, - "cli-table3": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.1.tgz", - "integrity": "sha512-w0q/enDHhPLq44ovMGdQeeDLvwxwavsJX7oQGYt/LrBlYsyaxyDnp6z3QzFut/6kLLKnlcUVJLrpB7KBfgG/RA==", + "cli-progress": { + "version": "3.11.2", + "resolved": "https://registry.npmjs.org/cli-progress/-/cli-progress-3.11.2.tgz", + "integrity": "sha512-lCPoS6ncgX4+rJu5bS3F/iCz17kZ9MPZ6dpuTtI0KXKABkhyXIdYB3Inby1OpaGti3YlI3EeEkM9AuWpelJrVA==", "dev": true, "requires": { - "colors": "1.4.0", - "string-width": "^4.2.0" + "string-width": "^4.2.3" }, "dependencies": { "ansi-regex": { @@ -4298,12 +3266,6 @@ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -4332,79 +3294,101 @@ } } }, - "cli-width": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", - "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", - "dev": true - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "cli-table3": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.2.tgz", + "integrity": "sha512-QyavHCaIC80cMivimWu4aWHilIpiDpfm3hGmqAmXVL1UsnbLuBSMd21hTX6VY4ZSDSM73ESLeF8TOYId3rBTbw==", "dev": true, "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" + "@colors/colors": "1.5.0", + "string-width": "^4.2.0" }, "dependencies": { "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" } }, "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { - "ansi-regex": "^4.1.0" + "ansi-regex": "^5.0.1" } } } }, + "cli-width": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", + "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", + "dev": true + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + } + }, "clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", + "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", "dev": true, "requires": { "mimic-response": "^1.0.0" + }, + "dependencies": { + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true + } } }, "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=" + "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==" }, "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "requires": { - "color-name": "1.1.3" + "color-name": "~1.1.4" } }, "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "colors": { "version": "1.4.0", @@ -4444,14 +3428,32 @@ "dev": true }, "compare-versions": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-4.1.3.tgz", - "integrity": "sha512-WQfnbDcrYnGr55UwbxKiQKASnTtNnaAWVi8jZyy8NTpVAXWACSne8lMD1iaIo9AiU6mnuLvSVshCzewVuWxHUg==" + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-4.1.4.tgz", + "integrity": "sha512-FemMreK9xNyL8gQevsdRMrvO4lFCkQP7qbuktn1q8ndcNk1+0mz7lgE7b/sNvbhVgY4w6tMN1FDp6aADjqw2rw==" + }, + "compress-brotli": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/compress-brotli/-/compress-brotli-1.3.8.tgz", + "integrity": "sha512-lVcQsjhxhIXsuupfy9fmZUFtAIdBmXA7EGY6GBdgZ++qkM9zG4YFT8iU7FoBxzryNDMOpD1HIFHUSX4D87oqhQ==", + "dev": true, + "requires": { + "@types/json-buffer": "~3.0.0", + "json-buffer": "~3.0.1" + }, + "dependencies": { + "json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + } + } }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, "concat-stream": { @@ -4469,22 +3471,22 @@ "console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", "optional": true }, "content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "dev": true, "requires": { - "safe-buffer": "5.1.2" + "safe-buffer": "5.2.1" }, "dependencies": { "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true } } @@ -4507,33 +3509,33 @@ "dev": true }, "cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", "dev": true }, "cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", "dev": true }, "cookiejar": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", - "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz", + "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==", "dev": true }, "core-js-pure": { - "version": "3.20.3", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.20.3.tgz", - "integrity": "sha512-Q2H6tQ5MtPtcC7f3HxJ48i4Q7T9ybPKgvWyuH7JXIoNa2pm0KuBnycsET/qw1SLLZYfbsbrZQNMeIOClb+6WIA==", + "version": "3.25.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.25.0.tgz", + "integrity": "sha512-IeHpLwk3uoci37yoI2Laty59+YqH9x5uR65/yiA0ARAJrTrN4YU0rmauLWfvqOuk77SlNJXj2rM6oT/dBD87+A==", "dev": true }, "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, "cors": { "version": "2.8.5", @@ -4557,10 +3559,29 @@ "parse-json": "^4.0.0" }, "dependencies": { + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", "dev": true, "requires": { "error-ex": "^1.3.1", @@ -4570,14 +3591,10 @@ } }, "crc-32": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.0.tgz", - "integrity": "sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA==", - "dev": true, - "requires": { - "exit-on-epipe": "~1.0.1", - "printj": "~1.1.0" - } + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "dev": true }, "create-ecdh": { "version": "4.0.4", @@ -4587,6 +3604,14 @@ "requires": { "bn.js": "^4.1.0", "elliptic": "^6.5.3" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } } }, "create-hash": { @@ -4620,6 +3645,15 @@ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, + "cross-fetch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", + "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", + "dev": true, + "requires": { + "node-fetch": "2.6.7" + } + }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -4644,7 +3678,7 @@ "crypt": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=", + "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", "dev": true }, "crypto-browserify": { @@ -4679,7 +3713,7 @@ "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", "dev": true, "requires": { "assert-plus": "^1.0.0" @@ -4688,37 +3722,36 @@ "death": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", - "integrity": "sha1-AaqcQB7dknUFFEcLgmY5DGbGcxg=", + "integrity": "sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w==", "dev": true }, "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", "dev": true }, "decode-uri-component": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "integrity": "sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==", "dev": true }, "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "dev": true, + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", + "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "optional": true, "requires": { - "mimic-response": "^1.0.0" + "mimic-response": "^2.0.0" } }, "deep-eql": { @@ -4737,9 +3770,9 @@ "optional": true }, "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=", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, "defer-to-connect": { @@ -4774,23 +3807,24 @@ } }, "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", "dev": true, "requires": { - "object-keys": "^1.0.12" + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" } }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" }, "delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", "optional": true }, "delete-empty": { @@ -4806,9 +3840,9 @@ } }, "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "dev": true }, "des.js": { @@ -4822,15 +3856,15 @@ } }, "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "dev": true }, "detect-libc": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", "optional": true }, "detect-port": { @@ -4855,15 +3889,15 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true } } }, "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true }, "diffie-hellman": { @@ -4875,6 +3909,14 @@ "bn.js": "^4.1.0", "miller-rabin": "^4.0.0", "randombytes": "^2.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } } }, "dir-glob": { @@ -4914,27 +3956,16 @@ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" }, - "drbg.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", - "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", - "dev": true, - "requires": { - "browserify-aes": "^1.0.6", - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4" - } - }, "duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz", + "integrity": "sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==", "dev": true }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", "dev": true, "requires": { "jsbn": "~0.1.0", @@ -4944,9 +3975,18 @@ "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", "dev": true }, + "ejs": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz", + "integrity": "sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==", + "dev": true, + "requires": { + "jake": "^10.8.5" + } + }, "elliptic": { "version": "6.5.4", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", @@ -4959,18 +3999,25 @@ "inherits": "^2.0.4", "minimalistic-assert": "^1.0.1", "minimalistic-crypto-utils": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + } } }, "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "dev": true }, "encoding-down": { @@ -5027,43 +4074,56 @@ } }, "es-abstract": { - "version": "1.18.0-next.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.3.tgz", - "integrity": "sha512-VMzHx/Bczjg59E6jZOQjHeN3DEoptdhejpARgflAViidlqSpjdq9zA6lKwlhRRs/lOw1gHJv2xkkSFRgvEwbQg==", + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.1.tgz", + "integrity": "sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==", "dev": true, "requires": { "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", + "function.prototype.name": "^1.1.5", "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", "has": "^1.0.3", - "has-symbols": "^1.0.2", - "is-callable": "^1.2.3", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.2", - "is-string": "^1.0.5", - "object-inspect": "^1.9.0", + "has-property-descriptors": "^1.0.0", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.0", "object-keys": "^1.1.1", "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.0" + "regexp.prototype.flags": "^1.4.3", + "string.prototype.trimend": "^1.0.5", + "string.prototype.trimstart": "^1.0.5", + "unbox-primitive": "^1.0.2" }, "dependencies": { "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", "dev": true, "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", "object-keys": "^1.1.1" } } } }, + "es-array-method-boxes-properly": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", + "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", + "dev": true + }, "es-to-primitive": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", @@ -5076,20 +4136,20 @@ } }, "es5-ext": { - "version": "0.10.53", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", - "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", + "version": "0.10.62", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", + "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", "dev": true, "requires": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.3", - "next-tick": "~1.0.0" + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "next-tick": "^1.1.0" } }, "es6-iterator": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", "dev": true, "requires": { "d": "1", @@ -5097,6 +4157,12 @@ "es6-symbol": "^3.1.1" } }, + "es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", + "dev": true + }, "es6-symbol": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", @@ -5107,22 +4173,28 @@ "ext": "^1.1.2" } }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "dev": true }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true }, "escodegen": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", - "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", + "integrity": "sha512-yhi5S+mNTOuRvyW4gWlg5W1byMaQGWWSYHXsuFZ7GBo7tpyOwi2EdzMP/QWxh9hwkD2m+wDVHJsxhRIj+v/b/A==", "dev": true, "requires": { "esprima": "^2.7.1", @@ -5135,14 +4207,24 @@ "esprima": { "version": "2.7.3", "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "integrity": "sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==", "dev": true }, "estraverse": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", - "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", + "integrity": "sha512-25w1fMXQrGdoquWnScXZGckOv+Wes+JDnuN/+7ex3SauFRS72r2lFDec0EKPt2YD1wUJ/IrfEex+9yp4hfSOJA==", "dev": true + }, + "source-map": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", + "integrity": "sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA==", + "dev": true, + "optional": true, + "requires": { + "amdefine": ">=0.0.4" + } } } }, @@ -5190,30 +4272,117 @@ "text-table": "^0.2.0" }, "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "requires": { - "ms": "2.1.2" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" + "color-convert": "^1.9.0" } }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, "resolve-from": { "version": "4.0.0", @@ -5226,6 +4395,75 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true + }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + } + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "requires": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + } } } }, @@ -5281,9 +4519,9 @@ }, "dependencies": { "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true } } @@ -5298,9 +4536,9 @@ }, "dependencies": { "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true } } @@ -5320,30 +4558,38 @@ "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "dev": true }, "eth-ens-namehash": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz", - "integrity": "sha1-IprEbsqG1S4MmR58sq74P/D2i88=", + "integrity": "sha512-VWEI1+KJfz4Km//dadyvBBoBeSQ0MHTXPvr8UIXiLW6IanxvAV+DmlZAijZwAyggqGUfwQBeHf7tc9wzc1piSw==", "dev": true, "requires": { "idna-uts46-hx": "^2.3.1", "js-sha3": "^0.5.7" + }, + "dependencies": { + "js-sha3": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", + "integrity": "sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==", + "dev": true + } } }, "eth-gas-reporter": { - "version": "0.2.24", - "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.24.tgz", - "integrity": "sha512-RbXLC2bnuPHzIMU/rnLXXlb6oiHEEKu7rq2UrAX/0mfo0Lzrr/kb9QTjWjfz8eNvc+uu6J8AuBwI++b+MLNI2w==", + "version": "0.2.25", + "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.25.tgz", + "integrity": "sha512-1fRgyE4xUB8SoqLgN3eDfpDfwEfRxh2Sz1b7wzFbyQA+9TekMmvSjjoRu9SKcSVyK+vLkLIsVbJDsTWjw195OQ==", "dev": true, "requires": { "@ethersproject/abi": "^5.0.0-beta.146", "@solidity-parser/parser": "^0.14.0", "cli-table3": "^0.5.0", "colors": "1.4.0", - "ethereumjs-util": "6.2.0", + "ethereum-cryptography": "^1.0.3", "ethers": "^4.0.40", "fs-readdir-recursive": "^1.1.0", "lodash": "^4.17.14", @@ -5356,13 +4602,84 @@ "sync-request": "^6.0.0" }, "dependencies": { - "@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "ansi-colors": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", + "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", + "dev": true + }, + "ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "@types/node": "*" + "color-convert": "^1.9.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "chokidar": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", + "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.1", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.2.0" } }, "cli-table3": { @@ -5376,19 +4693,91 @@ "string-width": "^2.1.1" } }, - "ethereumjs-util": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.0.tgz", - "integrity": "sha512-vb0XN9J2QGdZGIEKG2vXM+kUdEivUfU6Wmi5y0cg+LRhDYKnXIZ/Lz7XjFbHRR9VIKq2lVGLzGBkA++y2nOdOQ==", + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", "dev": true, "requires": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "ethjs-util": "0.1.6", - "keccak": "^2.0.0", - "rlp": "^2.2.3", - "secp256k1": "^3.0.1" + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "ethereum-cryptography": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.1.2.tgz", + "integrity": "sha512-XDSJlg4BD+hq9N2FjvotwUET9Tfxpxc3kWGE2AqUG5vcbeunnbImVk3cj6e/xT3phdW21mE8R5IugU4fspQDcQ==", + "dev": true, + "requires": { + "@noble/hashes": "1.1.2", + "@noble/secp256k1": "1.6.3", + "@scure/bip32": "1.1.0", + "@scure/bip39": "1.1.0" } }, "ethers": { @@ -5408,119 +4797,424 @@ "xmlhttprequest": "1.8.0" } }, - "hash.js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", - "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.0" + "locate-path": "^3.0.0" } }, - "keccak": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-2.1.0.tgz", - "integrity": "sha512-m1wbJRTo+gWbctZWay9i26v5fFnYkOn7D5PCxJ3fZUGUEb49dE1Pm4BREUYCt/aoO6di7jeoGmhvqN9Nzylm3Q==", + "flat": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", + "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", "dev": true, "requires": { - "bindings": "^1.5.0", - "inherits": "^2.0.4", - "nan": "^2.14.0", - "safe-buffer": "^5.2.0" + "is-buffer": "~2.0.3" } }, - "scrypt-js": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz", - "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==", + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, - "secp256k1": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.8.0.tgz", - "integrity": "sha512-k5ke5avRZbtl9Tqx/SA7CbY3NF6Ro+Sj9cZxezFzuBlLDmyqPiL8hJJ+EmzD8Ig4LUDByHJ3/iPOVoRixs/hmw==", + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", "dev": true, "requires": { - "bindings": "^1.5.0", - "bip66": "^1.1.5", - "bn.js": "^4.11.8", - "create-hash": "^1.2.0", - "drbg.js": "^1.0.1", - "elliptic": "^6.5.2", - "nan": "^2.14.0", - "safe-buffer": "^5.1.2" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "hash.js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", + "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true + }, + "js-sha3": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", + "integrity": "sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "log-symbols": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", + "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "dev": true, + "requires": { + "chalk": "^2.4.2" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "mocha": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", + "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", + "dev": true, + "requires": { + "ansi-colors": "3.2.3", + "browser-stdout": "1.3.1", + "chokidar": "3.3.0", + "debug": "3.2.6", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "find-up": "3.0.0", + "glob": "7.1.3", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.13.1", + "log-symbols": "3.0.0", + "minimatch": "3.0.4", + "mkdirp": "0.5.5", + "ms": "2.1.1", + "node-environment-flags": "1.0.6", + "object.assign": "4.1.0", + "strip-json-comments": "2.0.1", + "supports-color": "6.0.0", + "which": "1.3.1", + "wide-align": "1.1.3", + "yargs": "13.3.2", + "yargs-parser": "13.1.2", + "yargs-unparser": "1.6.0" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true + }, + "readdirp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", + "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", + "dev": true, + "requires": { + "picomatch": "^2.0.4" } }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "scrypt-js": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz", + "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==", + "dev": true + }, "setimmediate": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz", - "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=", + "integrity": "sha512-/TjEmXQVEzdod/FFskf3o7oOAsGhHf2j1dZqRFbDzq4F3mvvxflIIi4Hd3bLQE9y/CpwqfSQam5JakI/mi3Pog==", "dev": true }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "supports-color": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", + "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, "uuid": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", - "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=", + "integrity": "sha512-nWg9+Oa3qD2CQzHIP4qKUqwNfzKn8P0LtFhotaCTFchsV7ZfDhAybeip/HZVeMIpZi9JgY1E3nUlwaCmZT1sEg==", + "dev": true + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", + "dev": true + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", "dev": true + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "yargs-unparser": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", + "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", + "dev": true, + "requires": { + "flat": "^4.1.0", + "lodash": "^4.17.15", + "yargs": "^13.3.0" + } } } }, "eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "version": "0.1.29", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.29.tgz", + "integrity": "sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ==", "dev": true, "requires": { "bn.js": "^4.11.6", "elliptic": "^6.4.0", + "nano-json-stream-parser": "^0.1.2", + "servify": "^0.1.12", + "ws": "^3.0.0", "xhr-request-promise": "^0.1.2" - } - }, - "eth-sig-util": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-2.5.4.tgz", - "integrity": "sha512-aCMBwp8q/4wrW4QLsF/HYBOSA7TpLKmkVwP3pYQNkEEseW2Rr8Z5Uxc9/h6HX+OG3tuHo+2bINVSihIeBfym6A==", - "dev": true, - "requires": { - "ethereumjs-abi": "0.6.8", - "ethereumjs-util": "^5.1.1", - "tweetnacl": "^1.0.3", - "tweetnacl-util": "^0.15.0" }, "dependencies": { - "ethereumjs-util": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz", - "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==", + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", "dev": true, "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" } } } }, "ethereum-bloom-filters": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.9.tgz", - "integrity": "sha512-GiK/RQkAkcVaEdxKVkPcG07PQ5vD7v2MFSHgZmBJSfMzNRHimntdBithsHAT89tAXnIpzVDWt8iaCD1DvkaxGg==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz", + "integrity": "sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA==", "dev": true, "requires": { "js-sha3": "^0.8.0" - }, - "dependencies": { - "js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", - "dev": true - } } }, "ethereum-cryptography": { @@ -5546,15 +5240,15 @@ } }, "ethereum-waffle": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/ethereum-waffle/-/ethereum-waffle-3.4.0.tgz", - "integrity": "sha512-ADBqZCkoSA5Isk486ntKJVjFEawIiC+3HxNqpJqONvh3YXBTNiRfXvJtGuAFLXPG91QaqkGqILEHANAo7j/olQ==", + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/ethereum-waffle/-/ethereum-waffle-3.4.4.tgz", + "integrity": "sha512-PA9+jCjw4WC3Oc5ocSMBj5sXvueWQeAbvCA+hUlb6oFgwwKyq5ka3bWQ7QZcjzIX+TdFkxP4IbFmoY2D8Dkj9Q==", "dev": true, "requires": { - "@ethereum-waffle/chai": "^3.4.0", - "@ethereum-waffle/compiler": "^3.4.0", - "@ethereum-waffle/mock-contract": "^3.3.0", - "@ethereum-waffle/provider": "^3.4.0", + "@ethereum-waffle/chai": "^3.4.4", + "@ethereum-waffle/compiler": "^3.4.4", + "@ethereum-waffle/mock-contract": "^3.4.4", + "@ethereum-waffle/provider": "^3.4.4", "ethers": "^5.0.1" } }, @@ -5577,6 +5271,12 @@ "@types/node": "*" } }, + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, "ethereumjs-util": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", @@ -5595,66 +5295,58 @@ } }, "ethereumjs-util": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.3.tgz", - "integrity": "sha512-y+82tEbyASO0K0X1/SRhbJJoAlfcvq8JbrG4a5cjrOks7HS/36efU/0j2flxCPOUM++HFahk33kr/ZxyC4vNuw==", + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", + "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", "requires": { "@types/bn.js": "^5.1.0", "bn.js": "^5.1.2", "create-hash": "^1.1.2", "ethereum-cryptography": "^0.1.3", "rlp": "^2.2.4" - }, - "dependencies": { - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - } } }, "ethers": { - "version": "5.4.4", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.4.4.tgz", - "integrity": "sha512-zaTs8yaDjfb0Zyj8tT6a+/hEkC+kWAA350MWRp6yP5W7NdGcURRPMOpOU+6GtkfxV9wyJEShWesqhE/TjdqpMA==", - "dev": true, - "requires": { - "@ethersproject/abi": "5.4.0", - "@ethersproject/abstract-provider": "5.4.1", - "@ethersproject/abstract-signer": "5.4.1", - "@ethersproject/address": "5.4.0", - "@ethersproject/base64": "5.4.0", - "@ethersproject/basex": "5.4.0", - "@ethersproject/bignumber": "5.4.1", - "@ethersproject/bytes": "5.4.0", - "@ethersproject/constants": "5.4.0", - "@ethersproject/contracts": "5.4.1", - "@ethersproject/hash": "5.4.0", - "@ethersproject/hdnode": "5.4.0", - "@ethersproject/json-wallets": "5.4.0", - "@ethersproject/keccak256": "5.4.0", - "@ethersproject/logger": "5.4.0", - "@ethersproject/networks": "5.4.2", - "@ethersproject/pbkdf2": "5.4.0", - "@ethersproject/properties": "5.4.0", - "@ethersproject/providers": "5.4.3", - "@ethersproject/random": "5.4.0", - "@ethersproject/rlp": "5.4.0", - "@ethersproject/sha2": "5.4.0", - "@ethersproject/signing-key": "5.4.0", - "@ethersproject/solidity": "5.4.0", - "@ethersproject/strings": "5.4.0", - "@ethersproject/transactions": "5.4.0", - "@ethersproject/units": "5.4.0", - "@ethersproject/wallet": "5.4.0", - "@ethersproject/web": "5.4.0", - "@ethersproject/wordlists": "5.4.0" + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.0.tgz", + "integrity": "sha512-5Xhzp2ZQRi0Em+0OkOcRHxPzCfoBfgtOQA+RUylSkuHbhTEaQklnYi2hsWbRgs3ztJsXVXd9VKBcO1ScWL8YfA==", + "requires": { + "@ethersproject/abi": "5.7.0", + "@ethersproject/abstract-provider": "5.7.0", + "@ethersproject/abstract-signer": "5.7.0", + "@ethersproject/address": "5.7.0", + "@ethersproject/base64": "5.7.0", + "@ethersproject/basex": "5.7.0", + "@ethersproject/bignumber": "5.7.0", + "@ethersproject/bytes": "5.7.0", + "@ethersproject/constants": "5.7.0", + "@ethersproject/contracts": "5.7.0", + "@ethersproject/hash": "5.7.0", + "@ethersproject/hdnode": "5.7.0", + "@ethersproject/json-wallets": "5.7.0", + "@ethersproject/keccak256": "5.7.0", + "@ethersproject/logger": "5.7.0", + "@ethersproject/networks": "5.7.0", + "@ethersproject/pbkdf2": "5.7.0", + "@ethersproject/properties": "5.7.0", + "@ethersproject/providers": "5.7.0", + "@ethersproject/random": "5.7.0", + "@ethersproject/rlp": "5.7.0", + "@ethersproject/sha2": "5.7.0", + "@ethersproject/signing-key": "5.7.0", + "@ethersproject/solidity": "5.7.0", + "@ethersproject/strings": "5.7.0", + "@ethersproject/transactions": "5.7.0", + "@ethersproject/units": "5.7.0", + "@ethersproject/wallet": "5.7.0", + "@ethersproject/web": "5.7.0", + "@ethersproject/wordlists": "5.7.0" } }, "ethjs-unit": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", - "integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=", + "integrity": "sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==", "dev": true, "requires": { "bn.js": "4.11.6", @@ -5664,7 +5356,7 @@ "bn.js": { "version": "4.11.6", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", "dev": true } } @@ -5705,12 +5397,6 @@ "safe-buffer": "^5.1.1" } }, - "exit-on-epipe": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz", - "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==", - "dev": true - }, "expand-template": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", @@ -5718,47 +5404,48 @@ "optional": true }, "express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", + "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", "dev": true, "requires": { - "accepts": "~1.3.7", + "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", + "body-parser": "1.20.0", + "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.4.0", + "cookie": "0.5.0", "cookie-signature": "1.0.6", "debug": "2.6.9", - "depd": "~1.1.2", + "depd": "2.0.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "~1.1.2", + "finalhandler": "1.2.0", "fresh": "0.5.2", + "http-errors": "2.0.0", "merge-descriptors": "1.0.1", "methods": "~1.1.2", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", + "proxy-addr": "~2.0.7", + "qs": "6.10.3", "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" }, "dependencies": { "cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", "dev": true }, "debug": { @@ -5773,36 +5460,39 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", - "dev": true + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", + "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "dev": true, + "requires": { + "side-channel": "^1.0.4" + } }, "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==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true } } }, "ext": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", - "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.6.0.tgz", + "integrity": "sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==", "dev": true, "requires": { - "type": "^2.0.0" + "type": "^2.5.0" }, "dependencies": { "type": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/type/-/type-2.5.0.tgz", - "integrity": "sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", "dev": true } } @@ -5827,7 +5517,7 @@ "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", "dev": true }, "fast-deep-equal": { @@ -5843,17 +5533,16 @@ "dev": true }, "fast-glob": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", - "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", + "glob-parent": "^5.1.2", "merge2": "^1.3.0", - "micromatch": "^4.0.2", - "picomatch": "^2.2.1" + "micromatch": "^4.0.4" } }, "fast-json-stable-stringify": { @@ -5865,13 +5554,13 @@ "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, "fastq": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", - "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", "dev": true, "requires": { "reusify": "^1.0.4" @@ -5880,7 +5569,7 @@ "figures": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", "dev": true, "requires": { "escape-string-regexp": "^1.0.5" @@ -5898,7 +5587,37 @@ "file-uri-to-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "optional": true + }, + "filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dev": true, + "requires": { + "minimatch": "^5.0.1" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", + "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } + } }, "fill-range": { "version": "7.0.1", @@ -5909,17 +5628,17 @@ } }, "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", "dev": true, "requires": { "debug": "2.6.9", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "parseurl": "~1.3.3", - "statuses": "~1.5.0", + "statuses": "2.0.1", "unpipe": "~1.0.0" }, "dependencies": { @@ -5932,968 +5651,216 @@ "ms": "2.0.0" } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "find-replace": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-1.0.3.tgz", - "integrity": "sha1-uI5zZNLZyVlVnziMZmcNYTBEH6A=", - "dev": true, - "requires": { - "array-back": "^1.0.4", - "test-value": "^2.1.0" - }, - "dependencies": { - "array-back": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", - "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", - "dev": true, - "requires": { - "typical": "^2.6.0" - } - } - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "find-yarn-workspace-root": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz", - "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==", - "dev": true, - "requires": { - "micromatch": "^4.0.2" - } - }, - "flat": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", - "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - } - }, - "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", - "dev": true, - "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" - }, - "dependencies": { - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", - "dev": true - }, - "follow-redirects": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz", - "integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==", - "dev": true - }, - "foreach": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", - "dev": true - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true - }, - "form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "dev": true - }, - "fp-ts": { - "version": "1.19.3", - "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz", - "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==", - "dev": true - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "dev": true - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "optional": true - }, - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "fs-minipass": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", - "dev": true, - "requires": { - "minipass": "^2.6.0" - } - }, - "fs-readdir-recursive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", - "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "ganache-cli": { - "version": "6.12.2", - "resolved": "https://registry.npmjs.org/ganache-cli/-/ganache-cli-6.12.2.tgz", - "integrity": "sha512-bnmwnJDBDsOWBUP8E/BExWf85TsdDEFelQSzihSJm9VChVO1SHp94YXLP5BlA4j/OTxp0wR4R1Tje9OHOuAJVw==", - "dev": true, - "requires": { - "ethereumjs-util": "6.2.1", - "source-map-support": "0.5.12", - "yargs": "13.2.4" - }, - "dependencies": { - "@types/bn.js": { - "version": "4.11.6", - "bundled": true, - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/node": { - "version": "14.11.2", - "bundled": true, - "dev": true - }, - "@types/pbkdf2": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/secp256k1": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "ansi-regex": { - "version": "4.1.0", - "bundled": true, - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "bundled": true, - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "base-x": { - "version": "3.0.8", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "blakejs": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "bn.js": { - "version": "4.11.9", - "bundled": true, - "dev": true - }, - "brorand": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "bs58": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "requires": { - "base-x": "^3.0.2" - } - }, - "bs58check": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "requires": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" - } - }, - "buffer-from": { - "version": "1.1.1", - "bundled": true, - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "bundled": true, - "dev": true - }, - "camelcase": { - "version": "5.3.1", - "bundled": true, - "dev": true - }, - "cipher-base": { - "version": "1.0.4", - "bundled": true, - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "cliui": { - "version": "5.0.0", - "bundled": true, - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "color-convert": { - "version": "1.9.3", - "bundled": true, - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "bundled": true, - "dev": true - }, - "create-hash": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "bundled": true, - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "cross-spawn": { - "version": "6.0.5", - "bundled": true, - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "decamelize": { - "version": "1.2.0", - "bundled": true, - "dev": true - }, - "elliptic": { - "version": "6.5.3", - "bundled": true, - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "bundled": true, - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "bundled": true, - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "ethereum-cryptography": { - "version": "0.1.3", - "bundled": true, - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "ethereumjs-util": { - "version": "6.2.1", - "bundled": true, - "dev": true, - "requires": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - } - }, - "ethjs-util": { - "version": "0.1.6", - "bundled": true, - "dev": true, - "requires": { - "is-hex-prefixed": "1.0.0", - "strip-hex-prefix": "1.0.0" - } - }, - "evp_bytestokey": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "execa": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "find-up": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "get-caller-file": { - "version": "2.0.5", - "bundled": true, - "dev": true - }, - "get-stream": { - "version": "4.1.0", - "bundled": true, - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "hash-base": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - } - }, - "hash.js": { - "version": "1.1.7", - "bundled": true, - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "hmac-drbg": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "inherits": { - "version": "2.0.4", - "bundled": true, - "dev": true - }, - "invert-kv": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "is-hex-prefixed": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "is-stream": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "isexe": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "keccak": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - } - }, - "lcid": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "invert-kv": "^2.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "map-age-cleaner": { - "version": "0.1.3", - "bundled": true, - "dev": true, - "requires": { - "p-defer": "^1.0.0" - } - }, - "md5.js": { - "version": "1.3.5", - "bundled": true, - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "mem": { - "version": "4.3.0", - "bundled": true, - "dev": true, - "requires": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^2.0.0", - "p-is-promise": "^2.0.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "bundled": true, - "dev": true - }, - "minimalistic-assert": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "nice-try": { - "version": "1.0.5", - "bundled": true, - "dev": true - }, - "node-addon-api": { - "version": "2.0.2", - "bundled": true, - "dev": true - }, - "node-gyp-build": { - "version": "4.2.3", - "bundled": true, - "dev": true - }, - "npm-run-path": { - "version": "2.0.2", - "bundled": true, - "dev": true, - "requires": { - "path-key": "^2.0.0" - } - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "os-locale": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "execa": "^1.0.0", - "lcid": "^2.0.0", - "mem": "^4.0.0" - } - }, - "p-defer": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "p-finally": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "p-is-promise": { - "version": "2.1.0", - "bundled": true, - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "bundled": true, - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "bundled": true, - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "path-key": { - "version": "2.0.1", - "bundled": true, - "dev": true - }, - "pbkdf2": { - "version": "3.1.1", - "bundled": true, - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "pump": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "randombytes": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "3.6.0", - "bundled": true, - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "require-directory": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "ripemd160": { - "version": "2.0.2", - "bundled": true, - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "rlp": { - "version": "2.2.6", - "bundled": true, - "dev": true, - "requires": { - "bn.js": "^4.11.1" - } - }, - "safe-buffer": { - "version": "5.2.1", - "bundled": true, - "dev": true - }, - "scrypt-js": { - "version": "3.0.1", - "bundled": true, - "dev": true - }, - "secp256k1": { - "version": "4.0.2", - "bundled": true, - "dev": true, - "requires": { - "elliptic": "^6.5.2", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - } - }, - "semver": { - "version": "5.7.1", - "bundled": true, - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "setimmediate": { - "version": "1.0.5", - "bundled": true, - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "bundled": true, - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shebang-command": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "signal-exit": { - "version": "3.0.3", - "bundled": true, - "dev": true - }, - "source-map": { - "version": "0.6.1", - "bundled": true, - "dev": true - }, - "source-map-support": { - "version": "0.5.12", - "bundled": true, - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "string-width": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "string_decoder": { - "version": "1.3.0", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "strip-eof": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "strip-hex-prefix": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "is-hex-prefixed": "1.0.0" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "which": { - "version": "1.3.1", - "bundled": true, - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "wrap-ansi": { - "version": "5.1.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "y18n": { - "version": "4.0.0", - "bundled": true, - "dev": true - }, - "yargs": { - "version": "13.2.4", - "bundled": true, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + } + } + }, + "find-replace": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-1.0.3.tgz", + "integrity": "sha512-KrUnjzDCD9426YnCP56zGYy/eieTnhtK6Vn++j+JJzmlsWWwEkDnsyVF575spT6HJ6Ow9tlbT3TQTDsa+O4UWA==", + "dev": true, + "requires": { + "array-back": "^1.0.4", + "test-value": "^2.1.0" + }, + "dependencies": { + "array-back": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", + "integrity": "sha512-1WxbZvrmyhkNoeYcizokbmh5oiOCIfyvGtcqbK3Ls1v1fKcquzxnQSceOx6tzq7jmai2kFLWIpGND2cLhH6TPw==", "dev": true, "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "os-locale": "^3.1.0", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.0" + "typical": "^2.6.0" } - }, - "yargs-parser": { - "version": "13.1.2", - "bundled": true, + } + } + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==", + "dev": true, + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "find-yarn-workspace-root": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz", + "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==", + "dev": true, + "requires": { + "micromatch": "^4.0.2" + } + }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + }, + "dependencies": { + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", "dev": true, "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" + "glob": "^7.1.3" } } } }, + "flatted": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "dev": true + }, + "follow-redirects": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", + "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==" + }, + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "requires": { + "is-callable": "^1.1.3" + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "dev": true + }, + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "form-data-encoder": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.1.tgz", + "integrity": "sha512-EFRDrsMm/kyqbTQocNvRXMLjc7Es2Vk+IQFx/YW7hkUH1eBl4J1fqiP34l74Yt0pFLCNpc06fkbVk00008mzjg==", + "dev": true + }, + "forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true + }, + "fp-ts": { + "version": "1.19.3", + "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz", + "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==", + "dev": true + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true + }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "optional": true + }, + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "dev": true, + "requires": { + "minipass": "^2.6.0" + } + }, + "fs-readdir-recursive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", + "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + } + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "dev": true + }, + "functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true + }, "ganache-core": { "version": "2.13.2", "resolved": "https://registry.npmjs.org/ganache-core/-/ganache-core-2.13.2.tgz", @@ -7266,7 +6233,7 @@ "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", "dev": true }, "arr-flatten": { @@ -7278,20 +6245,20 @@ "arr-union": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", "dev": true }, "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", "dev": true, "optional": true }, "array-unique": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", "dev": true }, "asn1": { @@ -7319,13 +6286,13 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", "dev": true }, "assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", "dev": true }, "async": { @@ -7355,7 +6322,7 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "dev": true }, "atob": { @@ -7367,7 +6334,7 @@ "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=", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", "dev": true }, "aws4": { @@ -7379,7 +6346,7 @@ "babel-code-frame": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "integrity": "sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==", "dev": true, "requires": { "chalk": "^1.1.3", @@ -7390,19 +6357,19 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", "dev": true }, "ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", "dev": true }, "chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", "dev": true, "requires": { "ansi-styles": "^2.2.1", @@ -7415,13 +6382,13 @@ "js-tokens": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "integrity": "sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==", "dev": true }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", "dev": true, "requires": { "ansi-regex": "^2.0.0" @@ -7430,7 +6397,7 @@ "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", "dev": true } } @@ -7474,19 +6441,19 @@ "json5": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "integrity": "sha512-4xrs1aW+6N5DalkqSVA8fxh458CXvR99WU8WLKmq4v8eWAL86Xo3BVqyd3SkA9wEVjCMqyvvRRkshAdOnBp5rw==", "dev": true }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, "slash": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "integrity": "sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg==", "dev": true } } @@ -7510,7 +6477,7 @@ "jsesc": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", - "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", + "integrity": "sha512-Mke0DA0QjUWuJlhsE0ZPPhYiJkRap642SmI/4ztCFaUs6V2AiH1sfecc+57NgaryfAA2VR3v6O+CSjC1jZJKOA==", "dev": true } } @@ -7518,7 +6485,7 @@ "babel-helper-builder-binary-assignment-operator-visitor": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", - "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", + "integrity": "sha512-gCtfYORSG1fUMX4kKraymq607FWgMWg+j42IFPc18kFQEsmtaibP4UrqsXt8FlEJle25HUd4tsoDR7H2wDhe9Q==", "dev": true, "requires": { "babel-helper-explode-assignable-expression": "^6.24.1", @@ -7529,7 +6496,7 @@ "babel-helper-call-delegate": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", - "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", + "integrity": "sha512-RL8n2NiEj+kKztlrVJM9JT1cXzzAdvWFh76xh/H1I4nKwunzE4INBXn8ieCZ+wh4zWszZk7NBS1s/8HR5jDkzQ==", "dev": true, "requires": { "babel-helper-hoist-variables": "^6.24.1", @@ -7541,7 +6508,7 @@ "babel-helper-define-map": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", - "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", + "integrity": "sha512-bHkmjcC9lM1kmZcVpA5t2om2nzT/xiZpo6TJq7UlZ3wqKfzia4veeXbIhKvJXAMzhhEBd3cR1IElL5AenWEUpA==", "dev": true, "requires": { "babel-helper-function-name": "^6.24.1", @@ -7553,7 +6520,7 @@ "babel-helper-explode-assignable-expression": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", - "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", + "integrity": "sha512-qe5csbhbvq6ccry9G7tkXbzNtcDiH4r51rrPUbwwoTzZ18AqxWYRZT6AOmxrpxKnQBW0pYlBI/8vh73Z//78nQ==", "dev": true, "requires": { "babel-runtime": "^6.22.0", @@ -7564,7 +6531,7 @@ "babel-helper-function-name": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", - "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", + "integrity": "sha512-Oo6+e2iX+o9eVvJ9Y5eKL5iryeRdsIkwRYheCuhYdVHsdEQysbc2z2QkqCLIYnNxkT5Ss3ggrHdXiDI7Dhrn4Q==", "dev": true, "requires": { "babel-helper-get-function-arity": "^6.24.1", @@ -7577,7 +6544,7 @@ "babel-helper-get-function-arity": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", - "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", + "integrity": "sha512-WfgKFX6swFB1jS2vo+DwivRN4NB8XUdM3ij0Y1gnC21y1tdBoe6xjVnd7NSI6alv+gZXCtJqvrTeMW3fR/c0ng==", "dev": true, "requires": { "babel-runtime": "^6.22.0", @@ -7587,7 +6554,7 @@ "babel-helper-hoist-variables": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", - "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", + "integrity": "sha512-zAYl3tqerLItvG5cKYw7f1SpvIxS9zi7ohyGHaI9cgDUjAT6YcY9jIEH5CstetP5wHIVSceXwNS7Z5BpJg+rOw==", "dev": true, "requires": { "babel-runtime": "^6.22.0", @@ -7597,7 +6564,7 @@ "babel-helper-optimise-call-expression": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", - "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", + "integrity": "sha512-Op9IhEaxhbRT8MDXx2iNuMgciu2V8lDvYCNQbDGjdBNCjaMvyLf4wl4A3b8IgndCyQF8TwfgsQ8T3VD8aX1/pA==", "dev": true, "requires": { "babel-runtime": "^6.22.0", @@ -7607,7 +6574,7 @@ "babel-helper-regex": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", - "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", + "integrity": "sha512-VlPiWmqmGJp0x0oK27Out1D+71nVVCTSdlbhIVoaBAj2lUgrNjBCRR9+llO4lTSb2O4r7PJg+RobRkhBrf6ofg==", "dev": true, "requires": { "babel-runtime": "^6.26.0", @@ -7618,7 +6585,7 @@ "babel-helper-remap-async-to-generator": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", - "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", + "integrity": "sha512-RYqaPD0mQyQIFRu7Ho5wE2yvA/5jxqCIj/Lv4BXNq23mHYu/vxikOy2JueLiBxQknwapwrJeNCesvY0ZcfnlHg==", "dev": true, "requires": { "babel-helper-function-name": "^6.24.1", @@ -7631,7 +6598,7 @@ "babel-helper-replace-supers": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", - "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", + "integrity": "sha512-sLI+u7sXJh6+ToqDr57Bv973kCepItDhMou0xCP2YPVmR1jkHSCY+p1no8xErbV1Siz5QE8qKT1WIwybSWlqjw==", "dev": true, "requires": { "babel-helper-optimise-call-expression": "^6.24.1", @@ -7645,7 +6612,7 @@ "babel-helpers": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", - "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", + "integrity": "sha512-n7pFrqQm44TCYvrCDb0MqabAF+JUBq+ijBvNMUxpkLjJaAu32faIexewMumrH5KLLJ1HDyT0PTEqRyAe/GwwuQ==", "dev": true, "requires": { "babel-runtime": "^6.22.0", @@ -7655,7 +6622,7 @@ "babel-messages": { "version": "6.23.0", "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", - "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "integrity": "sha512-Bl3ZiA+LjqaMtNYopA9TYE9HP1tQ+E5dLxE0XrAzcIJeK2UqF0/EaqXwBn9esd4UmTfEab+P+UYQ1GnioFIb/w==", "dev": true, "requires": { "babel-runtime": "^6.22.0" @@ -7664,7 +6631,7 @@ "babel-plugin-check-es2015-constants": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", - "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", + "integrity": "sha512-B1M5KBP29248dViEo1owyY32lk1ZSH2DaNNrXLGt8lyjjHm7pBqAdQ7VKUPR6EEDO323+OvT3MQXbCin8ooWdA==", "dev": true, "requires": { "babel-runtime": "^6.22.0" @@ -7673,25 +6640,25 @@ "babel-plugin-syntax-async-functions": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", - "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=", + "integrity": "sha512-4Zp4unmHgw30A1eWI5EpACji2qMocisdXhAftfhXoSV9j0Tvj6nRFE3tOmRY912E0FMRm/L5xWE7MGVT2FoLnw==", "dev": true }, "babel-plugin-syntax-exponentiation-operator": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", - "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=", + "integrity": "sha512-Z/flU+T9ta0aIEKl1tGEmN/pZiI1uXmCiGFRegKacQfEJzp7iNsKloZmyJlQr+75FCJtiFfGIK03SiCvCt9cPQ==", "dev": true }, "babel-plugin-syntax-trailing-function-commas": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", - "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=", + "integrity": "sha512-Gx9CH3Q/3GKbhs07Bszw5fPTlU+ygrOGfAhEt7W2JICwufpC4SuO0mG0+4NykPBSYPMJhqvVlDBU17qB1D+hMQ==", "dev": true }, "babel-plugin-transform-async-to-generator": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", - "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", + "integrity": "sha512-7BgYJujNCg0Ti3x0c/DL3tStvnKS6ktIYOmo9wginv/dfZOrbSZ+qG4IRRHMBOzZ5Awb1skTiAsQXg/+IWkZYw==", "dev": true, "requires": { "babel-helper-remap-async-to-generator": "^6.24.1", @@ -7702,7 +6669,7 @@ "babel-plugin-transform-es2015-arrow-functions": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", - "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", + "integrity": "sha512-PCqwwzODXW7JMrzu+yZIaYbPQSKjDTAsNNlK2l5Gg9g4rz2VzLnZsStvp/3c46GfXpwkyufb3NCyG9+50FF1Vg==", "dev": true, "requires": { "babel-runtime": "^6.22.0" @@ -7711,7 +6678,7 @@ "babel-plugin-transform-es2015-block-scoped-functions": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", - "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", + "integrity": "sha512-2+ujAT2UMBzYFm7tidUsYh+ZoIutxJ3pN9IYrF1/H6dCKtECfhmB8UkHVpyxDwkj0CYbQG35ykoz925TUnBc3A==", "dev": true, "requires": { "babel-runtime": "^6.22.0" @@ -7720,7 +6687,7 @@ "babel-plugin-transform-es2015-block-scoping": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", - "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", + "integrity": "sha512-YiN6sFAQ5lML8JjCmr7uerS5Yc/EMbgg9G8ZNmk2E3nYX4ckHR01wrkeeMijEf5WHNK5TW0Sl0Uu3pv3EdOJWw==", "dev": true, "requires": { "babel-runtime": "^6.26.0", @@ -7733,7 +6700,7 @@ "babel-plugin-transform-es2015-classes": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", - "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", + "integrity": "sha512-5Dy7ZbRinGrNtmWpquZKZ3EGY8sDgIVB4CU8Om8q8tnMLrD/m94cKglVcHps0BCTdZ0TJeeAWOq2TK9MIY6cag==", "dev": true, "requires": { "babel-helper-define-map": "^6.24.1", @@ -7750,7 +6717,7 @@ "babel-plugin-transform-es2015-computed-properties": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", - "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", + "integrity": "sha512-C/uAv4ktFP/Hmh01gMTvYvICrKze0XVX9f2PdIXuriCSvUmV9j+u+BB9f5fJK3+878yMK6dkdcq+Ymr9mrcLzw==", "dev": true, "requires": { "babel-runtime": "^6.22.0", @@ -7760,7 +6727,7 @@ "babel-plugin-transform-es2015-destructuring": { "version": "6.23.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", - "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", + "integrity": "sha512-aNv/GDAW0j/f4Uy1OEPZn1mqD+Nfy9viFGBfQ5bZyT35YqOiqx7/tXdyfZkJ1sC21NyEsBdfDY6PYmLHF4r5iA==", "dev": true, "requires": { "babel-runtime": "^6.22.0" @@ -7769,7 +6736,7 @@ "babel-plugin-transform-es2015-duplicate-keys": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", - "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", + "integrity": "sha512-ossocTuPOssfxO2h+Z3/Ea1Vo1wWx31Uqy9vIiJusOP4TbF7tPs9U0sJ9pX9OJPf4lXRGj5+6Gkl/HHKiAP5ug==", "dev": true, "requires": { "babel-runtime": "^6.22.0", @@ -7779,7 +6746,7 @@ "babel-plugin-transform-es2015-for-of": { "version": "6.23.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", - "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", + "integrity": "sha512-DLuRwoygCoXx+YfxHLkVx5/NpeSbVwfoTeBykpJK7JhYWlL/O8hgAK/reforUnZDlxasOrVPPJVI/guE3dCwkw==", "dev": true, "requires": { "babel-runtime": "^6.22.0" @@ -7788,7 +6755,7 @@ "babel-plugin-transform-es2015-function-name": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", - "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", + "integrity": "sha512-iFp5KIcorf11iBqu/y/a7DK3MN5di3pNCzto61FqCNnUX4qeBwcV1SLqe10oXNnCaxBUImX3SckX2/o1nsrTcg==", "dev": true, "requires": { "babel-helper-function-name": "^6.24.1", @@ -7799,7 +6766,7 @@ "babel-plugin-transform-es2015-literals": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", - "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", + "integrity": "sha512-tjFl0cwMPpDYyoqYA9li1/7mGFit39XiNX5DKC/uCNjBctMxyL1/PT/l4rSlbvBG1pOKI88STRdUsWXB3/Q9hQ==", "dev": true, "requires": { "babel-runtime": "^6.22.0" @@ -7808,7 +6775,7 @@ "babel-plugin-transform-es2015-modules-amd": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", - "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", + "integrity": "sha512-LnIIdGWIKdw7zwckqx+eGjcS8/cl8D74A3BpJbGjKTFFNJSMrjN4bIh22HY1AlkUbeLG6X6OZj56BDvWD+OeFA==", "dev": true, "requires": { "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", @@ -7831,7 +6798,7 @@ "babel-plugin-transform-es2015-modules-systemjs": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", - "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", + "integrity": "sha512-ONFIPsq8y4bls5PPsAWYXH/21Hqv64TBxdje0FvU3MhIV6QM2j5YS7KvAzg/nTIVLot2D2fmFQrFWCbgHlFEjg==", "dev": true, "requires": { "babel-helper-hoist-variables": "^6.24.1", @@ -7842,7 +6809,7 @@ "babel-plugin-transform-es2015-modules-umd": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", - "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", + "integrity": "sha512-LpVbiT9CLsuAIp3IG0tfbVo81QIhn6pE8xBJ7XSeCtFlMltuar5VuBV6y6Q45tpui9QWcy5i0vLQfCfrnF7Kiw==", "dev": true, "requires": { "babel-plugin-transform-es2015-modules-amd": "^6.24.1", @@ -7853,7 +6820,7 @@ "babel-plugin-transform-es2015-object-super": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", - "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", + "integrity": "sha512-8G5hpZMecb53vpD3mjs64NhI1au24TAmokQ4B+TBFBjN9cVoGoOvotdrMMRmHvVZUEvqGUPWL514woru1ChZMA==", "dev": true, "requires": { "babel-helper-replace-supers": "^6.24.1", @@ -7863,7 +6830,7 @@ "babel-plugin-transform-es2015-parameters": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", - "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", + "integrity": "sha512-8HxlW+BB5HqniD+nLkQ4xSAVq3bR/pcYW9IigY+2y0dI+Y7INFeTbfAQr+63T3E4UDsZGjyb+l9txUnABWxlOQ==", "dev": true, "requires": { "babel-helper-call-delegate": "^6.24.1", @@ -7877,7 +6844,7 @@ "babel-plugin-transform-es2015-shorthand-properties": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", - "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", + "integrity": "sha512-mDdocSfUVm1/7Jw/FIRNw9vPrBQNePy6wZJlR8HAUBLybNp1w/6lr6zZ2pjMShee65t/ybR5pT8ulkLzD1xwiw==", "dev": true, "requires": { "babel-runtime": "^6.22.0", @@ -7887,7 +6854,7 @@ "babel-plugin-transform-es2015-spread": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", - "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", + "integrity": "sha512-3Ghhi26r4l3d0Js933E5+IhHwk0A1yiutj9gwvzmFbVV0sPMYk2lekhOufHBswX7NCoSeF4Xrl3sCIuSIa+zOg==", "dev": true, "requires": { "babel-runtime": "^6.22.0" @@ -7896,7 +6863,7 @@ "babel-plugin-transform-es2015-sticky-regex": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", - "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", + "integrity": "sha512-CYP359ADryTo3pCsH0oxRo/0yn6UsEZLqYohHmvLQdfS9xkf+MbCzE3/Kolw9OYIY4ZMilH25z/5CbQbwDD+lQ==", "dev": true, "requires": { "babel-helper-regex": "^6.24.1", @@ -7907,7 +6874,7 @@ "babel-plugin-transform-es2015-template-literals": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", - "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", + "integrity": "sha512-x8b9W0ngnKzDMHimVtTfn5ryimars1ByTqsfBDwAqLibmuuQY6pgBQi5z1ErIsUOWBdw1bW9FSz5RZUojM4apg==", "dev": true, "requires": { "babel-runtime": "^6.22.0" @@ -7916,7 +6883,7 @@ "babel-plugin-transform-es2015-typeof-symbol": { "version": "6.23.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", - "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", + "integrity": "sha512-fz6J2Sf4gYN6gWgRZaoFXmq93X+Li/8vf+fb0sGDVtdeWvxC9y5/bTD7bvfWMEq6zetGEHpWjtzRGSugt5kNqw==", "dev": true, "requires": { "babel-runtime": "^6.22.0" @@ -7925,7 +6892,7 @@ "babel-plugin-transform-es2015-unicode-regex": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", - "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", + "integrity": "sha512-v61Dbbihf5XxnYjtBN04B/JBvsScY37R1cZT5r9permN1cp+b70DY3Ib3fIkgn1DI9U3tGgBJZVD8p/mE/4JbQ==", "dev": true, "requires": { "babel-helper-regex": "^6.24.1", @@ -7936,7 +6903,7 @@ "babel-plugin-transform-exponentiation-operator": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", - "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", + "integrity": "sha512-LzXDmbMkklvNhprr20//RStKVcT8Cu+SQtX18eMHLhjHf2yFzwtQ0S2f0jQ+89rokoNdmwoSqYzAhq86FxlLSQ==", "dev": true, "requires": { "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", @@ -7947,7 +6914,7 @@ "babel-plugin-transform-regenerator": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", - "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", + "integrity": "sha512-LS+dBkUGlNR15/5WHKe/8Neawx663qttS6AGqoOUhICc9d1KciBvtrQSuc0PI+CxQ2Q/S1aKuJ+u64GtLdcEZg==", "dev": true, "requires": { "regenerator-transform": "^0.10.0" @@ -7956,7 +6923,7 @@ "babel-plugin-transform-strict-mode": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", - "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", + "integrity": "sha512-j3KtSpjyLSJxNoCDrhwiJad8kw0gJ9REGj8/CqL0HeRyLnvUNYV9zcqluL6QJSXh3nfsLEmSLvwRfGzrgR96Pw==", "dev": true, "requires": { "babel-runtime": "^6.22.0", @@ -8012,7 +6979,7 @@ "babel-register": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", - "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", + "integrity": "sha512-veliHlHX06wjaeY8xNITbveXSiI+ASFnOqvne/LaIJIqOWi2Ogmj91KOugEz/hoh/fwMhXNBJPCv8Xaz5CyM4A==", "dev": true, "requires": { "babel-core": "^6.26.0", @@ -8038,7 +7005,7 @@ "babel-runtime": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==", "dev": true, "requires": { "core-js": "^2.4.0", @@ -8048,7 +7015,7 @@ "babel-template": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", - "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", + "integrity": "sha512-PCOcLFW7/eazGUKIoqH97sO9A2UYMahsn/yRQ7uOk37iutwjq7ODtcTNF+iFDSHNfkctqsLRjLP7URnOx0T1fg==", "dev": true, "requires": { "babel-runtime": "^6.26.0", @@ -8061,7 +7028,7 @@ "babel-traverse": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", - "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", + "integrity": "sha512-iSxeXx7apsjCHe9c7n8VtRXGzI2Bk1rBSOJgCCjfyXb6v1aCqE1KSEpq/8SXuVN8Ka/Rh1WDTF0MDzkvTA4MIA==", "dev": true, "requires": { "babel-code-frame": "^6.26.0", @@ -8093,7 +7060,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true } } @@ -8101,7 +7068,7 @@ "babel-types": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "integrity": "sha512-zhe3V/26rCWsEZK8kZN+HaQj5yQ1CilTObixFzKW1UWjqG7618Twz6YEsCnjfg5gBcJh02DrpCkS9h98ZqDY+g==", "dev": true, "requires": { "babel-runtime": "^6.26.0", @@ -8113,7 +7080,7 @@ "to-fast-properties": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", + "integrity": "sha512-lxrWP8ejsq+7E3nNjwYmUBMAgjMTZoTI+sdBOpvNyijeDLa29LUn9QaoXAHv4+Z578hbmHHJKZknzxVtvo77og==", "dev": true } } @@ -8121,7 +7088,7 @@ "babelify": { "version": "7.3.0", "resolved": "https://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", - "integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=", + "integrity": "sha512-vID8Fz6pPN5pJMdlUnNFSfrlcx5MUule4k9aKs/zbZPyXxMTcRrB0M4Tarw22L8afr8eYSWxDPYCob3TdrqtlA==", "dev": true, "requires": { "babel-core": "^6.0.14", @@ -8137,7 +7104,7 @@ "backoff": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/backoff/-/backoff-2.5.0.tgz", - "integrity": "sha1-9hbtqdPktmuMp/ynn2lXIsX44m8=", + "integrity": "sha512-wC5ihrnUXmR2douXmXLCe5O3zg3GKIyvRi/hi58a/XyRxVI+3/yM0PYueQOZXPXQ9pxBislYkw+sF9b7C/RuMA==", "dev": true, "requires": { "precond": "0.2" @@ -8146,7 +7113,7 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "integrity": "sha512-9Y0g0Q8rmSt+H33DfKv7FOc3v+iRI+o1lbzt8jGcIosYW37IIW/2XVYq5NPdmaD5NQ59Nk26Kl/vZbwW9Fr8vg==", "dev": true }, "base": { @@ -8167,7 +7134,7 @@ "define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", "dev": true, "requires": { "is-descriptor": "^1.0.0" @@ -8193,7 +7160,7 @@ "bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", "dev": true, "requires": { "tweetnacl": "^0.14.3" @@ -8202,7 +7169,7 @@ "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", "dev": true } } @@ -8230,7 +7197,7 @@ "blakejs": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", - "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=", + "integrity": "sha512-1TSf2Cf2KycDPzjJpzamYhr6PFSEgKWyoc4rQ/BarXJzp/jM0FC7yP1rLWtMOWT2EIJtjPv9fwpKquRNbRV7Lg==", "dev": true }, "bluebird": { @@ -8278,7 +7245,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true, "optional": true }, @@ -8304,7 +7271,7 @@ "brorand": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", "dev": true }, "browserify-aes": { @@ -8418,7 +7385,7 @@ "bs58": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", "dev": true, "requires": { "base-x": "^3.0.2" @@ -8454,14 +7421,14 @@ "buffer-to-arraybuffer": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz", - "integrity": "sha1-YGSkD6dutDxyOrqe+PbhIW0QURo=", + "integrity": "sha512-3dthu5CYiVB1DEJp61FtApNnNndTckcqe4pFcLdvHtrpG+kcyekCJKg4MRiDcFW7A6AODnXB9U4dwQiCW5kzJQ==", "dev": true, "optional": true }, "buffer-xor": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", "dev": true }, "bufferutil": { @@ -8483,7 +7450,7 @@ "bytewise": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/bytewise/-/bytewise-1.1.0.tgz", - "integrity": "sha1-HRPL/3F65xWAlKqIGzXQgbOHJT4=", + "integrity": "sha512-rHuuseJ9iQ0na6UDhnrRVDh8YnWVlU6xM3VH6q/+yHDeUH2zIhUzP+2/h3LIrhLDBtTqzWpE3p3tP/boefskKQ==", "dev": true, "requires": { "bytewise-core": "^1.2.2", @@ -8493,7 +7460,7 @@ "bytewise-core": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/bytewise-core/-/bytewise-core-1.2.3.tgz", - "integrity": "sha1-P7QQx+kVWOsasiqCg0V3qmvWHUI=", + "integrity": "sha512-nZD//kc78OOxeYtRlVk8/zXqTB4gf/nlguL1ggWA8FuchMyOxcyHR4QPQZMUmA7czC+YnaBrPUCubqAWe50DaA==", "dev": true, "requires": { "typewise-core": "^1.2" @@ -8544,7 +7511,7 @@ "cachedown": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/cachedown/-/cachedown-1.0.0.tgz", - "integrity": "sha1-1D8DbkUQaWsxJG19sx6/D3rDLRU=", + "integrity": "sha512-t+yVk82vQWCJF3PsWHMld+jhhjkkWjcAzz8NbFx1iULOXWl8Tm/FdM4smZNVw3MRr0X+lVTx9PKzvEn4Ng19RQ==", "dev": true, "requires": { "abstract-leveldown": "^2.4.1", @@ -8563,7 +7530,7 @@ "lru-cache": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-3.2.0.tgz", - "integrity": "sha1-cXibO39Tmb7IVl3aOKow0qCX7+4=", + "integrity": "sha512-91gyOKTc2k66UG6kHiH4h3S2eltcPwE1STVfMYC/NG+nZwf8IIuiamfmpGZjpbbxzSyEJaLC0tNSmhjlQUTJow==", "dev": true, "requires": { "pseudomap": "^1.0.1" @@ -8590,7 +7557,7 @@ "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", "dev": true }, "chalk": { @@ -8607,7 +7574,7 @@ "checkpoint-store": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/checkpoint-store/-/checkpoint-store-1.1.0.tgz", - "integrity": "sha1-BOTLUWuRQziTWB5tRgGnjpVS6gY=", + "integrity": "sha512-J/NdY2WvIx654cc6LWSq/IYFFCUf75fFTgwzFnmbqyORH4MwgiQCgswLLKBGzmsyTI5V7i5bp/So6sMbDWhedg==", "dev": true, "requires": { "functional-red-black-tree": "^1.0.1" @@ -8685,7 +7652,7 @@ "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", "dev": true, "requires": { "is-descriptor": "^0.1.0" @@ -8694,7 +7661,7 @@ "is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", "dev": true, "requires": { "kind-of": "^3.0.2" @@ -8703,7 +7670,7 @@ "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -8720,7 +7687,7 @@ "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", "dev": true, "requires": { "kind-of": "^3.0.2" @@ -8729,7 +7696,7 @@ "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -8759,13 +7726,13 @@ "clone": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", "dev": true }, "clone-response": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "integrity": "sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q==", "dev": true, "optional": true, "requires": { @@ -8775,7 +7742,7 @@ "collection-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", "dev": true, "requires": { "map-visit": "^1.0.0", @@ -8794,7 +7761,7 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, "combined-stream": { @@ -8815,7 +7782,7 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, "concat-stream": { @@ -8895,7 +7862,7 @@ "cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", "dev": true, "optional": true }, @@ -8909,7 +7876,7 @@ "copy-descriptor": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", "dev": true }, "core-js": { @@ -8927,7 +7894,7 @@ "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=", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", "dev": true }, "cors": { @@ -9022,7 +7989,7 @@ "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", "dev": true, "requires": { "assert-plus": "^1.0.0" @@ -9040,13 +8007,13 @@ "decode-uri-component": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "integrity": "sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==", "dev": true }, "decompress-response": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", "dev": true, "optional": true, "requires": { @@ -9117,19 +8084,19 @@ "defined": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", - "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", + "integrity": "sha512-Y2caI5+ZwS5c3RiNDJ6u53VhQHv+hHKwhkI1iHvceKUHw9Df6EK2zRLfjejRgMuCuxK7PfSWIMwWecceVvThjQ==", "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=", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "dev": true }, "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", "dev": true, "optional": true }, @@ -9147,14 +8114,14 @@ "destroy": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "integrity": "sha512-3NdhDuEXnfun/z7x9GOElY49LoqVHoGScmOKwmxhsS8N5Y+Z8KyPPDnaSzqWgYt/ji4mqwfTS34Htrk0zPIXVg==", "dev": true, "optional": true }, "detect-indent": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", - "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", + "integrity": "sha512-BDKtmHlOzwI7iRuEkhzsnPoi5ypEhWAJB5RvHWe1kMr06js3uK5B3734i3ui5Yd+wOJV1cpE4JnivPD283GU/A==", "dev": true, "requires": { "repeating": "^2.0.0" @@ -9190,14 +8157,14 @@ "duplexer3": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "integrity": "sha512-CEj8FwwNA4cVH2uFCoHUrmojhYh1vmCdOaneKJXwkeY1i9jnlslVo9dx+hQ5Hl9GnH/Bwy/IjxAyOePyPKYnzA==", "dev": true, "optional": true }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", "dev": true, "requires": { "jsbn": "~0.1.0", @@ -9207,7 +8174,7 @@ "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", "dev": true, "optional": true }, @@ -9235,7 +8202,7 @@ "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "dev": true, "optional": true }, @@ -9346,7 +8313,7 @@ "es6-iterator": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", "dev": true, "requires": { "d": "1", @@ -9367,14 +8334,14 @@ "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "dev": true, "optional": true }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true }, "esutils": { @@ -9386,7 +8353,7 @@ "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "dev": true, "optional": true }, @@ -9433,7 +8400,7 @@ "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "dev": true } } @@ -9441,7 +8408,7 @@ "eth-ens-namehash": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz", - "integrity": "sha1-IprEbsqG1S4MmR58sq74P/D2i88=", + "integrity": "sha512-VWEI1+KJfz4Km//dadyvBBoBeSQ0MHTXPvr8UIXiLW6IanxvAV+DmlZAijZwAyggqGUfwQBeHf7tc9wzc1piSw==", "dev": true, "optional": true, "requires": { @@ -9636,7 +8603,7 @@ "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", "dev": true }, "level-codec": { @@ -9657,7 +8624,7 @@ "level-iterator-stream": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz", - "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=", + "integrity": "sha512-1qua0RHNtr4nrZBgYlpV0qHHeHpcRRWTxEZJ8xsemoHAXNL5tbooh4tPEEqIqsbWCAJBmUmkwYK/sW5OrFjWWw==", "dev": true, "requires": { "inherits": "^2.0.1", @@ -9669,7 +8636,7 @@ "readable-stream": { "version": "1.1.14", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", "dev": true, "requires": { "core-util-is": "~1.0.0", @@ -9683,7 +8650,7 @@ "level-ws": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz", - "integrity": "sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=", + "integrity": "sha512-XUTaO/+Db51Uiyp/t7fCMGVFOTdtLS/NIACxE/GHsij15mKzxksZifKVjlXDF41JMUP/oM1Oc4YNGdKnc3dVLw==", "dev": true, "requires": { "readable-stream": "~1.0.15", @@ -9693,7 +8660,7 @@ "readable-stream": { "version": "1.0.34", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", "dev": true, "requires": { "core-util-is": "~1.0.0", @@ -9705,7 +8672,7 @@ "xtend": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", - "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", + "integrity": "sha512-vMNKzr2rHP9Dp/e1NQFnLQlwlhp9L/LfvnsVdHxN1f+uggyVI3i08uD14GPvCToPkdsRfyPqIyYGmIk58V98ZQ==", "dev": true, "requires": { "object-keys": "~0.4.0" @@ -9731,13 +8698,13 @@ "ltgt": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", - "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=", + "integrity": "sha512-AI2r85+4MquTw9ZYqabu4nMwy9Oftlfa/e/52t9IjtfG+mGBbTNdAoZ3RQKLHR6r0wQnwZnPIEh/Ya6XTWAKNA==", "dev": true }, "memdown": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz", - "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=", + "integrity": "sha512-iVrGHZB8i4OQfM155xx8akvG9FIj+ht14DX5CQkCTG4EHzZ3d3sgckIf/Lm9ivZalEsFuEVnWv2B2WZvbrro2w==", "dev": true, "requires": { "abstract-leveldown": "~2.7.1", @@ -9778,7 +8745,7 @@ "async": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", "dev": true } } @@ -9786,7 +8753,7 @@ "object-keys": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", - "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=", + "integrity": "sha512-ncrLw+X55z7bkl5PnUvHwFK9FcGuFYo9gtjws2XtSzL+aZ8tm830P60WJ0dSmFVaSalWieW5MD7kEdnXda9yJw==", "dev": true }, "safe-buffer": { @@ -9804,7 +8771,7 @@ "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", "dev": true } } @@ -9827,7 +8794,7 @@ "eth-query": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/eth-query/-/eth-query-2.1.2.tgz", - "integrity": "sha1-1nQdkAAQa1FRDHLbktY2VFam2l4=", + "integrity": "sha512-srES0ZcvwkR/wd5OQBRA1bIJMww1skfGS0s8wlwK3/oNP4+wnds60krvu5R1QbpRQjMmpG5OMIWro5s7gvDPsA==", "dev": true, "requires": { "json-rpc-random-id": "^1.0.0", @@ -9851,7 +8818,7 @@ "ethereumjs-abi": { "version": "0.6.5", "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.5.tgz", - "integrity": "sha1-WmN+8Wq0NHP6cqKa2QhxQFs/UkE=", + "integrity": "sha512-rCjJZ/AE96c/AAZc6O3kaog4FhOsAViaysBxqJNy2+LHP0ttH0zkZ7nXdVHOAyt6lFwLO0nlCwWszysG/ao1+g==", "dev": true, "requires": { "bn.js": "^4.10.0", @@ -10062,7 +9029,7 @@ "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", "dev": true }, "level-codec": { @@ -10083,7 +9050,7 @@ "level-iterator-stream": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz", - "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=", + "integrity": "sha512-1qua0RHNtr4nrZBgYlpV0qHHeHpcRRWTxEZJ8xsemoHAXNL5tbooh4tPEEqIqsbWCAJBmUmkwYK/sW5OrFjWWw==", "dev": true, "requires": { "inherits": "^2.0.1", @@ -10095,7 +9062,7 @@ "readable-stream": { "version": "1.1.14", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", "dev": true, "requires": { "core-util-is": "~1.0.0", @@ -10109,7 +9076,7 @@ "level-ws": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz", - "integrity": "sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=", + "integrity": "sha512-XUTaO/+Db51Uiyp/t7fCMGVFOTdtLS/NIACxE/GHsij15mKzxksZifKVjlXDF41JMUP/oM1Oc4YNGdKnc3dVLw==", "dev": true, "requires": { "readable-stream": "~1.0.15", @@ -10119,7 +9086,7 @@ "readable-stream": { "version": "1.0.34", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", "dev": true, "requires": { "core-util-is": "~1.0.0", @@ -10131,7 +9098,7 @@ "xtend": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", - "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", + "integrity": "sha512-vMNKzr2rHP9Dp/e1NQFnLQlwlhp9L/LfvnsVdHxN1f+uggyVI3i08uD14GPvCToPkdsRfyPqIyYGmIk58V98ZQ==", "dev": true, "requires": { "object-keys": "~0.4.0" @@ -10157,13 +9124,13 @@ "ltgt": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", - "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=", + "integrity": "sha512-AI2r85+4MquTw9ZYqabu4nMwy9Oftlfa/e/52t9IjtfG+mGBbTNdAoZ3RQKLHR6r0wQnwZnPIEh/Ya6XTWAKNA==", "dev": true }, "memdown": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz", - "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=", + "integrity": "sha512-iVrGHZB8i4OQfM155xx8akvG9FIj+ht14DX5CQkCTG4EHzZ3d3sgckIf/Lm9ivZalEsFuEVnWv2B2WZvbrro2w==", "dev": true, "requires": { "abstract-leveldown": "~2.7.1", @@ -10204,7 +9171,7 @@ "async": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", "dev": true } } @@ -10212,7 +9179,7 @@ "object-keys": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", - "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=", + "integrity": "sha512-ncrLw+X55z7bkl5PnUvHwFK9FcGuFYo9gtjws2XtSzL+aZ8tm830P60WJ0dSmFVaSalWieW5MD7kEdnXda9yJw==", "dev": true }, "safe-buffer": { @@ -10230,7 +9197,7 @@ "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", "dev": true } } @@ -10300,7 +9267,7 @@ "ethereum-common": { "version": "0.0.18", "resolved": "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.0.18.tgz", - "integrity": "sha1-L9w1dvIykDNYl26znaeDIT/5Uj8=", + "integrity": "sha512-EoltVQTRNg2Uy4o84qpa2aXymXDJhxm7eos/ACOg0DG4baAbMjhbdAEsx9GeE8sC3XCxnYvrrzZDH8D8MtA2iQ==", "dev": true }, "ethereum-cryptography": { @@ -10396,7 +9363,7 @@ "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", "dev": true }, "level-codec": { @@ -10417,7 +9384,7 @@ "level-iterator-stream": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz", - "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=", + "integrity": "sha512-1qua0RHNtr4nrZBgYlpV0qHHeHpcRRWTxEZJ8xsemoHAXNL5tbooh4tPEEqIqsbWCAJBmUmkwYK/sW5OrFjWWw==", "dev": true, "requires": { "inherits": "^2.0.1", @@ -10429,7 +9396,7 @@ "readable-stream": { "version": "1.1.14", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", "dev": true, "requires": { "core-util-is": "~1.0.0", @@ -10443,7 +9410,7 @@ "level-ws": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz", - "integrity": "sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=", + "integrity": "sha512-XUTaO/+Db51Uiyp/t7fCMGVFOTdtLS/NIACxE/GHsij15mKzxksZifKVjlXDF41JMUP/oM1Oc4YNGdKnc3dVLw==", "dev": true, "requires": { "readable-stream": "~1.0.15", @@ -10453,7 +9420,7 @@ "readable-stream": { "version": "1.0.34", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", "dev": true, "requires": { "core-util-is": "~1.0.0", @@ -10465,7 +9432,7 @@ "xtend": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", - "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", + "integrity": "sha512-vMNKzr2rHP9Dp/e1NQFnLQlwlhp9L/LfvnsVdHxN1f+uggyVI3i08uD14GPvCToPkdsRfyPqIyYGmIk58V98ZQ==", "dev": true, "requires": { "object-keys": "~0.4.0" @@ -10491,13 +9458,13 @@ "ltgt": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", - "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=", + "integrity": "sha512-AI2r85+4MquTw9ZYqabu4nMwy9Oftlfa/e/52t9IjtfG+mGBbTNdAoZ3RQKLHR6r0wQnwZnPIEh/Ya6XTWAKNA==", "dev": true }, "memdown": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz", - "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=", + "integrity": "sha512-iVrGHZB8i4OQfM155xx8akvG9FIj+ht14DX5CQkCTG4EHzZ3d3sgckIf/Lm9ivZalEsFuEVnWv2B2WZvbrro2w==", "dev": true, "requires": { "abstract-leveldown": "~2.7.1", @@ -10538,7 +9505,7 @@ "async": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", "dev": true } } @@ -10546,7 +9513,7 @@ "object-keys": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", - "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=", + "integrity": "sha512-ncrLw+X55z7bkl5PnUvHwFK9FcGuFYo9gtjws2XtSzL+aZ8tm830P60WJ0dSmFVaSalWieW5MD7kEdnXda9yJw==", "dev": true }, "safe-buffer": { @@ -10564,7 +9531,7 @@ "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", "dev": true } } @@ -10662,7 +9629,7 @@ "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", "dev": true }, "level-codec": { @@ -10683,7 +9650,7 @@ "level-iterator-stream": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz", - "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=", + "integrity": "sha512-1qua0RHNtr4nrZBgYlpV0qHHeHpcRRWTxEZJ8xsemoHAXNL5tbooh4tPEEqIqsbWCAJBmUmkwYK/sW5OrFjWWw==", "dev": true, "requires": { "inherits": "^2.0.1", @@ -10695,7 +9662,7 @@ "readable-stream": { "version": "1.1.14", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", "dev": true, "requires": { "core-util-is": "~1.0.0", @@ -10709,7 +9676,7 @@ "level-ws": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz", - "integrity": "sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=", + "integrity": "sha512-XUTaO/+Db51Uiyp/t7fCMGVFOTdtLS/NIACxE/GHsij15mKzxksZifKVjlXDF41JMUP/oM1Oc4YNGdKnc3dVLw==", "dev": true, "requires": { "readable-stream": "~1.0.15", @@ -10719,7 +9686,7 @@ "readable-stream": { "version": "1.0.34", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", "dev": true, "requires": { "core-util-is": "~1.0.0", @@ -10731,7 +9698,7 @@ "xtend": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", - "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", + "integrity": "sha512-vMNKzr2rHP9Dp/e1NQFnLQlwlhp9L/LfvnsVdHxN1f+uggyVI3i08uD14GPvCToPkdsRfyPqIyYGmIk58V98ZQ==", "dev": true, "requires": { "object-keys": "~0.4.0" @@ -10757,13 +9724,13 @@ "ltgt": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", - "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=", + "integrity": "sha512-AI2r85+4MquTw9ZYqabu4nMwy9Oftlfa/e/52t9IjtfG+mGBbTNdAoZ3RQKLHR6r0wQnwZnPIEh/Ya6XTWAKNA==", "dev": true }, "memdown": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz", - "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=", + "integrity": "sha512-iVrGHZB8i4OQfM155xx8akvG9FIj+ht14DX5CQkCTG4EHzZ3d3sgckIf/Lm9ivZalEsFuEVnWv2B2WZvbrro2w==", "dev": true, "requires": { "abstract-leveldown": "~2.7.1", @@ -10804,7 +9771,7 @@ "async": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", "dev": true }, "ethereumjs-util": { @@ -10827,7 +9794,7 @@ "object-keys": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", - "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=", + "integrity": "sha512-ncrLw+X55z7bkl5PnUvHwFK9FcGuFYo9gtjws2XtSzL+aZ8tm830P60WJ0dSmFVaSalWieW5MD7kEdnXda9yJw==", "dev": true }, "safe-buffer": { @@ -10845,7 +9812,7 @@ "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", "dev": true } } @@ -10871,7 +9838,7 @@ "ethjs-unit": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", - "integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=", + "integrity": "sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==", "dev": true, "optional": true, "requires": { @@ -10882,7 +9849,7 @@ "bn.js": { "version": "4.11.6", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", "dev": true, "optional": true } @@ -10924,7 +9891,7 @@ "expand-brackets": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", "dev": true, "requires": { "debug": "^2.3.3", @@ -10948,7 +9915,7 @@ "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", "dev": true, "requires": { "is-descriptor": "^0.1.0" @@ -10957,7 +9924,7 @@ "extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", "dev": true, "requires": { "is-extendable": "^0.1.0" @@ -10966,7 +9933,7 @@ "is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", "dev": true, "requires": { "kind-of": "^3.0.2" @@ -10975,7 +9942,7 @@ "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -10992,7 +9959,7 @@ "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", "dev": true, "requires": { "kind-of": "^3.0.2" @@ -11001,7 +9968,7 @@ "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -11023,7 +9990,7 @@ "is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", "dev": true }, "kind-of": { @@ -11035,7 +10002,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true } } @@ -11092,7 +10059,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true, "optional": true }, @@ -11138,7 +10105,7 @@ "extend-shallow": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", "dev": true, "requires": { "assign-symbols": "^1.0.0", @@ -11164,7 +10131,7 @@ "define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", "dev": true, "requires": { "is-descriptor": "^1.0.0" @@ -11173,7 +10140,7 @@ "extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", "dev": true, "requires": { "is-extendable": "^0.1.0" @@ -11182,7 +10149,7 @@ "is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", "dev": true } } @@ -11190,13 +10157,13 @@ "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", "dev": true }, "fake-merkle-patricia-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/fake-merkle-patricia-tree/-/fake-merkle-patricia-tree-1.0.1.tgz", - "integrity": "sha1-S4w6z7Ugr635hgsfFM2M40As3dM=", + "integrity": "sha512-Tgq37lkc9pUIgIKw5uitNUKcgcYL3R6JvXtKQbOf/ZSavXbidsksgp/pAY6p//uhw0I4yoMsvTSovvVIsk/qxA==", "dev": true, "requires": { "checkpoint-store": "^1.1.0" @@ -11217,7 +10184,7 @@ "fetch-ponyfill": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/fetch-ponyfill/-/fetch-ponyfill-4.1.0.tgz", - "integrity": "sha1-rjzl9zLGReq4fkroeTQUcJsjmJM=", + "integrity": "sha512-knK9sGskIg2T7OnYLdZ2hZXn0CtDrAIBxYQLpmEf0BqfdWnwmM1weccUl5+4EdA44tzNSFAuxITPbXtPehUB3g==", "dev": true, "requires": { "node-fetch": "~1.7.1" @@ -11226,7 +10193,7 @@ "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", "dev": true }, "node-fetch": { @@ -11270,7 +10237,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true, "optional": true } @@ -11307,7 +10274,7 @@ "extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", "dev": true, "requires": { "is-extendable": "^0.1.0" @@ -11318,7 +10285,7 @@ "fill-range": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", "dev": true, "requires": { "extend-shallow": "^2.0.1", @@ -11330,7 +10297,7 @@ "extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", "dev": true, "requires": { "is-extendable": "^0.1.0" @@ -11358,13 +10325,13 @@ "is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", "dev": true }, "is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", "dev": true, "requires": { "kind-of": "^3.0.2" @@ -11373,7 +10340,7 @@ "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -11405,7 +10372,7 @@ "to-regex-range": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", "dev": true, "requires": { "is-number": "^3.0.0", @@ -11417,7 +10384,7 @@ "flow-stoplight": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/flow-stoplight/-/flow-stoplight-1.0.0.tgz", - "integrity": "sha1-SiksW8/4s5+mzAyxqFPYbyfu/3s=", + "integrity": "sha512-rDjbZUKpN8OYhB0IE/vY/I8UWO/602IIJEU/76Tv4LvYnwHCk0BCsvz4eRr9n+FQcri7L5cyaXOo0+/Kh4HisA==", "dev": true }, "for-each": { @@ -11432,13 +10399,13 @@ "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", "dev": true }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", "dev": true }, "form-data": { @@ -11455,14 +10422,14 @@ "forwarded": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "integrity": "sha512-Ua9xNhH0b8pwE3yRbFfXJvfdWF0UHNCdeyb2sbi9Ul/M+r3PTdrz7Cv4SCfZRMjmzEM9PhraqfZFbGTIg3OMyA==", "dev": true, "optional": true }, "fragment-cache": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", "dev": true, "requires": { "map-cache": "^0.2.2" @@ -11471,7 +10438,7 @@ "fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "dev": true, "optional": true }, @@ -11489,7 +10456,7 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, "function-bind": { @@ -11501,7 +10468,7 @@ "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", "dev": true }, "get-intrinsic": { @@ -11528,13 +10495,13 @@ "get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", "dev": true }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", "dev": true, "requires": { "assert-plus": "^1.0.0" @@ -11605,7 +10572,7 @@ "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", "dev": true }, "har-validator": { @@ -11630,7 +10597,7 @@ "has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", "dev": true, "requires": { "ansi-regex": "^2.0.0" @@ -11639,7 +10606,7 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", "dev": true } } @@ -11647,7 +10614,7 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true }, "has-symbol-support-x": { @@ -11676,7 +10643,7 @@ "has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", "dev": true, "requires": { "get-value": "^2.0.6", @@ -11687,7 +10654,7 @@ "has-values": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", "dev": true, "requires": { "is-number": "^3.0.0", @@ -11703,7 +10670,7 @@ "is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", "dev": true, "requires": { "kind-of": "^3.0.2" @@ -11712,7 +10679,7 @@ "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -11723,7 +10690,7 @@ "kind-of": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -11768,13 +10735,13 @@ "heap": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.6.tgz", - "integrity": "sha1-CH4fELBGky/IWU3Z5tN4r8nR5aw=", + "integrity": "sha512-MzzWcnfB1e4EG2vHi3dXHoBupmuXNZzx6pY6HldVS55JKKBoq3xOyzfSaZRkJp37HIhEYC78knabHff3zc4dQQ==", "dev": true }, "hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", "dev": true, "requires": { "hash.js": "^1.0.3", @@ -11785,7 +10752,7 @@ "home-or-tmp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", - "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", + "integrity": "sha512-ycURW7oUxE2sNiPVw1HVEFsW+ecOpJ5zaj7eC0RlwhibhRBod20muUN8qu/gzx956YrLolVvs1MTXwKgC2rVEg==", "dev": true, "requires": { "os-homedir": "^1.0.0", @@ -11816,7 +10783,7 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", "dev": true, "optional": true } @@ -11825,14 +10792,14 @@ "http-https": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz", - "integrity": "sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs=", + "integrity": "sha512-o0PWwVCSp3O0wS6FvNr6xfBCHgt0m1tvPLFOCc2iFDKTRAXhB7m8klDf7ErowFH8POa6dVdGatKU5I1YYwzUyg==", "dev": true, "optional": true }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", "dev": true, "requires": { "assert-plus": "^1.0.0", @@ -11863,7 +10830,7 @@ "punycode": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", - "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=", + "integrity": "sha512-Yxz2kRwT90aPiWEMHVYnEf4+rhwF1tBmmZ4KepCP+Wkium9JxtWnUm1nqGwpiAHr/tnTSeHqr3wb++jgSkXjhA==", "dev": true, "optional": true } @@ -11878,13 +10845,13 @@ "immediate": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.2.3.tgz", - "integrity": "sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw=", + "integrity": "sha512-RrGCXRm/fRVqMIhqXrGEX9rRADavPiDFSoMb/k64i9XMk8uH4r/Omi5Ctierj6XzNecwDbO4WuFbDD1zmpl3Tg==", "dev": true }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, "requires": { "once": "^1.3.0", @@ -11990,7 +10957,7 @@ "is-fn": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fn/-/is-fn-1.0.0.tgz", - "integrity": "sha1-lUPV3nvPWwiiLsiiC65uKG1RDYw=", + "integrity": "sha512-XoFPJQmsAShb3jEQRfzf2rqXavq7fIqF/jOekp308JlThqrODnMpweVSGilKTCXELfLhltGP2AGgbQGVP8F1dg==", "dev": true }, "is-function": { @@ -12002,7 +10969,7 @@ "is-hex-prefixed": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", - "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=", + "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", "dev": true }, "is-negative-zero": { @@ -12021,7 +10988,7 @@ "is-plain-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", "dev": true, "optional": true }, @@ -12062,7 +11029,7 @@ "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", "dev": true }, "is-windows": { @@ -12074,25 +11041,25 @@ "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", "dev": true }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "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=", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", "dev": true }, "isurl": { @@ -12109,7 +11076,7 @@ "js-sha3": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=", + "integrity": "sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==", "dev": true, "optional": true }, @@ -12122,13 +11089,13 @@ "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", "dev": true }, "json-buffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==", "dev": true, "optional": true }, @@ -12149,7 +11116,7 @@ "json-rpc-error": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/json-rpc-error/-/json-rpc-error-2.0.0.tgz", - "integrity": "sha1-p6+cICg4tekFxyUOVH8a/3cligI=", + "integrity": "sha512-EwUeWP+KgAZ/xqFpaP6YDAXMtCJi+o/QQpCQFIYyxr01AdADi2y413eM8hSqJcoQym9WMePAJWoaODEJufC4Ug==", "dev": true, "requires": { "inherits": "^2.0.1" @@ -12158,13 +11125,13 @@ "json-rpc-random-id": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-rpc-random-id/-/json-rpc-random-id-1.0.1.tgz", - "integrity": "sha1-uknZat7RRE27jaPSA3SKy7zeyMg=", + "integrity": "sha512-RJ9YYNCkhVDBuP4zN5BBtYAzEl03yq/jIIsyif0JY9qyJuQQZNeDK7anAPKKlyEtLSj2s8h6hNh2F8zO5q7ScA==", "dev": true }, "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "integrity": "sha512-a3xHnILGMtk+hDOqNwHzF6e2fNbiMrXZvxKQiEv2MlgQP+pjIOzqAmKYD2mDpXYE/44M7g+n9p2bKkYWDUcXCQ==", "dev": true }, "json-schema-traverse": { @@ -12176,7 +11143,7 @@ "json-stable-stringify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", - "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "integrity": "sha512-i/J297TW6xyj7sDFa7AmBPkQvLIxWr2kKPWI26tXydnZrzVAocNqn5DMNT1Mzk0vit1V5UkRM7C1KdVNp7Lmcg==", "dev": true, "requires": { "jsonify": "~0.0.0" @@ -12185,13 +11152,13 @@ "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=", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", "dev": true }, "jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "dev": true, "requires": { "graceful-fs": "^4.1.6" @@ -12200,13 +11167,13 @@ "jsonify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "integrity": "sha512-trvBk1ki43VZptdBI5rIlG4YOzyeH/WefQt5rj1grasPn4iiZWKet8nkgc4GlsAylaztn0qZfUYOiTsASJFdNA==", "dev": true }, "jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "integrity": "sha512-4Dj8Rf+fQ+/Pn7C5qeEX02op1WfOss3PKTE9Nsop3Dx+6UPxlm1dr/og7o2cRa5hNN07CACr4NFzRLtj/rjWog==", "dev": true, "requires": { "assert-plus": "1.0.0", @@ -12301,7 +11268,7 @@ "ltgt": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", - "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=", + "integrity": "sha512-AI2r85+4MquTw9ZYqabu4nMwy9Oftlfa/e/52t9IjtfG+mGBbTNdAoZ3RQKLHR6r0wQnwZnPIEh/Ya6XTWAKNA==", "dev": true }, "memdown": { @@ -12408,7 +11375,7 @@ "looper": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/looper/-/looper-2.0.0.tgz", - "integrity": "sha1-Zs0Md0rz1P7axTeU90LbVtqPCew=", + "integrity": "sha512-6DzMHJcjbQX/UPHc1rRCBfKlLwDkvuGZ715cIR36wSdYqWXFT35uLXq5P/2orl3tz+t+VOVPxw4yPinQlUDGDQ==", "dev": true }, "loose-envify": { @@ -12439,19 +11406,19 @@ "ltgt": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.1.3.tgz", - "integrity": "sha1-EIUaBtmWS5cReEQcI8nlJpjuzjQ=", + "integrity": "sha512-5VjHC5GsENtIi5rbJd+feEpDKhfr7j0odoUR2Uh978g+2p93nd5o34cTjQWohXsPsCZeqoDnIqEf88mPCe0Pfw==", "dev": true }, "map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", "dev": true }, "map-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", "dev": true, "requires": { "object-visit": "^1.0.0" @@ -12471,14 +11438,14 @@ "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "dev": true, "optional": true }, "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", "dev": true, "optional": true }, @@ -12528,7 +11495,7 @@ "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", "dev": true, "optional": true }, @@ -12574,7 +11541,7 @@ "min-document": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", + "integrity": "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==", "dev": true, "requires": { "dom-walk": "^0.1.0" @@ -12589,7 +11556,7 @@ "minimalistic-crypto-utils": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", "dev": true }, "minimatch": { @@ -12652,7 +11619,7 @@ "mkdirp-promise": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz", - "integrity": "sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE=", + "integrity": "sha512-Hepn5kb1lJPtVW84RFT40YG1OddBNTOVUZR2bzQUHc+Z03en8/3uX0+060JDhcEzyO08HmipsN9DcnFMxhIL9w==", "dev": true, "optional": true, "requires": { @@ -12721,7 +11688,7 @@ "nano-json-stream-parser": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz", - "integrity": "sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18=", + "integrity": "sha512-9MqxMH/BSJC7dnLsEMPyfN5Dvoo49IsPFYMcHw3Bcfc2kN0lpHRBSzlMSVx4HGyJ7s9B31CyBTVehWJoQ8Ctew==", "dev": true, "optional": true }, @@ -12754,7 +11721,7 @@ "next-tick": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", + "integrity": "sha512-mc/caHeUcdjnC/boPWJefDr4KUIWQNv+tlnFnJd38QMou86QtxQzBJfxgGRzvx8jazYRqrVlaHarfO72uNxPOg==", "dev": true }, "nice-try": { @@ -12772,7 +11739,7 @@ "node-fetch": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz", - "integrity": "sha1-q4hOjn5X44qUR1POxwb3iNF2i7U=", + "integrity": "sha512-IHLHYskTc2arMYsHZH82PVX8CSKT5lzb7AXeyO06QnjGDKtkv+pv3mEki6S7reB/x1QPo+YPxQRNEVgR5V/w3Q==", "dev": true }, "node-gyp-build": { @@ -12791,7 +11758,7 @@ "number-to-bn": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", - "integrity": "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=", + "integrity": "sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==", "dev": true, "optional": true, "requires": { @@ -12802,7 +11769,7 @@ "bn.js": { "version": "4.11.6", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", "dev": true, "optional": true } @@ -12817,13 +11784,13 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "dev": true }, "object-copy": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", "dev": true, "requires": { "copy-descriptor": "^0.1.0", @@ -12834,7 +11801,7 @@ "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", "dev": true, "requires": { "is-descriptor": "^0.1.0" @@ -12843,7 +11810,7 @@ "is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", "dev": true, "requires": { "kind-of": "^3.0.2" @@ -12858,7 +11825,7 @@ "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", "dev": true, "requires": { "kind-of": "^3.0.2" @@ -12886,7 +11853,7 @@ "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -12919,7 +11886,7 @@ "object-visit": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", "dev": true, "requires": { "isobject": "^3.0.0" @@ -12951,7 +11918,7 @@ "object.pick": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", "dev": true, "requires": { "isobject": "^3.0.1" @@ -12960,7 +11927,7 @@ "oboe": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.4.tgz", - "integrity": "sha1-IMiM2wwVNxuwQRklfU/dNLCqSfY=", + "integrity": "sha512-ymBJ4xSC6GBXLT9Y7lirj+xbqBLa+jADGJldGEYG7u8sZbS9GyG+u1Xk9c5cbriKwSpCg41qUhPjvU5xOpvIyQ==", "dev": true, "optional": true, "requires": { @@ -12970,7 +11937,7 @@ "on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", "dev": true, "optional": true, "requires": { @@ -12980,7 +11947,7 @@ "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, "requires": { "wrappy": "1" @@ -12989,13 +11956,13 @@ "os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==", "dev": true }, "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", "dev": true }, "p-cancelable": { @@ -13008,7 +11975,7 @@ "p-timeout": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", - "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=", + "integrity": "sha512-gb0ryzr+K2qFqFv6qi3khoeqMZF/+ajxQipEF6NteZVnvz9tzdsfAVj3lYtn1gAXvH5lfLwfxEII799gt/mRIA==", "dev": true, "optional": true, "requires": { @@ -13018,7 +11985,7 @@ "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", "dev": true, "optional": true } @@ -13054,7 +12021,7 @@ "pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", "dev": true }, "patch-package": { @@ -13093,7 +12060,7 @@ "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", "dev": true }, "semver": { @@ -13105,7 +12072,7 @@ "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", "dev": true, "requires": { "shebang-regex": "^1.0.0" @@ -13114,7 +12081,7 @@ "shebang-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", "dev": true }, "slash": { @@ -13146,7 +12113,7 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true }, "path-parse": { @@ -13158,7 +12125,7 @@ "path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", "dev": true, "optional": true }, @@ -13178,25 +12145,25 @@ "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", "dev": true }, "posix-character-classes": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", "dev": true }, "precond": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/precond/-/precond-0.2.3.tgz", - "integrity": "sha1-qpWRvKokkj8eD0hJ0kD0fvwQdaw=", + "integrity": "sha512-QCYG84SgGyGzqJ/vlMsxeXd/pgL/I94ixdNFyh1PusWmTCyVfPJjZ1K1jvHtsbfnXQs2TSkEP2fR7QiMZAnKFQ==", "dev": true }, "prepend-http": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==", "dev": true, "optional": true }, @@ -13209,7 +12176,7 @@ "process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", "dev": true }, "process-nextick-args": { @@ -13221,7 +12188,7 @@ "promise-to-callback": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/promise-to-callback/-/promise-to-callback-1.0.0.tgz", - "integrity": "sha1-XSp0kBC/tn2WNZj805YHRqaP7vc=", + "integrity": "sha512-uhMIZmKM5ZteDMfLgJnoSq9GCwsNKrYau73Awf1jIy6/eUcuuZ3P+CD9zUv0kJsIUbU+x6uLNIhXhLHDs1pNPA==", "dev": true, "requires": { "is-fn": "^1.0.0", @@ -13242,13 +12209,13 @@ "prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", "dev": true }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", "dev": true }, "psl": { @@ -13275,7 +12242,7 @@ "pull-cat": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/pull-cat/-/pull-cat-1.1.11.tgz", - "integrity": "sha1-tkLdElXaN2pwa220+pYvX9t0wxs=", + "integrity": "sha512-i3w+xZ3DCtTVz8S62hBOuNLRHqVDsHMNZmgrZsjPnsxXUgbWtXEee84lo1XswE7W2a3WHyqsNuDJTjVLAQR8xg==", "dev": true }, "pull-defer": { @@ -13302,7 +12269,7 @@ "pull-live": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/pull-live/-/pull-live-1.0.1.tgz", - "integrity": "sha1-pOzuAeMwFV6RJLu89HYfIbOPUfU=", + "integrity": "sha512-tkNz1QT5gId8aPhV5+dmwoIiA1nmfDOzJDlOOUpU5DNusj6neNd3EePybJ5+sITr2FwyCs/FVpx74YMCfc8YeA==", "dev": true, "requires": { "pull-cat": "^1.1.9", @@ -13312,7 +12279,7 @@ "pull-pushable": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/pull-pushable/-/pull-pushable-2.2.0.tgz", - "integrity": "sha1-Xy867UethpGfAbEqLpnW8b13ZYE=", + "integrity": "sha512-M7dp95enQ2kaHvfCt2+DJfyzgCSpWVR2h2kWYnVsW6ZpxQBx5wOu0QWOvQPVoPnBLUZYitYP2y7HyHkLQNeGXg==", "dev": true }, "pull-stream": { @@ -13324,7 +12291,7 @@ "pull-window": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/pull-window/-/pull-window-2.1.4.tgz", - "integrity": "sha1-/DuG/uvRkgx64pdpHiP3BfiFUvA=", + "integrity": "sha512-cbDzN76BMlcGG46OImrgpkMf/VkCnupj8JhsrpBw3aWBM9ye345aYnqitmZCgauBkc0HbbRRn9hCnsa3k2FNUg==", "dev": true, "requires": { "looper": "^2.0.0" @@ -13495,7 +12462,7 @@ "regexpu-core": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", - "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", + "integrity": "sha512-tJ9+S4oKjxY8IZ9jmjnp/mtytu1u3iyIQAfmI51IKWH6bFf7XR1ybtaO6j7INhZKXOTYADk7V5qxaqLkmNxiZQ==", "dev": true, "requires": { "regenerate": "^1.2.1", @@ -13506,13 +12473,13 @@ "regjsgen": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", - "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", + "integrity": "sha512-x+Y3yA24uF68m5GA+tBjbGYo64xXVJpbToBaWCoSNSc1hdk6dfctaRWrNFTVJZIIhL5GxW8zwjoixbnifnK59g==", "dev": true }, "regjsparser": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", - "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", + "integrity": "sha512-jlQ9gYLfk2p3V5Ag5fYhA7fv7OHzd1KUH0PRP46xc3TgwjwgROIW572AfYg/X9kaNq/LJnu6oJcFRXlIrGoTRw==", "dev": true, "requires": { "jsesc": "~0.5.0" @@ -13521,7 +12488,7 @@ "jsesc": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", "dev": true } } @@ -13535,13 +12502,13 @@ "repeat-string": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", "dev": true }, "repeating": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "integrity": "sha512-ZqtSMuVybkISo2OWvqvm7iHSWngvdaW3IpsT9/uP8v4gMi591LY6h35wdOfvQdWCKFWZWm2Y1Opp4kV7vQKT6A==", "dev": true, "requires": { "is-finite": "^1.0.0" @@ -13578,13 +12545,13 @@ "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", "dev": true }, "responselike": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==", "dev": true, "optional": true, "requires": { @@ -13594,7 +12561,7 @@ "resumer": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", - "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", + "integrity": "sha512-Fn9X8rX8yYF4m81rZCK/5VmrmsSbqS/i3rDLl6ZZHAXgC2nTAx3dhwG8q8odP/RmdLa2YrybDJaAMg+X1ajY3w==", "dev": true, "requires": { "through": "~2.3.4" @@ -13658,7 +12625,7 @@ "safe-regex": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", "dev": true, "requires": { "ret": "~0.1.10" @@ -13679,7 +12646,7 @@ "scryptsy": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/scryptsy/-/scryptsy-1.2.1.tgz", - "integrity": "sha1-oyJfpLJST4AnAHYeKFW987LZIWM=", + "integrity": "sha512-aldIRgMozSJ/Gl6K6qmJZysRP82lz83Wb42vl4PWN8SaLFHIaOzLPc9nUUW2jQN88CuGm5q5HefJ9jZ3nWSmTw==", "dev": true, "optional": true, "requires": { @@ -13744,7 +12711,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true, "optional": true } @@ -13789,7 +12756,7 @@ "set-immediate-shim": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", + "integrity": "sha512-Li5AOqrZWCVA2n5kryzEmqai6bKSIvpz5oUJHPVj6+dsbD3X1ixtsY5tEnsaNpH3pFAHmG8eIHUrtEtohrg+UQ==", "dev": true }, "set-value": { @@ -13807,7 +12774,7 @@ "extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", "dev": true, "requires": { "is-extendable": "^0.1.0" @@ -13816,7 +12783,7 @@ "is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", "dev": true } } @@ -13824,7 +12791,7 @@ "setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", "dev": true }, "setprototypeof": { @@ -13891,7 +12858,7 @@ "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", "dev": true, "requires": { "is-descriptor": "^0.1.0" @@ -13900,7 +12867,7 @@ "extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", "dev": true, "requires": { "is-extendable": "^0.1.0" @@ -13909,7 +12876,7 @@ "is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", "dev": true, "requires": { "kind-of": "^3.0.2" @@ -13918,7 +12885,7 @@ "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -13935,7 +12902,7 @@ "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", "dev": true, "requires": { "kind-of": "^3.0.2" @@ -13944,7 +12911,7 @@ "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -13966,7 +12933,7 @@ "is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", "dev": true }, "kind-of": { @@ -13978,7 +12945,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true } } @@ -13997,7 +12964,7 @@ "define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", "dev": true, "requires": { "is-descriptor": "^1.0.0" @@ -14023,7 +12990,7 @@ "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -14034,7 +13001,7 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", "dev": true }, "source-map-resolve": { @@ -14071,7 +13038,7 @@ "source-map-url": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "integrity": "sha512-liJwHPI9x9d9w5WSIjM58MqGmmb7XzNqwdUA3kSBQ4lmDngexlKwawGzK3J1mKXi6+sysoMDlpVyZh9sv5vRfw==", "dev": true }, "split-string": { @@ -14103,7 +13070,7 @@ "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", "dev": true } } @@ -14111,7 +13078,7 @@ "static-extend": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", "dev": true, "requires": { "define-property": "^0.2.5", @@ -14121,7 +13088,7 @@ "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", "dev": true, "requires": { "is-descriptor": "^0.1.0" @@ -14130,7 +13097,7 @@ "is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", "dev": true, "requires": { "kind-of": "^3.0.2" @@ -14139,7 +13106,7 @@ "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -14156,7 +13123,7 @@ "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", "dev": true, "requires": { "kind-of": "^3.0.2" @@ -14165,7 +13132,7 @@ "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -14195,7 +13162,7 @@ "statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", "dev": true, "optional": true }, @@ -14212,7 +13179,7 @@ "looper": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/looper/-/looper-3.0.0.tgz", - "integrity": "sha1-LvpUw7HLq6m5Su4uWRSwvlf7t0k=", + "integrity": "sha512-LJ9wplN/uSn72oJRsXTx+snxPet5c8XiZmOKCm906NVYu+ag6SB6vUcnJcWxgnl2NfbIyeobAn7Bwv6xRj2XJg==", "dev": true } } @@ -14220,7 +13187,7 @@ "strict-uri-encode": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", + "integrity": "sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==", "dev": true, "optional": true }, @@ -14275,7 +13242,7 @@ "strip-hex-prefix": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", - "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=", + "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", "dev": true, "requires": { "is-hex-prefixed": "1.0.0" @@ -14325,7 +13292,7 @@ "get-stream": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", "dev": true, "optional": true }, @@ -14355,7 +13322,7 @@ "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", "dev": true, "optional": true }, @@ -14369,14 +13336,14 @@ "prepend-http": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", + "integrity": "sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg==", "dev": true, "optional": true }, "url-parse-lax": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", - "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", + "integrity": "sha512-BVA4lR5PIviy2PMseNd2jbFQ+jwSwQGdJejf5ctd1rEXt0Ypd7yanUK9+lYechVlN5VaTJGsu2U/3MDDu6KgBA==", "dev": true, "optional": true, "requires": { @@ -14490,7 +13457,7 @@ "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "dev": true }, "through2": { @@ -14506,7 +13473,7 @@ "timed-out": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", + "integrity": "sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==", "dev": true, "optional": true }, @@ -14522,7 +13489,7 @@ "to-object-path": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", "dev": true, "requires": { "kind-of": "^3.0.2" @@ -14537,7 +13504,7 @@ "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -14584,13 +13551,13 @@ "trim-right": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", + "integrity": "sha512-WZGXGstmCWgeevgTL54hrCuw1dyMQIzWy7ZfqRJfSmJZBwklI15egmQytFP6bPidmw3M8d5yEowl1niq4vmqZw==", "dev": true }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", "dev": true, "requires": { "safe-buffer": "^5.0.1" @@ -14628,7 +13595,7 @@ "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", "dev": true }, "typedarray-to-buffer": { @@ -14643,7 +13610,7 @@ "typewise": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/typewise/-/typewise-1.0.3.tgz", - "integrity": "sha1-EGeTZUCvl5N8xdz5kiSG6fooRlE=", + "integrity": "sha512-aXofE06xGhaQSPzt8hlTY+/YWQhm9P0jYUp1f2XtmW/3Bk0qzXcyFWAtPoo2uTGQj1ZwbDuSyuxicq+aDo8lCQ==", "dev": true, "requires": { "typewise-core": "^1.2.0" @@ -14652,13 +13619,13 @@ "typewise-core": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/typewise-core/-/typewise-core-1.2.0.tgz", - "integrity": "sha1-l+uRgFx/VdL5QXSPpQ0xXZke8ZU=", + "integrity": "sha512-2SCC/WLzj2SbUwzFOzqMCkz5amXLlxtJqDKTICqg30x+2DZxcfZN2MvQZmGfXWKNWaKK9pBPsvkcwv8bF/gxKg==", "dev": true }, "typewiselite": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/typewiselite/-/typewiselite-1.0.0.tgz", - "integrity": "sha1-yIgvobsQksBgBal/NO9chQjjZk4=", + "integrity": "sha512-J9alhjVHupW3Wfz6qFRGgQw0N3gr8hOkw6zm7FZ6UR1Cse/oD9/JVok7DNE9TT9IbciDHX2Ex9+ksE6cRmtymw==", "dev": true }, "ultron": { @@ -14690,7 +13657,7 @@ "is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", "dev": true } } @@ -14710,14 +13677,14 @@ "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "dev": true, "optional": true }, "unset-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", "dev": true, "requires": { "has-value": "^0.3.1", @@ -14727,7 +13694,7 @@ "has-value": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", "dev": true, "requires": { "get-value": "^2.0.3", @@ -14738,7 +13705,7 @@ "isobject": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", "dev": true, "requires": { "isarray": "1.0.0" @@ -14749,7 +13716,7 @@ "has-values": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", "dev": true } } @@ -14766,13 +13733,13 @@ "urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", "dev": true }, "url-parse-lax": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "integrity": "sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==", "dev": true, "optional": true, "requires": { @@ -14782,14 +13749,14 @@ "url-set-query": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz", - "integrity": "sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk=", + "integrity": "sha512-3AChu4NiXquPfeckE5R5cGdiHCMWJx1dwCWOmWIL4KHAziJNOFIYJlpGFeKDvwLPHovZRCxK3cYlwzqI9Vp+Gg==", "dev": true, "optional": true }, "url-to-options": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", - "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=", + "integrity": "sha512-0kQLIzG4fdk/G5NONku64rSH/x32NOA39LVQqlK8Le6lvTF6GGRJpqaQFGgU+CLwySIqBSMdwYM0sYcW9f6P4A==", "dev": true, "optional": true }, @@ -14818,7 +13785,7 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, "util.promisify": { @@ -14837,7 +13804,7 @@ "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", "dev": true, "optional": true }, @@ -14857,14 +13824,14 @@ "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "dev": true, "optional": true }, "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", "dev": true, "requires": { "assert-plus": "^1.0.0", @@ -15205,7 +14172,7 @@ "eth-sig-util": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz", - "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", + "integrity": "sha512-iNZ576iTOGcfllftB73cPB5AN+XUQAT/T8xzsILsghXC1o8gJUqe3RHlcDqagu+biFpYQ61KQrZZJza8eRSYqw==", "dev": true, "requires": { "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git", @@ -15374,7 +14341,7 @@ "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", "dev": true }, "level-codec": { @@ -15395,7 +14362,7 @@ "level-iterator-stream": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz", - "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=", + "integrity": "sha512-1qua0RHNtr4nrZBgYlpV0qHHeHpcRRWTxEZJ8xsemoHAXNL5tbooh4tPEEqIqsbWCAJBmUmkwYK/sW5OrFjWWw==", "dev": true, "requires": { "inherits": "^2.0.1", @@ -15407,7 +14374,7 @@ "readable-stream": { "version": "1.1.14", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", "dev": true, "requires": { "core-util-is": "~1.0.0", @@ -15421,7 +14388,7 @@ "level-ws": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz", - "integrity": "sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=", + "integrity": "sha512-XUTaO/+Db51Uiyp/t7fCMGVFOTdtLS/NIACxE/GHsij15mKzxksZifKVjlXDF41JMUP/oM1Oc4YNGdKnc3dVLw==", "dev": true, "requires": { "readable-stream": "~1.0.15", @@ -15431,7 +14398,7 @@ "readable-stream": { "version": "1.0.34", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", "dev": true, "requires": { "core-util-is": "~1.0.0", @@ -15443,7 +14410,7 @@ "xtend": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", - "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", + "integrity": "sha512-vMNKzr2rHP9Dp/e1NQFnLQlwlhp9L/LfvnsVdHxN1f+uggyVI3i08uD14GPvCToPkdsRfyPqIyYGmIk58V98ZQ==", "dev": true, "requires": { "object-keys": "~0.4.0" @@ -15469,13 +14436,13 @@ "ltgt": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", - "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=", + "integrity": "sha512-AI2r85+4MquTw9ZYqabu4nMwy9Oftlfa/e/52t9IjtfG+mGBbTNdAoZ3RQKLHR6r0wQnwZnPIEh/Ya6XTWAKNA==", "dev": true }, "memdown": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz", - "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=", + "integrity": "sha512-iVrGHZB8i4OQfM155xx8akvG9FIj+ht14DX5CQkCTG4EHzZ3d3sgckIf/Lm9ivZalEsFuEVnWv2B2WZvbrro2w==", "dev": true, "requires": { "abstract-leveldown": "~2.7.1", @@ -15516,7 +14483,7 @@ "async": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", "dev": true } } @@ -15524,7 +14491,7 @@ "object-keys": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", - "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=", + "integrity": "sha512-ncrLw+X55z7bkl5PnUvHwFK9FcGuFYo9gtjws2XtSzL+aZ8tm830P60WJ0dSmFVaSalWieW5MD7kEdnXda9yJw==", "dev": true }, "safe-buffer": { @@ -15542,7 +14509,7 @@ "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", "dev": true }, "ws": { @@ -15662,7 +14629,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true } } @@ -15676,7 +14643,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, "ws": { @@ -15741,7 +14708,7 @@ "xhr2-cookies": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz", - "integrity": "sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg=", + "integrity": "sha512-hjXUA6q+jl/bd8ADHcVfFsSPIf+tyLIjuO9TwJC9WI6JP2zKcS7C+p56I9kCLLsaCiNT035iYvEUUzdEFj/8+g==", "dev": true, "optional": true, "requires": { @@ -15757,7 +14724,7 @@ "yaeti": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", - "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=", + "integrity": "sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug==", "dev": true }, "yallist": { @@ -15771,7 +14738,7 @@ "gauge": { "version": "2.7.4", "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "integrity": "sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==", "optional": true, "requires": { "aproba": "^1.0.3", @@ -15782,72 +14749,41 @@ "string-width": "^1.0.1", "strip-ansi": "^3.0.1", "wide-align": "^1.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "optional": true - }, - "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=", - "optional": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "optional": true, - "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": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "optional": true, - "requires": { - "ansi-regex": "^2.0.0" - } - } } }, "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", "dev": true }, "get-func-name": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", "dev": true }, "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", + "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", "dev": true, "requires": { "function-bind": "^1.1.1", "has": "^1.0.3", - "has-symbols": "^1.0.1" + "has-symbols": "^1.0.3" } }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true + }, "get-port": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", - "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=", + "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==", "dev": true }, "get-stream": { @@ -15872,7 +14808,7 @@ "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", "dev": true, "requires": { "assert-plus": "^1.0.0" @@ -15886,32 +14822,84 @@ "requires": { "chalk": "^2.4.2", "node-emoji": "^1.10.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, "github-from-package": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", "optional": true }, "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "requires": { "is-glob": "^4.0.1" } @@ -15973,6 +14961,12 @@ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true } } }, @@ -15993,12 +14987,29 @@ "p-cancelable": "^1.0.0", "to-readable-stream": "^1.0.0", "url-parse-lax": "^3.0.0" + }, + "dependencies": { + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true + } } }, "graceful-fs": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, "growl": { "version": "1.10.5", @@ -16017,20 +15028,12 @@ "source-map": "^0.6.1", "uglify-js": "^3.1.4", "wordwrap": "^1.0.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } } }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", "dev": true }, "har-validator": { @@ -16041,26 +15044,48 @@ "requires": { "ajv": "^6.12.3", "har-schema": "^2.0.0" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + } } }, "hardhat": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.6.2.tgz", - "integrity": "sha512-83kCYIrkRq+vrsjOLIv349fbMpL7Vp/ZGpWtu+KLMH3wcAAs+aMsABZJ8W5hb5uo69+06KeF0pCHQ6y8tBAcwA==", + "version": "2.10.2", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.10.2.tgz", + "integrity": "sha512-L/KvDDT/MA6332uAtYTqdcHoSABljw4pPjHQe5SHdIJ+xKfaSc6vDKw03CmrQ5Xup0gHs8XnVSBpZo1AbbIW7g==", "dev": true, "requires": { - "@ethereumjs/block": "^3.4.0", - "@ethereumjs/blockchain": "^5.4.0", - "@ethereumjs/common": "^2.4.0", - "@ethereumjs/tx": "^3.3.0", - "@ethereumjs/vm": "^5.5.2", + "@ethereumjs/block": "^3.6.2", + "@ethereumjs/blockchain": "^5.5.2", + "@ethereumjs/common": "^2.6.4", + "@ethereumjs/tx": "^3.5.1", + "@ethereumjs/vm": "^5.9.0", "@ethersproject/abi": "^5.1.2", + "@metamask/eth-sig-util": "^4.0.0", "@sentry/node": "^5.18.1", - "@solidity-parser/parser": "^0.11.0", + "@solidity-parser/parser": "^0.14.2", "@types/bn.js": "^5.1.0", "@types/lru-cache": "^5.1.0", "abort-controller": "^3.0.0", "adm-zip": "^0.4.16", + "aggregate-error": "^3.0.0", "ansi-escapes": "^4.3.0", "chalk": "^2.4.2", "chokidar": "^3.4.0", @@ -16068,22 +15093,20 @@ "debug": "^4.1.1", "enquirer": "^2.3.0", "env-paths": "^2.2.0", - "eth-sig-util": "^2.5.2", - "ethereum-cryptography": "^0.1.2", + "ethereum-cryptography": "^1.0.3", "ethereumjs-abi": "^0.6.8", - "ethereumjs-util": "^7.1.0", + "ethereumjs-util": "^7.1.4", "find-up": "^2.1.0", "fp-ts": "1.19.3", "fs-extra": "^7.0.1", - "glob": "^7.1.3", - "https-proxy-agent": "^5.0.0", + "glob": "7.2.0", "immutable": "^4.0.0-rc.12", "io-ts": "1.10.4", "lodash": "^4.17.11", - "merkle-patricia-tree": "^4.2.0", + "merkle-patricia-tree": "^4.2.4", "mnemonist": "^0.38.0", - "mocha": "^7.1.2", - "node-fetch": "^2.6.0", + "mocha": "^10.0.0", + "p-map": "^4.0.0", "qs": "^6.7.0", "raw-body": "^2.4.1", "resolve": "1.17.0", @@ -16094,380 +15117,205 @@ "stacktrace-parser": "^0.1.10", "true-case-path": "^2.2.1", "tsort": "0.0.1", - "uuid": "^3.3.2", + "undici": "^5.4.0", + "uuid": "^8.3.2", "ws": "^7.4.6" }, "dependencies": { - "@solidity-parser/parser": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.11.1.tgz", - "integrity": "sha512-H8BSBoKE8EubJa0ONqecA2TviT3TnHeC4NpgnAHSUiuhZoQBfPB4L2P9bs8R6AoTW10Endvh3vc+fomVMIDIYQ==", - "dev": true - }, - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", - "dev": true - }, - "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "solc": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.7.3.tgz", - "integrity": "sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==", - "dev": true, - "requires": { - "command-exists": "^1.2.8", - "commander": "3.0.2", - "follow-redirects": "^1.12.1", - "fs-extra": "^0.30.0", - "js-sha3": "0.8.0", - "memorystream": "^0.3.1", - "require-from-string": "^2.0.0", - "semver": "^5.5.0", - "tmp": "0.0.33" - }, - "dependencies": { - "fs-extra": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - } - } - }, - "hardhat-abi-exporter": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/hardhat-abi-exporter/-/hardhat-abi-exporter-2.8.0.tgz", - "integrity": "sha512-HQwd9Agr2O5znUg9Dzicw8grsXacoMSQsS5ZhBBNyaxKeVbvxL1Ubm9ss8sSVGr74511a8qiR2Ljm/lsLS9Mew==", - "dev": true, - "requires": { - "@ethersproject/abi": "^5.5.0", - "delete-empty": "^3.0.0" - }, - "dependencies": { - "@ethersproject/abi": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.5.0.tgz", - "integrity": "sha512-loW7I4AohP5KycATvc0MgujU6JyCHPqHdeoo9z3Nr9xEiNioxa65ccdm1+fsoJhkuhdRtfcL8cfyGamz2AxZ5w==", - "dev": true, - "requires": { - "@ethersproject/address": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/constants": "^5.5.0", - "@ethersproject/hash": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/strings": "^5.5.0" - } - }, - "@ethersproject/abstract-provider": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.5.1.tgz", - "integrity": "sha512-m+MA/ful6eKbxpr99xUYeRvLkfnlqzrF8SZ46d/xFB1A7ZVknYc/sXJG0RcufF52Qn2jeFj1hhcoQ7IXjNKUqg==", - "dev": true, - "requires": { - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/networks": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/transactions": "^5.5.0", - "@ethersproject/web": "^5.5.0" - } - }, - "@ethersproject/abstract-signer": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.5.0.tgz", - "integrity": "sha512-lj//7r250MXVLKI7sVarXAbZXbv9P50lgmJQGr2/is82EwEb8r7HrxsmMqAjTsztMYy7ohrIhGMIml+Gx4D3mA==", - "dev": true, - "requires": { - "@ethersproject/abstract-provider": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0" - } - }, - "@ethersproject/address": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.5.0.tgz", - "integrity": "sha512-l4Nj0eWlTUh6ro5IbPTgbpT4wRbdH5l8CQf7icF7sb/SI3Nhd9Y9HzhonTSTi6CefI0necIw7LJqQPopPLZyWw==", - "dev": true, - "requires": { - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/rlp": "^5.5.0" - } - }, - "@ethersproject/base64": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.5.0.tgz", - "integrity": "sha512-tdayUKhU1ljrlHzEWbStXazDpsx4eg1dBXUSI6+mHlYklOXoXF6lZvw8tnD6oVaWfnMxAgRSKROg3cVKtCcppA==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.5.0" - } - }, - "@ethersproject/bignumber": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.5.0.tgz", - "integrity": "sha512-6Xytlwvy6Rn3U3gKEc1vP7nR92frHkv6wtVr95LFR3jREXiCPzdWxKQ1cx4JGQBXxcguAwjA8murlYN2TSiEbg==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "bn.js": "^4.11.9" - } - }, - "@ethersproject/bytes": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.5.0.tgz", - "integrity": "sha512-ABvc7BHWhZU9PNM/tANm/Qx4ostPGadAuQzWTr3doklZOhDlmcBqclrQe/ZXUIj3K8wC28oYeuRa+A37tX9kog==", - "dev": true, - "requires": { - "@ethersproject/logger": "^5.5.0" - } - }, - "@ethersproject/constants": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.5.0.tgz", - "integrity": "sha512-2MsRRVChkvMWR+GyMGY4N1sAX9Mt3J9KykCsgUFd/1mwS0UH1qw+Bv9k1UJb3X3YJYFco9H20pjSlOIfCG5HYQ==", + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "@ethersproject/bignumber": "^5.5.0" + "color-convert": "^1.9.0" } }, - "@ethersproject/hash": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.5.0.tgz", - "integrity": "sha512-dnGVpK1WtBjmnp3mUT0PlU2MpapnwWI0PibldQEq1408tQBAbZpPidkWoVVuNMOl/lISO3+4hXZWCL3YV7qzfg==", + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/address": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/strings": "^5.5.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, - "@ethersproject/keccak256": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.5.0.tgz", - "integrity": "sha512-5VoFCTjo2rYbBe1l2f4mccaRFN/4VQEYFwwn04aJV2h7qf4ZvI2wFxUE1XOX+snbwCLRzIeikOqtAoPwMza9kg==", + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, "requires": { - "@ethersproject/bytes": "^5.5.0", - "js-sha3": "0.8.0" + "color-name": "1.1.3" } }, - "@ethersproject/logger": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.5.0.tgz", - "integrity": "sha512-rIY/6WPm7T8n3qS2vuHTUBPdXHl+rGxWxW5okDfo9J4Z0+gRRZT0msvUdIJkE4/HS29GUMziwGaaKO2bWONBrg==", + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, - "@ethersproject/networks": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.5.2.tgz", - "integrity": "sha512-NEqPxbGBfy6O3x4ZTISb90SjEDkWYDUbEeIFhJly0F7sZjoQMnj5KYzMSkMkLKZ+1fGpx00EDpHQCy6PrDupkQ==", - "dev": true, - "requires": { - "@ethersproject/logger": "^5.5.0" - } - }, - "@ethersproject/properties": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.5.0.tgz", - "integrity": "sha512-l3zRQg3JkD8EL3CPjNK5g7kMx4qSwiR60/uk5IVjd3oq1MZR5qUg40CNOoEJoX5wc3DyY5bt9EbMk86C7x0DNA==", - "dev": true, - "requires": { - "@ethersproject/logger": "^5.5.0" - } - }, - "@ethersproject/rlp": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.5.0.tgz", - "integrity": "sha512-hLv8XaQ8PTI9g2RHoQGf/WSxBfTB/NudRacbzdxmst5VHAqd1sMibWG7SENzT5Dj3yZ3kJYx+WiRYEcQTAkcYA==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0" - } - }, - "@ethersproject/signing-key": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.5.0.tgz", - "integrity": "sha512-5VmseH7qjtNmDdZBswavhotYbWB0bOwKIlOTSlX14rKn5c11QmJwGt4GHeo7NrL/Ycl7uo9AHvEqs5xZgFBTng==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "bn.js": "^4.11.9", - "elliptic": "6.5.4", - "hash.js": "1.1.7" - } - }, - "@ethersproject/strings": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.5.0.tgz", - "integrity": "sha512-9fy3TtF5LrX/wTrBaT8FGE6TDJyVjOvXynXJz5MT5azq+E6D92zuKNx7i29sWW2FjVOaWjAsiZ1ZWznuduTIIQ==", + "ethereum-cryptography": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.1.2.tgz", + "integrity": "sha512-XDSJlg4BD+hq9N2FjvotwUET9Tfxpxc3kWGE2AqUG5vcbeunnbImVk3cj6e/xT3phdW21mE8R5IugU4fspQDcQ==", "dev": true, "requires": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/constants": "^5.5.0", - "@ethersproject/logger": "^5.5.0" + "@noble/hashes": "1.1.2", + "@noble/secp256k1": "1.6.3", + "@scure/bip32": "1.1.0", + "@scure/bip39": "1.1.0" } }, - "@ethersproject/transactions": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.5.0.tgz", - "integrity": "sha512-9RZYSKX26KfzEd/1eqvv8pLauCKzDTub0Ko4LfIgaERvRuwyaNV78mJs7cpIgZaDl6RJui4o49lHwwCM0526zA==", + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", "dev": true, "requires": { - "@ethersproject/address": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/constants": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/rlp": "^5.5.0", - "@ethersproject/signing-key": "^5.5.0" + "locate-path": "^2.0.0" } }, - "@ethersproject/web": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.5.1.tgz", - "integrity": "sha512-olvLvc1CB12sREc1ROPSHTdFCdvMh0J5GSJYiQg2D0hdD4QmJDy8QYDb1CvoqD/bF1c++aeKv2sR5uduuG9dQg==", + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "dev": true, "requires": { - "@ethersproject/base64": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/strings": "^5.5.0" + "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" } }, - "js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true - } - } - }, - "hardhat-contract-sizer": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/hardhat-contract-sizer/-/hardhat-contract-sizer-2.4.0.tgz", - "integrity": "sha512-ww+Fw5Fq+q6gkVxB8KFvicqZFH5pH9HGZwV4ZSTxd0QrxA162qzLdbScJseUP30VvIBPYN9wpdj0cWlz6M9j6g==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "cli-table3": "^0.6.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + }, + "jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", "dev": true, "requires": { - "color-convert": "^2.0.1" + "graceful-fs": "^4.1.6" } }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", "dev": true, "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "side-channel": "^1.0.4" } }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", "dev": true, "requires": { - "color-name": "~1.1.4" + "path-parse": "^1.0.6" } }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, + "solc": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.7.3.tgz", + "integrity": "sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==", + "dev": true, + "requires": { + "command-exists": "^1.2.8", + "commander": "3.0.2", + "follow-redirects": "^1.12.1", + "fs-extra": "^0.30.0", + "js-sha3": "0.8.0", + "memorystream": "^0.3.1", + "require-from-string": "^2.0.0", + "semver": "^5.5.0", + "tmp": "0.0.33" + }, + "dependencies": { + "fs-extra": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", + "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { - "has-flag": "^4.0.0" + "has-flag": "^3.0.0" } + }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true } } }, + "hardhat-abi-exporter": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/hardhat-abi-exporter/-/hardhat-abi-exporter-2.10.0.tgz", + "integrity": "sha512-ynYGUptkal3leyUNGP3aJ6GRYtSHed3lHcfMv6imawqEd7MERueEkeFy+X4kWH3Vf5w4k6xeeCJHJsegGBJUPA==", + "dev": true, + "requires": { + "@ethersproject/abi": "^5.5.0", + "delete-empty": "^3.0.0" + } + }, + "hardhat-contract-sizer": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/hardhat-contract-sizer/-/hardhat-contract-sizer-2.6.1.tgz", + "integrity": "sha512-b8wS7DBvyo22kmVwpzstAQTdDCThpl/ySBqZh5ga9Yxjf61/uTL12TEg5nl7lDeWy73ntEUzxMwY6XxbQEc2wA==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "cli-table3": "^0.6.0" + } + }, "hardhat-gas-reporter": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.7.tgz", - "integrity": "sha512-calJH1rbhUFwCnw0odJb3Cw+mDmBIsHdVyutsHhA3RY6JELyFVaVxCnITYGr/crkmHqt4tQCYROy7ty6DTLkuA==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.8.tgz", + "integrity": "sha512-1G5thPnnhcwLHsFnl759f2tgElvuwdkzxlI65fC9PwxYMEe9cmjkVAAWTf3/3y8uP6ZSPiUiOW8PgZnykmZe0g==", "dev": true, "requires": { "array-uniq": "1.0.3", @@ -16482,11 +15330,11 @@ "dev": true }, "hardhat-watcher": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/hardhat-watcher/-/hardhat-watcher-2.1.1.tgz", - "integrity": "sha512-zilmvxAYD34IofBrwOliQn4z92UiDmt2c949DW4Gokf0vS0qk4YTfVCi/LmUBICThGygNANE3WfnRTpjCJGtDA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/hardhat-watcher/-/hardhat-watcher-2.5.0.tgz", + "integrity": "sha512-Su2qcSMIo2YO2PrmJ0/tdkf+6pSt8zf9+4URR5edMVti6+ShI8T3xhPrwugdyTOFuyj8lKHrcTZNKUFYowYiyA==", "requires": { - "chokidar": "^3.4.3" + "chokidar": "^3.5.3" } }, "has": { @@ -16499,16 +15347,24 @@ } }, "has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", "dev": true }, "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.1" + } }, "has-symbol-support-x": { "version": "1.4.2", @@ -16517,9 +15373,9 @@ "dev": true }, "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "dev": true }, "has-to-string-tag-x": { @@ -16543,7 +15399,7 @@ "has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", "optional": true }, "hash-base": { @@ -16565,6 +15421,11 @@ "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" } } }, @@ -16586,7 +15447,7 @@ "hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", "requires": { "hash.js": "^1.0.3", "minimalistic-assert": "^1.0.0", @@ -16618,22 +15479,22 @@ "dev": true }, "http-errors": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", - "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "dev": true, "requires": { - "depd": "~1.1.2", + "depd": "2.0.0", "inherits": "2.0.4", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" } }, "http-https": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz", - "integrity": "sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs=", + "integrity": "sha512-o0PWwVCSp3O0wS6FvNr6xfBCHgt0m1tvPLFOCc2iFDKTRAXhB7m8klDf7ErowFH8POa6dVdGatKU5I1YYwzUyg==", "dev": true }, "http-response-object": { @@ -16656,7 +15517,7 @@ "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", "dev": true, "requires": { "assert-plus": "^1.0.0", @@ -16664,33 +15525,32 @@ "sshpk": "^1.7.0" } }, + "http2-wrapper": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.1.11.tgz", + "integrity": "sha512-aNAk5JzLturWEUiuhAN73Jcbq96R7rTitAoXV54FYMatvihnpD2+6PUgU4ce3D/m5VDbw+F5CsyKSF176ptitQ==", + "dev": true, + "requires": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.2.0" + } + }, "https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "dev": true, "requires": { "agent-base": "6", "debug": "4" - }, - "dependencies": { - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } } }, + "hyperlinker": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hyperlinker/-/hyperlinker-1.0.0.tgz", + "integrity": "sha512-Ty8UblRWFEcfSuIaajM34LdPXIhbs1ajEX/BBPv24J+enSVaEVY63xQ6lTO9VRYS5LAoghIG0IDJ+p+IPzKUQQ==", + "dev": true + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -16707,6 +15567,14 @@ "dev": true, "requires": { "punycode": "2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", + "integrity": "sha512-Yxz2kRwT90aPiWEMHVYnEf4+rhwF1tBmmZ4KepCP+Wkium9JxtWnUm1nqGwpiAHr/tnTSeHqr3wb++jgSkXjhA==", + "dev": true + } } }, "ieee754": { @@ -16727,15 +15595,15 @@ "dev": true }, "immutable": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz", - "integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz", + "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==", "dev": true }, "import-fresh": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==", "dev": true, "requires": { "caller-path": "^2.0.0", @@ -16745,7 +15613,7 @@ "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true }, "indent-string": { @@ -16757,7 +15625,7 @@ "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, "requires": { "once": "^1.3.0", @@ -16802,11 +15670,79 @@ "dev": true }, "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", "dev": true }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, "strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", @@ -16814,6 +15750,23 @@ "dev": true, "requires": { "ansi-regex": "^4.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true + } + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" } } } @@ -16846,7 +15799,7 @@ "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=", + "integrity": "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==", "dev": true }, "io-ts": { @@ -16865,25 +15818,29 @@ "dev": true }, "is-arguments": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", - "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", "dev": true, "requires": { - "call-bind": "^1.0.0" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" } }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true }, "is-bigint": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.1.tgz", - "integrity": "sha512-J0ELF4yHFxHy0cmSxZuheDOz2luOdVvqjwmEcj8H/L1JHeuEDSDbeRP+Dk9kFVk5RTFzbucJ2Kb9F7ixY2QaCg==", - "dev": true + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "requires": { + "has-bigints": "^1.0.1" + } }, "is-binary-path": { "version": "2.1.0", @@ -16894,12 +15851,13 @@ } }, "is-boolean-object": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.0.tgz", - "integrity": "sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", "dev": true, "requires": { - "call-bind": "^1.0.0" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" } }, "is-buffer": { @@ -16909,9 +15867,9 @@ "dev": true }, "is-callable": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", - "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", "dev": true }, "is-ci": { @@ -16923,16 +15881,28 @@ "ci-info": "^2.0.0" } }, + "is-core-module": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", + "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } }, "is-directory": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", + "integrity": "sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==", "dev": true }, "is-docker": { @@ -16944,12 +15914,15 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" }, "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", + "requires": { + "number-is-nan": "^1.0.0" + } }, "is-function": { "version": "1.0.2", @@ -16958,15 +15931,18 @@ "dev": true }, "is-generator-function": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.9.tgz", - "integrity": "sha512-ZJ34p1uvIfptHCN7sFTjGibB9/oBg17sHqzDLfuwhvmN/qLVvIQXRQ8licZQ35WJ8KuEQt/etnnzQFI9C9Ue/A==", - "dev": true + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } }, "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "requires": { "is-extglob": "^2.1.1" } @@ -16974,20 +15950,28 @@ "is-hex-prefixed": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", - "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=", + "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", "dev": true }, "is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", "dev": true }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, "is-number-object": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz", - "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==", - "dev": true + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } }, "is-object": { "version": "1.0.2", @@ -16996,19 +15980,19 @@ "dev": true }, "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true }, "is-regex": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", - "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dev": true, "requires": { "call-bind": "^1.0.2", - "has-symbols": "^1.0.1" + "has-tostringtag": "^1.0.0" } }, "is-retry-allowed": { @@ -17017,50 +16001,62 @@ "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", "dev": true }, - "is-shared-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", - "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", - "dev": true + "is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } }, "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", "dev": true }, "is-string": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", - "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", - "dev": true + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } }, "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", "dev": true, "requires": { - "has-symbols": "^1.0.1" + "has-symbols": "^1.0.2" } }, "is-typed-array": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.5.tgz", - "integrity": "sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug==", + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.9.tgz", + "integrity": "sha512-kfrlnTTn8pZkfpJMUgYD7YZ3qzeJgWUn8XfVYBARc4wnmNOmLbmuuaAs3q5fvB0UJOn6yHAKaGTPM7d6ezoD/A==", "dev": true, "requires": { - "available-typed-arrays": "^1.0.2", + "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", - "es-abstract": "^1.18.0-next.2", - "foreach": "^2.0.5", - "has-symbols": "^1.0.1" + "es-abstract": "^1.20.0", + "for-each": "^0.3.3", + "has-tostringtag": "^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=", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true + }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true }, "is-url": { @@ -17072,7 +16068,7 @@ "is-utf8": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", "dev": true }, "is-weakref": { @@ -17096,18 +16092,18 @@ "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "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=", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", "dev": true }, "isurl": { @@ -17120,11 +16116,30 @@ "is-object": "^1.0.1" } }, + "jake": { + "version": "10.8.5", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz", + "integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==", + "dev": true, + "requires": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.1", + "minimatch": "^3.0.4" + }, + "dependencies": { + "async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", + "dev": true + } + } + }, "js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=", - "dev": true + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" }, "js-tokens": { "version": "4.0.0", @@ -17132,25 +16147,24 @@ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "^2.0.1" } }, "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", "dev": true }, "json-buffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==", "dev": true }, "json-parse-better-errors": { @@ -17160,62 +16174,59 @@ "dev": true }, "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", "dev": true }, "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, "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=", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", "dev": true }, "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", + "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "dev": true }, "jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "dev": true, "requires": { "graceful-fs": "^4.1.6" } }, "jsonschema": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.0.tgz", - "integrity": "sha512-/YgW6pRMr6M7C+4o8kS+B/2myEpHCrxO4PEWnqJNBFMjn7EWXqlQ4tGwL6xTHeRplwuZmcAncdvfOad1nT2yMw==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz", + "integrity": "sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==", "dev": true }, "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", "dev": true, "requires": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", - "json-schema": "0.2.3", + "json-schema": "0.4.0", "verror": "1.10.0" } }, @@ -17264,7 +16275,7 @@ "klaw": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", - "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "integrity": "sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==", "dev": true, "requires": { "graceful-fs": "^4.1.9" @@ -17282,7 +16293,7 @@ "lcid": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "integrity": "sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==", "dev": true, "requires": { "invert-kv": "^1.0.0" @@ -17405,7 +16416,7 @@ "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", "dev": true, "requires": { "prelude-ls": "~1.1.2", @@ -17415,7 +16426,7 @@ "load-json-file": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "integrity": "sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==", "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -17428,11 +16439,19 @@ "locate-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", "dev": true, "requires": { "p-locate": "^2.0.0", "path-exists": "^3.0.0" + }, + "dependencies": { + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true + } } }, "lodash": { @@ -17443,16 +16462,23 @@ "lodash.assign": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", - "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=", + "integrity": "sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw==", + "dev": true + }, + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", "dev": true }, "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, "requires": { - "chalk": "^2.4.2" + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" } }, "loose-envify": { @@ -17463,6 +16489,15 @@ "js-tokens": "^3.0.0 || ^4.0.0" } }, + "loupe": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", + "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", + "dev": true, + "requires": { + "get-func-name": "^2.0.0" + } + }, "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", @@ -17475,25 +16510,18 @@ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "requires": { "yallist": "^4.0.0" - }, - "dependencies": { - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - } } }, "lru_map": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", - "integrity": "sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0=", + "integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==", "dev": true }, "ltgt": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", - "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=", + "integrity": "sha512-AI2r85+4MquTw9ZYqabu4nMwy9Oftlfa/e/52t9IjtfG+mGBbTNdAoZ3RQKLHR6r0wQnwZnPIEh/Ya6XTWAKNA==", "dev": true }, "make-error": { @@ -17527,7 +16555,7 @@ "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "dev": true }, "memdown": { @@ -17560,7 +16588,13 @@ "immediate": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.2.3.tgz", - "integrity": "sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw=", + "integrity": "sha512-RrGCXRm/fRVqMIhqXrGEX9rRADavPiDFSoMb/k64i9XMk8uH4r/Omi5Ctierj6XzNecwDbO4WuFbDD1zmpl3Tg==", + "dev": true + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true } } @@ -17568,13 +16602,13 @@ "memorystream": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", - "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", "dev": true }, "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", "dev": true }, "merge2": { @@ -17584,17 +16618,16 @@ "dev": true }, "merkle-patricia-tree": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-4.2.2.tgz", - "integrity": "sha512-eqZYNTshcYx9aESkSPr71EqwsR/QmpnObDEV4iLxkt/x/IoLYZYjJvKY72voP/27Vy61iMOrfOG6jrn7ttXD+Q==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-4.2.4.tgz", + "integrity": "sha512-eHbf/BG6eGNsqqfbLED9rIqbsF4+sykEaBn6OLNs71tjclbMcMOk1tEPmJKcNcNCLkvbpY/lwyOlizWsqPNo8w==", "dev": true, "requires": { "@types/levelup": "^4.3.0", - "ethereumjs-util": "^7.1.2", + "ethereumjs-util": "^7.1.4", "level-mem": "^5.0.1", "level-ws": "^2.0.0", "readable-stream": "^3.6.0", - "rlp": "^2.2.4", "semaphore-async-await": "^1.5.1" }, "dependencies": { @@ -17614,17 +16647,17 @@ "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", "dev": true }, "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" + "braces": "^3.0.2", + "picomatch": "^2.3.1" } }, "miller-rabin": { @@ -17635,6 +16668,14 @@ "requires": { "bn.js": "^4.0.0", "brorand": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } } }, "mime": { @@ -17644,16 +16685,16 @@ "dev": true }, "mime-db": { - "version": "1.46.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.46.0.tgz", - "integrity": "sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ==" + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" }, "mime-types": { - "version": "2.1.29", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.29.tgz", - "integrity": "sha512-Y/jMt/S5sR9OaqteJtslsFZKWOIIqMACsJSiHghlCAyhf7jfVYjKBmLiX8OgpWeW+fjJ2b+Az69aPFPkUOY6xQ==", + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "requires": { - "mime-db": "1.46.0" + "mime-db": "1.52.0" } }, "mimic-fn": { @@ -17663,15 +16704,15 @@ "dev": true }, "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "optional": true }, "min-document": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", + "integrity": "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==", "dev": true, "requires": { "dom-walk": "^0.1.0" @@ -17685,21 +16726,21 @@ "minimalistic-crypto-utils": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" }, "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" }, "minipass": { "version": "2.9.0", @@ -17709,6 +16750,14 @@ "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" + }, + "dependencies": { + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + } } }, "minizlib": { @@ -17721,12 +16770,12 @@ } }, "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "dev": true, "requires": { - "minimist": "^1.2.5" + "minimist": "^1.2.6" } }, "mkdirp-classic": { @@ -17738,7 +16787,7 @@ "mkdirp-promise": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz", - "integrity": "sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE=", + "integrity": "sha512-Hepn5kb1lJPtVW84RFT40YG1OddBNTOVUZR2bzQUHc+Z03en8/3uX0+060JDhcEzyO08HmipsN9DcnFMxhIL9w==", "dev": true, "requires": { "mkdirp": "*" @@ -17754,88 +16803,84 @@ } }, "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.0.0.tgz", + "integrity": "sha512-0Wl+elVUD43Y0BqPZBzZt8Tnkw9CMUdNYnUsTfOM1vuhJVZL+kiesFYsqwBkEEuEixaiPe5ZQdqDgX2jddhmoA==", "dev": true, "requires": { - "ansi-colors": "3.2.3", + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", + "chokidar": "3.5.3", + "debug": "4.3.4", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.2.0", "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "5.0.1", + "ms": "2.1.3", + "nanoid": "3.3.3", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "workerpool": "6.2.1", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" }, "dependencies": { "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", "dev": true }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "requires": { - "ms": "^2.1.1" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" } }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "requires": { - "locate-path": "^3.0.0" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" } }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true }, "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -17844,74 +16889,156 @@ "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" + }, + "dependencies": { + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } } }, - "locate-path": { + "is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" + "p-locate": "^5.0.0" + } + }, + "minimatch": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + } } }, "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "requires": { - "p-try": "^2.0.0" + "yocto-queue": "^0.1.0" } }, "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "requires": { - "p-limit": "^2.0.0" + "p-limit": "^3.0.2" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { - "picomatch": "^2.0.4" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" } }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" } }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "requires": { - "string-width": "^1.0.2 || 2" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" } + }, + "yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true } } }, @@ -17922,10 +17049,9 @@ "dev": true }, "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "multibase": { "version": "0.6.1", @@ -17972,18 +17098,25 @@ "mute-stream": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "integrity": "sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==", "dev": true }, "nan": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", - "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==" + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.16.0.tgz", + "integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==", + "optional": true }, "nano-json-stream-parser": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz", - "integrity": "sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18=", + "integrity": "sha512-9MqxMH/BSJC7dnLsEMPyfN5Dvoo49IsPFYMcHw3Bcfc2kN0lpHRBSzlMSVx4HGyJ7s9B31CyBTVehWJoQ8Ctew==", + "dev": true + }, + "nanoid": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", + "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", "dev": true }, "napi-build-utils": { @@ -17995,13 +17128,19 @@ "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "natural-orderby": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/natural-orderby/-/natural-orderby-2.0.3.tgz", + "integrity": "sha512-p7KTHxU0CUrcOXe62Zfrb5Z13nLvPhSWR/so3kFulUQU0sgUll2Z0LwpsLN351eOOD+hRGu/F1g+6xDfPeD++Q==", "dev": true }, "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "dev": true }, "neo-async": { @@ -18011,9 +17150,9 @@ "dev": true }, "next-tick": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", "dev": true }, "nice-try": { @@ -18073,15 +17212,18 @@ } }, "node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", - "dev": true + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, + "requires": { + "whatwg-url": "^5.0.0" + } }, "node-gyp-build": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", - "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==" + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.5.0.tgz", + "integrity": "sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==" }, "node-hid": { "version": "1.3.0", @@ -18095,21 +17237,6 @@ "prebuild-install": "^5.3.4" }, "dependencies": { - "decompress-response": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", - "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", - "optional": true, - "requires": { - "mimic-response": "^2.0.0" - } - }, - "mimic-response": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", - "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", - "optional": true - }, "prebuild-install": { "version": "5.3.6", "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.6.tgz", @@ -18132,36 +17259,24 @@ "tunnel-agent": "^0.6.0", "which-pm-runs": "^1.0.0" } - }, - "simple-get": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", - "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", - "optional": true, - "requires": { - "decompress-response": "^4.2.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } } } }, "nofilter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-1.0.4.tgz", - "integrity": "sha512-N8lidFp+fCz+TD51+haYdbDGrcBWwuHX40F5+z0qkUjMJ5Tp+rdSuAkMJ9N9eoolDlEVTf6u5icM+cNKkKW2mA==", - "dev": true + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", + "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==" }, "noop-logger": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", - "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=", + "integrity": "sha512-6kM8CLXvuW5crTxsAtva2YLrRrDaiTIkIePWs9moLHqbFWT94WpNFjwS/5dfLfECg5i/lkmw3aoqVidxt23TEQ==", "optional": true }, "nopt": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "integrity": "sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==", "dev": true, "requires": { "abbrev": "1" @@ -18213,12 +17328,12 @@ "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=" + "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==" }, "number-to-bn": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", - "integrity": "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=", + "integrity": "sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==", "dev": true, "requires": { "bn.js": "4.11.6", @@ -18228,7 +17343,7 @@ "bn.js": { "version": "4.11.6", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", "dev": true } } @@ -18242,12 +17357,12 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" }, "object-inspect": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", - "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", "dev": true }, "object-keys": { @@ -18256,6 +17371,12 @@ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true }, + "object-treeify": { + "version": "1.1.33", + "resolved": "https://registry.npmjs.org/object-treeify/-/object-treeify-1.1.33.tgz", + "integrity": "sha512-EFVjAYfzWqWsBMRHPMAXLCDIJnpMhdWAqR7xG6M6a2cs6PMFpl/+Z20w9zDW4vkxOFfddegBKq9Rehd0bxWE7A==", + "dev": true + }, "object.assign": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", @@ -18269,120 +17390,36 @@ } }, "object.getownpropertydescriptors": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz", - "integrity": "sha512-VdDoCwvJI4QdC6ndjpqFmoL3/+HxffFBbcJzKi5hwLLqqx3mdbedRpfZDdK0SrOSauj8X4GzBvnDZl4vTN7dOw==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.4.tgz", + "integrity": "sha512-sccv3L/pMModT6dJAYF3fzGMVcb38ysQ0tEE6ixv2yXJDtEIPph268OlAdJj5/qZMZDq2g/jqvwppt36uS/uQQ==", "dev": true, "requires": { + "array.prototype.reduce": "^1.0.4", "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - }, - "dependencies": { - "es-abstract": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", - "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", - "is-string": "^1.0.7", - "is-weakref": "^1.0.1", - "object-inspect": "^1.11.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" - } - }, - "is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", - "dev": true - }, - "is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "object-inspect": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", - "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", - "dev": true - }, - "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } - }, - "unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - } - } + "define-properties": "^1.1.4", + "es-abstract": "^1.20.1" } }, "obliterator": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.1.tgz", - "integrity": "sha512-XnkiCrrBcIZQitJPAI36mrrpEUvatbte8hLcTcQwKA1v9NkCKasSi+UAguLsLDs/out7MoRzAlmz7VXvY6ph6w==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz", + "integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==", "dev": true }, "oboe": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.5.tgz", - "integrity": "sha1-VVQoTFQ6ImbXo48X4HOCH73jk80=", + "integrity": "sha512-zRFWiF+FoicxEs3jNI/WYUrVEgA7DeET/InK0XQuudGHRg8iIob3cNPrJTKaz4004uaA9Pbe+Dwa8iluhjLZWA==", "dev": true, "requires": { "http-https": "^1.0.0" } }, "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dev": true, "requires": { "ee-first": "1.1.1" @@ -18391,7 +17428,7 @@ "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "requires": { "wrappy": "1" } @@ -18399,7 +17436,7 @@ "onetime": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==", "dev": true, "requires": { "mimic-fn": "^1.0.0" @@ -18432,7 +17469,7 @@ "os-locale": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "integrity": "sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==", "dev": true, "requires": { "lcid": "^1.0.0" @@ -18441,7 +17478,7 @@ "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", "dev": true }, "p-cancelable": { @@ -18453,7 +17490,7 @@ "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", "dev": true }, "p-limit": { @@ -18468,16 +17505,25 @@ "p-locate": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", "dev": true, "requires": { "p-limit": "^1.1.0" } }, + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, "p-timeout": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", - "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=", + "integrity": "sha512-gb0ryzr+K2qFqFv6qi3khoeqMZF/+ajxQipEF6NteZVnvz9tzdsfAVj3lYtn1gAXvH5lfLwfxEII799gt/mRIA==", "dev": true, "requires": { "p-finally": "^1.0.0" @@ -18486,7 +17532,7 @@ "p-try": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", "dev": true }, "parent-module": { @@ -18522,19 +17568,19 @@ "parse-cache-control": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", - "integrity": "sha1-juqz5U+laSD+Fro493+iGqzC104=", + "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==", "dev": true }, "parse-headers": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.3.tgz", - "integrity": "sha512-QhhZ+DCCit2Coi2vmAKbq5RGTRcQUOE2+REgv8vdyu7MnYx2eZztegqtTx99TZ86GTIwqiy3+4nQTWZ2tgmdCA==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.5.tgz", + "integrity": "sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==", "dev": true }, "parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", "dev": true, "requires": { "error-ex": "^1.2.0" @@ -18546,6 +17592,24 @@ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "dev": true }, + "password-prompt": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/password-prompt/-/password-prompt-1.1.2.tgz", + "integrity": "sha512-bpuBhROdrhuN3E7G/koAju0WjVw9/uQOG5Co5mokNj0MiOSBVZS1JTwM4zl55hu0WFmIEFvO9cU9sJQiBIYeIA==", + "dev": true, + "requires": { + "ansi-escapes": "^3.1.0", + "cross-spawn": "^6.0.5" + }, + "dependencies": { + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true + } + } + }, "patch-package": { "version": "6.4.7", "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-6.4.7.tgz", @@ -18567,17 +17631,61 @@ "tmp": "^0.0.33" }, "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true }, - "slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "dev": true + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } } } }, @@ -18588,33 +17696,36 @@ "dev": true }, "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==", + "dev": true, + "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=", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true }, "path-is-inside": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", "dev": true }, "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", "dev": true }, "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==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, "path-starts-with": { @@ -18626,13 +17737,13 @@ "path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", "dev": true }, "path-type": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "integrity": "sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==", "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -18647,9 +17758,9 @@ "dev": true }, "pbkdf2": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz", - "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", "requires": { "create-hash": "^1.1.2", "create-hmac": "^1.1.4", @@ -18661,30 +17772,30 @@ "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", "dev": true }, "picomatch": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", - "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==" + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" }, "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "dev": true }, "pinkie": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", "dev": true }, "pinkie-promise": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", "dev": true, "requires": { "pinkie": "^2.0.0" @@ -18715,64 +17826,30 @@ "simple-get": "^3.0.3", "tar-fs": "^2.0.0", "tunnel-agent": "^0.6.0" - }, - "dependencies": { - "decompress-response": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", - "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", - "optional": true, - "requires": { - "mimic-response": "^2.0.0" - } - }, - "mimic-response": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", - "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", - "optional": true - }, - "simple-get": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", - "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", - "optional": true, - "requires": { - "decompress-response": "^4.2.0", - "once": "^1.3.1", - "simple-concat": "^1.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=", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", "dev": true }, "prepend-http": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==", "dev": true }, "prettier": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", - "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", - "dev": true - }, - "printj": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz", - "integrity": "sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", "dev": true }, "process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", "dev": true }, "process-nextick-args": { @@ -18818,13 +17895,13 @@ "prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", "dev": true }, "psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", "dev": true }, "public-encrypt": { @@ -18839,6 +17916,14 @@ "parse-asn1": "^5.0.0", "randombytes": "^2.0.1", "safe-buffer": "^5.1.2" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } } }, "pump": { @@ -18851,19 +17936,16 @@ } }, "punycode": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", - "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true }, "qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", - "dev": true, - "requires": { - "side-channel": "^1.0.4" - } + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "dev": true }, "query-string": { "version": "5.1.1", @@ -18879,7 +17961,7 @@ "querystring": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", "dev": true }, "queue-microtask": { @@ -18888,6 +17970,12 @@ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true }, + "quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true + }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -18913,48 +18001,15 @@ "dev": true }, "raw-body": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz", - "integrity": "sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", "dev": true, "requires": { - "bytes": "3.1.1", - "http-errors": "1.8.1", + "bytes": "3.1.2", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" - }, - "dependencies": { - "bytes": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz", - "integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==", - "dev": true - }, - "http-errors": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", - "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.1" - } - }, - "setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true - }, - "toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "dev": true - } } }, "rc": { @@ -18972,7 +18027,7 @@ "read-pkg": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "integrity": "sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==", "dev": true, "requires": { "load-json-file": "^1.0.0", @@ -18983,32 +18038,11 @@ "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=", + "integrity": "sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==", "dev": true, "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - }, - "dependencies": { - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - } + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" } }, "readable-stream": { @@ -19023,19 +18057,12 @@ "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - } } }, "readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "requires": { "picomatch": "^2.2.1" } @@ -19043,7 +18070,7 @@ "rechoir": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", "dev": true, "requires": { "resolve": "^1.1.6" @@ -19056,6 +18083,37 @@ "dev": true, "requires": { "minimatch": "3.0.4" + }, + "dependencies": { + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "redeyed": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", + "integrity": "sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==", + "dev": true, + "requires": { + "esprima": "~4.0.0" + } + }, + "regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" } }, "regexpp": { @@ -19067,7 +18125,7 @@ "req-cwd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-2.0.0.tgz", - "integrity": "sha1-1AgrTURZgDZkD7c93qAe1T20nrw=", + "integrity": "sha512-ueoIoLo1OfB6b05COxAA9UpeoscNpYyM+BqYlA7H6LVF4hKGPXQQSSaD2YmvDVJMkk4UDpAHIeU1zG53IqjvlQ==", "dev": true, "requires": { "req-from": "^2.0.0" @@ -19076,7 +18134,7 @@ "req-from": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/req-from/-/req-from-2.0.0.tgz", - "integrity": "sha1-10GI5H+TeW9Kpx327jWuaJ8+DnA=", + "integrity": "sha512-LzTfEVDVQHBRfjOUMgNBA+V6DWsSnoeKzf42J7l0xa/B4jyPOuuF5MlNSmomLNGemWTnV2TIdjSSLnEn95fOQA==", "dev": true, "requires": { "resolve-from": "^3.0.0" @@ -19120,12 +18178,6 @@ "combined-stream": "^1.0.6", "mime-types": "^2.1.12" } - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true } } }, @@ -19152,7 +18204,7 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true }, "require-from-string": { @@ -19162,30 +18214,38 @@ "dev": true }, "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==", "dev": true }, "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", "dev": true, "requires": { - "path-parse": "^1.0.6" + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" } }, + "resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "dev": true + }, "resolve-from": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", "dev": true }, "responselike": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==", "dev": true, "requires": { "lowercase-keys": "^1.0.0" @@ -19194,7 +18254,7 @@ "restore-cursor": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==", "dev": true, "requires": { "onetime": "^2.0.0", @@ -19204,7 +18264,7 @@ "retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=" + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==" }, "reusify": { "version": "1.0.4", @@ -19236,13 +18296,6 @@ "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", "requires": { "bn.js": "^5.2.0" - }, - "dependencies": { - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - } } }, "run-async": { @@ -19275,9 +18328,9 @@ } }, "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + "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", @@ -19307,22 +18360,31 @@ "wordwrap": "^1.0.0" }, "dependencies": { + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, "async": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", "dev": true }, "esprima": { "version": "2.7.3", "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "integrity": "sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==", "dev": true }, "glob": { "version": "5.0.15", "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "integrity": "sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==", "dev": true, "requires": { "inflight": "^1.0.4", @@ -19335,19 +18397,37 @@ "has-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "integrity": "sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==", "dev": true }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "dependencies": { + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + } + } + }, "resolve": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "integrity": "sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==", "dev": true }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "integrity": "sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==", "dev": true, "requires": { "has-flag": "^1.0.0" @@ -19380,34 +18460,36 @@ "semaphore-async-await": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/semaphore-async-await/-/semaphore-async-await-1.5.1.tgz", - "integrity": "sha1-hXvvXjZEYBykuVcLh+nfXKEpdPo=", + "integrity": "sha512-b/ptP11hETwYWpeilHXXQiV5UJNJl7ZWWooKRE5eBIYWoom6dZ0SluCIdCtKycsMtZgKWE01/qAw6jblw1YVhg==", "dev": true }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "requires": { + "lru-cache": "^6.0.0" + } }, "send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", "dev": true, "requires": { "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", + "depd": "2.0.0", + "destroy": "1.2.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "~1.7.2", + "http-errors": "2.0.0", "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", + "ms": "2.1.3", + "on-finished": "2.4.1", "range-parser": "~1.2.1", - "statuses": "~1.5.0" + "statuses": "2.0.1" }, "dependencies": { "debug": { @@ -19422,29 +18504,38 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true } } }, "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true } } }, + "serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, "serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", "dev": true, "requires": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.17.1" + "send": "0.18.0" } }, "servify": { @@ -19463,17 +18554,17 @@ "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" }, "setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" }, "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "dev": true }, "sha.js": { @@ -19488,7 +18579,7 @@ "sha1": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/sha1/-/sha1-1.1.1.tgz", - "integrity": "sha1-rdqnqTFo85PxnrKxUJFhjicA+Eg=", + "integrity": "sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA==", "dev": true, "requires": { "charenc": ">= 0.0.1", @@ -19498,7 +18589,7 @@ "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", "dev": true, "requires": { "shebang-regex": "^1.0.0" @@ -19507,7 +18598,7 @@ "shebang-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", "dev": true }, "shelljs": { @@ -19533,9 +18624,9 @@ } }, "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, "simple-concat": { "version": "1.0.1", @@ -19543,81 +18634,37 @@ "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==" }, "simple-get": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.1.tgz", - "integrity": "sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==", - "dev": true, + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz", + "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==", + "optional": true, "requires": { - "decompress-response": "^3.3.0", + "decompress-response": "^4.2.0", "once": "^1.3.1", "simple-concat": "^1.0.0" } }, "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", "dev": true }, "slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - } - }, - "solc": { - "version": "0.6.12", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.6.12.tgz", - "integrity": "sha512-Lm0Ql2G9Qc7yPP2Ba+WNmzw2jwsrd3u4PobHYlSOxaut3TtUbj9+5ZrT6f4DUpNPEoBaFUOEg9Op9C0mk7ge9g==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, "requires": { - "command-exists": "^1.2.8", - "commander": "3.0.2", - "fs-extra": "^0.30.0", - "js-sha3": "0.8.0", - "memorystream": "^0.3.1", - "require-from-string": "^2.0.0", - "semver": "^5.5.0", - "tmp": "0.0.33" + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" }, "dependencies": { - "fs-extra": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, - "js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", - "dev": true - }, - "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true } } @@ -19642,7 +18689,7 @@ "fs-extra": { "version": "0.30.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", + "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -19652,16 +18699,10 @@ "rimraf": "^2.2.8" } }, - "js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", - "dev": true - }, "jsonfile": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", "dev": true, "requires": { "graceful-fs": "^4.1.6" @@ -19676,12 +18717,12 @@ } }, "solhint": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/solhint/-/solhint-3.3.6.tgz", - "integrity": "sha512-HWUxTAv2h7hx3s3hAab3ifnlwb02ZWhwFU/wSudUHqteMS3ll9c+m1FlGn9V8ztE2rf3Z82fQZA005Wv7KpcFA==", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/solhint/-/solhint-3.3.7.tgz", + "integrity": "sha512-NjjjVmXI3ehKkb3aNtRJWw55SUVJ8HMKKodwe0HnejA+k0d2kmhw7jvpa+MCTbcEgt8IWSwx0Hu6aCo/iYOZzQ==", "dev": true, "requires": { - "@solidity-parser/parser": "^0.13.2", + "@solidity-parser/parser": "^0.14.1", "ajv": "^6.6.1", "antlr4": "4.7.1", "ast-parents": "0.0.1", @@ -19698,48 +18739,131 @@ "semver": "^6.3.0" }, "dependencies": { - "@solidity-parser/parser": { - "version": "0.13.2", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.13.2.tgz", - "integrity": "sha512-RwHnpRnfrnD2MSPveYoPh8nhofEvX7fgjHk1Oq+NNvCcLx4r1js91CO9o+F/F3fBzOCyvm8kKRTriFICX/odWw==", + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, "requires": { - "antlr4ts": "^0.5.0-alpha.4" + "color-name": "1.1.3" } }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, "commander": { "version": "2.18.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.18.0.tgz", "integrity": "sha512-6CYPa+JP2ftfRU2qkDK+UTVeQYosOg/2GbcjIcKPHfinyOLPVGXu/ovN86RP49Re5ndJK1N0kuiidFFuepc4ZQ==", "dev": true }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "prettier": { "version": "1.19.1", "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", "dev": true, "optional": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } } } }, "solidity-ast": { - "version": "0.4.29", - "resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.29.tgz", - "integrity": "sha512-sp4+lbgZPQJLBNFWoLiRb/NXZOhqAEPK9AIOh5htKOTx72w5j9Bu5eQl0jcUc5wiyCqsgpFWLCGfgu3edkSWog==" + "version": "0.4.35", + "resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.35.tgz", + "integrity": "sha512-F5bTDLh3rmDxRmLSrs3qt3nvxJprWSEkS7h2KmuXDx7XTfJ6ZKVTV1rtPIYCqJAuPsU/qa8YUeFn7jdOAZcTPA==" }, "solidity-coverage": { - "version": "0.7.18", - "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.7.18.tgz", - "integrity": "sha512-H1UhB9QqLISJPgttaulnStUyOaJm0wZXvBGWUN9+HH3dl2hYjSmo3RBBFRm7U+dBNpPysS835XFGe+hG4ZhMrA==", + "version": "0.7.21", + "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.7.21.tgz", + "integrity": "sha512-O8nuzJ9yXiKUx3NdzVvHrUW0DxoNVcGzq/I7NzewNO9EZE3wYAQ4l8BwcnV64r4aC/HB6Vnw/q2sF0BQHv/3fg==", "dev": true, "requires": { - "@solidity-parser/parser": "^0.13.2", + "@solidity-parser/parser": "^0.14.0", "@truffle/provider": "^0.2.24", "chalk": "^2.4.2", "death": "^1.1.0", "detect-port": "^1.3.0", "fs-extra": "^8.1.0", - "ganache-cli": "^6.12.2", "ghost-testrpc": "^0.0.2", "global-modules": "^2.0.0", "globby": "^10.0.1", @@ -19754,15 +18878,41 @@ "web3-utils": "^1.3.0" }, "dependencies": { - "@solidity-parser/parser": { - "version": "0.13.2", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.13.2.tgz", - "integrity": "sha512-RwHnpRnfrnD2MSPveYoPh8nhofEvX7fgjHk1Oq+NNvCcLx4r1js91CO9o+F/F3fBzOCyvm8kKRTriFICX/odWw==", + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, "requires": { - "antlr4ts": "^0.5.0-alpha.4" + "color-name": "1.1.3" } }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, "fs-extra": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", @@ -19774,14 +18924,11 @@ "universalify": "^0.1.0" } }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true }, "pify": { "version": "4.0.1", @@ -19789,63 +18936,57 @@ "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { - "lru-cache": "^6.0.0" + "has-flag": "^3.0.0" } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true } } }, "solidity-docgen": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/solidity-docgen/-/solidity-docgen-0.5.16.tgz", - "integrity": "sha512-rFVpqSNnDGKvL68mPf4J9mEQIl+Ixy6bIz/YE6AgjBCPtrlm4KjWQhcBMQWc/LarSCenOpzhbG1tHqP9gf9kcg==", + "version": "0.5.17", + "resolved": "https://registry.npmjs.org/solidity-docgen/-/solidity-docgen-0.5.17.tgz", + "integrity": "sha512-RX5SPLFL9z0ZVBcZ/o5l/TKXMgSjNhWdumLuuv+Dy1O/66sThpHYd0HVpzdwAjVff0Ajk76bYM2zZYiMnqBfng==", "dev": true, "requires": { "@oclif/command": "^1.8.0", "@oclif/config": "^1.17.0", "@oclif/errors": "^1.3.3", - "@oclif/plugin-help": "^3.2.0", + "@oclif/plugin-help": "^5.0.0", "globby": "^11.0.0", "handlebars": "^4.7.6", "json5": "^2.1.3", "lodash": "^4.17.15", "micromatch": "^4.0.2", - "minimatch": "^3.0.4", + "minimatch": "^5.0.0", "semver": "^7.3.2", "solc": "^0.6.7" }, "dependencies": { - "fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" + "balanced-match": "^1.0.0" } }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "fs-extra": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", + "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", "dev": true, "requires": { - "is-glob": "^4.0.1" + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" } }, "globby": { @@ -19868,26 +19009,61 @@ "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "minimatch": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", + "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "solc": { + "version": "0.6.12", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.6.12.tgz", + "integrity": "sha512-Lm0Ql2G9Qc7yPP2Ba+WNmzw2jwsrd3u4PobHYlSOxaut3TtUbj9+5ZrT6f4DUpNPEoBaFUOEg9Op9C0mk7ge9g==", "dev": true, "requires": { - "lru-cache": "^6.0.0" + "command-exists": "^1.2.8", + "commander": "3.0.2", + "fs-extra": "^0.30.0", + "js-sha3": "0.8.0", + "memorystream": "^0.3.1", + "require-from-string": "^2.0.0", + "semver": "^5.5.0", + "tmp": "0.0.33" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "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" - } + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true }, "source-map-support": { "version": "0.5.21", @@ -19897,14 +19073,6 @@ "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } } }, "spdx-correct": { @@ -19934,21 +19102,21 @@ } }, "spdx-license-ids": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz", - "integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ==", + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", + "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==", "dev": true }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", + "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", "dev": true, "requires": { "asn1": "~0.2.3", @@ -19960,14 +19128,6 @@ "jsbn": "~0.1.0", "safer-buffer": "^2.0.2", "tweetnacl": "~0.14.0" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true - } } }, "stacktrace-parser": { @@ -19988,50 +19148,53 @@ } }, "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "dev": true }, "stealthy-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "integrity": "sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==", "dev": true }, "strict-uri-encode": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", + "integrity": "sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==", "dev": true }, "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } }, "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", + "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" } }, "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", + "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" } }, "string_decoder": { @@ -20040,27 +19203,20 @@ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "requires": { "safe-buffer": "~5.1.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - } } }, "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", "requires": { - "ansi-regex": "^3.0.0" + "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=", + "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==", "dev": true, "requires": { "is-utf8": "^0.2.0" @@ -20069,7 +19225,7 @@ "strip-hex-prefix": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", - "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=", + "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", "dev": true, "requires": { "is-hex-prefixed": "1.0.0" @@ -20078,17 +19234,32 @@ "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==" }, "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-hyperlinks": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", + "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" } }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, "swarm-js": { "version": "0.1.40", "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.40.tgz", @@ -20108,18 +19279,13 @@ "xhr-request": "^1.0.1" }, "dependencies": { - "eth-lib": { - "version": "0.1.29", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.29.tgz", - "integrity": "sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ==", + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", "dev": true, "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "nano-json-stream-parser": "^0.1.2", - "servify": "^0.1.12", - "ws": "^3.0.0", - "xhr-request-promise": "^0.1.2" + "mimic-response": "^1.0.0" } }, "fs-extra": { @@ -20136,7 +19302,7 @@ "get-stream": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", "dev": true }, "got": { @@ -20161,6 +19327,18 @@ "url-to-options": "^1.0.1" } }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "dev": true + }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true + }, "p-cancelable": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", @@ -20170,34 +19348,17 @@ "prepend-http": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", - "dev": true - }, - "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==", + "integrity": "sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg==", "dev": true }, "url-parse-lax": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", - "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", + "integrity": "sha512-BVA4lR5PIviy2PMseNd2jbFQ+jwSwQGdJejf5ctd1rEXt0Ypd7yanUK9+lYechVlN5VaTJGsu2U/3MDDu6KgBA==", "dev": true, "requires": { "prepend-http": "^1.0.1" } - }, - "ws": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" - } } } }, @@ -20222,58 +19383,79 @@ } }, "table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", + "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", "dev": true, "requires": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" }, "dependencies": { "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" } }, "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { - "ansi-regex": "^4.1.0" + "ansi-regex": "^5.0.1" } } } }, "tar": { - "version": "4.4.13", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", - "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", - "dev": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" + "version": "4.4.19", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", + "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", + "dev": true, + "requires": { + "chownr": "^1.1.4", + "fs-minipass": "^1.2.7", + "minipass": "^2.9.0", + "minizlib": "^1.3.3", + "mkdirp": "^0.5.5", + "safe-buffer": "^5.2.1", + "yallist": "^3.1.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + } } }, "tar-fs": { @@ -20317,7 +19499,7 @@ "test-value": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/test-value/-/test-value-2.1.0.tgz", - "integrity": "sha1-Edpv9nDzRxpztiXKTz/c97t0gpE=", + "integrity": "sha512-+1epbAxtKeXttkGFMTX9H42oqzOTufR1ceCF+GYA5aOmvaPq9wd4PUS8329fn2RRLGNeUkgRLnVpycjx8DsO2w==", "dev": true, "requires": { "array-back": "^1.0.3", @@ -20327,7 +19509,7 @@ "array-back": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", - "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", + "integrity": "sha512-1WxbZvrmyhkNoeYcizokbmh5oiOCIfyvGtcqbK3Ls1v1fKcquzxnQSceOx6tzq7jmai2kFLWIpGND2cLhH6TPw==", "dev": true, "requires": { "typical": "^2.6.0" @@ -20344,7 +19526,7 @@ "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, "then-request": { @@ -20388,13 +19570,13 @@ "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "dev": true }, "timed-out": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", + "integrity": "sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==", "dev": true }, "tmp": { @@ -20418,19 +19600,12 @@ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "requires": { "is-number": "^7.0.0" - }, - "dependencies": { - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" - } } }, "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "dev": true }, "tough-cookie": { @@ -20441,16 +19616,14 @@ "requires": { "psl": "^1.1.28", "punycode": "^2.1.1" - }, - "dependencies": { - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - } } }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, "true-case-path": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-2.2.1.tgz", @@ -20478,15 +19651,67 @@ "prettier": "^2.1.2", "resolve": "^1.8.1", "ts-essentials": "^1.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, "ts-node": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.4.0.tgz", - "integrity": "sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==", + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", "dev": true, "requires": { - "@cspotcode/source-map-support": "0.7.0", + "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", "@tsconfig/node12": "^1.0.7", "@tsconfig/node14": "^1.0.0", @@ -20497,13 +19722,14 @@ "create-require": "^1.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", "yn": "3.1.1" }, "dependencies": { "acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", + "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", "dev": true }, "diff": { @@ -20522,21 +19748,21 @@ "tsort": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz", - "integrity": "sha1-4igPXoF/i/QnVlf9D5rr1E9aJ4Y=", + "integrity": "sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==", "dev": true }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", "requires": { "safe-buffer": "^5.0.1" } }, "tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", "dev": true }, "tweetnacl-util": { @@ -20554,7 +19780,7 @@ "type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", "dev": true, "requires": { "prelude-ls": "~1.1.2" @@ -20597,27 +19823,6 @@ "ts-generator": "^0.1.1" }, "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", - "dev": true - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "ts-essentials": { "version": "6.0.7", "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-6.0.7.tgz", @@ -20629,7 +19834,7 @@ "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", "dev": true }, "typedarray-to-buffer": { @@ -20642,15 +19847,15 @@ } }, "typescript": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz", - "integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==", + "version": "4.7.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", + "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", "dev": true }, "typical": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", - "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", + "integrity": "sha512-ofhi8kjIje6npGozTip9Fr8iecmYfEbS06i0JnIg+rh51KakryWF4+jX8lLKZVhy6N+ID45WYSFCxPOdTWCzNg==", "dev": true }, "u2f-api": { @@ -20659,9 +19864,9 @@ "integrity": "sha512-fqLNg8vpvLOD5J/z4B6wpPg4Lvowz1nJ9xdHcCzdUPKcFE/qNCceV2gNZxSJd5vhAZemHr/K/hbzVA0zxB5mkg==" }, "uglify-js": { - "version": "3.13.5", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.5.tgz", - "integrity": "sha512-xtB8yEqIkn7zmOyS2zUNBsYCBRhDkvlNxMMY2smuJ/qA8NCHeQvKCF3i9Z4k8FJH4+PJvZRtMrPynfZ75+CSZw==", + "version": "3.17.0", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.0.tgz", + "integrity": "sha512-aTeNPVmgIMPpm1cxXr2Q/nEbvkmV8yq66F3om7X3P/cvOXQ0TMQ64Wk63iyT1gPlmdmGzjGpyLh1f3y8MZWXGg==", "dev": true, "optional": true }, @@ -20672,27 +19877,21 @@ "dev": true }, "unbox-primitive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.0.tgz", - "integrity": "sha512-P/51NX+JXyxK/aigg1/ZgyccdAxm5K1+n8+tvqSntjOivPt19gvm1VC49RWYetsiub8WViUchdxl/KWHHB0kzA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dev": true, "requires": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.0", - "has-symbols": "^1.0.0", - "which-boxed-primitive": "^1.0.1" + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" } }, - "underscore": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", - "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==", - "dev": true - }, "undici": { - "version": "4.16.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-4.16.0.tgz", - "integrity": "sha512-tkZSECUYi+/T1i4u+4+lwZmQgLXd4BLGlrc7KZPcLIW7Jpq99+Xpc30ONv7nS6F5UNOxp/HBZSSL9MafUrvJbw==", + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.10.0.tgz", + "integrity": "sha512-c8HsD3IbwmjjbLvoZuRI26TZic+TSEe8FPMLLOkN1AfYRhdjnKBU6yL+IwcSCbdZiX4e5t0lfMDLDCqj4Sq70g==", "dev": true }, "universalify": { @@ -20704,7 +19903,7 @@ "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "dev": true }, "uri-js": { @@ -20719,7 +19918,7 @@ "url": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==", "dev": true, "requires": { "punycode": "1.3.2", @@ -20729,7 +19928,7 @@ "punycode": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", "dev": true } } @@ -20737,7 +19936,7 @@ "url-parse-lax": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "integrity": "sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==", "dev": true, "requires": { "prepend-http": "^2.0.0" @@ -20746,13 +19945,13 @@ "url-set-query": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz", - "integrity": "sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk=", + "integrity": "sha512-3AChu4NiXquPfeckE5R5cGdiHCMWJx1dwCWOmWIL4KHAziJNOFIYJlpGFeKDvwLPHovZRCxK3cYlwzqI9Vp+Gg==", "dev": true }, "url-to-options": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", - "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=", + "integrity": "sha512-0kQLIzG4fdk/G5NONku64rSH/x32NOA39LVQqlK8Le6lvTF6GGRJpqaQFGgU+CLwySIqBSMdwYM0sYcW9f6P4A==", "dev": true }, "usb": { @@ -20766,26 +19965,20 @@ }, "dependencies": { "node-addon-api": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.2.0.tgz", - "integrity": "sha512-eazsqzwG2lskuzBqCGPi7Ac2UgOoMz8JVOXVhTvvPDYhthvNpefx8jWD8Np7Gv+2Sz0FlPWZk0nJV0z598Wn8Q==", - "optional": true - }, - "node-gyp-build": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz", - "integrity": "sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", + "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==", "optional": true } } }, "utf-8-validate": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.4.tgz", - "integrity": "sha512-MEF05cPSq3AwJ2C7B7sHAA6i53vONoZbMGX8My5auEVm6W+dJ2Jd/TZPyGJ5CH42V2XtbI5FD28HeHeqlPzZ3Q==", + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.9.tgz", + "integrity": "sha512-Yek7dAy0v3Kl0orwMlvi7TPtiCNrdfHNd7Gcc/pLq4BLXqfAmd0J7OWMizUQnTTJsyjKn02mU7anqwfmUP4J8Q==", "dev": true, "requires": { - "node-gyp-build": "^4.2.0" + "node-gyp-build": "^4.3.0" } }, "utf8": { @@ -20811,12 +20004,12 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", "dev": true }, "uuid": { @@ -20825,6 +20018,12 @@ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", "dev": true }, + "v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, "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", @@ -20844,56 +20043,468 @@ "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "dev": true }, "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", "dev": true, "requires": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", "extsprintf": "^1.2.0" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true + } } }, "web3": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/web3/-/web3-1.7.0.tgz", - "integrity": "sha512-n39O7QQNkpsjhiHMJ/6JY6TaLbdX+2FT5iGs8tb3HbIWOhPm4+a7UDbr5Lkm+gLa9aRKWesZs5D5hWyEvg4aJA==", - "dev": true, - "requires": { - "web3-bzz": "1.7.0", - "web3-core": "1.7.0", - "web3-eth": "1.7.0", - "web3-eth-personal": "1.7.0", - "web3-net": "1.7.0", - "web3-shh": "1.7.0", - "web3-utils": "1.7.0" + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/web3/-/web3-1.7.5.tgz", + "integrity": "sha512-3jHZTWyXt975AOXgnZKayiSWDLpoSKk9fZtLk1hURQtt7AdSbXPT8AK9ooBCm0Dt3GYaOeNcHGaiHC3gtyqhLg==", + "dev": true, + "requires": { + "web3-bzz": "1.7.5", + "web3-core": "1.7.5", + "web3-eth": "1.7.5", + "web3-eth-personal": "1.7.5", + "web3-net": "1.7.5", + "web3-shh": "1.7.5", + "web3-utils": "1.7.5" }, "dependencies": { - "web3-utils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.0.tgz", - "integrity": "sha512-O8Tl4Ky40Sp6pe89Olk2FsaUkgHyb5QAXuaKo38ms3CxZZ4d3rPGfjP9DNKGm5+IUgAZBNpF1VmlSmNCqfDI1w==", + "@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "dev": true + }, + "@szmarczak/http-timer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", + "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", "dev": true, "requires": { - "bn.js": "^4.11.9", - "ethereum-bloom-filters": "^1.0.6", - "ethereumjs-util": "^7.1.0", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" + "defer-to-connect": "^2.0.1" + } + }, + "@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", + "dev": true + }, + "cacheable-request": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", + "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", + "dev": true, + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "dependencies": { + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true + } + } + }, + "decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "requires": { + "mimic-response": "^3.1.0" + } + }, + "defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true + }, + "eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "requires": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + } + }, + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true + }, + "got": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/got/-/got-12.1.0.tgz", + "integrity": "sha512-hBv2ty9QN2RdbJJMK3hesmSkFTjVIHyIDDbssCKnSmq62edGgImJWD10Eb1k77TiV1bxloxqcFAVK8+9pkhOig==", + "dev": true, + "requires": { + "@sindresorhus/is": "^4.6.0", + "@szmarczak/http-timer": "^5.0.1", + "@types/cacheable-request": "^6.0.2", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^6.0.4", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "form-data-encoder": "1.7.1", + "get-stream": "^6.0.1", + "http2-wrapper": "^2.1.10", + "lowercase-keys": "^3.0.0", + "p-cancelable": "^3.0.0", + "responselike": "^2.0.0" + } + }, + "json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "keyv": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.4.1.tgz", + "integrity": "sha512-PzByhNxfBLnSBW2MZi1DF+W5+qB/7BMpOokewqIvqS8GFtP7xHm2oeGU72Y1fhtfOv/FiEnI4+nyViYDmUChnw==", + "dev": true, + "requires": { + "compress-brotli": "^1.3.8", + "json-buffer": "3.0.1" + } + }, + "lowercase-keys": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", + "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", + "dev": true + }, + "mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true + }, + "normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true + }, + "p-cancelable": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", + "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", + "dev": true + }, + "responselike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "dev": true, + "requires": { + "lowercase-keys": "^2.0.0" + }, + "dependencies": { + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true + } + } + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + }, + "web3-bzz": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.7.5.tgz", + "integrity": "sha512-Z53sY0YK/losqjJncmL4vP0zZI9r6tiXg6o7R6e1JD2Iy7FH3serQvU+qXmPjqEBzsnhf8wTG+YcBPB3RHpr0Q==", + "dev": true, + "requires": { + "@types/node": "^12.12.6", + "got": "12.1.0", + "swarm-js": "^0.1.40" + } + }, + "web3-core": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.7.5.tgz", + "integrity": "sha512-UgOWXZr1fR/3cUQJKWbfMwRxj1/N7o6RSd/dHqdXBlOD+62EjNZItFmLRg5veq5kp9YfXzrNw9bnDkXfsL+nKQ==", + "dev": true, + "requires": { + "@types/bn.js": "^5.1.0", + "@types/node": "^12.12.6", + "bignumber.js": "^9.0.0", + "web3-core-helpers": "1.7.5", + "web3-core-method": "1.7.5", + "web3-core-requestmanager": "1.7.5", + "web3-utils": "1.7.5" + } + }, + "web3-core-helpers": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.5.tgz", + "integrity": "sha512-lDDjTks6Q6aNUO87RYrY2xub3UWTKr/RIWxpHJODEqkLxZS1dWdyliJ6aIx3031VQwsNT5HE7NvABe/t0p3iDQ==", + "dev": true, + "requires": { + "web3-eth-iban": "1.7.5", + "web3-utils": "1.7.5" + } + }, + "web3-core-method": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.7.5.tgz", + "integrity": "sha512-ApTvq1Llzlbxmy0n4L7QaE6NodIsR80VJqk8qN4kLg30SGznt/pNJFebryLI2kpyDmxSgj1TjEWzmHJBp6FhYg==", + "dev": true, + "requires": { + "@ethersproject/transactions": "^5.6.2", + "web3-core-helpers": "1.7.5", + "web3-core-promievent": "1.7.5", + "web3-core-subscriptions": "1.7.5", + "web3-utils": "1.7.5" + } + }, + "web3-core-promievent": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.7.5.tgz", + "integrity": "sha512-uZ1VRErVuhiLtHlyt3oEH/JSvAf6bWPndChHR9PG7i1Zfqm6ZVCeM91ICTPmiL8ddsGQOxASpnJk4vhApcTIww==", + "dev": true, + "requires": { + "eventemitter3": "4.0.4" + } + }, + "web3-core-requestmanager": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.7.5.tgz", + "integrity": "sha512-3KpfxW/wVH4mgwWEsSJGHKrtRVoijWlDxtUrm17xgtqRNZ2mFolifKnHAUKa0fY48C9CrxmcCiMIi3W4G6WYRw==", + "dev": true, + "requires": { + "util": "^0.12.0", + "web3-core-helpers": "1.7.5", + "web3-providers-http": "1.7.5", + "web3-providers-ipc": "1.7.5", + "web3-providers-ws": "1.7.5" + } + }, + "web3-core-subscriptions": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.7.5.tgz", + "integrity": "sha512-YK6utQ7Wwjbe4XZOIA8quWGBPi1lFDS1A+jQYwxKKrCvm6BloBNc3FhvrcSYlDhLe/kOy8+2Je8i9amndgT4ww==", + "dev": true, + "requires": { + "eventemitter3": "4.0.4", + "web3-core-helpers": "1.7.5" + } + }, + "web3-eth": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.7.5.tgz", + "integrity": "sha512-BucjvqZyDWYkGlsFX+OnOBub0YutlC1KZiNGibdmvtNX0NQK+8iw1uzAoL9yTTwCSszL7lnkFe8N+HCOl9B4Dw==", + "dev": true, + "requires": { + "web3-core": "1.7.5", + "web3-core-helpers": "1.7.5", + "web3-core-method": "1.7.5", + "web3-core-subscriptions": "1.7.5", + "web3-eth-abi": "1.7.5", + "web3-eth-accounts": "1.7.5", + "web3-eth-contract": "1.7.5", + "web3-eth-ens": "1.7.5", + "web3-eth-iban": "1.7.5", + "web3-eth-personal": "1.7.5", + "web3-net": "1.7.5", + "web3-utils": "1.7.5" + } + }, + "web3-eth-abi": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.7.5.tgz", + "integrity": "sha512-qWHvF7sayxql9BD1yqK9sZRLBQ66eJzGeaU53Y1PRq2iFPrhY6NUWxQ3c3ps0rg+dyObvRbloviWpKXcS4RE/A==", + "dev": true, + "requires": { + "@ethersproject/abi": "^5.6.3", + "web3-utils": "1.7.5" + } + }, + "web3-eth-accounts": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.7.5.tgz", + "integrity": "sha512-AzMLoTj3RGwKpyp3x3TtHrEeU4VpR99iMOD6NKrWSDumS6QEi0lCo+y7QZhdTlINw3iIA3SFIdvbAOO4NCHSDg==", + "dev": true, + "requires": { + "@ethereumjs/common": "^2.5.0", + "@ethereumjs/tx": "^3.3.2", + "crypto-browserify": "3.12.0", + "eth-lib": "0.2.8", + "ethereumjs-util": "^7.0.10", + "scrypt-js": "^3.0.1", + "uuid": "3.3.2", + "web3-core": "1.7.5", + "web3-core-helpers": "1.7.5", + "web3-core-method": "1.7.5", + "web3-utils": "1.7.5" + } + }, + "web3-eth-contract": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.7.5.tgz", + "integrity": "sha512-qab7NPJRKRlTs58ozsqK8YIEwWpxIm3vD/okSIKBGkFx5gIHWW+vGmMh5PDSfefLJM9rCd+T+Lc0LYvtME7uqg==", + "dev": true, + "requires": { + "@types/bn.js": "^5.1.0", + "web3-core": "1.7.5", + "web3-core-helpers": "1.7.5", + "web3-core-method": "1.7.5", + "web3-core-promievent": "1.7.5", + "web3-core-subscriptions": "1.7.5", + "web3-eth-abi": "1.7.5", + "web3-utils": "1.7.5" + } + }, + "web3-eth-ens": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.7.5.tgz", + "integrity": "sha512-k1Q0msdRv/wac2egpZBIwG3n/sa/KdrVmVJvFm471gLTL4xfUizV5qJjkDVf+ikf9JyDvWJTs5eWNUUbOFIw/A==", + "dev": true, + "requires": { + "content-hash": "^2.5.2", + "eth-ens-namehash": "2.0.8", + "web3-core": "1.7.5", + "web3-core-helpers": "1.7.5", + "web3-core-promievent": "1.7.5", + "web3-eth-abi": "1.7.5", + "web3-eth-contract": "1.7.5", + "web3-utils": "1.7.5" + } + }, + "web3-eth-iban": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.5.tgz", + "integrity": "sha512-mn2W5t/1IpL8OZvzAabLKT4kvwRnZSJ9K0tctndl9sDNWkfITYQibEEhUaNNA50Q5fJKgVudHI/m0gwIVTyG8Q==", + "dev": true, + "requires": { + "bn.js": "^5.2.1", + "web3-utils": "1.7.5" + } + }, + "web3-eth-personal": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.7.5.tgz", + "integrity": "sha512-txh2P/eN8I4AOUKFi9++KKddoD0tWfCuu9Y1Kc41jSRbk6smO88Fum0KWNmYFYhSCX2qiknS1DfqsONl3igoKQ==", + "dev": true, + "requires": { + "@types/node": "^12.12.6", + "web3-core": "1.7.5", + "web3-core-helpers": "1.7.5", + "web3-core-method": "1.7.5", + "web3-net": "1.7.5", + "web3-utils": "1.7.5" + } + }, + "web3-net": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.7.5.tgz", + "integrity": "sha512-xwuCb2YWw49PmW81AJQ/G+Xi2ikRsYyZXSgyPt4LmZuKjiqg/6kSdK8lZvUi3Pi3wM+QDBXbpr73M/WEkW0KvA==", + "dev": true, + "requires": { + "web3-core": "1.7.5", + "web3-core-method": "1.7.5", + "web3-utils": "1.7.5" + } + }, + "web3-providers-http": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.7.5.tgz", + "integrity": "sha512-vPgr4Kzy0M3CHtoP/Bh7qwK/D9h2fhjpoqctdMWVJseOfeTgfOphCKN0uwV8w2VpZgDPXA8aeTdBx5OjmDdStA==", + "dev": true, + "requires": { + "abortcontroller-polyfill": "^1.7.3", + "cross-fetch": "^3.1.4", + "es6-promise": "^4.2.8", + "web3-core-helpers": "1.7.5" + } + }, + "web3-providers-ipc": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.7.5.tgz", + "integrity": "sha512-aNHx+RAROzO+apDEzy8Zncj78iqWBadIXtpmFDg7uiTn8i+oO+IcP1Yni7jyzkltsysVJHgHWG4kPx50ANCK3Q==", + "dev": true, + "requires": { + "oboe": "2.1.5", + "web3-core-helpers": "1.7.5" + } + }, + "web3-providers-ws": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.7.5.tgz", + "integrity": "sha512-9uJNVVkIGC8PmM9kNbgPth56HDMSSsxZh3ZEENdwO3LNWemaADiQYUDCsD/dMVkn0xsGLHP5dgAy4Q5msqySLg==", + "dev": true, + "requires": { + "eventemitter3": "4.0.4", + "web3-core-helpers": "1.7.5", + "websocket": "^1.0.32" + } + }, + "web3-shh": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.7.5.tgz", + "integrity": "sha512-aCIWJyLMH5H76OybU4ZpUCJ93yNOPATGhJ+KboRPU8QZDzS2CcVhtEzyl27bbvw+rSnVroMLqBgTXBB4mmKI7A==", + "dev": true, + "requires": { + "web3-core": "1.7.5", + "web3-core-method": "1.7.5", + "web3-core-subscriptions": "1.7.5", + "web3-net": "1.7.5" } } } }, "web3-bzz": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.7.0.tgz", - "integrity": "sha512-XPhTWUnZa8gnARfiqaag3jJ9+6+a66Li8OikgBUJoMUqPuQTCJPncTbGYqOJIfRFGavEAdlMnfYXx9lvgv2ZPw==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.7.4.tgz", + "integrity": "sha512-w9zRhyEqTK/yi0LGRHjZMcPCfP24LBjYXI/9YxFw9VqsIZ9/G0CRCnUt12lUx0A56LRAMpF7iQ8eA73aBcO29Q==", "dev": true, "requires": { "@types/node": "^12.12.6", @@ -20902,50 +20513,41 @@ }, "dependencies": { "@types/node": { - "version": "12.20.42", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.42.tgz", - "integrity": "sha512-aI3/oo5DzyiI5R/xAhxxRzfZlWlsbbqdgxfTPkqu/Zt+23GXiJvMCyPJT4+xKSXOnLqoL8jJYMLTwvK2M3a5hw==", + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", "dev": true } } }, "web3-core": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.7.0.tgz", - "integrity": "sha512-U/CRL53h3T5KHl8L3njzCBT7fCaHkbE6BGJe3McazvFldRbfTDEHXkUJCyM30ZD0RoLi3aDfTVeFIusmEyCctA==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.7.4.tgz", + "integrity": "sha512-L0DCPlIh9bgIED37tYbe7bsWrddoXYc897ANGvTJ6MFkSNGiMwDkTLWSgYd9Mf8qu8b4iuPqXZHMwIo4atoh7Q==", "dev": true, "requires": { - "@types/bn.js": "^4.11.5", + "@types/bn.js": "^5.1.0", "@types/node": "^12.12.6", "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.7.0", - "web3-core-method": "1.7.0", - "web3-core-requestmanager": "1.7.0", - "web3-utils": "1.7.0" + "web3-core-helpers": "1.7.4", + "web3-core-method": "1.7.4", + "web3-core-requestmanager": "1.7.4", + "web3-utils": "1.7.4" }, "dependencies": { - "@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, "@types/node": { - "version": "12.20.42", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.42.tgz", - "integrity": "sha512-aI3/oo5DzyiI5R/xAhxxRzfZlWlsbbqdgxfTPkqu/Zt+23GXiJvMCyPJT4+xKSXOnLqoL8jJYMLTwvK2M3a5hw==", + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", "dev": true }, "web3-utils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.0.tgz", - "integrity": "sha512-O8Tl4Ky40Sp6pe89Olk2FsaUkgHyb5QAXuaKo38ms3CxZZ4d3rPGfjP9DNKGm5+IUgAZBNpF1VmlSmNCqfDI1w==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", + "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", "dev": true, "requires": { - "bn.js": "^4.11.9", + "bn.js": "^5.2.1", "ethereum-bloom-filters": "^1.0.6", "ethereumjs-util": "^7.1.0", "ethjs-unit": "0.1.6", @@ -20957,22 +20559,22 @@ } }, "web3-core-helpers": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.0.tgz", - "integrity": "sha512-kFiqsZFHJliKF8VKZNjt2JvKu3gu7h3N1/ke3EPhdp9Li/rLmiyzFVr6ApryZ1FSjbSx6vyOkibG3m6xQ5EHJA==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.4.tgz", + "integrity": "sha512-F8PH11qIkE/LpK4/h1fF/lGYgt4B6doeMi8rukeV/s4ivseZHHslv1L6aaijLX/g/j4PsFmR42byynBI/MIzFg==", "dev": true, "requires": { - "web3-eth-iban": "1.7.0", - "web3-utils": "1.7.0" + "web3-eth-iban": "1.7.4", + "web3-utils": "1.7.4" }, "dependencies": { "web3-utils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.0.tgz", - "integrity": "sha512-O8Tl4Ky40Sp6pe89Olk2FsaUkgHyb5QAXuaKo38ms3CxZZ4d3rPGfjP9DNKGm5+IUgAZBNpF1VmlSmNCqfDI1w==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", + "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", "dev": true, "requires": { - "bn.js": "^4.11.9", + "bn.js": "^5.2.1", "ethereum-bloom-filters": "^1.0.6", "ethereumjs-util": "^7.1.0", "ethjs-unit": "0.1.6", @@ -20984,25 +20586,25 @@ } }, "web3-core-method": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.7.0.tgz", - "integrity": "sha512-43Om+kZX8wU5u1pJ28TltF9e9pSTRph6b8wrOb6wgXAfPHqMulq6UTBJWjXXIRVN46Eiqv0nflw35hp9bbgnbA==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.7.4.tgz", + "integrity": "sha512-56K7pq+8lZRkxJyzf5MHQPI9/VL3IJLoy4L/+q8HRdZJ3CkB1DkXYaXGU2PeylG1GosGiSzgIfu1ljqS7CP9xQ==", "dev": true, "requires": { - "@ethersproject/transactions": "^5.0.0-beta.135", - "web3-core-helpers": "1.7.0", - "web3-core-promievent": "1.7.0", - "web3-core-subscriptions": "1.7.0", - "web3-utils": "1.7.0" + "@ethersproject/transactions": "^5.6.2", + "web3-core-helpers": "1.7.4", + "web3-core-promievent": "1.7.4", + "web3-core-subscriptions": "1.7.4", + "web3-utils": "1.7.4" }, "dependencies": { "web3-utils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.0.tgz", - "integrity": "sha512-O8Tl4Ky40Sp6pe89Olk2FsaUkgHyb5QAXuaKo38ms3CxZZ4d3rPGfjP9DNKGm5+IUgAZBNpF1VmlSmNCqfDI1w==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", + "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", "dev": true, "requires": { - "bn.js": "^4.11.9", + "bn.js": "^5.2.1", "ethereum-bloom-filters": "^1.0.6", "ethereumjs-util": "^7.1.0", "ethjs-unit": "0.1.6", @@ -21014,64 +20616,64 @@ } }, "web3-core-promievent": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.7.0.tgz", - "integrity": "sha512-xPH66XeC0K0k29GoRd0vyPQ07yxERPRd4yVPrbMzGAz/e9E4M3XN//XK6+PdfGvGw3fx8VojS+tNIMiw+PujbQ==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.7.4.tgz", + "integrity": "sha512-o4uxwXKDldN7ER7VUvDfWsqTx9nQSP1aDssi1XYXeYC2xJbVo0n+z6ryKtmcoWoRdRj7uSpVzal3nEmlr480mA==", "dev": true, "requires": { "eventemitter3": "4.0.4" } }, "web3-core-requestmanager": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.7.0.tgz", - "integrity": "sha512-rA3dBTBPrt+eIfTAQ2/oYNTN/2wbZaYNR3pFZGqG8+2oCK03+7oQyz4sWISKy/nYQhURh4GK01rs9sN4o/Tq9w==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.7.4.tgz", + "integrity": "sha512-IuXdAm65BQtPL4aI6LZJJOrKAs0SM5IK2Cqo2/lMNvVMT9Kssq6qOk68Uf7EBDH0rPuINi+ReLP+uH+0g3AnPA==", "dev": true, "requires": { "util": "^0.12.0", - "web3-core-helpers": "1.7.0", - "web3-providers-http": "1.7.0", - "web3-providers-ipc": "1.7.0", - "web3-providers-ws": "1.7.0" + "web3-core-helpers": "1.7.4", + "web3-providers-http": "1.7.4", + "web3-providers-ipc": "1.7.4", + "web3-providers-ws": "1.7.4" } }, "web3-core-subscriptions": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.7.0.tgz", - "integrity": "sha512-6giF8pyJrPmWrRpc2WLoVCvQdMMADp20ZpAusEW72axauZCNlW1XfTjs0i4QHQBfdd2lFp65qad9IuATPhuzrQ==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.7.4.tgz", + "integrity": "sha512-VJvKWaXRyxk2nFWumOR94ut9xvjzMrRtS38c4qj8WBIRSsugrZr5lqUwgndtj0qx4F+50JhnU++QEqUEAtKm3g==", "dev": true, "requires": { "eventemitter3": "4.0.4", - "web3-core-helpers": "1.7.0" + "web3-core-helpers": "1.7.4" } }, "web3-eth": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.7.0.tgz", - "integrity": "sha512-3uYwjMjn/MZjKIzXCt4YL9ja/k9X5shfa4lKparZhZE6uesmu+xmSmrEFXA/e9qcveF50jkV7frjkT8H+cLYtw==", - "dev": true, - "requires": { - "web3-core": "1.7.0", - "web3-core-helpers": "1.7.0", - "web3-core-method": "1.7.0", - "web3-core-subscriptions": "1.7.0", - "web3-eth-abi": "1.7.0", - "web3-eth-accounts": "1.7.0", - "web3-eth-contract": "1.7.0", - "web3-eth-ens": "1.7.0", - "web3-eth-iban": "1.7.0", - "web3-eth-personal": "1.7.0", - "web3-net": "1.7.0", - "web3-utils": "1.7.0" + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.7.4.tgz", + "integrity": "sha512-JG0tTMv0Ijj039emXNHi07jLb0OiWSA9O24MRSk5vToTQyDNXihdF2oyq85LfHuF690lXZaAXrjhtLNlYqb7Ug==", + "dev": true, + "requires": { + "web3-core": "1.7.4", + "web3-core-helpers": "1.7.4", + "web3-core-method": "1.7.4", + "web3-core-subscriptions": "1.7.4", + "web3-eth-abi": "1.7.4", + "web3-eth-accounts": "1.7.4", + "web3-eth-contract": "1.7.4", + "web3-eth-ens": "1.7.4", + "web3-eth-iban": "1.7.4", + "web3-eth-personal": "1.7.4", + "web3-net": "1.7.4", + "web3-utils": "1.7.4" }, "dependencies": { "web3-utils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.0.tgz", - "integrity": "sha512-O8Tl4Ky40Sp6pe89Olk2FsaUkgHyb5QAXuaKo38ms3CxZZ4d3rPGfjP9DNKGm5+IUgAZBNpF1VmlSmNCqfDI1w==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", + "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", "dev": true, "requires": { - "bn.js": "^4.11.9", + "bn.js": "^5.2.1", "ethereum-bloom-filters": "^1.0.6", "ethereumjs-util": "^7.1.0", "ethjs-unit": "0.1.6", @@ -21083,39 +20685,22 @@ } }, "web3-eth-abi": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.7.0.tgz", - "integrity": "sha512-heqR0bWxgCJwjWIhq2sGyNj9bwun5+Xox/LdZKe+WMyTSy0cXDXEAgv3XKNkXC4JqdDt/ZlbTEx4TWak4TRMSg==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.7.4.tgz", + "integrity": "sha512-eMZr8zgTbqyL9MCTCAvb67RbVyN5ZX7DvA0jbLOqRWCiw+KlJKTGnymKO6jPE8n5yjk4w01e165Qb11hTDwHgg==", "dev": true, "requires": { - "@ethersproject/abi": "5.0.7", - "web3-utils": "1.7.0" + "@ethersproject/abi": "^5.6.3", + "web3-utils": "1.7.4" }, "dependencies": { - "@ethersproject/abi": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz", - "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==", - "dev": true, - "requires": { - "@ethersproject/address": "^5.0.4", - "@ethersproject/bignumber": "^5.0.7", - "@ethersproject/bytes": "^5.0.4", - "@ethersproject/constants": "^5.0.4", - "@ethersproject/hash": "^5.0.4", - "@ethersproject/keccak256": "^5.0.3", - "@ethersproject/logger": "^5.0.5", - "@ethersproject/properties": "^5.0.3", - "@ethersproject/strings": "^5.0.4" - } - }, "web3-utils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.0.tgz", - "integrity": "sha512-O8Tl4Ky40Sp6pe89Olk2FsaUkgHyb5QAXuaKo38ms3CxZZ4d3rPGfjP9DNKGm5+IUgAZBNpF1VmlSmNCqfDI1w==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", + "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", "dev": true, "requires": { - "bn.js": "^4.11.9", + "bn.js": "^5.2.1", "ethereum-bloom-filters": "^1.0.6", "ethereumjs-util": "^7.1.0", "ethjs-unit": "0.1.6", @@ -21127,9 +20712,9 @@ } }, "web3-eth-accounts": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.7.0.tgz", - "integrity": "sha512-Zwm7TlQXdXGRuS6+ib1YsR5fQwpfnFyL6UAZg1zERdrUrs3IkCZSL3yCP/8ZYbAjdTEwWljoott2iSqXNH09ug==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.7.4.tgz", + "integrity": "sha512-Y9vYLRKP7VU7Cgq6wG1jFaG2k3/eIuiTKAG8RAuQnb6Cd9k5BRqTm5uPIiSo0AP/u11jDomZ8j7+WEgkU9+Btw==", "dev": true, "requires": { "@ethereumjs/common": "^2.5.0", @@ -21139,30 +20724,27 @@ "ethereumjs-util": "^7.0.10", "scrypt-js": "^3.0.1", "uuid": "3.3.2", - "web3-core": "1.7.0", - "web3-core-helpers": "1.7.0", - "web3-core-method": "1.7.0", - "web3-utils": "1.7.0" + "web3-core": "1.7.4", + "web3-core-helpers": "1.7.4", + "web3-core-method": "1.7.4", + "web3-utils": "1.7.4" }, "dependencies": { - "@ethereumjs/common": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.0.tgz", - "integrity": "sha512-Cq2qS0FTu6O2VU1sgg+WyU9Ps0M6j/BEMHN+hRaECXCV/r0aI78u4N6p52QW/BDVhwWZpCdrvG8X7NJdzlpNUA==", - "dev": true, - "requires": { - "crc-32": "^1.2.0", - "ethereumjs-util": "^7.1.3" - } + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true }, - "@ethereumjs/tx": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.4.0.tgz", - "integrity": "sha512-WWUwg1PdjHKZZxPPo274ZuPsJCWV3SqATrEKQP1n2DrVYVP1aZIYpo/mFaA0BDoE0tIQmBeimRCEA0Lgil+yYw==", + "eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", "dev": true, "requires": { - "@ethereumjs/common": "^2.6.0", - "ethereumjs-util": "^7.1.3" + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" } }, "uuid": { @@ -21172,54 +20754,53 @@ "dev": true }, "web3-utils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.0.tgz", - "integrity": "sha512-O8Tl4Ky40Sp6pe89Olk2FsaUkgHyb5QAXuaKo38ms3CxZZ4d3rPGfjP9DNKGm5+IUgAZBNpF1VmlSmNCqfDI1w==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", + "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", "dev": true, "requires": { - "bn.js": "^4.11.9", + "bn.js": "^5.2.1", "ethereum-bloom-filters": "^1.0.6", "ethereumjs-util": "^7.1.0", "ethjs-unit": "0.1.6", "number-to-bn": "1.7.0", "randombytes": "^2.1.0", "utf8": "3.0.0" + }, + "dependencies": { + "bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", + "dev": true + } } } } }, "web3-eth-contract": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.7.0.tgz", - "integrity": "sha512-2LY1Xwxu5rx468nqHuhvupQAIpytxIUj3mGL9uexszkhrQf05THVe3i4OnUCzkeN6B2cDztNOqLT3j9SSnVQDg==", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.5", - "web3-core": "1.7.0", - "web3-core-helpers": "1.7.0", - "web3-core-method": "1.7.0", - "web3-core-promievent": "1.7.0", - "web3-core-subscriptions": "1.7.0", - "web3-eth-abi": "1.7.0", - "web3-utils": "1.7.0" + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.7.4.tgz", + "integrity": "sha512-ZgSZMDVI1pE9uMQpK0T0HDT2oewHcfTCv0osEqf5qyn5KrcQDg1GT96/+S0dfqZ4HKj4lzS5O0rFyQiLPQ8LzQ==", + "dev": true, + "requires": { + "@types/bn.js": "^5.1.0", + "web3-core": "1.7.4", + "web3-core-helpers": "1.7.4", + "web3-core-method": "1.7.4", + "web3-core-promievent": "1.7.4", + "web3-core-subscriptions": "1.7.4", + "web3-eth-abi": "1.7.4", + "web3-utils": "1.7.4" }, "dependencies": { - "@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, "web3-utils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.0.tgz", - "integrity": "sha512-O8Tl4Ky40Sp6pe89Olk2FsaUkgHyb5QAXuaKo38ms3CxZZ4d3rPGfjP9DNKGm5+IUgAZBNpF1VmlSmNCqfDI1w==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", + "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", "dev": true, "requires": { - "bn.js": "^4.11.9", + "bn.js": "^5.2.1", "ethereum-bloom-filters": "^1.0.6", "ethereumjs-util": "^7.1.0", "ethjs-unit": "0.1.6", @@ -21231,28 +20812,28 @@ } }, "web3-eth-ens": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.7.0.tgz", - "integrity": "sha512-I1bikYJJWQ/FJZIAvwsGOvzAgcRIkosWG4s1L6veRoXaU8OEJFeh4s00KcfHDxg7GWZZGbUSbdbzKpwRbWnvkg==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.7.4.tgz", + "integrity": "sha512-Gw5CVU1+bFXP5RVXTCqJOmHn71X2ghNk9VcEH+9PchLr0PrKbHTA3hySpsPco1WJAyK4t8SNQVlNr3+bJ6/WZA==", "dev": true, "requires": { "content-hash": "^2.5.2", "eth-ens-namehash": "2.0.8", - "web3-core": "1.7.0", - "web3-core-helpers": "1.7.0", - "web3-core-promievent": "1.7.0", - "web3-eth-abi": "1.7.0", - "web3-eth-contract": "1.7.0", - "web3-utils": "1.7.0" + "web3-core": "1.7.4", + "web3-core-helpers": "1.7.4", + "web3-core-promievent": "1.7.4", + "web3-eth-abi": "1.7.4", + "web3-eth-contract": "1.7.4", + "web3-utils": "1.7.4" }, "dependencies": { "web3-utils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.0.tgz", - "integrity": "sha512-O8Tl4Ky40Sp6pe89Olk2FsaUkgHyb5QAXuaKo38ms3CxZZ4d3rPGfjP9DNKGm5+IUgAZBNpF1VmlSmNCqfDI1w==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", + "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", "dev": true, "requires": { - "bn.js": "^4.11.9", + "bn.js": "^5.2.1", "ethereum-bloom-filters": "^1.0.6", "ethereumjs-util": "^7.1.0", "ethjs-unit": "0.1.6", @@ -21264,22 +20845,22 @@ } }, "web3-eth-iban": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.0.tgz", - "integrity": "sha512-1PFE/Og+sPZaug+M9TqVUtjOtq0HecE+SjDcsOOysXSzslNC2CItBGkcRwbvUcS+LbIkA7MFsuqYxOL0IV/gyA==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.4.tgz", + "integrity": "sha512-XyrsgWlZQMv5gRcjXMsNvAoCRvV5wN7YCfFV5+tHUCqN8g9T/o4XUS20vDWD0k4HNiAcWGFqT1nrls02MGZ08w==", "dev": true, "requires": { - "bn.js": "^4.11.9", - "web3-utils": "1.7.0" + "bn.js": "^5.2.1", + "web3-utils": "1.7.4" }, "dependencies": { "web3-utils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.0.tgz", - "integrity": "sha512-O8Tl4Ky40Sp6pe89Olk2FsaUkgHyb5QAXuaKo38ms3CxZZ4d3rPGfjP9DNKGm5+IUgAZBNpF1VmlSmNCqfDI1w==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", + "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", "dev": true, "requires": { - "bn.js": "^4.11.9", + "bn.js": "^5.2.1", "ethereum-bloom-filters": "^1.0.6", "ethereumjs-util": "^7.1.0", "ethjs-unit": "0.1.6", @@ -21291,32 +20872,32 @@ } }, "web3-eth-personal": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.7.0.tgz", - "integrity": "sha512-Dr9RZTNOR80PhrPKGdktDUXpOgExEcCcosBj080lKCJFU1paSPj9Zfnth3u6BtIOXyKsVFTrpqekqUDyAwXnNw==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.7.4.tgz", + "integrity": "sha512-O10C1Hln5wvLQsDhlhmV58RhXo+GPZ5+W76frSsyIrkJWLtYQTCr5WxHtRC9sMD1idXLqODKKgI2DL+7xeZ0/g==", "dev": true, "requires": { "@types/node": "^12.12.6", - "web3-core": "1.7.0", - "web3-core-helpers": "1.7.0", - "web3-core-method": "1.7.0", - "web3-net": "1.7.0", - "web3-utils": "1.7.0" + "web3-core": "1.7.4", + "web3-core-helpers": "1.7.4", + "web3-core-method": "1.7.4", + "web3-net": "1.7.4", + "web3-utils": "1.7.4" }, "dependencies": { "@types/node": { - "version": "12.20.42", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.42.tgz", - "integrity": "sha512-aI3/oo5DzyiI5R/xAhxxRzfZlWlsbbqdgxfTPkqu/Zt+23GXiJvMCyPJT4+xKSXOnLqoL8jJYMLTwvK2M3a5hw==", + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", "dev": true }, "web3-utils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.0.tgz", - "integrity": "sha512-O8Tl4Ky40Sp6pe89Olk2FsaUkgHyb5QAXuaKo38ms3CxZZ4d3rPGfjP9DNKGm5+IUgAZBNpF1VmlSmNCqfDI1w==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", + "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", "dev": true, "requires": { - "bn.js": "^4.11.9", + "bn.js": "^5.2.1", "ethereum-bloom-filters": "^1.0.6", "ethereumjs-util": "^7.1.0", "ethjs-unit": "0.1.6", @@ -21328,23 +20909,23 @@ } }, "web3-net": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.7.0.tgz", - "integrity": "sha512-8pmfU1Se7DmG40Pu8nOCKlhuI12VsVzCtdFDnLAai0zGVAOUuuOCK71B2aKm6u9amWBJjtOlyrCwvsG+QEd6dw==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.7.4.tgz", + "integrity": "sha512-d2Gj+DIARHvwIdmxFQ4PwAAXZVxYCR2lET0cxz4KXbE5Og3DNjJi+MoPkX+WqoUXqimu/EOd4Cd+7gefqVAFDg==", "dev": true, "requires": { - "web3-core": "1.7.0", - "web3-core-method": "1.7.0", - "web3-utils": "1.7.0" + "web3-core": "1.7.4", + "web3-core-method": "1.7.4", + "web3-utils": "1.7.4" }, "dependencies": { "web3-utils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.0.tgz", - "integrity": "sha512-O8Tl4Ky40Sp6pe89Olk2FsaUkgHyb5QAXuaKo38ms3CxZZ4d3rPGfjP9DNKGm5+IUgAZBNpF1VmlSmNCqfDI1w==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", + "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", "dev": true, "requires": { - "bn.js": "^4.11.9", + "bn.js": "^5.2.1", "ethereum-bloom-filters": "^1.0.6", "ethereumjs-util": "^7.1.0", "ethjs-unit": "0.1.6", @@ -21356,64 +20937,69 @@ } }, "web3-providers-http": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.7.0.tgz", - "integrity": "sha512-Y9reeEiApfvQKLUUtrU4Z0c+H6b7BMWcsxjgoXndI1C5NB297mIUfltXxfXsh5C/jk5qn4Q3sJp3SwQTyVjH7Q==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.7.4.tgz", + "integrity": "sha512-AU+/S+49rcogUER99TlhW+UBMk0N2DxvN54CJ2pK7alc2TQ7+cprNPLHJu4KREe8ndV0fT6JtWUfOMyTvl+FRA==", "dev": true, "requires": { - "web3-core-helpers": "1.7.0", + "web3-core-helpers": "1.7.4", "xhr2-cookies": "1.1.0" } }, "web3-providers-ipc": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.7.0.tgz", - "integrity": "sha512-U5YLXgu6fvAK4nnMYqo9eoml3WywgTym0dgCdVX/n1UegLIQ4nctTubBAuWQEJzmAzwh+a6ValGcE7ZApTRI7Q==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.7.4.tgz", + "integrity": "sha512-jhArOZ235dZy8fS8090t60nTxbd1ap92ibQw5xIrAQ9m7LcZKNfmLAQUVsD+3dTFvadRMi6z1vCO7zRi84gWHw==", "dev": true, "requires": { "oboe": "2.1.5", - "web3-core-helpers": "1.7.0" + "web3-core-helpers": "1.7.4" } }, "web3-providers-ws": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.7.0.tgz", - "integrity": "sha512-0a8+lVV3JBf+eYnGOsdzOpftK1kis5X7s35QAdoaG5SDapnEylXFlR4xDSSSU88ZwMwvse8hvng2xW6A7oeWxw==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.7.4.tgz", + "integrity": "sha512-g72X77nrcHMFU8hRzQJzfgi/072n8dHwRCoTw+WQrGp+XCQ71fsk2qIu3Tp+nlp5BPn8bRudQbPblVm2uT4myQ==", "dev": true, "requires": { "eventemitter3": "4.0.4", - "web3-core-helpers": "1.7.0", + "web3-core-helpers": "1.7.4", "websocket": "^1.0.32" } }, "web3-shh": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.7.0.tgz", - "integrity": "sha512-RZhxcevALIPK178VZCpwMBvQeW+IoWtRJ4EMdegpbnETeZaC3aRUcs6vKnrf0jXJjm4J/E2Dt438Y1Ord/1IMw==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.7.4.tgz", + "integrity": "sha512-mlSZxSYcMkuMCxqhTYnZkUdahZ11h+bBv/8TlkXp/IHpEe4/Gg+KAbmfudakq3EzG/04z70XQmPgWcUPrsEJ+A==", "dev": true, "requires": { - "web3-core": "1.7.0", - "web3-core-method": "1.7.0", - "web3-core-subscriptions": "1.7.0", - "web3-net": "1.7.0" + "web3-core": "1.7.4", + "web3-core-method": "1.7.4", + "web3-core-subscriptions": "1.7.4", + "web3-net": "1.7.4" } }, "web3-utils": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.3.5.tgz", - "integrity": "sha512-5apMRm8ElYjI/92GHqijmaLC+s+d5lgjpjHft+rJSs/dsnX8I8tQreqev0dmU+wzU+2EEe4Sx9a/OwGWHhQv3A==", + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.5.tgz", + "integrity": "sha512-9AqNOziQky4wNQadEwEfHiBdOZqopIHzQQVzmvvv6fJwDSMhP+khqmAZC7YTiGjs0MboyZ8tWNivqSO1699XQw==", "dev": true, "requires": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", + "bn.js": "^5.2.1", "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", "ethjs-unit": "0.1.6", "number-to-bn": "1.7.0", "randombytes": "^2.1.0", - "underscore": "1.9.1", "utf8": "3.0.0" } }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, "websocket": { "version": "1.0.34", "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.34.tgz", @@ -21440,11 +21026,21 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true } } }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -21468,30 +21064,29 @@ } }, "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ==", "dev": true }, "which-pm-runs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", - "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.1.0.tgz", + "integrity": "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==", "optional": true }, "which-typed-array": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.4.tgz", - "integrity": "sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA==", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.8.tgz", + "integrity": "sha512-Jn4e5PItbcAHyLoRDwvPj1ypu27DJbtdYXUa5zsinrUx77Uvfb0cXwwnGMTn7cjUfhhqgVQnVJCwF+7cgU7tpw==", "dev": true, "requires": { - "available-typed-arrays": "^1.0.2", - "call-bind": "^1.0.0", - "es-abstract": "^1.18.0-next.1", - "foreach": "^2.0.5", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.1", - "is-typed-array": "^1.1.3" + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-abstract": "^1.20.0", + "for-each": "^0.3.3", + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.9" } }, "wide-align": { @@ -21518,12 +21113,6 @@ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -21555,7 +21144,7 @@ "window-size": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", - "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=", + "integrity": "sha512-UD7d8HFA2+PZsbKyaOCEy8gMh1oDtHgJh1LfgjQ4zVXmYjAT/kvz3PueITKuqDiIXQe7yzpPnxX3lNc+AhQMyw==", "dev": true }, "word-wrap": { @@ -21567,52 +21156,29 @@ "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true + }, + "workerpool": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", + "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", "dev": true }, "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==", "dev": true, "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } + "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=" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "write": { "version": "1.0.3", @@ -21653,6 +21219,34 @@ "timed-out": "^4.0.1", "url-set-query": "^1.0.0", "xhr": "^2.0.4" + }, + "dependencies": { + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true + }, + "simple-get": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.2.tgz", + "integrity": "sha512-Ijd/rV5o+mSBBs4F/x9oDPtTx9Zb6X9brmnXvMW4J7IR15ngi9q5xxqWBKU744jTZiaXtxaPL7uHG6vtN8kUkw==", + "dev": true, + "requires": { + "decompress-response": "^3.3.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + } } }, "xhr-request-promise": { @@ -21667,7 +21261,7 @@ "xhr2-cookies": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz", - "integrity": "sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg=", + "integrity": "sha512-hjXUA6q+jl/bd8ADHcVfFsSPIf+tyLIjuO9TwJC9WI6JP2zKcS7C+p56I9kCLLsaCiNT035iYvEUUzdEFj/8+g==", "dev": true, "requires": { "cookiejar": "^2.1.1" @@ -21676,7 +21270,7 @@ "xmlhttprequest": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", - "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=", + "integrity": "sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA==", "dev": true }, "xtend": { @@ -21686,131 +21280,78 @@ "dev": true }, "y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", + "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", "dev": true }, "yaeti": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", - "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=", + "integrity": "sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug==", "dev": true }, "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", + "integrity": "sha512-LqodLrnIDM3IFT+Hf/5sxBnEGECrfdC1uIbgZeJmESCSo4HoCAaKEus8MylXHAkdacGc0ye+Qa+dpkuom8uVYA==", "dev": true, "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", + "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": "^2.0.0", + "require-main-filename": "^1.0.1", "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.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": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz", + "integrity": "sha512-9pIKIJhnI5tonzG6OnCFlz/yln8xHYcGl+pn3xR0Vzff0vzN1PbNRaelgfgRUwZ3s4i3jvxT9WhmUGL4whnasA==", "dev": true, "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" + "camelcase": "^3.0.0", + "lodash.assign": "^4.0.6" } }, "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", "dev": true, "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "dependencies": { + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true + }, + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true + } } }, "yn": { @@ -21818,6 +21359,12 @@ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true } } } diff --git a/package.json b/package.json index d2cd9a11..f28a0c17 100644 --- a/package.json +++ b/package.json @@ -37,8 +37,8 @@ }, "dependencies": { "@ethersproject/hardware-wallets": "^5.5.0", - "@openzeppelin/contracts": "^4.3.2", - "@openzeppelin/contracts-upgradeable": "^4.3.2", + "@openzeppelin/contracts": "~4.3.2", + "@openzeppelin/contracts-upgradeable": "~4.3.2", "@openzeppelin/hardhat-upgrades": "^1.13.0", "@uniswap/v3-core": "^1.0.0", "@uniswap/v3-periphery": "^1.1.1", diff --git a/scripts/aurora/deploy-native-locker.ts b/scripts/aurora/deploy-native-locker.ts new file mode 100644 index 00000000..76046e44 --- /dev/null +++ b/scripts/aurora/deploy-native-locker.ts @@ -0,0 +1,192 @@ +// Requires following fields in .env + +// AURORA_URL +// AURORA_ACCOUNTS +// AURORASCAN_API_KEY + +// PRIVATE_KEYS +// RINKEBY_ACCOUNTS +// RINKEBY_ALCHEMY_KEY + +import hardhat from "hardhat"; +const { waffle, ethers } = hardhat; +const { provider } = waffle; +const BN = ethers.BigNumber; +const { parseUnits } = ethers.utils +import { config as dotenv_config } from "dotenv"; +dotenv_config(); +const deployer = new ethers.Wallet(JSON.parse(process.env.PRIVATE_KEYS || '[]')[0], provider); + +import { logContractAddress } from "../utils"; + +import { import_artifacts, ArtifactImports } from "../../test/utilities/artifact_importer"; +import { Registry, Erc20, UnderwritingLockVoting, UnderwritingLocker, GaugeController, DepositHelper } from "../../typechain"; +import { expectDeployed, isDeployed } from "../../test/utilities/expectDeployed"; +import { getNetworkSettings } from "../getNetworkSettings"; +import { create2Contract } from "../create2Contract"; +import { formatUnits } from "ethers/lib/utils"; + +const DEPLOYER_CONTRACT_ADDRESS = "0x501aCe4732E4A80CC1bc5cd081BEe7f88ff694EF"; +const REGISTRY_ADDRESS = "0x501ACe0f576fc4ef9C0380AA46A578eA96b85776"; +const UWP_ADDRESS = "0x501ACEb41708De16FbedE3b31f3064919E9d7F23"; +const UWE_ADDRESS = "0x501AcE91E8832CDeA18b9e685751079CCddfc0e2"; +const REVENUE_ROUTER_ADDRESS = "0x0436C20030d0C2e278E7e8e4b42D304a6420D3bb"; +const UNDERWRITING_LOCKER_ADDRESS = "0x501aceAC7279713F33d8cd1eBDCfd8E442909CA5"; +const GAUGE_CONTROLLER_ADDRESS = "0x501AcE75E1f2098099E73e05BC73d5F16ED7b6f1"; +const UNDERWRITING_LOCK_VOTING_ADDRESS = "0x501ace085C07AfB7EB070ddbC7b4bC3D4379761a"; +const DEPOSIT_HELPER_ADDRESS = "0x501acE8830E73F81172C4877c9d273D6a3767AD1"; +let GOVERNOR_ADDRESS: string; + +let artifacts: ArtifactImports; +let registry: Registry; +let underwritingLocker: UnderwritingLocker; +let voting: UnderwritingLockVoting; +let gaugeController: GaugeController; +let depositHelper: DepositHelper; + +let signerAddress: string; +let networkSettings: any; + +async function main() { + artifacts = await import_artifacts(); + signerAddress = await deployer.getAddress(); + console.log(`Using ${signerAddress} as deployer`); + GOVERNOR_ADDRESS = signerAddress; + + let chainID = (await provider.getNetwork()).chainId; + networkSettings = getNetworkSettings(chainID); + + await expectDeployed(DEPLOYER_CONTRACT_ADDRESS); + await expectDeployed(UWP_ADDRESS); + await expectDeployed(UWE_ADDRESS); + await expectDeployed(REGISTRY_ADDRESS); + + /********************* + DEPLOY SEQUENCE + *********************/ + + registry = (await ethers.getContractAt(artifacts.Registry.abi, REGISTRY_ADDRESS)) as Registry; + + //await setRegistry1(); // Set 'uwe' in the registry + await deployUnderwritingLocker(); + await deployGaugeController(); + //await setRegistry2(); // Set 'revenueRouter', 'underwritingLocker' and 'gaugeController' in the registry + await deployUnderwritingLockVoting(); + //await gaugeSetup(); + //await addGauges(); + await deployDepositHelper(); + + // log addresses + await logAddresses(); +} + +async function setRegistry1() { + console.log("Setting 'uwe' in the Registry.") + const keys = ["uwe"]; + const values = [UWE_ADDRESS]; + let tx = await registry.connect(deployer).set(keys, values, networkSettings.overrides); + await tx.wait(networkSettings.confirmations); +} + +async function deployUnderwritingLocker() { + if (await isDeployed(UNDERWRITING_LOCKER_ADDRESS)) { + underwritingLocker = (await ethers.getContractAt(artifacts.UnderwritingLocker.abi, UNDERWRITING_LOCKER_ADDRESS)) as UnderwritingLocker; + } else { + console.log("Deploying UnderwritingLocker"); + const res = await create2Contract(deployer, artifacts.UnderwritingLocker, [GOVERNOR_ADDRESS, REGISTRY_ADDRESS], {}, "", DEPLOYER_CONTRACT_ADDRESS); + underwritingLocker = (await ethers.getContractAt(artifacts.UnderwritingLocker.abi, res.address)) as unknown as UnderwritingLocker; + console.log(`Deployed UnderwritingLocker to ${underwritingLocker.address}`); + } +} + +async function deployGaugeController() { + if (await isDeployed(GAUGE_CONTROLLER_ADDRESS)) { + gaugeController = (await ethers.getContractAt(artifacts.GaugeController.abi, GAUGE_CONTROLLER_ADDRESS)) as GaugeController; + } else { + console.log("Deploying GaugeController"); + const res = await create2Contract(deployer, artifacts.GaugeController, [GOVERNOR_ADDRESS, UWE_ADDRESS], {}, "", DEPLOYER_CONTRACT_ADDRESS); + gaugeController = (await ethers.getContractAt(artifacts.GaugeController.abi, res.address)) as unknown as GaugeController; + console.log(`Deployed GaugeController to ${gaugeController.address}`); + } +} + +async function setRegistry2() { + console.log("Setting 'revenueRouter', 'underwritingLocker' and 'gaugeController' in the Registry.") + const keys = ["revenueRouter", "underwritingLocker", "gaugeController"]; + const values = [REVENUE_ROUTER_ADDRESS, underwritingLocker.address, gaugeController.address] + let tx = await registry.connect(deployer).set(keys, values, networkSettings.overrides); + await tx.wait(networkSettings.confirmations); +} + +async function deployUnderwritingLockVoting() { + if (await isDeployed(UNDERWRITING_LOCK_VOTING_ADDRESS)) { + voting = (await ethers.getContractAt(artifacts.UnderwritingLockVoting.abi, UNDERWRITING_LOCK_VOTING_ADDRESS)) as UnderwritingLockVoting; + } else { + console.log("Deploying UnderwritingLockVoting"); + const res = await create2Contract(deployer, artifacts.UnderwritingLockVoting, [GOVERNOR_ADDRESS, REGISTRY_ADDRESS], {}, "", DEPLOYER_CONTRACT_ADDRESS); + voting = (await ethers.getContractAt(artifacts.UnderwritingLockVoting.abi, res.address)) as unknown as UnderwritingLockVoting; + console.log(`Deployed UnderwritingLockVoting to ${voting.address}`); + } +} + +async function gaugeSetup() { + console.log("Adding UnderwritingLocker as $UWE capacity source in GaugeController"); + const tx1 = await gaugeController.connect(deployer).addTokenholder(underwritingLocker.address, networkSettings.overrides); + await tx1.wait(networkSettings.confirmations); + + console.log("Adding UnderwritingLockVoting as vote source in GaugeController"); + const tx2 = await gaugeController.connect(deployer).addVotingContract(voting.address, {...networkSettings.overrides, gasLimit: 1000000}); + await tx2.wait(networkSettings.confirmations); + + console.log("Adding 'underwritingLockVoting' to the registry"); + const tx3 = await registry.connect(deployer).set(["underwritingLockVoting"], [voting.address], {...networkSettings.overrides, gasLimit: 1000000}); + await tx3.wait(networkSettings.confirmations); + + console.log("Enabling UnderwritingLockVoting to charge premium to UnderwritingLocker"); + const tx4 = await underwritingLocker.connect(deployer).setVotingContract(networkSettings.overrides); + await tx4.wait(networkSettings.confirmations); +} + +async function addGauges() { + console.log("Adding gauges to GaugeController"); + let rol = BN.from(10).pow(18).mul(250).div(10000); // 2.5% + let appIDs = ["aurora-plus", "aurigami", "bastion-protocol", "bluebit", "trisolaris", "vaporwave-finance"]; + let len = (await gaugeController.totalGauges()).toNumber(); + if(len > 0) { + console.log(`${len} gauges already found. skipping`); + return; + } + for(let i = 0; i < appIDs.length; ++i) { + let tx = await gaugeController.connect(deployer).addGauge(appIDs[i], rol, networkSettings.overrides); + await tx.wait(networkSettings.confirmations); + } + console.log("Added gauges to GaugeController"); +} + +async function deployDepositHelper() { + if(await isDeployed(DEPOSIT_HELPER_ADDRESS)) { + depositHelper = (await ethers.getContractAt(artifacts.DepositHelper.abi, DEPOSIT_HELPER_ADDRESS)) as DepositHelper; + } else { + console.log("Deploying DepositHelper"); + const res = await create2Contract(deployer, artifacts.DepositHelper, [UWP_ADDRESS, UWE_ADDRESS, underwritingLocker.address], {}, "", DEPLOYER_CONTRACT_ADDRESS); + depositHelper = (await ethers.getContractAt(artifacts.DepositHelper.abi, res.address)) as DepositHelper; + console.log(`Deployed DepositHelper to ${depositHelper.address}`); + } +} + +async function logAddresses() { + console.log(""); + console.log("| Contract Name | Address |"); + console.log("|------------------------------|----------------------------------------------|"); + logContractAddress("UnderwritingLocker", underwritingLocker.address); + logContractAddress("GaugeController", gaugeController.address); + logContractAddress("UnderwritingLockVoting", voting.address); + logContractAddress("DepositHelper", depositHelper.address); +} + +main() + .then(() => process.exit(0)) + .catch(error => { + console.error(error); + process.exit(1); + }); diff --git a/scripts/aurora/deploy-native-uwp.ts b/scripts/aurora/deploy-native-uwp.ts new file mode 100644 index 00000000..cac7e1a1 --- /dev/null +++ b/scripts/aurora/deploy-native-uwp.ts @@ -0,0 +1,241 @@ +// deploys v3 of solace wallet coverage + +import hardhat from "hardhat"; +const { waffle, ethers } = hardhat; +const { provider } = waffle; +const BN = ethers.BigNumber; +import { config as dotenv_config } from "dotenv"; +dotenv_config(); +const deployer = new ethers.Wallet(JSON.parse(process.env.PRIVATE_KEYS || '[]')[0], provider); + +import { logContractAddress } from "./../utils"; + +import { import_artifacts, ArtifactImports } from "./../../test/utilities/artifact_importer"; +import { SolaceMegaOracle, FluxMegaOracle, UnderwritingPool, UnderwritingEquity, MockErc20 } from "../../typechain"; +import { expectDeployed, isDeployed } from "../../test/utilities/expectDeployed"; +import { getNetworkSettings } from "../getNetworkSettings"; +import { create2Contract } from "../create2Contract"; + +const DEPLOYER_CONTRACT_ADDRESS = "0x501aCe4732E4A80CC1bc5cd081BEe7f88ff694EF"; + +// price feed addresses +const USDC_PRICE_FEED_ADDRESS = "0xdD170e697d7ADed472a9284f07576c3449284502"; +const DAI_PRICE_FEED_ADDRESS = "0x9e3C7532d9E4bfF3298a132101Bcc62576D80e36"; +const USDT_PRICE_FEED_ADDRESS = "0x55b9eD56737B161677dC5146873E643647Ba5a43"; +const FRAX_PRICE_FEED_ADDRESS = ""; +const BTC_PRICE_FEED_ADDRESS = "0xBE46e430d336fC827d096Db044cBaEECE72e17bC"; +const ETH_PRICE_FEED_ADDRESS = "0x842AF8074Fa41583E3720821cF1435049cf93565"; + +// token addresses +const USDC_ADDRESS = "0xB12BFcA5A55806AaF64E99521918A4bf0fC40802"; +const DAI_ADDRESS = "0xe3520349F477A5F6EB06107066048508498A291b"; +const USDT_ADDRESS = "0x4988a896b1227218e4A686fdE5EabdcAbd91571f"; +const FRAX_ADDRESS = "0xDA2585430fEf327aD8ee44Af8F1f989a2A91A3d2"; +const WBTC_ADDRESS = "0xf4eb217ba2454613b15dbdea6e5f22276410e89e"; +const WETH_ADDRESS = "0xC9BdeEd33CD01541e1eeD10f90519d2C06Fe3feB"; +const SOLACE_ADDRESS = "0x501acE9c35E60f03A2af4d484f49F9B1EFde9f40"; +const AURORA_ADDRESS = "0x8BEc47865aDe3B172A928df8f990Bc7f2A3b9f79"; +const PLY_ADDRESS = "0x09C9D464b58d96837f8d8b6f4d9fE4aD408d3A4f"; +const BSTN_ADDRESS = "0x9f1F933C660a1DC856F0E0Fe058435879c5CCEf0"; +const BBT_ADDRESS = "0x4148d2Ce7816F0AE378d98b40eB3A7211E1fcF0D"; +const TRI_ADDRESS = "0xFa94348467f64D5A457F75F8bc40495D33c65aBB"; +const VWAVE_ADDRESS = "0x2451dB68DeD81900C4F16ae1af597E9658689734"; + +// contract addresses +const SOLACE_MEGA_ORACLE_ADDRESS = "0x501acEC7AD3F8bb5Fc3C925dcAC1C4077e2bb7C5"; +const FLUX_MEGA_ORACLE_ADDRESS = "0x501AcE8E475B7fD921fcfeBB365374cA62cED1a5"; +const UWP_ADDRESS = "0x501ACEb41708De16FbedE3b31f3064919E9d7F23"; +const UWE_ADDRESS = "0x501AcE91E8832CDeA18b9e685751079CCddfc0e2"; + +let artifacts: ArtifactImports; + +let solaceMegaOracle: SolaceMegaOracle; +let fluxMegaOracle: FluxMegaOracle; +let uwp: UnderwritingPool; +let uwe: UnderwritingEquity; + +let signerAddress: string; +let networkSettings: any; + +async function main() { + artifacts = await import_artifacts(); + signerAddress = await deployer.getAddress(); + console.log(`Using ${signerAddress} as deployer and governor`); + + let chainID = (await provider.getNetwork()).chainId; + networkSettings = getNetworkSettings(chainID); + + await expectDeployed(DEPLOYER_CONTRACT_ADDRESS); + /* + await expectDeployed(USDC_PRICE_FEED_ADDRESS); + await expectDeployed(DAI_PRICE_FEED_ADDRESS); + await expectDeployed(USDT_PRICE_FEED_ADDRESS); + await expectDeployed(FRAX_PRICE_FEED_ADDRESS); + await expectDeployed(BTC_PRICE_FEED_ADDRESS); + await expectDeployed(ETH_PRICE_FEED_ADDRESS); + await expectDeployed(USDC_ADDRESS); + await expectDeployed(DAI_ADDRESS); + await expectDeployed(USDT_ADDRESS); + await expectDeployed(FRAX_ADDRESS); + await expectDeployed(WBTC_ADDRESS); + await expectDeployed(WETH_ADDRESS); + await expectDeployed(SOLACE_ADDRESS); + await expectDeployed(AURORA_ADDRESS); + await expectDeployed(PLY_ADDRESS); + await expectDeployed(BSTN_ADDRESS); + await expectDeployed(BBT_ADDRESS); + await expectDeployed(TRI_ADDRESS); + await expectDeployed(VWAVE_ADDRESS); + */ + + // deploy and configure contracts + // SolaceMegaOracle + await deploySolaceMegaOracle(); + //await configureSolaceMegaOracle(); + // FluxMegaOracle + await deployFluxMegaOracle(); + //await configureFluxMegaOracle(); + // uwp + await deployUwp(); + //await configureUwp(); + // uwe + await deployUwe(); + + // log addresses + await logAddresses(); +} + +async function deploySolaceMegaOracle() { + if(await isDeployed(SOLACE_MEGA_ORACLE_ADDRESS)) { + solaceMegaOracle = (await ethers.getContractAt(artifacts.SolaceMegaOracle.abi, SOLACE_MEGA_ORACLE_ADDRESS)) as SolaceMegaOracle; + } else { + console.log("Deploying SolaceMegaOracle"); + const res = await create2Contract(deployer, artifacts.SolaceMegaOracle, [signerAddress], {}, "", DEPLOYER_CONTRACT_ADDRESS); + solaceMegaOracle = (await ethers.getContractAt(artifacts.SolaceMegaOracle.abi, res.address)) as SolaceMegaOracle; + console.log(`Deployed SolaceMegaOracle to ${solaceMegaOracle.address}`); + } +} + +async function configureSolaceMegaOracle() { + console.log('Adding updater to SolaceMegaOracle'); + let tx1 = await solaceMegaOracle.connect(deployer).setUpdaterStatuses([deployer.address], [true], networkSettings.overrides); + await tx1.wait(networkSettings.confirmations); + console.log('Added updater to SolaceMegaOracle'); + + console.log('Adding price feeds to SolaceMegaOracle'); + let tx = await solaceMegaOracle.connect(deployer).addPriceFeeds([ + { token: SOLACE_ADDRESS, latestPrice: 0, tokenDecimals: 18, priceFeedDecimals: 18 }, + { token: AURORA_ADDRESS, latestPrice: 0, tokenDecimals: 18, priceFeedDecimals: 18 }, + { token: PLY_ADDRESS, latestPrice: 0, tokenDecimals: 18, priceFeedDecimals: 18 }, + { token: BSTN_ADDRESS, latestPrice: 0, tokenDecimals: 18, priceFeedDecimals: 18 }, + { token: BBT_ADDRESS, latestPrice: 0, tokenDecimals: 18, priceFeedDecimals: 18 }, + { token: TRI_ADDRESS, latestPrice: 0, tokenDecimals: 18, priceFeedDecimals: 18 }, + { token: VWAVE_ADDRESS, latestPrice: 0, tokenDecimals: 18, priceFeedDecimals: 18 }, + ], networkSettings.overrides); + await tx.wait(networkSettings.confirmations); + console.log('Added price feeds to SolaceMegaOracle'); +} + +async function deployFluxMegaOracle() { + if(await isDeployed(FLUX_MEGA_ORACLE_ADDRESS)) { + fluxMegaOracle = (await ethers.getContractAt(artifacts.FluxMegaOracle.abi, FLUX_MEGA_ORACLE_ADDRESS)) as FluxMegaOracle; + } else { + console.log("Deploying FluxMegaOracle"); + const res = await create2Contract(deployer, artifacts.FluxMegaOracle, [signerAddress], {}, "", DEPLOYER_CONTRACT_ADDRESS); + fluxMegaOracle = (await ethers.getContractAt(artifacts.FluxMegaOracle.abi, res.address)) as FluxMegaOracle; + console.log(`Deployed FluxMegaOracle to ${fluxMegaOracle.address}`); + } +} + +async function configureFluxMegaOracle() { + console.log('Adding price feeds to FluxMegaOracle'); + let tx = await fluxMegaOracle.connect(deployer).addPriceFeeds([ + { token: USDC_ADDRESS, priceFeed: USDC_PRICE_FEED_ADDRESS, tokenDecimals: 6, priceFeedDecimals: 8 }, + { token: DAI_ADDRESS, priceFeed: DAI_PRICE_FEED_ADDRESS, tokenDecimals: 18, priceFeedDecimals: 8 }, + { token: USDT_ADDRESS, priceFeed: USDT_PRICE_FEED_ADDRESS, tokenDecimals: 6, priceFeedDecimals: 8 }, + { token: FRAX_ADDRESS, priceFeed: FRAX_PRICE_FEED_ADDRESS, tokenDecimals: 18, priceFeedDecimals: 8 }, + { token: WBTC_ADDRESS, priceFeed: BTC_PRICE_FEED_ADDRESS, tokenDecimals: 8, priceFeedDecimals: 8 }, + { token: WETH_ADDRESS, priceFeed: ETH_PRICE_FEED_ADDRESS, tokenDecimals: 18, priceFeedDecimals: 8 }, + ], networkSettings.overrides); + await tx.wait(networkSettings.confirmations); + console.log('Added price feeds to FluxMegaOracle'); +} + +async function deployUwp() { + if(await isDeployed(UWP_ADDRESS)) { + uwp = (await ethers.getContractAt(artifacts.UnderwritingPool.abi, UWP_ADDRESS)) as UnderwritingPool; + } else { + console.log('Deploying UnderwritingPool'); + const res = await create2Contract(deployer, artifacts.UnderwritingPool, [signerAddress], {}, "", DEPLOYER_CONTRACT_ADDRESS); + uwp = (await ethers.getContractAt(artifacts.UnderwritingPool.abi, res.address)) as UnderwritingPool; + console.log(`Deploying UnderwritingPool to ${uwp.address}`); + } +} + +async function configureUwp() { + console.log('Adding tokens to uwp'); + let tx = await uwp.connect(deployer).addTokensToPool([ + { token: USDC_ADDRESS, oracle: fluxMegaOracle.address, min: 0, max: ethers.constants.MaxUint256 }, + { token: DAI_ADDRESS, oracle: fluxMegaOracle.address, min: 0, max: ethers.constants.MaxUint256 }, + { token: USDT_ADDRESS, oracle: fluxMegaOracle.address, min: 0, max: ethers.constants.MaxUint256 }, + { token: FRAX_ADDRESS, oracle: fluxMegaOracle.address, min: 0, max: ethers.constants.MaxUint256 }, + { token: WBTC_ADDRESS, oracle: fluxMegaOracle.address, min: 0, max: ethers.constants.MaxUint256 }, + { token: WETH_ADDRESS, oracle: fluxMegaOracle.address, min: 0, max: ethers.constants.MaxUint256 }, + { token: SOLACE_ADDRESS, oracle: solaceMegaOracle.address, min: 0, max: ethers.constants.MaxUint256 }, + { token: AURORA_ADDRESS, oracle: solaceMegaOracle.address, min: 0, max: ethers.constants.MaxUint256 }, + { token: PLY_ADDRESS, oracle: solaceMegaOracle.address, min: 0, max: ethers.constants.MaxUint256 }, + { token: BSTN_ADDRESS, oracle: solaceMegaOracle.address, min: 0, max: ethers.constants.MaxUint256 }, + { token: BBT_ADDRESS, oracle: solaceMegaOracle.address, min: 0, max: ethers.constants.MaxUint256 }, + { token: TRI_ADDRESS, oracle: solaceMegaOracle.address, min: 0, max: ethers.constants.MaxUint256 }, + { token: VWAVE_ADDRESS, oracle: solaceMegaOracle.address, min: 0, max: ethers.constants.MaxUint256 }, + ], networkSettings.overrides); + await tx.wait(networkSettings.confirmations); + console.log('Added tokens to uwp'); +} + +async function deployUwe() { + if(await isDeployed(UWE_ADDRESS)) { + uwe = (await ethers.getContractAt(artifacts.UnderwritingEquity.abi, UWE_ADDRESS)) as UnderwritingEquity; + } else { + console.log('Deploying UnderwritingEquity'); + const res = await create2Contract(deployer, artifacts.UnderwritingEquity, [signerAddress, uwp.address], {}, "", DEPLOYER_CONTRACT_ADDRESS); + uwe = (await ethers.getContractAt(artifacts.UnderwritingEquity.abi, res.address)) as UnderwritingEquity; + console.log(`Deploying UnderwritingEquity to ${uwe.address}`); + } +} + +async function logAddresses() { + console.log(""); + console.log("| Contract Name | Address |"); + console.log("|------------------------------|----------------------------------------------|"); + logContractAddress("UnderwritingPool", uwp.address); + logContractAddress("UnderwritingEquity", uwe.address); + console.log(''); + logContractAddress("SolaceMegaOracle", solaceMegaOracle.address); + logContractAddress("FluxMegaOracle", fluxMegaOracle.address); + console.log(''); + logContractAddress("USDC", USDC_ADDRESS); + logContractAddress("DAI", DAI_ADDRESS); + logContractAddress("USDT", USDT_ADDRESS); + logContractAddress("FRAX", FRAX_ADDRESS); + logContractAddress("WBTC", WBTC_ADDRESS); + logContractAddress("WETH", WETH_ADDRESS); + logContractAddress("SOLACE", SOLACE_ADDRESS) + logContractAddress("AURORA", AURORA_ADDRESS); + logContractAddress("PLY", PLY_ADDRESS); + logContractAddress("BSTN", BSTN_ADDRESS); + logContractAddress("BBT", BBT_ADDRESS); + logContractAddress("TRI", TRI_ADDRESS); + logContractAddress("VWAVE", VWAVE_ADDRESS); + console.log(''); + logContractAddress("USDC price feed", USDC_PRICE_FEED_ADDRESS); + logContractAddress("BTC price feed", BTC_PRICE_FEED_ADDRESS); + logContractAddress("ETH price feed", ETH_PRICE_FEED_ADDRESS); +} + +main() + .then(() => process.exit(0)) + .catch(error => { + console.error(error); + process.exit(1); + }); diff --git a/scripts/create2Contract.ts b/scripts/create2Contract.ts index 79f88a84..89de2440 100644 --- a/scripts/create2Contract.ts +++ b/scripts/create2Contract.ts @@ -3,7 +3,7 @@ import { deployContract } from "ethereum-waffle"; import { ContractJSON } from "ethereum-waffle/dist/esm/ContractJSON"; import { Contract, BigNumber as BN } from "ethers"; import { keccak256, bufferToHex } from "ethereumjs-util"; -import { readFileSync, writeFileSync } from "fs"; +import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs"; import hardhat from "hardhat"; const { waffle, ethers } = hardhat; @@ -51,9 +51,13 @@ export async function create2Contract(wallet: Signer, factoryOrContractJson: Con } // initializes global variables if not done yet +// and inits stash/ async function _init() { if(initialized) return; artifacts = await import_artifacts(); + if(!existsSync("stash/")) mkdirSync("stash/"); + if(!existsSync("stash/scripts/")) mkdirSync("stash/scripts/"); + if(!existsSync("stash/.gitignore")) writeFileSync("stash/.gitignore", "*"); try { knownHashes = JSON.parse(readFileSync("stash/scripts/knownHashes.json").toString()); } catch(e) {} @@ -67,13 +71,15 @@ async function _initCodeGetter(wallet: Signer, factoryOrContractJson: ContractJS // TODO: intelligently construct the initCode instead of depending on failed transaction let contract; try { - contract = await deployContract(failDeployer, factoryOrContractJson, args, overrideOptions); + contract = await deployContract(failDeployer, factoryOrContractJson, args, {...overrideOptions, gasLimit: 21000}); } catch(e: any) { - if(!e.tx || !e.tx.data) console.error(e); - return e.tx.data; + if(e.tx && e.tx.data) return e.tx.data; + if(e.transaction && e.transaction.data) return e.transaction.data; + console.error(e); } console.log(contract); throw "somehow created the contract"; + return contract.deployTransaction.data; } // test salts until one results in an acceptable address diff --git a/scripts/goerli/deploy-faucet.ts b/scripts/goerli/deploy-faucet.ts index 0994b00b..c2d4c2d9 100644 --- a/scripts/goerli/deploy-faucet.ts +++ b/scripts/goerli/deploy-faucet.ts @@ -29,6 +29,14 @@ const WBTC_ADDRESS = "0xD129f9A01Eb0d41302A2F808e9Ebfd5eB92cE17 const USDT_ADDRESS = "0x92f2F8d238183f678a5652a04EDa83eD7BCfa99e"; const FRAX_ADDRESS = "0xA542486E4Dc48580fFf76B75b5c406C211218AE2"; +const NEAR_ADDRESS = "0x19435895aDC47127AA3151a9bf96dfa74f8b2C33"; +const AURORA_ADDRESS = "0x9727B423892C3BCBEBe9458F4FE5e86A954A0980"; +const PLY_ADDRESS = "0xfdA6cF34193993c28E32340fc7CEf9361e48C7Ac"; +const BSTN_ADDRESS = "0xb191d201073Bb24453419Eb3c1e0B790e6EFA6DF"; +const BBT_ADDRESS = "0xAaF70eE6d386dD0410E2681FA33367f53b3BCc18"; +const TRI_ADDRESS = "0x13fcD385A20496ed729AF787EC109A6aB4B44d75"; +const VWAVE_ADDRESS = "0x5C4Ccc7b2a2bC3E5c009364917fff92d12a08fF4"; + const ONE_ETHER = BN.from("1000000000000000000"); let artifacts: ArtifactImports; @@ -53,8 +61,8 @@ async function main() { solace = (await ethers.getContractAt(artifacts.SOLACE.abi, SOLACE_ADDRESS)) as Solace; //await deployTestnetTokens(); - //await mintTestnetTokens(); - await deployFaucet(); + await mintTestnetTokens(); + //await deployFaucet(); await logAddresses(); } @@ -78,15 +86,24 @@ async function deployFaucet() { } async function deployTestnetTokens() { + /* console.log(`Deploying WETH`); let weth = await deployContract(deployer, artifacts.WETH, [], {...networkSettings.overrides, gasLimit:6000000}); console.log(`Deployed to ${weth.address}`); + */ let tokens: any[] = [ {name: "Dai Stablecoin", symbol: "DAI", supply: ONE_ETHER.mul(1000000), decimals: 18, permit: false}, {name: "USD Coin", symbol: "USDC", supply: BN.from("1000000000"), decimals: 6, permit: true}, {name: "Wrapped Bitcoin", symbol: "WBTC", supply: BN.from("1000000000"), decimals: 8, permit: false}, {name: "USD Token", symbol: "USDT", supply: BN.from("1000000000"), decimals: 6, permit: false}, {name: "Frax", symbol: "FRAX", supply: ONE_ETHER.mul(1000000), decimals: 18, permit: false}, + {name: "NEAR", symbol: "NEAR", supply: 0, decimals: 24, permit: false}, + {name: "Aurora", symbol: "AURORA", supply: ONE_ETHER.mul(1000000), decimals: 18, permit: false}, + {name: "Aurigami Token", symbol: "PLY", supply: ONE_ETHER.mul(1000000), decimals: 18, permit: false}, + {name: "Bastion", symbol: "BSTN", supply: ONE_ETHER.mul(1000000), decimals: 18, permit: false}, + {name: "BlueBit Token", symbol: "BBT", supply: ONE_ETHER.mul(1000000), decimals: 18, permit: false}, + {name: "Trisolaris", symbol: "TRI", supply: ONE_ETHER.mul(1000000), decimals: 18, permit: false}, + {name: "vaporwave.finance", symbol: "VWAVE", supply: ONE_ETHER.mul(1000000), decimals: 18, permit: false}, ]; for(var i = 0; i < tokens.length; ++i) { let token = tokens[i]; @@ -98,18 +115,20 @@ async function deployTestnetTokens() { } async function mintTestnetTokens() { + /* let weth = await ethers.getContractAt(artifacts.WETH.abi, WETH_ADDRESS); console.log('start eth balance'); console.log(await provider.getBalance(signerAddress)); console.log('start weth balance'); console.log(await weth.balanceOf(signerAddress)); console.log('wrapping eth') - let tx1 = await weth.connect(deployer).deposit({...networkSettings.overrides, value: ONE_ETHER.div(1000)}); + let tx1 = await weth.connect(deployer).deposit({...networkSettings.overrides, value: ONE_ETHER}); await tx1.wait(networkSettings.confirmations); console.log('end eth balance'); console.log(await provider.getBalance(signerAddress)); console.log('end weth balance'); console.log(await weth.balanceOf(signerAddress)); + */ let tokens: any[] = [ {name: "Dai Stablecoin", symbol: "DAI", supply: ONE_ETHER.mul(1000000), decimals: 18, permit: false, address: DAI_ADDRESS}, @@ -117,10 +136,27 @@ async function mintTestnetTokens() { {name: "Wrapped Bitcoin", symbol: "WBTC", supply: BN.from("1000000000"), decimals: 8, permit: false, address: WBTC_ADDRESS}, {name: "USD Token", symbol: "USDT", supply: BN.from("1000000000"), decimals: 6, permit: false, address: USDT_ADDRESS}, {name: "Frax", symbol: "FRAX", supply: ONE_ETHER.mul(1000000), decimals: 18, permit: false, address: FRAX_ADDRESS}, + {name: "NEAR", symbol: "NEAR", supply: 0, decimals: 24, permit: false, address: NEAR_ADDRESS}, + {name: "Aurora", symbol: "AURORA", supply: ONE_ETHER.mul(1000000), decimals: 18, permit: false, address: AURORA_ADDRESS}, + {name: "Aurigami Token", symbol: "PLY", supply: ONE_ETHER.mul(1000000), decimals: 18, permit: false, address: PLY_ADDRESS}, + {name: "Bastion", symbol: "BSTN", supply: ONE_ETHER.mul(1000000), decimals: 18, permit: false, address: BSTN_ADDRESS}, + {name: "BlueBit Token", symbol: "BBT", supply: ONE_ETHER.mul(1000000), decimals: 18, permit: false, address: BBT_ADDRESS}, + {name: "Trisolaris", symbol: "TRI", supply: ONE_ETHER.mul(1000000), decimals: 18, permit: false, address: TRI_ADDRESS}, + {name: "vaporwave.finance", symbol: "VWAVE", supply: ONE_ETHER.mul(1000000), decimals: 18, permit: false, address: VWAVE_ADDRESS}, + ]; + let recipients = [ + "0x0fb78424e5021404093aA0cFcf50B176B30a3c1d", + "0x34Bb9e91dC8AC1E13fb42A0e23f7236999e063D4", + "0xc32e0d89e25222abb4d2d68755babf5aa6648f15", + "0x67367Ca1DE9d7Eb10908f646a2a56Bc01B03b406", + "0x8b80755C441d355405CA7571443Bb9247B77Ec16", + "0x8021dA485A6bcD7b5AD20ACDa353A79C912cb12D", + "0x9BEdBBB7B64Ff5e9b4225EE70fdCedCdEc51637D", + signerAddress ]; - let recipients = [signerAddress]; for(var j = 0; j < recipients.length; ++j) { let recipient = recipients[j]; + console.log(`Minting to ${recipient}`); for(var i = 0; i < tokens.length; ++i) { let token = tokens[i]; let artifact = token.permit ? artifacts.MockERC20Permit : artifacts.MockERC20Decimals; @@ -133,15 +169,17 @@ async function mintTestnetTokens() { console.log(`Transferring ${token.symbol}`); let tx2 = await tokenContract.connect(deployer).transfer(recipient, bal2.sub(bal1), networkSettings.overrides); await tx2.wait(networkSettings.confirmations); - console.log(`Checking balance of ${token.symbol}`); - console.log(await tokenContract.balanceOf(recipient)); + console.log(ethers.utils.formatUnits(await tokenContract.balanceOf(recipient), tokens[i].decimals)); } + /* console.log('Minting SOLACE'); let tx3 = await solace.connect(deployer).mint(recipient, ONE_ETHER.mul(1000), networkSettings.overrides); await tx3.wait(networkSettings.confirmations) console.log('Checking balance of SOLACE'); - console.log(await solace.balanceOf(recipient)); + console.log(ethers.utils.formatUnits(await solace.balanceOf(recipient))); + console.log('') + */ } } @@ -150,13 +188,22 @@ async function logAddresses() { console.log("| Contract Name | Address |"); console.log("|------------------------------|----------------------------------------------|"); logContractAddress("SOLACE", solace.address); - logContractAddress("Faucet", faucet.address); logContractAddress("DAI", DAI_ADDRESS); logContractAddress("WETH", WETH_ADDRESS); logContractAddress("USDC", USDC_ADDRESS); logContractAddress("WBTC", WBTC_ADDRESS); logContractAddress("USDT", USDT_ADDRESS); logContractAddress("FRAX", FRAX_ADDRESS); + + logContractAddress("NEAR", NEAR_ADDRESS); + logContractAddress("AURORA", AURORA_ADDRESS); + logContractAddress("PLY", PLY_ADDRESS); + logContractAddress("BSTN", BSTN_ADDRESS); + logContractAddress("BBT", BBT_ADDRESS); + logContractAddress("TRI", TRI_ADDRESS); + logContractAddress("VWAVE", VWAVE_ADDRESS); + + logContractAddress("Faucet", faucet.address); } main() diff --git a/scripts/goerli/deploy-native-locker.ts b/scripts/goerli/deploy-native-locker.ts new file mode 100644 index 00000000..42ac9bfd --- /dev/null +++ b/scripts/goerli/deploy-native-locker.ts @@ -0,0 +1,202 @@ +// Requires following fields in .env + +// AURORA_URL +// AURORA_ACCOUNTS +// AURORASCAN_API_KEY + +// PRIVATE_KEYS +// RINKEBY_ACCOUNTS +// RINKEBY_ALCHEMY_KEY + +import hardhat from "hardhat"; +const { waffle, ethers } = hardhat; +const { provider } = waffle; +const BN = ethers.BigNumber; +const { parseUnits } = ethers.utils +import { config as dotenv_config } from "dotenv"; +dotenv_config(); +const deployer = new ethers.Wallet(JSON.parse(process.env.PRIVATE_KEYS || '[]')[0], provider); + +import { logContractAddress } from "../utils"; + +import { import_artifacts, ArtifactImports } from "../../test/utilities/artifact_importer"; +import { Registry, Erc20, UnderwritingLockVoting, UnderwritingLocker, GaugeController, DepositHelper } from "../../typechain"; +import { expectDeployed, isDeployed } from "../../test/utilities/expectDeployed"; +import { getNetworkSettings } from "../getNetworkSettings"; +import { create2Contract } from "../create2Contract"; +import { formatUnits } from "ethers/lib/utils"; + +const DEPLOYER_CONTRACT_ADDRESS = "0x501aCe4732E4A80CC1bc5cd081BEe7f88ff694EF"; +const REGISTRY_ADDRESS = "0x501ACe0f576fc4ef9C0380AA46A578eA96b85776"; +const UWP_ADDRESS = "0x501ACEb41708De16FbedE3b31f3064919E9d7F23"; +const UWE_ADDRESS = "0x501ACE809013C8916CAAe439e9653bc436172919"; +const REVENUE_ROUTER_ADDRESS = "0x501AcE0e8D16B92236763E2dEd7aE3bc2DFfA276"; +const UNDERWRITING_LOCKER_ADDRESS = "0x501ACeC465fEbc1b1b936Bdc937A9FD28F6E6E7E"; +const GAUGE_CONTROLLER_ADDRESS = "0x501acEB8a1D613D4aa1CD101881174bFAFAF1700"; +const UNDERWRITING_LOCK_VOTING_ADDRESS = "0x501AcE58312fa3EED60fc38Ce0E5562112E72dF0"; +const DEPOSIT_HELPER_ADDRESS = "0x501ACE3b845e959fa9b4C06e71973d9AB13853F3"; +let GOVERNOR_ADDRESS: string; + +let artifacts: ArtifactImports; +let registry: Registry; +let underwritingLocker: UnderwritingLocker; +let voting: UnderwritingLockVoting; +let gaugeController: GaugeController; +let depositHelper: DepositHelper; + +let signerAddress: string; +let networkSettings: any; + +async function main() { + artifacts = await import_artifacts(); + signerAddress = await deployer.getAddress(); + console.log(`Using ${signerAddress} as deployer`); + GOVERNOR_ADDRESS = signerAddress; + + let chainID = (await provider.getNetwork()).chainId; + networkSettings = getNetworkSettings(chainID); + + await expectDeployed(DEPLOYER_CONTRACT_ADDRESS); + await expectDeployed(UWP_ADDRESS); + await expectDeployed(UWE_ADDRESS); + await expectDeployed(REGISTRY_ADDRESS); + + /********************* + DEPLOY SEQUENCE + *********************/ + + registry = (await ethers.getContractAt(artifacts.Registry.abi, REGISTRY_ADDRESS)) as Registry; + + await setRegistry1(); // Set 'uwe' in the registry + await deployUnderwritingLocker(); + await deployGaugeController(); + await setRegistry2(); // Set 'revenueRouter', 'underwritingLocker' and 'gaugeController' in the registry + await deployUnderwritingLockVoting(); + await gaugeSetup(); + await addGauges(); + await deployDepositHelper(); + await setRegistry3(); // Set registry contract + + // log addresses + await logAddresses(); +} + +async function setRegistry1() { + console.log("Setting 'uwe' in the Registry.") + const keys = ["uwe"]; + const values = [UWE_ADDRESS]; + let tx = await registry.connect(deployer).set(keys, values, networkSettings.overrides); + await tx.wait(networkSettings.confirmations); +} + +async function deployUnderwritingLocker() { + if (await isDeployed(UNDERWRITING_LOCKER_ADDRESS)) { + underwritingLocker = (await ethers.getContractAt(artifacts.UnderwritingLocker.abi, UNDERWRITING_LOCKER_ADDRESS)) as UnderwritingLocker; + } else { + console.log("Deploying UnderwritingLocker"); + const res = await create2Contract(deployer, artifacts.UnderwritingLocker, [GOVERNOR_ADDRESS, REGISTRY_ADDRESS], {}, "", DEPLOYER_CONTRACT_ADDRESS); + underwritingLocker = (await ethers.getContractAt(artifacts.UnderwritingLocker.abi, res.address)) as unknown as UnderwritingLocker; + console.log(`Deployed UnderwritingLocker to ${underwritingLocker.address}`); + } +} + +async function deployGaugeController() { + if (await isDeployed(GAUGE_CONTROLLER_ADDRESS)) { + gaugeController = (await ethers.getContractAt(artifacts.GaugeController.abi, GAUGE_CONTROLLER_ADDRESS)) as GaugeController; + } else { + console.log("Deploying GaugeController"); + const res = await create2Contract(deployer, artifacts.GaugeController, [GOVERNOR_ADDRESS, UWE_ADDRESS], {}, "", DEPLOYER_CONTRACT_ADDRESS); + gaugeController = (await ethers.getContractAt(artifacts.GaugeController.abi, res.address)) as unknown as GaugeController; + console.log(`Deployed GaugeController to ${gaugeController.address}`); + } +} + +async function setRegistry2() { + console.log("Setting 'revenueRouter', 'underwritingLocker' and 'gaugeController' in the Registry.") + const keys = ["revenueRouter", "underwritingLocker", "gaugeController"]; + const values = [REVENUE_ROUTER_ADDRESS, underwritingLocker.address, gaugeController.address] + let tx = await registry.connect(deployer).set(keys, values, networkSettings.overrides); + await tx.wait(networkSettings.confirmations); +} + +async function deployUnderwritingLockVoting() { + if (await isDeployed(UNDERWRITING_LOCK_VOTING_ADDRESS)) { + voting = (await ethers.getContractAt(artifacts.UnderwritingLockVoting.abi, UNDERWRITING_LOCK_VOTING_ADDRESS)) as UnderwritingLockVoting; + } else { + console.log("Deploying UnderwritingLockVoting"); + const res = await create2Contract(deployer, artifacts.UnderwritingLockVoting, [GOVERNOR_ADDRESS, REGISTRY_ADDRESS], {}, "", DEPLOYER_CONTRACT_ADDRESS); + voting = (await ethers.getContractAt(artifacts.UnderwritingLockVoting.abi, res.address)) as unknown as UnderwritingLockVoting; + console.log(`Deployed UnderwritingLockVoting to ${voting.address}`); + } +} + +async function gaugeSetup() { + console.log("Adding UnderwritingLocker as $UWE capacity source in GaugeController"); + const tx1 = await gaugeController.connect(deployer).addTokenholder(underwritingLocker.address, networkSettings.overrides); + await tx1.wait(networkSettings.confirmations); + + console.log("Adding UnderwritingLockVoting as vote source in GaugeController"); + const tx2 = await gaugeController.connect(deployer).addVotingContract(voting.address, networkSettings.overrides); + await tx2.wait(networkSettings.confirmations); + + console.log("Adding 'underwritingLockVoting' to the registry"); + const tx3 = await registry.connect(deployer).set(["underwritingLockVoting"], [voting.address], {...networkSettings.overrides, gasLimit: 1000000}); + await tx3.wait(networkSettings.confirmations); + + console.log("Enabling UnderwritingLockVoting to charge premium to UnderwritingLocker"); + const tx4 = await underwritingLocker.connect(deployer).setVotingContract(networkSettings.overrides); + await tx4.wait(networkSettings.confirmations); +} + +async function addGauges() { + console.log("Adding gauges to GaugeController"); + let rol = BN.from(10).pow(18).mul(250).div(10000); // 2.5% + let appIDs = ["aurora-plus", "aurigami", "bastion-protocol", "bluebit", "trisolaris", "vaporwave-finance"]; + let len = (await gaugeController.totalGauges()).toNumber(); + if(len > 0) { + console.log(`${len} gauges already found. skipping`); + return; + } + for(let i = 0; i < appIDs.length; ++i) { + let tx = await gaugeController.connect(deployer).addGauge(appIDs[i], rol, networkSettings.overrides); + await tx.wait(networkSettings.confirmations); + } + console.log("Added gauges to GaugeController"); +} + +async function deployDepositHelper() { + if(await isDeployed(DEPOSIT_HELPER_ADDRESS)) { + depositHelper = (await ethers.getContractAt(artifacts.DepositHelper.abi, DEPOSIT_HELPER_ADDRESS)) as DepositHelper; + } else { + console.log("Deploying DepositHelper"); + const res = await create2Contract(deployer, artifacts.DepositHelper, [UWE_ADDRESS, underwritingLocker.address], {}, "", DEPLOYER_CONTRACT_ADDRESS); + depositHelper = (await ethers.getContractAt(artifacts.DepositHelper.abi, res.address)) as DepositHelper; + console.log(`Deployed DepositHelper to ${depositHelper.address}`); + } +} + +async function setRegistry3() { + console.log("Setting registry"); + let tx1 = await underwritingLocker.connect(deployer).setRegistry(registry.address, networkSettings.overrides); + await tx1.wait(networkSettings.confirmations); + let tx2 = await voting.connect(deployer).setRegistry(registry.address, networkSettings.overrides); + await tx2.wait(networkSettings.confirmations); + console.log("Set registry"); +} + +async function logAddresses() { + console.log(""); + console.log("| Contract Name | Address |"); + console.log("|------------------------------|----------------------------------------------|"); + logContractAddress("UnderwritingLocker", underwritingLocker.address); + logContractAddress("GaugeController", gaugeController.address); + logContractAddress("UnderwritingLockVoting", voting.address); + logContractAddress("DepositHelper", depositHelper.address); +} + +main() + .then(() => process.exit(0)) + .catch(error => { + console.error(error); + process.exit(1); + }); diff --git a/scripts/goerli/deploy-native-uwp.ts b/scripts/goerli/deploy-native-uwp.ts new file mode 100644 index 00000000..ce935856 --- /dev/null +++ b/scripts/goerli/deploy-native-uwp.ts @@ -0,0 +1,238 @@ +// deploys v3 of solace wallet coverage + +import hardhat from "hardhat"; +const { waffle, ethers } = hardhat; +const { provider } = waffle; +const BN = ethers.BigNumber; +import { config as dotenv_config } from "dotenv"; +dotenv_config(); +const deployer = new ethers.Wallet(JSON.parse(process.env.PRIVATE_KEYS || '[]')[0], provider); + +import { logContractAddress } from "./../utils"; + +import { import_artifacts, ArtifactImports } from "./../../test/utilities/artifact_importer"; +import { SolaceMegaOracle, FluxMegaOracle, UnderwritingPool, UnderwritingEquity, MockErc20 } from "../../typechain"; +import { expectDeployed, isDeployed } from "../../test/utilities/expectDeployed"; +import { getNetworkSettings } from "../getNetworkSettings"; +import { create2Contract } from "../create2Contract"; + +const DEPLOYER_CONTRACT_ADDRESS = "0x501aCe4732E4A80CC1bc5cd081BEe7f88ff694EF"; + +// price feed addresses +const USDC_PRICE_FEED_ADDRESS = "0xB61119a7349494b694be8C0e1580C1CFCD55753f"; +const BTC_PRICE_FEED_ADDRESS = "0x887e7e9097d7d2AB44ba31dE0C022040Fb26FC9D"; +const ETH_PRICE_FEED_ADDRESS = "0xEB3DA77d163055634335aA65F29e612BeaBf4391"; + +// token addresses +const USDC_ADDRESS = "0x995714E92a094Ea9b50e9F23934C36F86136A46c"; +const DAI_ADDRESS = "0x6a49238e4d0fA003BA07fbd5ec8B6b045f980574"; +const USDT_ADDRESS = "0x92f2F8d238183f678a5652a04EDa83eD7BCfa99e"; +const FRAX_ADDRESS = "0xA542486E4Dc48580fFf76B75b5c406C211218AE2"; +const WBTC_ADDRESS = "0xD129f9A01Eb0d41302A2F808e9Ebfd5eB92cE17C"; +const WETH_ADDRESS = "0x714ECD380a9700086eadAc03297027bAf4686276"; +const NEAR_ADDRESS = "0x19435895aDC47127AA3151a9bf96dfa74f8b2C33"; +const SOLACE_ADDRESS = "0x501acE9c35E60f03A2af4d484f49F9B1EFde9f40"; +const AURORA_ADDRESS = "0x9727B423892C3BCBEBe9458F4FE5e86A954A0980"; +const PLY_ADDRESS = "0xfdA6cF34193993c28E32340fc7CEf9361e48C7Ac"; +const BSTN_ADDRESS = "0xb191d201073Bb24453419Eb3c1e0B790e6EFA6DF"; +const BBT_ADDRESS = "0xAaF70eE6d386dD0410E2681FA33367f53b3BCc18"; +const TRI_ADDRESS = "0x13fcD385A20496ed729AF787EC109A6aB4B44d75"; +const VWAVE_ADDRESS = "0x5C4Ccc7b2a2bC3E5c009364917fff92d12a08fF4"; + +// contract addresses +const SOLACE_MEGA_ORACLE_ADDRESS = "0x501acE1701111C26Ac718952EEFB3698bDCe70Cf"; +const FLUX_MEGA_ORACLE_ADDRESS = "0x501AcEd36232595b46A1Fb03cCF3cE5e056d5F13"; +const UWP_ADDRESS = "0x501ACEb41708De16FbedE3b31f3064919E9d7F23"; +const UWE_ADDRESS = "0x501ACE809013C8916CAAe439e9653bc436172919"; + +let artifacts: ArtifactImports; + +let solaceMegaOracle: SolaceMegaOracle; +let fluxMegaOracle: FluxMegaOracle; +let uwp: UnderwritingPool; +let uwe: UnderwritingEquity; + +let signerAddress: string; +let networkSettings: any; + +async function main() { + artifacts = await import_artifacts(); + signerAddress = await deployer.getAddress(); + console.log(`Using ${signerAddress} as deployer and governor`); + + let chainID = (await provider.getNetwork()).chainId; + networkSettings = getNetworkSettings(chainID); + + await expectDeployed(DEPLOYER_CONTRACT_ADDRESS); + await expectDeployed(USDC_PRICE_FEED_ADDRESS); + await expectDeployed(BTC_PRICE_FEED_ADDRESS); + await expectDeployed(ETH_PRICE_FEED_ADDRESS); + await expectDeployed(USDC_ADDRESS); + await expectDeployed(DAI_ADDRESS); + await expectDeployed(USDT_ADDRESS); + await expectDeployed(FRAX_ADDRESS); + await expectDeployed(WBTC_ADDRESS); + await expectDeployed(WETH_ADDRESS); + await expectDeployed(NEAR_ADDRESS); + await expectDeployed(SOLACE_ADDRESS); + await expectDeployed(AURORA_ADDRESS); + await expectDeployed(PLY_ADDRESS); + await expectDeployed(BSTN_ADDRESS); + await expectDeployed(BBT_ADDRESS); + await expectDeployed(TRI_ADDRESS); + await expectDeployed(VWAVE_ADDRESS); + + // deploy and configure contracts + // SolaceMegaOracle + await deploySolaceMegaOracle(); + //await configureSolaceMegaOracle(); + // FluxMegaOracle + await deployFluxMegaOracle(); + //await configureFluxMegaOracle(); + // uwp + await deployUwp(); + //await configureUwp(); + // uwe + await deployUwe(); + + // log addresses + await logAddresses(); +} + +async function deploySolaceMegaOracle() { + if(await isDeployed(SOLACE_MEGA_ORACLE_ADDRESS)) { + solaceMegaOracle = (await ethers.getContractAt(artifacts.SolaceMegaOracle.abi, SOLACE_MEGA_ORACLE_ADDRESS)) as SolaceMegaOracle; + } else { + console.log("Deploying SolaceMegaOracle"); + const res = await create2Contract(deployer, artifacts.SolaceMegaOracle, [signerAddress], {}, "", DEPLOYER_CONTRACT_ADDRESS); + solaceMegaOracle = (await ethers.getContractAt(artifacts.SolaceMegaOracle.abi, res.address)) as SolaceMegaOracle; + console.log(`Deployed SolaceMegaOracle to ${solaceMegaOracle.address}`); + } +} + +async function configureSolaceMegaOracle() { + console.log('Adding updater to SolaceMegaOracle'); + let tx1 = await solaceMegaOracle.connect(deployer).setUpdaterStatuses([deployer.address], [true], networkSettings.overrides); + await tx1.wait(networkSettings.confirmations); + console.log('Added updater to SolaceMegaOracle'); + + console.log('Adding price feeds to SolaceMegaOracle'); + let tx = await solaceMegaOracle.connect(deployer).addPriceFeeds([ + { token: NEAR_ADDRESS, latestPrice: 0, tokenDecimals: 24, priceFeedDecimals: 18 }, + { token: SOLACE_ADDRESS, latestPrice: 0, tokenDecimals: 18, priceFeedDecimals: 18 }, + { token: AURORA_ADDRESS, latestPrice: 0, tokenDecimals: 18, priceFeedDecimals: 18 }, + { token: PLY_ADDRESS, latestPrice: 0, tokenDecimals: 18, priceFeedDecimals: 18 }, + { token: BSTN_ADDRESS, latestPrice: 0, tokenDecimals: 18, priceFeedDecimals: 18 }, + { token: BBT_ADDRESS, latestPrice: 0, tokenDecimals: 18, priceFeedDecimals: 18 }, + { token: TRI_ADDRESS, latestPrice: 0, tokenDecimals: 18, priceFeedDecimals: 18 }, + { token: VWAVE_ADDRESS, latestPrice: 0, tokenDecimals: 18, priceFeedDecimals: 18 }, + ], networkSettings.overrides); + await tx.wait(networkSettings.confirmations); + console.log('Added price feeds to SolaceMegaOracle'); +} + +async function deployFluxMegaOracle() { + if(await isDeployed(FLUX_MEGA_ORACLE_ADDRESS)) { + fluxMegaOracle = (await ethers.getContractAt(artifacts.FluxMegaOracle.abi, FLUX_MEGA_ORACLE_ADDRESS)) as FluxMegaOracle; + } else { + console.log("Deploying FluxMegaOracle"); + const res = await create2Contract(deployer, artifacts.FluxMegaOracle, [signerAddress], {}, "", DEPLOYER_CONTRACT_ADDRESS); + fluxMegaOracle = (await ethers.getContractAt(artifacts.FluxMegaOracle.abi, res.address)) as FluxMegaOracle; + console.log(`Deployed FluxMegaOracle to ${fluxMegaOracle.address}`); + } +} + +async function configureFluxMegaOracle() { + console.log('Adding price feeds to FluxMegaOracle'); + let tx = await fluxMegaOracle.connect(deployer).addPriceFeeds([ + { token: USDC_ADDRESS, priceFeed: USDC_PRICE_FEED_ADDRESS, tokenDecimals: 6, priceFeedDecimals: 8 }, + { token: DAI_ADDRESS, priceFeed: USDC_PRICE_FEED_ADDRESS, tokenDecimals: 18, priceFeedDecimals: 8 }, + { token: USDT_ADDRESS, priceFeed: USDC_PRICE_FEED_ADDRESS, tokenDecimals: 6, priceFeedDecimals: 8 }, + { token: FRAX_ADDRESS, priceFeed: USDC_PRICE_FEED_ADDRESS, tokenDecimals: 18, priceFeedDecimals: 8 }, + { token: WBTC_ADDRESS, priceFeed: BTC_PRICE_FEED_ADDRESS, tokenDecimals: 8, priceFeedDecimals: 8 }, + { token: WETH_ADDRESS, priceFeed: ETH_PRICE_FEED_ADDRESS, tokenDecimals: 18, priceFeedDecimals: 8 }, + ], networkSettings.overrides); + await tx.wait(networkSettings.confirmations); + console.log('Added price feeds to FluxMegaOracle'); +} + +async function deployUwp() { + if(await isDeployed(UWP_ADDRESS)) { + uwp = (await ethers.getContractAt(artifacts.UnderwritingPool.abi, UWP_ADDRESS)) as UnderwritingPool; + } else { + console.log('Deploying UnderwritingPool'); + const res = await create2Contract(deployer, artifacts.UnderwritingPool, [signerAddress], {}, "", DEPLOYER_CONTRACT_ADDRESS); + uwp = (await ethers.getContractAt(artifacts.UnderwritingPool.abi, res.address)) as UnderwritingPool; + console.log(`Deploying UnderwritingPool to ${uwp.address}`); + } +} + +async function configureUwp() { + console.log('Adding tokens to uwp'); + let tx = await uwp.connect(deployer).addTokensToPool([ + { token: USDC_ADDRESS, oracle: fluxMegaOracle.address, min: 0, max: ethers.constants.MaxUint256 }, + { token: DAI_ADDRESS, oracle: fluxMegaOracle.address, min: 0, max: ethers.constants.MaxUint256 }, + { token: USDT_ADDRESS, oracle: fluxMegaOracle.address, min: 0, max: ethers.constants.MaxUint256 }, + { token: FRAX_ADDRESS, oracle: fluxMegaOracle.address, min: 0, max: ethers.constants.MaxUint256 }, + { token: WBTC_ADDRESS, oracle: fluxMegaOracle.address, min: 0, max: ethers.constants.MaxUint256 }, + { token: WETH_ADDRESS, oracle: fluxMegaOracle.address, min: 0, max: ethers.constants.MaxUint256 }, + { token: NEAR_ADDRESS, oracle: solaceMegaOracle.address, min: 0, max: ethers.constants.MaxUint256 }, + { token: SOLACE_ADDRESS, oracle: solaceMegaOracle.address, min: 0, max: ethers.constants.MaxUint256 }, + { token: AURORA_ADDRESS, oracle: solaceMegaOracle.address, min: 0, max: ethers.constants.MaxUint256 }, + { token: PLY_ADDRESS, oracle: solaceMegaOracle.address, min: 0, max: ethers.constants.MaxUint256 }, + { token: BSTN_ADDRESS, oracle: solaceMegaOracle.address, min: 0, max: ethers.constants.MaxUint256 }, + { token: BBT_ADDRESS, oracle: solaceMegaOracle.address, min: 0, max: ethers.constants.MaxUint256 }, + { token: TRI_ADDRESS, oracle: solaceMegaOracle.address, min: 0, max: ethers.constants.MaxUint256 }, + { token: VWAVE_ADDRESS, oracle: solaceMegaOracle.address, min: 0, max: ethers.constants.MaxUint256 }, + ], networkSettings.overrides); + await tx.wait(networkSettings.confirmations); + console.log('Added tokens to uwp'); +} + +async function deployUwe() { + if(await isDeployed(UWE_ADDRESS)) { + uwe = (await ethers.getContractAt(artifacts.UnderwritingEquity.abi, UWE_ADDRESS)) as UnderwritingEquity; + } else { + console.log('Deploying UnderwritingEquity'); + const res = await create2Contract(deployer, artifacts.UnderwritingEquity, [signerAddress, uwp.address], {}, "", DEPLOYER_CONTRACT_ADDRESS); + uwe = (await ethers.getContractAt(artifacts.UnderwritingEquity.abi, res.address)) as UnderwritingEquity; + console.log(`Deploying UnderwritingEquity to ${uwe.address}`); + } +} + +async function logAddresses() { + console.log(""); + console.log("| Contract Name | Address |"); + console.log("|------------------------------|----------------------------------------------|"); + logContractAddress("UnderwritingPool", uwp.address); + logContractAddress("UnderwritingEquity", uwe.address); + console.log(''); + logContractAddress("SolaceMegaOracle", solaceMegaOracle.address); + logContractAddress("FluxMegaOracle", fluxMegaOracle.address); + console.log(''); + logContractAddress("USDC", USDC_ADDRESS); + logContractAddress("DAI", DAI_ADDRESS); + logContractAddress("USDT", USDT_ADDRESS); + logContractAddress("FRAX", FRAX_ADDRESS); + logContractAddress("WBTC", WBTC_ADDRESS); + logContractAddress("WETH", WETH_ADDRESS); + logContractAddress("NEAR", NEAR_ADDRESS); + logContractAddress("SOLACE", SOLACE_ADDRESS) + logContractAddress("AURORA", AURORA_ADDRESS); + logContractAddress("PLY", PLY_ADDRESS); + logContractAddress("BSTN", BSTN_ADDRESS); + logContractAddress("BBT", BBT_ADDRESS); + logContractAddress("TRI", TRI_ADDRESS); + logContractAddress("VWAVE", VWAVE_ADDRESS); + console.log(''); + logContractAddress("USDC price feed", USDC_PRICE_FEED_ADDRESS); + logContractAddress("BTC price feed", BTC_PRICE_FEED_ADDRESS); + logContractAddress("ETH price feed", ETH_PRICE_FEED_ADDRESS); +} + +main() + .then(() => process.exit(0)) + .catch(error => { + console.error(error); + process.exit(1); + }); diff --git a/scripts/goerli/deploy-registry.ts b/scripts/goerli/deploy-registry.ts index 6d53ceda..3f38c95f 100644 --- a/scripts/goerli/deploy-registry.ts +++ b/scripts/goerli/deploy-registry.ts @@ -84,6 +84,12 @@ async function registerAddresses() { "scp" : "0x501ACE72166956F57b44dbBcc531A8E741449997", "coverPaymentManager" : "0x501acE7a18b0F59E51eb198cD73480F8467DE100", "solaceCoverProduct" : "0x501ACeB72d62C9875825b71d9f78a27780B5624d", + // native + "uwe" : "0x501ACEF0d60A70F3bc1bFE090a3d51ca10757aaE", + "revenueRouter" : "0x501AcE0e8D16B92236763E2dEd7aE3bc2DFfA276", + "underwritingLocker" : "0x501ACed0A3cC374E470BF10cbB625AE774A20d75", + "gaugeController" : "0x501ACE3c9C22Ec7AE3c84D1863dE5AD3cb9760B1", + "underwritingLockVoting" : "0x501ACED282C623D53602cE29c3Ae8A22683843C2", } // set default addresses diff --git a/scripts/goerli/use-native.ts b/scripts/goerli/use-native.ts new file mode 100644 index 00000000..76f41616 --- /dev/null +++ b/scripts/goerli/use-native.ts @@ -0,0 +1,392 @@ +// deploys v3 of solace wallet coverage + +import hardhat from "hardhat"; +const { waffle, ethers } = hardhat; +const { provider } = waffle; +const BN = ethers.BigNumber; +import { config as dotenv_config } from "dotenv"; +dotenv_config(); +const deployer = new ethers.Wallet(JSON.parse(process.env.PRIVATE_KEYS || '[]')[0], provider); + +import { logContractAddress } from "./../utils"; + +import { import_artifacts, ArtifactImports } from "./../../test/utilities/artifact_importer"; +import { SolaceMegaOracle, FluxMegaOracle, UnderwritingPool, UnderwritingEquity, UnderwritingLockVoting, UnderwritingLocker, GaugeController, MockErc20, DepositHelper } from "../../typechain"; +import { expectDeployed, isDeployed } from "../../test/utilities/expectDeployed"; +import { getNetworkSettings } from "../getNetworkSettings"; +import { create2Contract } from "../create2Contract"; + +const DEPLOYER_CONTRACT_ADDRESS = "0x501aCe4732E4A80CC1bc5cd081BEe7f88ff694EF"; + +// price feed addresses +const USDC_PRICE_FEED_ADDRESS = "0xB61119a7349494b694be8C0e1580C1CFCD55753f"; +const BTC_PRICE_FEED_ADDRESS = "0x887e7e9097d7d2AB44ba31dE0C022040Fb26FC9D"; +const ETH_PRICE_FEED_ADDRESS = "0xEB3DA77d163055634335aA65F29e612BeaBf4391"; + +// token addresses +const USDC_ADDRESS = "0x995714E92a094Ea9b50e9F23934C36F86136A46c"; +const DAI_ADDRESS = "0x6a49238e4d0fA003BA07fbd5ec8B6b045f980574"; +const USDT_ADDRESS = "0x92f2F8d238183f678a5652a04EDa83eD7BCfa99e"; +const FRAX_ADDRESS = "0xA542486E4Dc48580fFf76B75b5c406C211218AE2"; +const WBTC_ADDRESS = "0xD129f9A01Eb0d41302A2F808e9Ebfd5eB92cE17C"; +const WETH_ADDRESS = "0x714ECD380a9700086eadAc03297027bAf4686276"; +const NEAR_ADDRESS = "0x19435895aDC47127AA3151a9bf96dfa74f8b2C33"; +const SOLACE_ADDRESS = "0x501acE9c35E60f03A2af4d484f49F9B1EFde9f40"; +const AURORA_ADDRESS = "0x9727B423892C3BCBEBe9458F4FE5e86A954A0980"; +const PLY_ADDRESS = "0xfdA6cF34193993c28E32340fc7CEf9361e48C7Ac"; +const BSTN_ADDRESS = "0xb191d201073Bb24453419Eb3c1e0B790e6EFA6DF"; +const BBT_ADDRESS = "0xAaF70eE6d386dD0410E2681FA33367f53b3BCc18"; +const TRI_ADDRESS = "0x13fcD385A20496ed729AF787EC109A6aB4B44d75"; +const VWAVE_ADDRESS = "0x5C4Ccc7b2a2bC3E5c009364917fff92d12a08fF4"; + +// contract addresses +const SOLACE_MEGA_ORACLE_ADDRESS = "0x501acE1701111C26Ac718952EEFB3698bDCe70Cf"; +const FLUX_MEGA_ORACLE_ADDRESS = "0x501AcEd36232595b46A1Fb03cCF3cE5e056d5F13"; +const UWP_ADDRESS = "0x501ACEb41708De16FbedE3b31f3064919E9d7F23"; +const UWE_ADDRESS = "0x501ACE809013C8916CAAe439e9653bc436172919"; +const REVENUE_ROUTER_ADDRESS = "0x501AcE0e8D16B92236763E2dEd7aE3bc2DFfA276"; +const UNDERWRITING_LOCKER_ADDRESS = "0x501ACeC465fEbc1b1b936Bdc937A9FD28F6E6E7E"; +const GAUGE_CONTROLLER_ADDRESS = "0x501acEB8a1D613D4aa1CD101881174bFAFAF1700"; +const UNDERWRITING_LOCK_VOTING_ADDRESS = "0x501AcE58312fa3EED60fc38Ce0E5562112E72dF0"; +const DEPOSIT_HELPER_ADDRESS = "0x501ACE3b845e959fa9b4C06e71973d9AB13853F3"; + + +const ONE_USDC = BN.from("1000000"); +const ONE_ETHER = BN.from("1000000000000000000"); +const ONE_NEAR = BN.from("1000000000000000000000000"); +const ONE_WBTC = BN.from("100000000"); + +let artifacts: ArtifactImports; + +let solaceMegaOracle: SolaceMegaOracle; +let fluxMegaOracle: FluxMegaOracle; +let uwp: UnderwritingPool; +let uwe: UnderwritingEquity; +let underwritingLocker: UnderwritingLocker; +let underwritingLockVoting: UnderwritingLockVoting; +let gaugeController: GaugeController; +let depositHelper: DepositHelper; + +let signerAddress: string; +let networkSettings: any; + +async function main() { + artifacts = await import_artifacts(); + signerAddress = await deployer.getAddress(); + console.log(`Using ${signerAddress} as deployer and governor`); + + let chainID = (await provider.getNetwork()).chainId; + networkSettings = getNetworkSettings(chainID); + + await expectDeployed(DEPLOYER_CONTRACT_ADDRESS); + await expectDeployed(USDC_PRICE_FEED_ADDRESS); + await expectDeployed(BTC_PRICE_FEED_ADDRESS); + await expectDeployed(ETH_PRICE_FEED_ADDRESS); + await expectDeployed(USDC_ADDRESS); + await expectDeployed(DAI_ADDRESS); + await expectDeployed(USDT_ADDRESS); + await expectDeployed(FRAX_ADDRESS); + await expectDeployed(WBTC_ADDRESS); + await expectDeployed(WETH_ADDRESS); + await expectDeployed(NEAR_ADDRESS); + await expectDeployed(SOLACE_ADDRESS); + await expectDeployed(AURORA_ADDRESS); + await expectDeployed(PLY_ADDRESS); + await expectDeployed(BSTN_ADDRESS); + await expectDeployed(BBT_ADDRESS); + await expectDeployed(TRI_ADDRESS); + await expectDeployed(VWAVE_ADDRESS); + + await expectDeployed(SOLACE_MEGA_ORACLE_ADDRESS); + await expectDeployed(FLUX_MEGA_ORACLE_ADDRESS); + await expectDeployed(UWP_ADDRESS); + await expectDeployed(UWE_ADDRESS); + await expectDeployed(UNDERWRITING_LOCKER_ADDRESS); + await expectDeployed(UNDERWRITING_LOCK_VOTING_ADDRESS); + await expectDeployed(GAUGE_CONTROLLER_ADDRESS); + await expectDeployed(DEPOSIT_HELPER_ADDRESS); + + solaceMegaOracle = (await ethers.getContractAt(artifacts.SolaceMegaOracle.abi, SOLACE_MEGA_ORACLE_ADDRESS)) as SolaceMegaOracle; + fluxMegaOracle = (await ethers.getContractAt(artifacts.FluxMegaOracle.abi, FLUX_MEGA_ORACLE_ADDRESS)) as FluxMegaOracle; + uwp = (await ethers.getContractAt(artifacts.UnderwritingPool.abi, UWP_ADDRESS)) as UnderwritingPool; + uwe = (await ethers.getContractAt(artifacts.UnderwritingEquity.abi, UWE_ADDRESS)) as UnderwritingEquity; + underwritingLocker = (await ethers.getContractAt(artifacts.UnderwritingLocker.abi, UNDERWRITING_LOCKER_ADDRESS)) as UnderwritingLocker; + gaugeController = (await ethers.getContractAt(artifacts.GaugeController.abi, GAUGE_CONTROLLER_ADDRESS)) as GaugeController; + underwritingLockVoting = (await ethers.getContractAt(artifacts.UnderwritingLockVoting.abi, UNDERWRITING_LOCK_VOTING_ADDRESS)) as UnderwritingLockVoting; + depositHelper = (await ethers.getContractAt(artifacts.DepositHelper.abi, DEPOSIT_HELPER_ADDRESS)) as DepositHelper; + + //await depositIntoUwp(); + //await depositIntoUwe(); + //await useDepositHelper(); + //await withdrawFromLocks(); + //await withdrawFromUwe(); + //await redeemFromUwp(); + + await setPriceFeeds(); + await getUwpTokens(); + //await getGauges(); + //await rolloverEpoch(); + //await castVote(); + //await getEpochTimestamps(); +} + +async function depositIntoUwp() { + let usdc = (await ethers.getContractAt(artifacts.MockERC20.abi, USDC_ADDRESS)) as MockErc20; + let wbtc = (await ethers.getContractAt(artifacts.MockERC20.abi, WBTC_ADDRESS)) as MockErc20; + let weth = (await ethers.getContractAt(artifacts.MockERC20.abi, WETH_ADDRESS)) as MockErc20; + + console.log("Depositing tokens into UWP"); + let tokens = [usdc, wbtc, weth]; + let tokenAddresses = [usdc.address, wbtc.address, weth.address]; + let symbols = ["USDC", "WBTC", "WETH"]; + let depositAmounts = [ONE_USDC.mul(100), ONE_WBTC.div(100), ONE_ETHER.div(10)]; + for(var i = 0; i < tokens.length; ++i) { + if((await tokens[i].allowance(signerAddress, uwp.address)).lt(depositAmounts[i])) { + let tx = await tokens[i].connect(deployer).approve(uwp.address, ethers.constants.MaxUint256, networkSettings.overrides); + await tx.wait(networkSettings.confirmations); + } + let bal = await tokens[i].balanceOf(signerAddress); + if(bal.lt(depositAmounts[i])) { + console.log(`insufficient ${symbols[i]} balance. depositing ${ethers.utils.formatUnits(depositAmounts[i])} have ${ethers.utils.formatUnits(bal)}`); + } + } + let bal1 = await uwp.balanceOf(signerAddress); + console.log(`uwp balance before : ${ethers.utils.formatUnits(bal1)}`); + let tx2 = await uwp.connect(deployer).issue(tokenAddresses, depositAmounts, signerAddress, networkSettings.overrides); + await tx2.wait(networkSettings.confirmations); + let bal2 = await uwp.balanceOf(signerAddress); + console.log(`uwp balance after : ${ethers.utils.formatUnits(bal2)}`); + console.log("Deposited tokens into UWP"); +} + +async function redeemFromUwp() { + console.log("Redeeming UWP"); + let bal = await uwp.balanceOf(signerAddress); + let tx = await uwp.connect(deployer).redeem(bal, signerAddress, networkSettings.overrides); + await tx.wait(networkSettings.confirmations); + console.log("Redeemed UWP"); +} + +async function depositIntoUwe() { + console.log("Depositing UWP into UWE"); + let bal = await uwp.balanceOf(signerAddress); + let allowance = await uwp.allowance(signerAddress, uwe.address); + if(allowance.lt(bal)) { + let tx1 = await uwp.connect(deployer).approve(uwe.address, ethers.constants.MaxUint256, networkSettings.overrides); + await tx1.wait(networkSettings.confirmations); + } + let bal1 = await uwe.balanceOf(signerAddress); + console.log(`uwe balance before : ${ethers.utils.formatUnits(bal1)}`); + console.log(`depositing ${ethers.utils.formatUnits(bal)} uwp`) + let tx2 = await uwe.connect(deployer).deposit(bal, signerAddress, networkSettings.overrides); + await tx2.wait(networkSettings.confirmations); + let bal2 = await uwe.balanceOf(signerAddress); + console.log(`uwe balance after : ${ethers.utils.formatUnits(bal2)}`); + console.log("Deposited UWP into UWE"); +} + +async function useDepositHelper() { + console.log("Depositing into new lock via DepositHelper"); + let tkn = (await ethers.getContractAt(artifacts.MockERC20.abi, DAI_ADDRESS)) as MockErc20; + let dec = 18; + let depositAmount = ONE_ETHER.mul(1000); + let bal = await tkn.balanceOf(signerAddress); + if(bal.lt(depositAmount)) { + console.log(`insufficient balance. depositing ${ethers.utils.formatUnits(depositAmount,dec)} have ${ethers.utils.formatUnits(bal,dec)}`); + return; + } + let allowance = await tkn.allowance(signerAddress, depositHelper.address); + if(allowance.lt(depositAmount)) { + let tx1 = await tkn.connect(deployer).approve(depositHelper.address, ethers.constants.MaxUint256, networkSettings.overrides); + await tx1.wait(networkSettings.confirmations); + } + let expiry = (await provider.getBlock('latest')).timestamp + 60*60*24*365*4; // 4 years from now + let tx2 = await depositHelper.connect(deployer).depositAndLock(tkn.address, depositAmount, expiry, networkSettings.overrides); + await tx2.wait(networkSettings.confirmations); + let bal2 = await underwritingLocker.balanceOf(signerAddress); + let lockID = await underwritingLocker.tokenOfOwnerByIndex(signerAddress, bal2.sub(1)); + let lock = await underwritingLocker.locks(lockID); + console.log(`created lockID=${lockID.toNumber()}. uwe=${ethers.utils.formatUnits(lock.amount)} expiry=${lock.end}`); + console.log("Deposited into new lock via DepositHelper"); +} + +async function withdrawFromLocks() { + console.log("Withdrawing from locks"); + let bal = (await underwritingLocker.balanceOf(signerAddress)).toNumber(); + let lockIDs = []; + for(let i = 0; i < bal; ++i) { + lockIDs.push((await underwritingLocker.tokenOfOwnerByIndex(signerAddress, i)).toNumber()); + } + console.log(`signer has ${bal} locks: ${lockIDs}`); + console.log(`starting uwe balance: ${ethers.utils.formatUnits(await uwe.balanceOf(signerAddress))}`) + for(let i = 0; i < bal; ++i) { + let lockID = lockIDs[i]; + let lock = await underwritingLocker.locks(lockID); + let amountOut = await underwritingLocker.getWithdrawAmount(lockID); + console.log(`withdrawing from lock ${lockID}. uwe=${ethers.utils.formatUnits(lock.amount)} end=${(new Date(lock.end.toNumber()*1000)).toUTCString()} amountOut=${ethers.utils.formatUnits(amountOut)}`); + let tx = await underwritingLocker.connect(deployer).withdraw(lockID, signerAddress, {...networkSettings.overrides, gasLimit:300000}); + await tx.wait(networkSettings.confirmations); + } + console.log(`end uwe balance: ${ethers.utils.formatUnits(await uwe.balanceOf(signerAddress))}`) + console.log("Withdrew from locks"); +} + +async function withdrawFromUwe() { + console.log("Redeeming UWE"); + let bal1p = await uwp.balanceOf(signerAddress); + let bal1e = await uwe.balanceOf(signerAddress); + console.log('before'); + console.log(`uwp balance: ${ethers.utils.formatUnits(bal1p)}`) + console.log(`uwe balance: ${ethers.utils.formatUnits(bal1e)}`) + let tx = await uwe.connect(deployer).withdraw(bal1e, signerAddress, networkSettings.overrides); + await tx.wait(networkSettings.confirmations); + let bal2p = await uwp.balanceOf(signerAddress); + let bal2e = await uwe.balanceOf(signerAddress); + console.log('after'); + console.log(`uwp balance: ${ethers.utils.formatUnits(bal2p)}`) + console.log(`uwe balance: ${ethers.utils.formatUnits(bal2e)}`) + console.log("Redeemed UWE"); +} + +async function setPriceFeeds() { + console.log('Setting prices in SolaceMegaOracle'); + let tx = await solaceMegaOracle.connect(deployer).transmit( + [NEAR_ADDRESS, SOLACE_ADDRESS, AURORA_ADDRESS, PLY_ADDRESS, BSTN_ADDRESS, BBT_ADDRESS, TRI_ADDRESS, VWAVE_ADDRESS], + [ONE_ETHER.mul(4), ONE_ETHER.mul(120).div(10000), ONE_ETHER.mul(14000).div(10000), ONE_ETHER.mul(16).div(10000), ONE_ETHER.mul(36).div(10000), ONE_ETHER.mul(9).div(10000), ONE_ETHER.mul(317).div(10000), ONE_ETHER.mul(223697).div(10000)], + networkSettings.overrides); + await tx.wait(networkSettings.confirmations); + console.log('Set prices in SolaceMegaOracle'); +} + +async function getUwpTokens() { + let len = (await uwp.tokensLength()).toNumber(); + let tokenData = []; + let tokenMetadata = []; + let oracleData = []; + for(let tokenID = 0; tokenID < len; ++tokenID) { + let data = await uwp.tokenList(tokenID); + tokenData.push(data); + let token = (await ethers.getContractAt(artifacts.MockERC20.abi, data.token)) as MockErc20; + let metadata = await Promise.all([ + token.name(), + token.symbol(), + token.decimals(), + token.balanceOf(uwp.address), + ]) + tokenMetadata.push(metadata); + let oracle2 = (await ethers.getContractAt(artifacts.FluxMegaOracle.abi, data.oracle)) as FluxMegaOracle; + oracleData.push(await Promise.all([ + oracle2.valueOfTokens(data.token, BN.from(10).pow(metadata[2])), // one token + oracle2.valueOfTokens(data.token, metadata[3]), // balance + ])); + } + console.log("| Name | Symbol | Decimals | Price | Balance | Value |"); + console.log("----------------------------------------------------------------------------------------"); + for(let tokenID = 0; tokenID < len; ++tokenID) { + console.log(`| ${leftPad(tokenMetadata[tokenID][0],17)} | ${leftPad(tokenMetadata[tokenID][1],6)} | ${leftPad(`${tokenMetadata[tokenID][2]}`,8)} | ${leftPad(ethers.utils.formatUnits(oracleData[tokenID][0]),15)} | ${leftPad(ethers.utils.formatUnits(tokenMetadata[tokenID][3],tokenMetadata[tokenID][2]),8)} | ${leftPad(ethers.utils.formatUnits(oracleData[tokenID][1]),15)} |`) + } +} + +async function getGauges() { + let len = (await gaugeController.totalGauges()).toNumber(); + let gauges = []; + for(let gaugeID = 1; gaugeID <= len; ++gaugeID) { + gauges.push(await Promise.all([ + gaugeController.getGaugeName(gaugeID), + gaugeController.isGaugeActive(gaugeID), + gaugeController.getRateOnLineOfGauge(gaugeID), + ])); + } + //let header = formatLine(['Gauge Name', 'Status', 'ROL']) + console.log("| Gauge ID | Gauge Name | Status | ROL |"); + console.log("----------------------------------------------------"); + for(let i = 0; i < len; ++i) { + let gauge = gauges[i]; + let gaugeID = `${i+1}` + console.log(`| ${leftPad(gaugeID,8)} | ${leftPad(gauge[0],18)} | ${leftPad(gauge[1]?'active':'inactive',8)} | ${ethers.utils.formatUnits(gauge[2])} |`); + } +} + +async function rolloverEpoch() { + console.log("Rolling over to next epoch"); + const EPOCH_START_TIME = await gaugeController.getEpochStartTimestamp(); + + while (!( EPOCH_START_TIME.eq(await gaugeController.lastTimeGaugeWeightsUpdated()) )) { + console.log("Rolling over gauge controller"); + const tx = await gaugeController.connect(deployer).updateGaugeWeights({...networkSettings.overrides, gasLimit: 6000000}) + await tx.wait(networkSettings.confirmations) + } + + while (!( EPOCH_START_TIME.eq(await underwritingLockVoting.lastTimePremiumsCharged()) )) { + console.log("Rolling over voting"); + const tx = await underwritingLockVoting.connect(deployer).chargePremiums({...networkSettings.overrides, gasLimit: 6000000}) + await tx.wait(networkSettings.confirmations) + } + console.log("Rolled over to next epoch"); +} + +async function castVote() { + console.log("Voting"); + let numGauges = (await gaugeController.totalGauges()).toNumber(); + let evenWeight = Math.floor(10000 / numGauges); + let gaugeIDs = []; + let gaugeWeights = []; + for(let gaugeID = 1; gaugeID <= numGauges; ++gaugeID) { + gaugeIDs.push(gaugeID); + gaugeWeights.push(evenWeight); + } + let tx = await underwritingLockVoting.connect(deployer).voteMultiple(signerAddress, gaugeIDs, gaugeWeights, networkSettings.overrides); + await tx.wait(networkSettings.confirmations); + console.log("Voted"); +} + +async function getEpochTimestamps() { + console.log("Fetching epoch timestamps\n"); + + console.log("Current time (javascript)"); + logDate(new Date()); + + console.log("Current time (solidity)"); + logDate(new Date((await provider.getBlock("latest")).timestamp * 1000)); + + console.log("epoch start"); + logDate(new Date((await gaugeController.getEpochStartTimestamp()).toNumber() * 1000)); + + console.log("epoch end"); + logDate(new Date((await gaugeController.getEpochEndTimestamp()).toNumber() * 1000)); + + console.log("last time gauge weights updated"); + logDate(new Date((await gaugeController.lastTimeGaugeWeightsUpdated()).toNumber() * 1000)); + + console.log("last time premiums charged"); + logDate(new Date((await underwritingLockVoting.lastTimePremiumsCharged()).toNumber() * 1000)); + + console.log("Fetched epoch timestamps"); +} + +function leftPad(s:string, l:number, f:string=' ') { + while(s.length < l) s = `${f}${s}`; + return s; +} + +function logDate(date:Date) { + console.log(Math.floor(date.valueOf()/1000)); + console.log(date.toLocaleString()); + console.log(date.toUTCString()); + console.log('') +} + +function range(start:number, stop:number) { + let numbers = []; + for(let i = start; i < stop; ++i) { + numbers.push(i); + } + return numbers; +} + +main() + .then(() => process.exit(0)) + .catch(error => { + console.error(error); + process.exit(1); + }); diff --git a/scripts/utils.ts b/scripts/utils.ts index cdc1b5b6..6060d9bc 100644 --- a/scripts/utils.ts +++ b/scripts/utils.ts @@ -20,17 +20,3 @@ export function logContractAddress(contractName: String, address: String) { export function sortTokens(tokenA: string, tokenB: string) { return BN.from(tokenA).lt(BN.from(tokenB)) ? [tokenA, tokenB] : [tokenB, tokenA]; } - -// creates, initializes, and returns a pool -export async function createPool(creator: Signer, uniswapFactory: Contract, tokenA: string, tokenB: string, fee: FeeAmount) { - let [token0, token1] = sortTokens(tokenA, tokenB); - let pool: Contract; - let tx = await uniswapFactory.connect(creator).createPool(token0, token1, fee); - let events = (await tx.wait()).events; - let poolAddress = events[0].args.pool; - pool = await ethers.getContractAt(UniswapV3PoolArtifact.abi, poolAddress); - let sqrtPrice = encodePriceSqrt(1,1); - let tx2 = await pool.connect(creator).initialize(sqrtPrice); - await tx2.wait(); - return pool; -} diff --git a/test/native/DepositHelper.test.ts b/test/native/DepositHelper.test.ts new file mode 100644 index 00000000..76f1f95d --- /dev/null +++ b/test/native/DepositHelper.test.ts @@ -0,0 +1,350 @@ +import chai from "chai"; +import { ethers, waffle } from "hardhat"; +const { expect } = chai; +const { deployContract, solidity } = waffle; +import { BigNumber as BN, Wallet } from "ethers"; +const provider = waffle.provider; +chai.use(solidity); + +import { import_artifacts, ArtifactImports } from "../utilities/artifact_importer"; +import { UnderwritingPool, FluxMegaOracle, MockFluxPriceFeed, MockErc20, MockErc20Decimals, UnderwritingEquity, UnderwritingLocker, Registry, DepositHelper, BlockGetter } from "../../typechain"; +import { expectDeployed } from "../utilities/expectDeployed"; + +const name = "Solace Native Underwriting Pool"; +const symbol = "UWP"; +const decimals = 18; + +const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000"; +const ETH_ADDRESS = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; +const ONE_USDC = BN.from("1000000"); +const ONE_ETHER = BN.from("1000000000000000000"); +const ONE_NEAR = BN.from("1000000000000000000000000"); +const EIGHT_DECIMALS = BN.from("100000000"); +const ONE_YEAR = 31536000; // in seconds + +describe("DepositHelper", function () { + let uwp: UnderwritingPool; + let uwe: UnderwritingEquity; + let registry: Registry; + let underwritingLocker: UnderwritingLocker; + let depositHelper: DepositHelper; + + let oracle: FluxMegaOracle; + let dai: MockErc20; + let usdc: MockErc20; + let weth: MockErc20; + let near: MockErc20; + let uni: MockErc20; + let comp: MockErc20; + let daiPriceFeed: MockFluxPriceFeed; + let ethPriceFeed: MockFluxPriceFeed; + let nearPriceFeed: MockFluxPriceFeed; + let usdcPriceFeed: MockFluxPriceFeed; + + let blockGetter: BlockGetter; + + const [deployer, governor, user1, user2, user3] = provider.getWallets(); + let artifacts: ArtifactImports; + let snapshot: BN; + + before(async function () { + artifacts = await import_artifacts(); + snapshot = await provider.send("evm_snapshot", []); + await deployer.sendTransaction({to:deployer.address}); // for some reason this helps solidity-coverage + + // deploy tokens + dai = (await deployContract(deployer, artifacts.MockERC20, ["Dai Stablecoin", "DAI", ONE_ETHER.mul(1000000)])) as MockErc20; + weth = (await deployContract(deployer, artifacts.MockERC20, ["Wrapped Ether", "WETH", ONE_ETHER.mul(1000000)])) as MockErc20; + near = (await deployContract(deployer, artifacts.MockERC20Decimals, ["Near", "NEAR", ONE_NEAR.mul(1000000), 24])) as MockErc20Decimals; + usdc = (await deployContract(deployer, artifacts.MockERC20Decimals, ["USD Coin", "USDC", ONE_USDC.mul(1000000), 24])) as MockErc20Decimals; + uni = (await deployContract(deployer, artifacts.MockERC20, ["Uniswap", "UNI", ONE_ETHER.mul(1000000)])) as MockErc20; + comp = (await deployContract(deployer, artifacts.MockERC20, ["Compound", "COMP", ONE_ETHER.mul(1000000)])) as MockErc20; + + // deploy price feeds + daiPriceFeed = (await deployContract(deployer, artifacts.MockFluxPriceFeed, [governor.address])) as MockFluxPriceFeed; + await daiPriceFeed.connect(governor).setAnswer(EIGHT_DECIMALS.mul(1)); + usdcPriceFeed = (await deployContract(deployer, artifacts.MockFluxPriceFeed, [governor.address])) as MockFluxPriceFeed; + await usdcPriceFeed.connect(governor).setAnswer(EIGHT_DECIMALS.mul(1)); + ethPriceFeed = (await deployContract(deployer, artifacts.MockFluxPriceFeed, [governor.address])) as MockFluxPriceFeed; + await ethPriceFeed.connect(governor).setAnswer(EIGHT_DECIMALS.mul(1300)); + nearPriceFeed = (await deployContract(deployer, artifacts.MockFluxPriceFeed, [governor.address])) as MockFluxPriceFeed; + await nearPriceFeed.connect(governor).setAnswer(EIGHT_DECIMALS.mul(4)); + + // deploy oracle + oracle = (await deployContract(deployer, artifacts.FluxMegaOracle, [governor.address])) as FluxMegaOracle; + await oracle.connect(governor).addPriceFeeds([ + { token: dai.address, priceFeed: daiPriceFeed.address, tokenDecimals: 18, priceFeedDecimals: 8 }, + { token: weth.address, priceFeed: ethPriceFeed.address, tokenDecimals: 18, priceFeedDecimals: 8 }, + { token: near.address, priceFeed: nearPriceFeed.address, tokenDecimals: 24, priceFeedDecimals: 8 }, + { token: usdc.address, priceFeed: usdcPriceFeed.address, tokenDecimals: 6, priceFeedDecimals: 8 }, + ]); + + // deploy uwp + uwp = (await deployContract(deployer, artifacts.UnderwritingPool, [governor.address])) as UnderwritingPool; + await uwp.connect(governor).addTokensToPool([ + { token: dai.address, oracle: oracle.address, min: 0, max: ethers.constants.MaxUint256 }, + { token: weth.address, oracle: oracle.address, min: 0, max: ethers.constants.MaxUint256 }, + ]); + // deploy uwe + uwe = (await deployContract(deployer, artifacts.UnderwritingEquity, [governor.address, uwp.address])) as UnderwritingEquity; + // deploy registry + registry = (await deployContract(deployer, artifacts.Registry, [governor.address])) as Registry; + await registry.connect(governor).set(["uwe"], [uwe.address]); + // deploy locker + underwritingLocker = (await deployContract(deployer, artifacts.UnderwritingLocker, [governor.address, registry.address])) as UnderwritingLocker; + + blockGetter = (await deployContract(deployer, artifacts.BlockGetter)) as BlockGetter; + }); + + after(async function () { + await provider.send("evm_revert", [snapshot]); + }); + + describe("deployment", function () { + it("reverts if zero uwe", async function () { + await expect(deployContract(deployer, artifacts.DepositHelper, [ZERO_ADDRESS, underwritingLocker.address])).to.be.revertedWith("zero address uwe"); + }); + it("reverts if zero locker", async function () { + await expect(deployContract(deployer, artifacts.DepositHelper, [uwe.address, ZERO_ADDRESS])).to.be.revertedWith("zero address locker"); + }); + it("deploys", async function () { + depositHelper = (await deployContract(deployer, artifacts.DepositHelper, [uwe.address, underwritingLocker.address])) as DepositHelper; + await expectDeployed(depositHelper.address); + }); + it("initializes correctly", async function () { + expect(await depositHelper.underwritingPool()).eq(uwp.address); + expect(await depositHelper.underwritingEquity()).eq(uwe.address); + expect(await depositHelper.underwritingLocker()).eq(underwritingLocker.address); + }); + }); + + describe("deposit", function () { + let end: BN; + before(async function () { + let timestamp = await blockGetter.getBlockTimestamp(); + end = timestamp.add(ONE_YEAR); + //let timestamp = (await provider.getBlock('latest')).timestamp; + //console.log('ts : ', timestamp); + //console.log('one : ', ONE_YEAR); + //let end = timestamp + ONE_YEAR; + //console.log('end : ', end); + }); + it("cannot deposit token not in pool", async function () { + await expect(depositHelper.connect(user1).calculateDeposit(near.address, 0)).to.be.revertedWith("token not in pool"); + await expect(depositHelper.connect(user1).depositAndLock(near.address, 0, 0)).to.be.revertedWith("token not in pool"); + await expect(depositHelper.connect(user1).depositIntoLock(near.address, 0, 0)).to.be.revertedWith("token not in pool"); + }); + /* + it("cannot deposit with insufficient balance", async function () { + await expect(depositHelper.connect(user1).depositAndLock(dai.address, 1, 0)).to.be.revertedWith("ERC20: transfer amount exceeds balance"); + await expect(depositHelper.connect(user1).depositAndLock(uwp.address, 1, 0)).to.be.revertedWith("ERC20: transfer amount exceeds balance"); + await expect(depositHelper.connect(user1).depositAndLock(uwe.address, 1, 0)).to.be.revertedWith("ERC20: transfer amount exceeds balance"); + await expect(depositHelper.connect(user1).depositIntoLock(dai.address, 1, 0)).to.be.revertedWith("ERC20: transfer amount exceeds balance"); + await expect(depositHelper.connect(user1).depositIntoLock(uwp.address, 1, 0)).to.be.revertedWith("ERC20: transfer amount exceeds balance"); + await expect(depositHelper.connect(user1).depositIntoLock(uwe.address, 1, 0)).to.be.revertedWith("ERC20: transfer amount exceeds balance"); + }); + it("cannot deposit with insufficient allowance", async function () { + await dai.connect(deployer).transfer(user1.address, ONE_ETHER.mul(100000)); + await expect(depositHelper.connect(user1).depositAndLock(dai.address, 1, 0)).to.be.revertedWith("ERC20: transfer amount exceeds allowance"); + await expect(depositHelper.connect(user1).depositIntoLock(dai.address, 1, 0)).to.be.revertedWith("ERC20: transfer amount exceeds allowance"); + }); + */ + it("cannot deposit into nonexistent lock", async function () { + await dai.connect(deployer).transfer(user1.address, ONE_ETHER.mul(100000)); + await dai.connect(user1).approve(depositHelper.address, ONE_ETHER.mul(100000)); + await expect(depositHelper.connect(user1).depositIntoLock(dai.address, 1, 999)).to.be.revertedWith("ERC721: owner query for nonexistent token"); + }); + it("can deposit 1", async function () { + // dai to new lock at 1:1 + let amt = await depositHelper.calculateDeposit(dai.address, ONE_ETHER.mul(1000)); + expect(amt).eq(ONE_ETHER.mul(1000)); + let lockID = await depositHelper.connect(user1).callStatic.depositAndLock(dai.address, ONE_ETHER.mul(1000), end); + expect(lockID).eq(1); + + let tx = await depositHelper.connect(user1).depositAndLock(dai.address, ONE_ETHER.mul(1000), end); + await expect(tx).to.emit(dai, "Transfer").withArgs(user1.address, depositHelper.address, ONE_ETHER.mul(1000)); + await expect(tx).to.emit(dai, "Transfer").withArgs(depositHelper.address, uwp.address, ONE_ETHER.mul(1000)); + await expect(tx).to.emit(uwp, "Transfer").withArgs(ZERO_ADDRESS, depositHelper.address, ONE_ETHER.mul(1000)); + await expect(tx).to.emit(uwp, "Transfer").withArgs(depositHelper.address, uwe.address, ONE_ETHER.mul(1000)); + await expect(tx).to.emit(uwe, "Transfer").withArgs(ZERO_ADDRESS, depositHelper.address, ONE_ETHER.mul(1000)); + await expect(tx).to.emit(uwe, "Transfer").withArgs(depositHelper.address, underwritingLocker.address, ONE_ETHER.mul(1000)); + await expect(tx).to.emit(underwritingLocker, "Transfer").withArgs(ZERO_ADDRESS, user1.address, 1); + expect(await underwritingLocker.balanceOf(user1.address)).eq(1); + expect(await underwritingLocker.ownerOf(1)).eq(user1.address); + let lock = await underwritingLocker.locks(1); + expect(lock.amount).eq(ONE_ETHER.mul(1000)); + expect(lock.end).eq(end); + }); + it("can deposit 2", async function () { + // weth to existing lock at 1:1 + let amt = await depositHelper.calculateDeposit(weth.address, ONE_ETHER); + expect(amt).eq(ONE_ETHER.mul(1300)); + + await weth.connect(deployer).transfer(user1.address, ONE_ETHER.mul(1000)); + await weth.connect(user1).approve(depositHelper.address, ethers.constants.MaxUint256); + let tx = await depositHelper.connect(user1).depositIntoLock(weth.address, ONE_ETHER, 1); + await expect(tx).to.emit(weth, "Transfer").withArgs(user1.address, depositHelper.address, ONE_ETHER); + await expect(tx).to.emit(weth, "Transfer").withArgs(depositHelper.address, uwp.address, ONE_ETHER); + await expect(tx).to.emit(uwp, "Transfer").withArgs(ZERO_ADDRESS, depositHelper.address, ONE_ETHER.mul(1300)); + await expect(tx).to.emit(uwp, "Transfer").withArgs(depositHelper.address, uwe.address, ONE_ETHER.mul(1300)); + await expect(tx).to.emit(uwe, "Transfer").withArgs(ZERO_ADDRESS, depositHelper.address, ONE_ETHER.mul(1300)); + await expect(tx).to.emit(uwe, "Transfer").withArgs(depositHelper.address, underwritingLocker.address, ONE_ETHER.mul(1300)); + expect(await underwritingLocker.balanceOf(user1.address)).eq(1); + expect(await underwritingLocker.ownerOf(1)).eq(user1.address); + let lock = await underwritingLocker.locks(1); + expect(lock.amount).eq(ONE_ETHER.mul(2300)); + expect(lock.end).eq(end); + }); + it("can deposit 3", async function () { + // uwp to new lock at 1:1 + await dai.connect(user1).approve(uwp.address, ethers.constants.MaxUint256); + await uwp.connect(user1).issue([dai.address], [ONE_ETHER.mul(1000)], user1.address); + await uwp.connect(user1).approve(depositHelper.address, ethers.constants.MaxUint256); + + let amt = await depositHelper.calculateDeposit(uwp.address, ONE_ETHER.mul(1000)); + expect(amt).eq(ONE_ETHER.mul(1000)); + let tx = await depositHelper.connect(user1).depositAndLock(uwp.address, ONE_ETHER.mul(1000), end); + await expect(tx).to.emit(uwp, "Transfer").withArgs(user1.address, depositHelper.address, ONE_ETHER.mul(1000)); + await expect(tx).to.emit(uwp, "Transfer").withArgs(depositHelper.address, uwe.address, ONE_ETHER.mul(1000)); + await expect(tx).to.emit(uwe, "Transfer").withArgs(ZERO_ADDRESS, depositHelper.address, ONE_ETHER.mul(1000)); + await expect(tx).to.emit(uwe, "Transfer").withArgs(depositHelper.address, underwritingLocker.address, ONE_ETHER.mul(1000)); + await expect(tx).to.emit(underwritingLocker, "Transfer").withArgs(ZERO_ADDRESS, user1.address, 2); + expect(await underwritingLocker.balanceOf(user1.address)).eq(2); + expect(await underwritingLocker.ownerOf(2)).eq(user1.address); + let lock = await underwritingLocker.locks(2); + expect(lock.amount).eq(ONE_ETHER.mul(1000)); + }); + it("can deposit 4", async function () { + // uwe to new lock at 1:1 + await dai.connect(user1).approve(uwp.address, ethers.constants.MaxUint256); + await uwp.connect(user1).issue([dai.address], [ONE_ETHER.mul(1000)], user1.address); + await uwp.connect(user1).approve(uwe.address, ethers.constants.MaxUint256); + await uwe.connect(user1).deposit(ONE_ETHER.mul(1000), user1.address); + await uwe.connect(user1).approve(depositHelper.address, ethers.constants.MaxUint256); + + let amt = await depositHelper.calculateDeposit(uwe.address, ONE_ETHER.mul(1000)); + expect(amt).eq(ONE_ETHER.mul(1000)); + let tx = await depositHelper.connect(user1).depositAndLock(uwe.address, ONE_ETHER.mul(1000), end); + await expect(tx).to.emit(uwe, "Transfer").withArgs(user1.address, depositHelper.address, ONE_ETHER.mul(1000)); + await expect(tx).to.emit(uwe, "Transfer").withArgs(depositHelper.address, underwritingLocker.address, ONE_ETHER.mul(1000)); + await expect(tx).to.emit(underwritingLocker, "Transfer").withArgs(ZERO_ADDRESS, user1.address, 3); + expect(await underwritingLocker.balanceOf(user1.address)).eq(3); + expect(await underwritingLocker.ownerOf(3)).eq(user1.address); + let lock = await underwritingLocker.locks(3); + expect(lock.amount).eq(ONE_ETHER.mul(1000)); + }); + it("can deposit 5", async function () { + // dai to new lock not at 1:1 + await dai.connect(user1).transfer(uwp.address, ONE_ETHER.mul(8600)); // uwp 3:1 + await dai.connect(user1).approve(uwp.address, ethers.constants.MaxUint256); + await uwp.connect(user1).issue([dai.address], [ONE_ETHER.mul(5700).mul(3)], user1.address); + await uwp.connect(user1).approve(uwe.address, ethers.constants.MaxUint256); + await uwe.connect(user1).deposit(ONE_ETHER.mul(5700), user1.address); // ts 10k + await uwe.connect(user1).burn(ONE_ETHER.mul(2000)); // uwe 4:5 + + let amt1 = await uwp.calculateIssue([dai.address], [ONE_ETHER.mul(1000)]); + expect(amt1).eq(ONE_ETHER.mul(1000).div(3)); + let amt2 = await uwe.calculateDeposit(ONE_ETHER.mul(1000)); + expect(amt2).eq(ONE_ETHER.mul(1000).mul(4).div(5)); + let amt = await depositHelper.calculateDeposit(dai.address, ONE_ETHER.mul(1000)); + expect(amt).eq(ONE_ETHER.mul(1000).div(3).mul(4).div(5)); + + let tx = await depositHelper.connect(user1).depositAndLock(dai.address, ONE_ETHER.mul(1000), end); + await expect(tx).to.emit(dai, "Transfer").withArgs(user1.address, depositHelper.address, ONE_ETHER.mul(1000)); + await expect(tx).to.emit(dai, "Transfer").withArgs(depositHelper.address, uwp.address, ONE_ETHER.mul(1000)); + await expect(tx).to.emit(uwp, "Transfer").withArgs(ZERO_ADDRESS, depositHelper.address, ONE_ETHER.mul(1000).div(3)); + await expect(tx).to.emit(uwp, "Transfer").withArgs(depositHelper.address, uwe.address, ONE_ETHER.mul(1000).div(3)); + await expect(tx).to.emit(uwe, "Transfer").withArgs(ZERO_ADDRESS, depositHelper.address, ONE_ETHER.mul(1000).div(3).mul(4).div(5)); + await expect(tx).to.emit(uwe, "Transfer").withArgs(depositHelper.address, underwritingLocker.address, ONE_ETHER.mul(1000).div(3).mul(4).div(5)); + await expect(tx).to.emit(underwritingLocker, "Transfer").withArgs(ZERO_ADDRESS, user1.address, 4); + expect(await underwritingLocker.balanceOf(user1.address)).eq(4); + expect(await underwritingLocker.ownerOf(4)).eq(user1.address); + let lock = await underwritingLocker.locks(4); + expect(lock.amount).eq(ONE_ETHER.mul(1000).div(3).mul(4).div(5)); + }); + it("can deposit 6", async function () { + // uwp to new lock not at 1:1 + await uwp.connect(user1).issue([dai.address], [ONE_ETHER.mul(1000)], user1.address); + let bal = await uwp.balanceOf(user1.address); + expect(bal).eq(ONE_ETHER.mul(1000).div(3)); + + let amt = await depositHelper.calculateDeposit(uwp.address, bal); + expect(amt).eq(ONE_ETHER.mul(1000).div(3).mul(4).div(5)); + + let tx = await depositHelper.connect(user1).depositAndLock(uwp.address, bal, end); + await expect(tx).to.emit(uwp, "Transfer").withArgs(user1.address, depositHelper.address, ONE_ETHER.mul(1000).div(3)); + await expect(tx).to.emit(uwp, "Transfer").withArgs(depositHelper.address, uwe.address, ONE_ETHER.mul(1000).div(3)); + await expect(tx).to.emit(uwe, "Transfer").withArgs(ZERO_ADDRESS, depositHelper.address, ONE_ETHER.mul(1000).div(3).mul(4).div(5)); + await expect(tx).to.emit(uwe, "Transfer").withArgs(depositHelper.address, underwritingLocker.address, ONE_ETHER.mul(1000).div(3).mul(4).div(5)); + await expect(tx).to.emit(underwritingLocker, "Transfer").withArgs(ZERO_ADDRESS, user1.address, 5); + expect(await underwritingLocker.balanceOf(user1.address)).eq(5); + expect(await underwritingLocker.ownerOf(5)).eq(user1.address); + let lock = await underwritingLocker.locks(5); + expect(lock.amount).eq(ONE_ETHER.mul(1000).div(3).mul(4).div(5)); + }); + it("can deposit 7", async function () { + // uwe to new lock not at 1:1 + let bal1 = await uwe.balanceOf(user1.address); + await uwe.connect(user1).transfer(user2.address, bal1); + await uwp.connect(user1).issue([dai.address], [ONE_ETHER.mul(1000)], user1.address); + await uwe.connect(user1).deposit(ONE_ETHER.mul(1000).div(3), user1.address); + let bal = await uwe.balanceOf(user1.address); + expect(bal).eq(ONE_ETHER.mul(1000).div(3).mul(4).div(5)); + + let amt = await depositHelper.calculateDeposit(uwe.address, bal); + expect(amt).eq(ONE_ETHER.mul(1000).div(3).mul(4).div(5)); + + let tx = await depositHelper.connect(user1).depositAndLock(uwe.address, bal, end); + await expect(tx).to.emit(uwe, "Transfer").withArgs(user1.address, depositHelper.address, ONE_ETHER.mul(1000).div(3).mul(4).div(5)); + await expect(tx).to.emit(uwe, "Transfer").withArgs(depositHelper.address, underwritingLocker.address, ONE_ETHER.mul(1000).div(3).mul(4).div(5)); + await expect(tx).to.emit(underwritingLocker, "Transfer").withArgs(ZERO_ADDRESS, user1.address, 6); + expect(await underwritingLocker.balanceOf(user1.address)).eq(6); + expect(await underwritingLocker.ownerOf(6)).eq(user1.address); + let lock = await underwritingLocker.locks(6); + expect(lock.amount).eq(ONE_ETHER.mul(1000).div(3).mul(4).div(5)); + }); + }); + + describe("edge case - uwp is upgraded", function () { + let uwp2: UnderwritingPool; + let end: BN; + + before(async function () { + let timestamp = await blockGetter.getBlockTimestamp(); + end = timestamp.add(ONE_YEAR); + // deploy uwp + uwp2 = (await deployContract(deployer, artifacts.UnderwritingPool, [governor.address])) as UnderwritingPool; + await uwp2.connect(governor).addTokensToPool([ + { token: dai.address, oracle: oracle.address, min: 0, max: ethers.constants.MaxUint256 }, + { token: weth.address, oracle: oracle.address, min: 0, max: ethers.constants.MaxUint256 }, + ]); + // mint uwp2 to uwe + let ts = await uwe.totalSupply(); + await dai.connect(deployer).approve(uwp2.address, ethers.constants.MaxUint256); + await uwp2.connect(deployer).issue([dai.address], [ts], uwe.address); + expect(await uwp2.balanceOf(uwe.address)).eq(ts); + // set + await uwe.connect(governor).setUwp(uwp2.address); + expect(await depositHelper.underwritingPool()).eq(uwp2.address); + }); + it("can deposit", async function () { + // dai to new lock at 1:1 + let amt = await depositHelper.calculateDeposit(dai.address, ONE_ETHER.mul(1000)); + expect(amt).eq(ONE_ETHER.mul(1000)); + + let tx = await depositHelper.connect(user1).depositAndLock(dai.address, ONE_ETHER.mul(1000), end); + await expect(tx).to.emit(dai, "Transfer").withArgs(user1.address, depositHelper.address, ONE_ETHER.mul(1000)); + await expect(tx).to.emit(dai, "Transfer").withArgs(depositHelper.address, uwp2.address, ONE_ETHER.mul(1000)); + await expect(tx).to.emit(uwp2, "Transfer").withArgs(ZERO_ADDRESS, depositHelper.address, ONE_ETHER.mul(1000)); + await expect(tx).to.emit(uwp2, "Transfer").withArgs(depositHelper.address, uwe.address, ONE_ETHER.mul(1000)); + await expect(tx).to.emit(uwe, "Transfer").withArgs(ZERO_ADDRESS, depositHelper.address, ONE_ETHER.mul(1000)); + await expect(tx).to.emit(uwe, "Transfer").withArgs(depositHelper.address, underwritingLocker.address, ONE_ETHER.mul(1000)); + await expect(tx).to.emit(underwritingLocker, "Transfer").withArgs(ZERO_ADDRESS, user1.address, 7); + expect(await underwritingLocker.balanceOf(user1.address)).eq(7); + expect(await underwritingLocker.ownerOf(7)).eq(user1.address); + let lock = await underwritingLocker.locks(7); + expect(lock.amount).eq(ONE_ETHER.mul(1000)); + expect(lock.end).eq(end); + }); + }); +}); diff --git a/test/native/FluxMegaOracle.test.ts b/test/native/FluxMegaOracle.test.ts new file mode 100644 index 00000000..3eb2a240 --- /dev/null +++ b/test/native/FluxMegaOracle.test.ts @@ -0,0 +1,235 @@ +import chai from "chai"; +import { ethers, waffle } from "hardhat"; +const { expect } = chai; +const { deployContract, solidity } = waffle; +import { BigNumber as BN, Wallet } from "ethers"; +const provider = waffle.provider; +chai.use(solidity); + +import { import_artifacts, ArtifactImports } from "../utilities/artifact_importer"; +import { FluxMegaOracle, MockFluxPriceFeed, MockErc20, MockErc20Decimals } from "../../typechain"; +import { expectDeployed } from "../utilities/expectDeployed"; + +const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000"; +const ETH_ADDRESS = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; +const ONE_USDC = BN.from("1000000"); +const ONE_ETHER = BN.from("1000000000000000000"); +const ONE_NEAR = BN.from("1000000000000000000000000"); +const EIGHT_DECIMALS = BN.from("100000000"); + +describe("FluxMegaOracle", function () { + let oracle: FluxMegaOracle; + let dai: MockErc20; + let usdc: MockErc20; + let weth: MockErc20; + let near: MockErc20; + let daiPriceFeed: MockFluxPriceFeed; + let ethPriceFeed1: MockFluxPriceFeed; + let ethPriceFeed2: MockFluxPriceFeed; + let nearPriceFeed: MockFluxPriceFeed; + let usdcPriceFeed: MockFluxPriceFeed; + + const [deployer, governor, user] = provider.getWallets(); + let artifacts: ArtifactImports; + let snapshot: BN; + + before(async function () { + artifacts = await import_artifacts(); + snapshot = await provider.send("evm_snapshot", []); + await deployer.sendTransaction({to:deployer.address}); // for some reason this helps solidity-coverage + + // deploy tokens + dai = (await deployContract(deployer, artifacts.MockERC20, ["Dai Stablecoin", "DAI", 0])) as MockErc20; + weth = (await deployContract(deployer, artifacts.MockERC20, ["Wrapped Ether", "WETH", 0])) as MockErc20; + near = (await deployContract(deployer, artifacts.MockERC20Decimals, ["Near", "NEAR", 0, 24])) as MockErc20Decimals; + usdc = (await deployContract(deployer, artifacts.MockERC20Decimals, ["USD Coin", "USDC", 0, 24])) as MockErc20Decimals; + + // deploy price feeds + daiPriceFeed = (await deployContract(deployer, artifacts.MockFluxPriceFeed, [governor.address])) as MockFluxPriceFeed; + await daiPriceFeed.connect(governor).setAnswer(EIGHT_DECIMALS.mul(1)); + usdcPriceFeed = (await deployContract(deployer, artifacts.MockFluxPriceFeed, [governor.address])) as MockFluxPriceFeed; + await usdcPriceFeed.connect(governor).setAnswer(EIGHT_DECIMALS.mul(1)); + ethPriceFeed1 = (await deployContract(deployer, artifacts.MockFluxPriceFeed, [governor.address])) as MockFluxPriceFeed; + await ethPriceFeed1.connect(governor).setAnswer(EIGHT_DECIMALS.mul(1300)); + ethPriceFeed2 = (await deployContract(deployer, artifacts.MockFluxPriceFeed, [governor.address])) as MockFluxPriceFeed; + await ethPriceFeed2.connect(governor).setAnswer(EIGHT_DECIMALS.mul(1400)); + nearPriceFeed = (await deployContract(deployer, artifacts.MockFluxPriceFeed, [governor.address])) as MockFluxPriceFeed; + await nearPriceFeed.connect(governor).setAnswer(EIGHT_DECIMALS.mul(4)); + }); + + after(async function () { + await provider.send("evm_revert", [snapshot]); + }); + + describe("deployment", function () { + it("reverts if zero governance", async function () { + await expect(deployContract(deployer, artifacts.FluxMegaOracle, [ZERO_ADDRESS])).to.be.revertedWith("zero address governance"); + }); + it("deploys", async function () { + oracle = (await deployContract(deployer, artifacts.FluxMegaOracle, [governor.address])) as FluxMegaOracle; + await expectDeployed(oracle.address); + }); + }); + + describe("setting feeds", function () { + it("starts with no feeds", async function () { + expect(await oracle.tokensLength()).eq(0); + await expect(oracle.tokenByIndex(0)).to.be.revertedWith("index out of bounds"); + }); + it("non governance cannot add feeds", async function () { + await expect(oracle.connect(user).addPriceFeeds([])).to.be.revertedWith("!governance"); + }); + it("governance can add feeds", async function () { + let tx1 = await oracle.connect(governor).addPriceFeeds([ + { token: dai.address, priceFeed: daiPriceFeed.address, tokenDecimals: 18, priceFeedDecimals: 8 }, + { token: weth.address, priceFeed: ethPriceFeed1.address, tokenDecimals: 18, priceFeedDecimals: 8 }, + ]); + await expect(tx1).to.emit(oracle, "PriceFeedAdded").withArgs(dai.address); + await expect(tx1).to.emit(oracle, "PriceFeedAdded").withArgs(weth.address); + let data1 = await oracle.priceFeedForToken(dai.address); + expect(data1.token).eq(dai.address); + expect(data1.priceFeed).eq(daiPriceFeed.address); + expect(data1.tokenDecimals).eq(18); + expect(data1.priceFeedDecimals).eq(8); + let data2 = await oracle.priceFeedForToken(weth.address); + expect(data2.token).eq(weth.address); + expect(data2.priceFeed).eq(ethPriceFeed1.address); + expect(data2.tokenDecimals).eq(18); + expect(data2.priceFeedDecimals).eq(8); + expect(await oracle.tokensLength()).eq(2); + expect(await oracle.tokenByIndex(0)).eq(dai.address); + expect(await oracle.tokenByIndex(1)).eq(weth.address); + await expect(oracle.tokenByIndex(2)).to.be.revertedWith("index out of bounds"); + + let tx2 = await oracle.connect(governor).addPriceFeeds([ + { token: weth.address, priceFeed: ethPriceFeed2.address, tokenDecimals: 18, priceFeedDecimals: 8 }, + { token: near.address, priceFeed: nearPriceFeed.address, tokenDecimals: 24, priceFeedDecimals: 8 }, + ]); + await expect(tx2).to.emit(oracle, "PriceFeedAdded").withArgs(weth.address); + await expect(tx2).to.emit(oracle, "PriceFeedAdded").withArgs(near.address); + let data3 = await oracle.priceFeedForToken(weth.address); + expect(data3.token).eq(weth.address); + expect(data3.priceFeed).eq(ethPriceFeed2.address); + expect(data3.tokenDecimals).eq(18); + expect(data3.priceFeedDecimals).eq(8); + let data4 = await oracle.priceFeedForToken(near.address); + expect(data4.token).eq(near.address); + expect(data4.priceFeed).eq(nearPriceFeed.address); + expect(data4.tokenDecimals).eq(24); + expect(data4.priceFeedDecimals).eq(8); + expect(await oracle.tokensLength()).eq(3); + expect(await oracle.tokenByIndex(0)).eq(dai.address); + expect(await oracle.tokenByIndex(1)).eq(weth.address); + expect(await oracle.tokenByIndex(2)).eq(near.address); + await expect(oracle.tokenByIndex(3)).to.be.revertedWith("index out of bounds"); + }); + it("non governance cannot remove feeds", async function () { + await expect(oracle.connect(user).removePriceFeeds([])).to.be.revertedWith("!governance"); + }); + it("governance can remove feeds", async function () { + let tx = await oracle.connect(governor).removePriceFeeds([dai.address, near.address]); + await expect(tx).to.emit(oracle, "PriceFeedRemoved").withArgs(dai.address); + await expect(tx).to.emit(oracle, "PriceFeedRemoved").withArgs(near.address); + let data1 = await oracle.priceFeedForToken(dai.address); + expect(data1.token).eq(ZERO_ADDRESS); + expect(data1.priceFeed).eq(ZERO_ADDRESS); + expect(data1.tokenDecimals).eq(0); + expect(data1.priceFeedDecimals).eq(0); + let data2 = await oracle.priceFeedForToken(near.address); + expect(data2.token).eq(ZERO_ADDRESS); + expect(data2.priceFeed).eq(ZERO_ADDRESS); + expect(data2.tokenDecimals).eq(0); + expect(data2.priceFeedDecimals).eq(0); + expect(await oracle.tokensLength()).eq(1); + expect(await oracle.tokenByIndex(0)).eq(weth.address); + await expect(oracle.tokenByIndex(1)).to.be.revertedWith("index out of bounds"); + + await oracle.connect(governor).removePriceFeeds([dai.address, near.address]); + expect(await oracle.tokensLength()).eq(1); + expect(await oracle.tokenByIndex(0)).eq(weth.address); + await expect(oracle.tokenByIndex(1)).to.be.revertedWith("index out of bounds"); + }); + }); + + describe("valueOfTokens", function () { + it("zero value if token unknown", async function () { + expect(await oracle.valueOfTokens(dai.address, ONE_ETHER)).eq(0); + }); + it("fetches value", async function () { + await oracle.connect(governor).addPriceFeeds([ + { token: dai.address, priceFeed: daiPriceFeed.address, tokenDecimals: 18, priceFeedDecimals: 8 }, + { token: near.address, priceFeed: nearPriceFeed.address, tokenDecimals: 24, priceFeedDecimals: 8 }, + { token: usdc.address, priceFeed: usdcPriceFeed.address, tokenDecimals: 6, priceFeedDecimals: 8 }, + ]); + expect(await oracle.tokensLength()).eq(4); + expect(await oracle.tokenByIndex(0)).eq(weth.address); + expect(await oracle.tokenByIndex(1)).eq(dai.address); + expect(await oracle.tokenByIndex(2)).eq(near.address); + expect(await oracle.tokenByIndex(3)).eq(usdc.address); + await expect(oracle.tokenByIndex(4)).to.be.revertedWith("index out of bounds"); + expect(await oracle.valueOfTokens(dai.address, ONE_ETHER)).eq(ONE_ETHER); + expect(await oracle.valueOfTokens(usdc.address, ONE_USDC.mul(123))).eq(ONE_ETHER.mul(123)); + expect(await oracle.valueOfTokens(weth.address, ONE_ETHER.mul(123))).eq(ONE_ETHER.mul(123).mul(1400)); + expect(await oracle.valueOfTokens(near.address, ONE_NEAR.mul(12345678))).eq(ONE_ETHER.mul(12345678).mul(4)); + await oracle.connect(governor).addPriceFeeds([ + { token: weth.address, priceFeed: ethPriceFeed1.address, tokenDecimals: 18, priceFeedDecimals: 8 }, + ]); + expect(await oracle.tokensLength()).eq(4); + expect(await oracle.tokenByIndex(0)).eq(weth.address); + expect(await oracle.tokenByIndex(1)).eq(dai.address); + expect(await oracle.tokenByIndex(2)).eq(near.address); + expect(await oracle.tokenByIndex(3)).eq(usdc.address); + await expect(oracle.tokenByIndex(4)).to.be.revertedWith("index out of bounds"); + expect(await oracle.valueOfTokens(weth.address, ONE_ETHER.mul(123))).eq(ONE_ETHER.mul(123).mul(1300)); + }); + it("reverts if price feed is wrong address", async function () { + await oracle.connect(governor).removePriceFeeds([usdc.address]); + expect(await oracle.tokensLength()).eq(3); + expect(await oracle.tokenByIndex(0)).eq(weth.address); + expect(await oracle.tokenByIndex(1)).eq(dai.address); + expect(await oracle.tokenByIndex(2)).eq(near.address); + await expect(oracle.tokenByIndex(3)).to.be.revertedWith("index out of bounds"); + await oracle.connect(governor).addPriceFeeds([ + { token: usdc.address, priceFeed: usdc.address, tokenDecimals: 18, priceFeedDecimals: 8 }, + ]); + expect(await oracle.tokensLength()).eq(4); + expect(await oracle.tokenByIndex(0)).eq(weth.address); + expect(await oracle.tokenByIndex(1)).eq(dai.address); + expect(await oracle.tokenByIndex(2)).eq(near.address); + expect(await oracle.tokenByIndex(3)).eq(usdc.address); + await expect(oracle.tokenByIndex(4)).to.be.revertedWith("index out of bounds"); + await expect(oracle.valueOfTokens(usdc.address, ONE_USDC)).to.be.reverted; + }); + it("reverts if price feed is negative", async function () { + await ethPriceFeed1.connect(governor).setAnswer(ONE_ETHER.mul(-1300)); + await expect(oracle.valueOfTokens(weth.address, ONE_ETHER)).to.be.revertedWith("negative price"); + }); + // TODO: integration testing + // using FORK_NETWORK=aurora seems to make tests stall out + /* + it("integrates with existing feeds", async function () { + let forkNetwork = process.env.FORK_NETWORK || ""; + if(forkNetwork != "aurora") { + console.log("set `FORK_NETWORK=aurora` in .env to continue this test"); + expect("FORK_NETWORK").eq("aurora"); + } + daiPriceFeed = (await ethers.getContractAt(artifacts.MockFluxPriceFeed.abi, "0x18aFC38b25229B797E2af47b5056A5f98249Ef12")) as MockFluxPriceFeed; + ethPriceFeed2 = (await ethers.getContractAt(artifacts.MockFluxPriceFeed.abi, "0xA8Ac2Fa1D239c7d96046967ED21503D1F1fB2354")) as MockFluxPriceFeed; + nearPriceFeed = (await ethers.getContractAt(artifacts.MockFluxPriceFeed.abi, "0x0a9A9cF9bDe10c861Fc1e45aCe4ea097eaa268eD")) as MockFluxPriceFeed; + await oracle.connect(governor).addPriceFeeds([ + { token: dai.address, priceFeed: daiPriceFeed.address, tokenDecimals: 18, priceFeedDecimals: 8 }, + { token: weth.address, priceFeed: ethPriceFeed2.address, tokenDecimals: 18, priceFeedDecimals: 8 }, + { token: near.address, priceFeed: nearPriceFeed.address, tokenDecimals: 24, priceFeedDecimals: 8 }, + ]); + let answer1 = await daiPriceFeed.latestAnswer(); + let amt1 = ONE_ETHER.mul(123); + let expectedAnswer1 = answer1.mul(123).mul(10**10); + expect(await oracle.valueOfTokens(dai.address, amt1)).eq(expectedAnswer1); + let answer2 = await ethPriceFeed2.latestAnswer(); + let amt2 = ONE_ETHER.mul(123); + let expectedAnswer2 = answer2.mul(123).mul(10**10); + expect(await oracle.valueOfTokens(weth.address, amt2)).eq(expectedAnswer2); + }); + */ + }); +}); diff --git a/test/native/GaugeController.test.ts b/test/native/GaugeController.test.ts new file mode 100644 index 00000000..666c79b1 --- /dev/null +++ b/test/native/GaugeController.test.ts @@ -0,0 +1,380 @@ +/// @dev Testing simple setter/getter functions only in this test file. +/// @dev More complex integration tests in `UnderwritingLockVoting.test.ts` + +import { ethers, waffle, upgrades } from "hardhat"; +const { deployContract, solidity } = waffle; +import { MockProvider } from "ethereum-waffle"; +const provider: MockProvider = waffle.provider; +import { BigNumber as BN, constants, BigNumberish, Wallet, ContractTransaction } from "ethers"; +import chai from "chai"; +const { expect } = chai; +chai.use(solidity); +import { import_artifacts, ArtifactImports } from "../utilities/artifact_importer"; +import { UnderwritingLocker, UnderwritingLockVoting, Registry, MockErc20Permit, GaugeController } from "../../typechain"; +import { expectDeployed } from "../utilities/expectDeployed"; +import { expectClose } from "./../utilities/math"; + +/******************* + GLOBAL CONSTANTS +*******************/ +const ZERO = BN.from("0"); +const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000"; +const ONE_ETHER = BN.from("1000000000000000000"); +const ONE_MILLION_ETHER = ONE_ETHER.mul(1000000); +const ONE_YEAR = 31536000; // in seconds +const ONE_MONTH = ONE_YEAR / 12; +const ONE_WEEK = 604800; // in seconds +const DEPOSIT_AMOUNT = ONE_ETHER; +const SCALE_FACTOR = ONE_ETHER; +const ONE_PERCENT = ONE_ETHER.div(100); +const ONE_HUNDRED_PERCENT = ONE_ETHER; +const CUSTOM_GAS_LIMIT = 6000000; + +describe("GaugeController", function () { + const [deployer, governor, revenueRouter, voter1, updater, anon] = provider.getWallets(); + + /*************************** + VARIABLE DECLARATIONS + ***************************/ + let token: MockErc20Permit; + let registry: Registry; + let underwritingLocker: UnderwritingLocker; + let gaugeController: GaugeController; + let voting: UnderwritingLockVoting; + let artifacts: ArtifactImports; + let snapshot: BN; + + before(async function () { + artifacts = await import_artifacts(); + snapshot = await provider.send("evm_snapshot", []); + await deployer.sendTransaction({to:deployer.address}); // for some reason this helps solidity-coverage + + // Deploy $UWE, and mint 1M $UWE to deployer + token = (await deployContract(deployer, artifacts.MockERC20Permit, ["Underwriting Equity - Solace Native", "UWE", ONE_MILLION_ETHER, 18])) as MockErc20Permit; + + // Deploy registry + registry = (await deployContract(deployer, artifacts.Registry, [governor.address])) as Registry; + }); + + after(async function () { + await provider.send("evm_revert", [snapshot]); + }); + + describe("deployment", function () { + it("reverts if zero address governance", async function () { + await expect(deployContract(deployer, artifacts.GaugeController, [ZERO_ADDRESS, registry.address])).to.be.revertedWith("zero address governance"); + }); + it("reverts if zero address token", async function () { + await expect(deployContract(deployer, artifacts.GaugeController, [governor.address, ZERO_ADDRESS])).to.be.revertedWith('ZeroAddressInput("token")'); + }); + it("deploys", async function () { + gaugeController = (await deployContract(deployer, artifacts.GaugeController, [governor.address, token.address])) as GaugeController; + await expectDeployed(gaugeController.address); + }); + it("initializes properly", async function () { + expect(await gaugeController.token()).eq(token.address); + expect(await gaugeController.updater()).eq(ZERO_ADDRESS); + expect(await gaugeController.leverageFactor()).eq(ONE_HUNDRED_PERCENT); + expect(await gaugeController.totalGauges()).eq(0); + expect(await gaugeController.lastTimeGaugeWeightsUpdated()).eq(0); + expect(await gaugeController.getGaugeWeight(0)).eq(ZERO); + expect(await gaugeController.getAllGaugeWeights()).deep.eq([ZERO]); + expect(await gaugeController.getNumActiveGauges()).eq(0); + expect(await gaugeController.getNumPausedGauges()).eq(0); + expect(await gaugeController.getGaugeName(0)).eq(""); + expect(await gaugeController.isGaugeActive(0)).eq(false); + expect(await gaugeController.getRateOnLineOfGauge(0)).eq(0); + expect(await gaugeController.getVotePowerSum()).eq(0); + }); + it("getEpochStartTimestamp gets current timestamp rounded down to a multiple of WEEK ", async function () { + const CURRENT_TIME = (await provider.getBlock('latest')).timestamp; + const EXPECTED_EPOCH_START_TIME = BN.from(CURRENT_TIME).div(ONE_WEEK).mul(ONE_WEEK) + expect(await gaugeController.getEpochStartTimestamp()).eq(EXPECTED_EPOCH_START_TIME) + }); + it("getEpochEndTimestamp() == getEpochStartTimestamp() + ONE_WEEK ", async function () { + expect(await gaugeController.getEpochEndTimestamp()).eq((await gaugeController.getEpochStartTimestamp()).add(ONE_WEEK)) + }); + it("getInsuranceCapacity should revert before tokenholder added", async function () { + await expect(gaugeController.getInsuranceCapacity()).to.be.revertedWith("NoTokenholdersAdded"); + }); + }); + + describe("governance", () => { + it("starts with the correct governor", async () => { + expect(await gaugeController.governance()).to.equal(governor.address); + }); + it("rejects setting new governance by non governor", async () => { + await expect(gaugeController.connect(voter1).setPendingGovernance(voter1.address)).to.be.revertedWith("!governance"); + }); + it("can set new governance", async () => { + let tx = await gaugeController.connect(governor).setPendingGovernance(deployer.address); + await expect(tx).to.emit(gaugeController, "GovernancePending").withArgs(deployer.address); + expect(await gaugeController.governance()).to.equal(governor.address); + expect(await gaugeController.pendingGovernance()).to.equal(deployer.address); + }); + it("rejects governance transfer by non governor", async () => { + await expect(gaugeController.connect(voter1).acceptGovernance()).to.be.revertedWith("!pending governance"); + }); + it("can transfer governance", async () => { + let tx = await gaugeController.connect(deployer).acceptGovernance(); + await expect(tx) + .to.emit(gaugeController, "GovernanceTransferred") + .withArgs(governor.address, deployer.address); + expect(await gaugeController.governance()).to.equal(deployer.address); + await gaugeController.connect(deployer).setPendingGovernance(governor.address); + await gaugeController.connect(governor).acceptGovernance(); + }); + }); + + describe("addVotingContract", () => { + it("non governor cannot add new voting contract", async () => { + await expect(gaugeController.connect(voter1).addVotingContract(voter1.address)).to.be.revertedWith("!governance"); + }); + it("can add new voting contract", async () => { + let tx = await gaugeController.connect(governor).addVotingContract(voter1.address); + await expect(tx).to.emit(gaugeController, "VotingContractAdded").withArgs(voter1.address); + }); + }); + + describe("removeVotingContract", () => { + it("rejects setting new governance by non governor", async () => { + await expect(gaugeController.connect(voter1).removeVotingContract(voter1.address)).to.be.revertedWith("!governance"); + }); + it("cannot remove address, that has not previously been added as voting contract", async () => { + await expect(gaugeController.connect(governor).removeVotingContract(deployer.address)).to.be.revertedWith("VotingContractNotAdded"); + }); + it("can remove voting contract", async () => { + let tx = await gaugeController.connect(governor).removeVotingContract(voter1.address); + await expect(tx).to.emit(gaugeController, "VotingContractRemoved").withArgs(voter1.address); + }); + }); + + describe("addTokenholder", () => { + it("non governor cannot add new tokenholder", async () => { + await expect(gaugeController.connect(voter1).addTokenholder(voter1.address)).to.be.revertedWith("!governance"); + }); + it("can add new tokenholder", async () => { + let tx = await gaugeController.connect(governor).addTokenholder(voter1.address); + await expect(tx).to.emit(gaugeController, "TokenholderAdded").withArgs(voter1.address); + }); + it("getInsurancePremium() will not throw after tokenholder added", async () => { + const tx = await gaugeController.getInsuranceCapacity() + }); + }); + + describe("removeTokenholder", () => { + it("rejects setting new governance by non governor", async () => { + await expect(gaugeController.connect(voter1).removeTokenholder(voter1.address)).to.be.revertedWith("!governance"); + }); + it("cannot remove address, that has not previously been added as voting contract", async () => { + await expect(gaugeController.connect(governor).removeTokenholder(deployer.address)).to.be.revertedWith("TokenholderNotPresent"); + }); + it("can remove voting contract", async () => { + let tx = await gaugeController.connect(governor).removeTokenholder(voter1.address); + await expect(tx).to.emit(gaugeController, "TokenholderRemoved").withArgs(voter1.address); + }); + }); + + describe("setLeverageFactor", () => { + it("non governor cannot setLeverageFactor", async () => { + await expect(gaugeController.connect(voter1).setLeverageFactor(ONE_HUNDRED_PERCENT)).to.be.revertedWith("!governance"); + }); + it("can set new leverage factor", async () => { + let tx = await gaugeController.connect(governor).setLeverageFactor(ONE_HUNDRED_PERCENT.mul(2)); + await expect(tx).to.emit(gaugeController, "LeverageFactorSet").withArgs(ONE_HUNDRED_PERCENT.mul(2)); + expect(await gaugeController.leverageFactor()).eq(ONE_HUNDRED_PERCENT.mul(2)) + await gaugeController.connect(governor).setLeverageFactor(ONE_HUNDRED_PERCENT) + }); + }); + + describe("setToken", () => { + it("non governor cannot setToken", async () => { + await expect(gaugeController.connect(voter1).setToken(voter1.address)).to.be.revertedWith("!governance"); + }); + it("can set new token", async () => { + let tx = await gaugeController.connect(governor).setToken(voter1.address); + await expect(tx).to.emit(gaugeController, "TokenSet").withArgs(voter1.address); + expect(await gaugeController.token()).eq(voter1.address) + await gaugeController.connect(governor).setToken(token.address) + }); + }); + + describe("setUpdater", () => { + it("non governor cannot setUpdater", async () => { + await expect(gaugeController.connect(voter1).setUpdater(updater.address)).to.be.revertedWith("!governance"); + }); + it("can set updater", async () => { + let tx = await gaugeController.connect(governor).setUpdater(updater.address); + await expect(tx).to.emit(gaugeController, "UpdaterSet").withArgs(updater.address); + expect(await gaugeController.updater()).eq(updater.address) + }); + }); + + describe("setEpochLengthInWeeks", () => { + it("non governor cannot setEpochLengthInWeeks", async () => { + await expect(gaugeController.connect(voter1).setEpochLengthInWeeks(1)).to.be.revertedWith("!governance"); + }); + it("can setEpochLengthInWeeks", async () => { + let tx = await gaugeController.connect(governor).setEpochLengthInWeeks(2); + await expect(tx).to.emit(gaugeController, "EpochLengthSet").withArgs(2); + expect(await gaugeController.getEpochLength()).eq(2 * ONE_WEEK); + await gaugeController.connect(governor).setEpochLengthInWeeks(1); + expect(await gaugeController.getEpochLength()).eq(ONE_WEEK); + }); + }); + + describe("addGauge", () => { + it("non governor cannot add new gauge", async () => { + await expect(gaugeController.connect(voter1).addGauge("1", ONE_PERCENT)).to.be.revertedWith("!governance"); + }); + it("can add new gauge", async () => { + let tx = await gaugeController.connect(governor).addGauge("1", ONE_PERCENT); + await expect(tx).to.emit(gaugeController, "GaugeAdded").withArgs(1, ONE_PERCENT, "1"); + expect(await gaugeController.totalGauges()).eq(1) + expect(await gaugeController.getNumActiveGauges()).eq(1) + expect(await gaugeController.getNumPausedGauges()).eq(0) + expect(await gaugeController.getGaugeName(1)).eq("1") + expect(await gaugeController.isGaugeActive(1)).eq(true) + expect(await gaugeController.getRateOnLineOfGauge(1)).eq(ONE_PERCENT) + expect(await gaugeController.getGaugeWeight(1)).eq(ZERO) + }); + }); + + describe("pauseGauge", () => { + it("non governor cannot pause gauge", async () => { + await expect(gaugeController.connect(voter1).pauseGauge(1)).to.be.revertedWith("!governance"); + }); + it("cannot pause non-existent gauge", async () => { + await expect(gaugeController.connect(governor).pauseGauge(2)).to.be.reverted; + }); + it("can pause gauge", async () => { + let tx = await gaugeController.connect(governor).pauseGauge(1); + await expect(tx).to.emit(gaugeController, "GaugePaused").withArgs(1, "1"); + expect(await gaugeController.totalGauges()).eq(1) + expect(await gaugeController.getNumActiveGauges()).eq(0) + expect(await gaugeController.getNumPausedGauges()).eq(1) + expect(await gaugeController.isGaugeActive(1)).eq(false) + expect(await gaugeController.getRateOnLineOfGauge(1)).eq(ONE_PERCENT) + expect(await gaugeController.getGaugeWeight(1)).eq(ZERO) + }); + it("cannot pause gauge again", async () => { + await expect(gaugeController.connect(governor).pauseGauge(1)).to.be.revertedWith("GaugeAlreadyPaused"); + }); + }); + + describe("unpauseGauge", () => { + it("non governor cannot unpause gauge", async () => { + await expect(gaugeController.connect(voter1).unpauseGauge(1)).to.be.revertedWith("!governance"); + }); + it("cannot unpause non-existent gauge", async () => { + await expect(gaugeController.connect(governor).unpauseGauge(2)).to.be.reverted; + }); + it("cannot unpause gaugeID 0", async () => { + await expect(gaugeController.connect(governor).unpauseGauge(0)).to.be.revertedWith("CannotUnpauseGaugeID0") + }); + it("can unpause gauge", async () => { + let tx = await gaugeController.connect(governor).unpauseGauge(1); + await expect(tx).to.emit(gaugeController, "GaugeUnpaused").withArgs(1, "1"); + expect(await gaugeController.totalGauges()).eq(1) + expect(await gaugeController.getNumActiveGauges()).eq(1) + expect(await gaugeController.getNumPausedGauges()).eq(0) + expect(await gaugeController.isGaugeActive(1)).eq(true) + expect(await gaugeController.getRateOnLineOfGauge(1)).eq(ONE_PERCENT) + expect(await gaugeController.getGaugeWeight(1)).eq(ZERO) + }); + it("cannot unpause gauge again", async () => { + await expect(gaugeController.connect(governor).unpauseGauge(1)).to.be.revertedWith("GaugeAlreadyUnpaused"); + }); + }); + + describe("setRateOnLine", () => { + it("non governor cannot setRateOnLine", async () => { + await expect(gaugeController.connect(voter1).setRateOnLine([1], [1])).to.be.revertedWith("!governance"); + }); + it("cannot setRateOnLine of non-existent gauge", async () => { + await expect(gaugeController.connect(voter1).setRateOnLine([2], [1])).to.be.revertedWith("!governance"); + }); + it("can set setRateOnLine", async () => { + let tx = await gaugeController.connect(governor).setRateOnLine([1], [1]); + await expect(tx).to.emit(gaugeController, "RateOnLineSet").withArgs(1, 1); + expect(await gaugeController.getRateOnLineOfGauge(1)).eq(1) + await gaugeController.connect(governor).setRateOnLine([1], [ONE_PERCENT]); + }); + }); + + describe("vote", () => { + it("cannot be vote for gaugeID 0", async () => { + await expect(gaugeController.connect(voter1).vote(voter1.address, 0, 1)).to.be.revertedWith("CannotVoteForGaugeID0"); + }); + it("cannot be called before gauge weight updated", async () => { + await expect(gaugeController.connect(voter1).vote(voter1.address, 1, 1)).to.be.revertedWith("GaugeWeightsNotYetUpdated"); + }); + }); + + /********************* + INTENTION STATEMENT + *********************/ + // voter1 will vote for gaugeID 1 with 100% of vote power + + describe("simple vote() scenario", () => { + before(async function () { + const CURRENT_TIME = (await provider.getBlock('latest')).timestamp; + + await registry.connect(governor).set(["uwe"], [token.address]); + underwritingLocker = (await deployContract(deployer, artifacts.UnderwritingLocker, [governor.address, registry.address])) as UnderwritingLocker; + await registry.connect(governor).set(["revenueRouter"], [revenueRouter.address]); + await registry.connect(governor).set(["underwritingLocker"], [underwritingLocker.address]); + await registry.connect(governor).set(["gaugeController"], [gaugeController.address]); + voting = (await deployContract(deployer, artifacts.UnderwritingLockVoting, [governor.address, registry.address])) as UnderwritingLockVoting; + await gaugeController.connect(governor).addTokenholder(underwritingLocker.address) + await gaugeController.connect(governor).addVotingContract(voting.address) + await registry.connect(governor).set(["underwritingLockVoting"], [voting.address]); + await underwritingLocker.connect(governor).setVotingContract() + await gaugeController.connect(governor).updateGaugeWeights(); + await voting.connect(governor).chargePremiums(); + await token.connect(deployer).transfer(voter1.address, ONE_ETHER.mul(1000)) + await token.connect(voter1).approve(underwritingLocker.address, constants.MaxUint256) + await underwritingLocker.connect(voter1).createLock(voter1.address, DEPOSIT_AMOUNT, CURRENT_TIME + 4 * ONE_YEAR) + await voting.connect(voter1).vote(voter1.address, 1, 10000) + }); + it("cannot vote for non existent gauge ID", async () => { + await expect(gaugeController.connect(voter1).vote(voter1.address, 2, 1)).to.be.revertedWith("GaugeIDNotExist"); + }); + it("will throw if not called by voting contract", async () => { + await expect(gaugeController.connect(voter1).vote(voter1.address, 1, 1)).to.be.revertedWith("NotVotingContract"); + }); + it("sanity check of view functions before votes processed", async () => { + expect(await gaugeController.lastTimeGaugeWeightsUpdated()).eq(await gaugeController.getEpochStartTimestamp()) + expect(await gaugeController.getGaugeWeight(1)).eq(0) + expect(await gaugeController.getAllGaugeWeights()).deep.eq([ZERO, ZERO]) + expect(await gaugeController.getVotePowerSum()).eq(0) + const votes = await gaugeController.getVotes(voting.address, voter1.address) + expect(votes.length).eq(1) + expect(votes[0].gaugeID).eq(1) + expect(votes[0].votePowerBPS).eq(10000) + expect(await gaugeController.getVoters(voting.address)).deep.eq([voter1.address]) + expect(await gaugeController.getVoteCount(voting.address, voter1.address)).eq(1) + expect(await gaugeController.getVotersCount(voting.address)).eq(1) + }); + it("updater can updateGaugeWeight in next epoch", async () => { + const CURRENT_TIME = (await provider.getBlock('latest')).timestamp; + await provider.send("evm_mine", [CURRENT_TIME + ONE_WEEK]); + const tx = await gaugeController.connect(updater).updateGaugeWeights({gasLimit: CUSTOM_GAS_LIMIT}) + const EPOCH_START_TIME = await gaugeController.getEpochStartTimestamp() + await expect(tx).to.emit(gaugeController, "GaugeWeightsUpdated").withArgs(EPOCH_START_TIME); + }); + it("sanity check of view functions after votes processed", async () => { + expect(await gaugeController.lastTimeGaugeWeightsUpdated()).eq(await gaugeController.getEpochStartTimestamp()) + expect(await gaugeController.getGaugeWeight(1)).eq(ONE_HUNDRED_PERCENT) + expect(await gaugeController.getAllGaugeWeights()).deep.eq([ZERO, ONE_HUNDRED_PERCENT]) + expect(await gaugeController.getVotePowerSum()).eq(await voting.getVotePower(voter1.address)) + const votes = await gaugeController.getVotes(voting.address, voter1.address) + expect(votes.length).eq(1) + expect(votes[0].gaugeID).eq(1) + expect(votes[0].votePowerBPS).eq(10000) + expect(await gaugeController.getVoters(voting.address)).deep.eq([voter1.address]) + expect(await gaugeController.getVoteCount(voting.address, voter1.address)).eq(1) + expect(await gaugeController.getVotersCount(voting.address)).eq(1) + }); + }); +}); diff --git a/test/native/SolaceMegaOracle.test.ts b/test/native/SolaceMegaOracle.test.ts new file mode 100644 index 00000000..e676e59f --- /dev/null +++ b/test/native/SolaceMegaOracle.test.ts @@ -0,0 +1,223 @@ +import chai from "chai"; +import { ethers, waffle } from "hardhat"; +const { expect } = chai; +const { deployContract, solidity } = waffle; +import { BigNumber as BN, Wallet } from "ethers"; +const provider = waffle.provider; +chai.use(solidity); + +import { import_artifacts, ArtifactImports } from "../utilities/artifact_importer"; +import { SolaceMegaOracle, MockErc20, MockErc20Decimals } from "../../typechain"; +import { expectDeployed } from "../utilities/expectDeployed"; + +const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000"; +const ETH_ADDRESS = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; +const ONE_USDC = BN.from("1000000"); +const ONE_ETHER = BN.from("1000000000000000000"); +const ONE_NEAR = BN.from("1000000000000000000000000"); +const EIGHT_DECIMALS = BN.from("100000000"); + +describe("SolaceMegaOracle", function () { + let oracle: SolaceMegaOracle; + let dai: MockErc20; + let usdc: MockErc20; + let weth: MockErc20; + let near: MockErc20; + let wbtc: MockErc20; + + const [deployer, governor, user, updater1, updater2] = provider.getWallets(); + let artifacts: ArtifactImports; + let snapshot: BN; + + before(async function () { + artifacts = await import_artifacts(); + snapshot = await provider.send("evm_snapshot", []); + await deployer.sendTransaction({to:deployer.address}); // for some reason this helps solidity-coverage + + // deploy tokens + dai = (await deployContract(deployer, artifacts.MockERC20, ["Dai Stablecoin", "DAI", 0])) as MockErc20; + weth = (await deployContract(deployer, artifacts.MockERC20, ["Wrapped Ether", "WETH", 0])) as MockErc20; + near = (await deployContract(deployer, artifacts.MockERC20Decimals, ["Near", "NEAR", 0, 24])) as MockErc20Decimals; + usdc = (await deployContract(deployer, artifacts.MockERC20Decimals, ["USD Coin", "USDC", 0, 24])) as MockErc20Decimals; + wbtc = (await deployContract(deployer, artifacts.MockERC20Decimals, ["Wrapped Bitcoin", "WBTC", 0, 8])) as MockErc20Decimals; + }); + + after(async function () { + await provider.send("evm_revert", [snapshot]); + }); + + describe("deployment", function () { + it("reverts if zero governance", async function () { + await expect(deployContract(deployer, artifacts.SolaceMegaOracle, [ZERO_ADDRESS])).to.be.revertedWith("zero address governance"); + }); + it("deploys", async function () { + oracle = (await deployContract(deployer, artifacts.SolaceMegaOracle, [governor.address])) as SolaceMegaOracle; + await expectDeployed(oracle.address); + }); + }); + + describe("updaters", function () { + it("non governance cannot set updaters", async function () { + await expect(oracle.connect(user).setUpdaterStatuses([],[])).to.be.revertedWith("!governance"); + }); + it("reverts length mismatch", async function () { + await expect(oracle.connect(governor).setUpdaterStatuses([],[true])).to.be.revertedWith("length mismatch"); + }); + it("governance can set updaters", async function () { + let tx = await oracle.connect(governor).setUpdaterStatuses([updater1.address, updater2.address], [true, false]); + await expect(tx).to.emit(oracle, "UpdaterSet").withArgs(updater1.address, true); + await expect(tx).to.emit(oracle, "UpdaterSet").withArgs(updater2.address, false); + expect(await oracle.isUpdater(updater1.address)).eq(true); + expect(await oracle.isUpdater(updater2.address)).eq(false); + }); + }); + + describe("setting feeds", function () { + it("starts with no feeds", async function () { + expect(await oracle.tokensLength()).eq(0); + await expect(oracle.tokenByIndex(0)).to.be.revertedWith("index out of bounds"); + }); + it("non updater cannot add feeds", async function () { + await expect(oracle.connect(user).addPriceFeeds([])).to.be.revertedWith("!updater"); + }); + it("updater can add feeds", async function () { + // first feeds + let tx1 = await oracle.connect(updater1).addPriceFeeds([ + { token: dai.address, latestPrice: ONE_ETHER.mul(1), tokenDecimals: 18, priceFeedDecimals: 18 }, + { token: weth.address, latestPrice: EIGHT_DECIMALS.mul(1300), tokenDecimals: 18, priceFeedDecimals: 8 }, + ]); + await expect(tx1).to.emit(oracle, "PriceFeedAdded").withArgs(dai.address); + await expect(tx1).to.emit(oracle, "PriceFeedAdded").withArgs(weth.address); + let data1 = await oracle.priceFeedForToken(dai.address); + expect(data1.token).eq(dai.address); + expect(data1.latestPrice).eq(ONE_ETHER.mul(1)); + expect(data1.tokenDecimals).eq(18); + expect(data1.priceFeedDecimals).eq(18); + let data2 = await oracle.priceFeedForToken(weth.address); + expect(data2.token).eq(weth.address); + expect(data2.latestPrice).eq(EIGHT_DECIMALS.mul(1300)); + expect(data2.tokenDecimals).eq(18); + expect(data2.priceFeedDecimals).eq(8); + expect(await oracle.tokensLength()).eq(2); + expect(await oracle.tokenByIndex(0)).eq(dai.address); + expect(await oracle.tokenByIndex(1)).eq(weth.address); + await expect(oracle.tokenByIndex(2)).to.be.revertedWith("index out of bounds"); + + // more feeds + let tx2 = await oracle.connect(updater1).addPriceFeeds([ + { token: weth.address, latestPrice: EIGHT_DECIMALS.mul(1400), tokenDecimals: 18, priceFeedDecimals: 8 }, + { token: near.address, latestPrice: ONE_ETHER.mul(4), tokenDecimals: 24, priceFeedDecimals: 18 }, + ]); + await expect(tx2).to.emit(oracle, "PriceFeedAdded").withArgs(weth.address); + await expect(tx2).to.emit(oracle, "PriceFeedAdded").withArgs(near.address); + let data3 = await oracle.priceFeedForToken(weth.address); + expect(data3.token).eq(weth.address); + expect(data3.latestPrice).eq(EIGHT_DECIMALS.mul(1400)); + expect(data3.tokenDecimals).eq(18); + expect(data3.priceFeedDecimals).eq(8); + let data4 = await oracle.priceFeedForToken(near.address); + expect(data4.token).eq(near.address); + expect(data4.latestPrice).eq(ONE_ETHER.mul(4)); + expect(data4.tokenDecimals).eq(24); + expect(data4.priceFeedDecimals).eq(18); + expect(await oracle.tokensLength()).eq(3); + expect(await oracle.tokenByIndex(0)).eq(dai.address); + expect(await oracle.tokenByIndex(1)).eq(weth.address); + expect(await oracle.tokenByIndex(2)).eq(near.address); + await expect(oracle.tokenByIndex(3)).to.be.revertedWith("index out of bounds"); + + // no new feeds + let tx3 = await oracle.connect(updater1).addPriceFeeds([ + { token: dai.address, latestPrice: EIGHT_DECIMALS.mul(1), tokenDecimals: 18, priceFeedDecimals: 8 }, + ]); + await expect(tx3).to.emit(oracle, "PriceFeedAdded").withArgs(dai.address); + data1 = await oracle.priceFeedForToken(dai.address); + expect(data1.token).eq(dai.address); + expect(data1.latestPrice).eq(EIGHT_DECIMALS.mul(1)); + expect(data1.tokenDecimals).eq(18); + expect(data1.priceFeedDecimals).eq(8); + expect(await oracle.tokensLength()).eq(3); + expect(await oracle.tokenByIndex(0)).eq(dai.address); + expect(await oracle.tokenByIndex(1)).eq(weth.address); + expect(await oracle.tokenByIndex(2)).eq(near.address); + await expect(oracle.tokenByIndex(3)).to.be.revertedWith("index out of bounds"); + }); + }); + + describe("valueOfTokens", function () { + it("zero value if token unknown", async function () { + expect(await oracle.valueOfTokens(usdc.address, ONE_USDC)).eq(0); + }); + it("fetches value", async function () { + await oracle.connect(updater1).addPriceFeeds([ + { token: dai.address, latestPrice: ONE_ETHER.mul(1), tokenDecimals: 18, priceFeedDecimals: 18 }, + { token: near.address, latestPrice: ONE_ETHER.mul(4), tokenDecimals: 24, priceFeedDecimals: 18 }, + { token: usdc.address, latestPrice: EIGHT_DECIMALS.mul(1), tokenDecimals: 6, priceFeedDecimals: 8 }, + ]); + expect(await oracle.tokensLength()).eq(4); + expect(await oracle.tokenByIndex(0)).eq(dai.address); + expect(await oracle.tokenByIndex(1)).eq(weth.address); + expect(await oracle.tokenByIndex(2)).eq(near.address); + expect(await oracle.tokenByIndex(3)).eq(usdc.address); + await expect(oracle.tokenByIndex(4)).to.be.revertedWith("index out of bounds"); + expect(await oracle.valueOfTokens(dai.address, ONE_ETHER)).eq(ONE_ETHER); + expect(await oracle.valueOfTokens(usdc.address, ONE_USDC.mul(123))).eq(ONE_ETHER.mul(123)); + expect(await oracle.valueOfTokens(weth.address, ONE_ETHER.mul(123))).eq(ONE_ETHER.mul(123).mul(1400)); + expect(await oracle.valueOfTokens(near.address, ONE_NEAR.mul(12345678))).eq(ONE_ETHER.mul(12345678).mul(4)); + }); + }); + + describe("transmit", function () { + it("non updater cannot transmit", async function () { + await expect(oracle.connect(user).transmit([],[])).to.be.revertedWith("!updater"); + }); + it("reverts length mismatch", async function () { + await expect(oracle.connect(updater1).transmit([],[1])).to.be.revertedWith("length mismatch"); + }); + it("updater can transmit", async function () { + let tx = await oracle.connect(updater1).transmit([weth.address, near.address], [EIGHT_DECIMALS.mul(1500), ONE_ETHER.mul(5)]); + await expect(tx).to.emit(oracle, "PriceTransmitted").withArgs(weth.address, EIGHT_DECIMALS.mul(1500)); + await expect(tx).to.emit(oracle, "PriceTransmitted").withArgs(near.address, ONE_ETHER.mul(5)); + let data3 = await oracle.priceFeedForToken(weth.address); + expect(data3.token).eq(weth.address); + expect(data3.latestPrice).eq(EIGHT_DECIMALS.mul(1500)); + expect(data3.tokenDecimals).eq(18); + expect(data3.priceFeedDecimals).eq(8); + let data4 = await oracle.priceFeedForToken(near.address); + expect(data4.token).eq(near.address); + expect(data4.latestPrice).eq(ONE_ETHER.mul(5)); + expect(data4.tokenDecimals).eq(24); + expect(data4.priceFeedDecimals).eq(18); + expect(await oracle.tokensLength()).eq(4); + expect(await oracle.tokenByIndex(0)).eq(dai.address); + expect(await oracle.tokenByIndex(1)).eq(weth.address); + expect(await oracle.tokenByIndex(2)).eq(near.address); + expect(await oracle.tokenByIndex(3)).eq(usdc.address); + await expect(oracle.tokenByIndex(4)).to.be.revertedWith("index out of bounds"); + }); + it("updates valueOfTokens", async function () { + expect(await oracle.valueOfTokens(weth.address, ONE_ETHER.mul(123))).eq(ONE_ETHER.mul(123).mul(1500)); + expect(await oracle.valueOfTokens(near.address, ONE_NEAR.mul(12345678))).eq(ONE_ETHER.mul(12345678).mul(5)); + }); + it("edge case - transmit before addPriceFeed", async function () { + // zero decimals + await oracle.connect(updater1).transmit([wbtc.address], [20000]); + let data4 = await oracle.priceFeedForToken(wbtc.address); + expect(data4.token).eq(ZERO_ADDRESS); + expect(data4.latestPrice).eq(20000); + expect(data4.tokenDecimals).eq(0); + expect(data4.priceFeedDecimals).eq(0); + expect(await oracle.tokensLength()).eq(4); + expect(await oracle.tokenByIndex(0)).eq(dai.address); + expect(await oracle.tokenByIndex(1)).eq(weth.address); + expect(await oracle.tokenByIndex(2)).eq(near.address); + expect(await oracle.tokenByIndex(3)).eq(usdc.address); + await expect(oracle.tokenByIndex(4)).to.be.revertedWith("index out of bounds"); + expect(await oracle.valueOfTokens(wbtc.address, 100)).eq(ONE_ETHER.mul(20000).mul(100)); + + // crazy decimals + await oracle.connect(updater1).transmit([wbtc.address], [ONE_ETHER.mul(20000)]); + expect(await oracle.valueOfTokens(wbtc.address, EIGHT_DECIMALS.mul(100))).eq(ONE_ETHER.mul(20000).mul(100).mul(ONE_ETHER).mul(EIGHT_DECIMALS)); + }); + }); +}); diff --git a/test/native/UnderwritingEquity.test.ts b/test/native/UnderwritingEquity.test.ts new file mode 100644 index 00000000..b2430f12 --- /dev/null +++ b/test/native/UnderwritingEquity.test.ts @@ -0,0 +1,382 @@ +import chai from "chai"; +import { ethers, waffle } from "hardhat"; +const { expect } = chai; +const { deployContract, solidity } = waffle; +import { BigNumber as BN, Wallet } from "ethers"; +const provider = waffle.provider; +chai.use(solidity); + +import { import_artifacts, ArtifactImports } from "../utilities/artifact_importer"; +import { MockErc20, UnderwritingEquity } from "../../typechain"; +import { expectDeployed } from "../utilities/expectDeployed"; + +const name = "Solace Native Underwriting Equity"; +const symbol = "UWE"; +const decimals = 18; + +const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000"; +const ETH_ADDRESS = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; +const ONE_USDC = BN.from("1000000"); +const ONE_ETHER = BN.from("1000000000000000000"); +const ONE_NEAR = BN.from("1000000000000000000000000"); +const EIGHT_DECIMALS = BN.from("100000000"); + +describe("UnderwritingEquity", function () { + let uwp: MockErc20; + let uwp2: MockErc20; + let uwe: UnderwritingEquity; + + let dai: MockErc20; + let weth: MockErc20; + + const [deployer, governor, user1, user2, user3] = provider.getWallets(); + let artifacts: ArtifactImports; + let snapshot: BN; + + before(async function () { + artifacts = await import_artifacts(); + snapshot = await provider.send("evm_snapshot", []); + await deployer.sendTransaction({to:deployer.address}); // for some reason this helps solidity-coverage + + // deploy tokens + uwp = (await deployContract(deployer, artifacts.MockERC20, ["Solace Native Underwriting Pool", "UWP", ONE_ETHER.mul(1000000)])) as MockErc20; + uwp2 = (await deployContract(deployer, artifacts.MockERC20, ["Solace Native Underwriting Pool", "UWP", ONE_ETHER.mul(1000000)])) as MockErc20; + dai = (await deployContract(deployer, artifacts.MockERC20, ["Dai Stablecoin", "DAI", ONE_ETHER.mul(1000000)])) as MockErc20; + weth = (await deployContract(deployer, artifacts.MockERC20, ["Wrapped Ether", "WETH", ONE_ETHER.mul(1000000)])) as MockErc20; + }); + + after(async function () { + await provider.send("evm_revert", [snapshot]); + }); + + describe("deployment", function () { + it("reverts if zero governance", async function () { + await expect(deployContract(deployer, artifacts.UnderwritingEquity, [ZERO_ADDRESS, uwp.address])).to.be.revertedWith("zero address governance"); + }); + it("reverts if zero uwp", async function () { + await expect(deployContract(deployer, artifacts.UnderwritingEquity, [governor.address, ZERO_ADDRESS])).to.be.revertedWith("zero address uwp"); + }); + it("deploys", async function () { + uwe = (await deployContract(deployer, artifacts.UnderwritingEquity, [governor.address, uwp.address])) as UnderwritingEquity; + await expectDeployed(uwe.address); + }); + it("initializes correctly", async function () { + expect(await uwe.name()).eq(name); + expect(await uwe.symbol()).eq(symbol); + expect(await uwe.decimals()).eq(decimals); + expect(await uwe.issueFee()).eq(0); + expect(await uwe.issueFeeTo()).eq(ZERO_ADDRESS); + expect(await uwe.underwritingPool()).eq(uwp.address); + let paused = await uwe.isPaused(); + expect(paused.depositIsPaused).eq(false); + expect(paused.withdrawIsPaused).eq(false); + expect(paused.lendIsPaused).eq(false); + }); + }); + + describe("pause", function () { + it("starts unpaused", async function () { + let paused = await uwe.isPaused(); + expect(paused.depositIsPaused).eq(false); + expect(paused.withdrawIsPaused).eq(false); + expect(paused.lendIsPaused).eq(false); + }); + it("cannot be paused by non governor", async function () { + await expect(uwe.connect(user1).setPause(true, true, true)).to.be.revertedWith("!governance"); + }); + it("can be paused and unpaused", async function () { + let tx1 = await uwe.connect(governor).setPause(true, false, false); + await expect(tx1).to.emit(uwe, "PauseSet").withArgs(true, false, false); + let paused1 = await uwe.isPaused(); + expect(paused1.depositIsPaused).eq(true); + expect(paused1.withdrawIsPaused).eq(false); + expect(paused1.lendIsPaused).eq(false); + + let tx2 = await uwe.connect(governor).setPause(false, true, false); + await expect(tx2).to.emit(uwe, "PauseSet").withArgs(false, true, false); + let paused2 = await uwe.isPaused(); + expect(paused2.depositIsPaused).eq(false); + expect(paused2.withdrawIsPaused).eq(true); + expect(paused2.lendIsPaused).eq(false); + + let tx3 = await uwe.connect(governor).setPause(false, false, true); + await expect(tx3).to.emit(uwe, "PauseSet").withArgs(false, false, true); + let paused3 = await uwe.isPaused(); + expect(paused3.depositIsPaused).eq(false); + expect(paused3.withdrawIsPaused).eq(false); + expect(paused3.lendIsPaused).eq(true); + + let tx4 = await uwe.connect(governor).setPause(false, false, false); + await expect(tx4).to.emit(uwe, "PauseSet").withArgs(false, false, false); + let paused4 = await uwe.isPaused(); + expect(paused4.depositIsPaused).eq(false); + expect(paused4.withdrawIsPaused).eq(false); + expect(paused4.lendIsPaused).eq(false); + }); + }); + + describe("issueFee", function () { + it("starts zero", async function () { + expect(await uwe.issueFee()).eq(0); + expect(await uwe.issueFeeTo()).eq(ZERO_ADDRESS); + }); + it("cannot be set by non governance", async function () { + await expect(uwe.connect(user1).setIssueFee(0, ZERO_ADDRESS)).to.be.revertedWith("!governance"); + }); + it("set has safety checks", async function () { + await expect(uwe.connect(governor).setIssueFee(ONE_ETHER.add(1), ZERO_ADDRESS)).to.be.revertedWith("invalid issue fee"); + await expect(uwe.connect(governor).setIssueFee(ONE_ETHER, ZERO_ADDRESS)).to.be.revertedWith("invalid issue fee to"); + }); + it("can be set by governance", async function () { + let tx = await uwe.connect(governor).setIssueFee(1, governor.address); + await expect(tx).to.emit(uwe, "IssueFeeSet").withArgs(1, governor.address); + expect(await uwe.issueFee()).eq(1); + expect(await uwe.issueFeeTo()).eq(governor.address); + await uwe.connect(governor).setIssueFee(0, ZERO_ADDRESS); + }); + }); + + describe("deposit", function () { + it("cannot deposit while paused", async function () { + await uwe.connect(governor).setPause(true, false, false); + await expect(uwe.connect(user1).deposit(0, user1.address)).to.be.revertedWith("deposit is paused"); + await uwe.connect(governor).setPause(false, false, false); + }); + it("cannot deposit without sufficient uwp balance", async function () { + await uwp.connect(deployer).transfer(user1.address, ONE_ETHER.mul(1000)); + await expect(uwe.connect(user1).deposit(ONE_ETHER.mul(1000).add(1), user1.address)).to.be.revertedWith("ERC20: transfer amount exceeds balance"); + }); + it("cannot deposit without sufficient uwp approval", async function () { + await expect(uwe.connect(user1).deposit(1, user1.address)).to.be.revertedWith("ERC20: transfer amount exceeds allowance"); + await uwp.connect(user1).approve(uwe.address, ONE_ETHER.mul(1000)); + }); + it("can deposit 1", async function () { + // 0 bal 0 ts => mint 1:1 + let amt1 = await uwe.calculateDeposit(ONE_ETHER); + expect(amt1).eq(ONE_ETHER); + let amt2 = await uwe.connect(user1).callStatic.deposit(ONE_ETHER, user2.address); + expect(amt2).eq(ONE_ETHER); + let tx = await uwe.connect(user1).deposit(ONE_ETHER, user2.address); + await expect(tx).to.emit(uwe, "DepositMade").withArgs(user1.address, ONE_ETHER, ONE_ETHER); + await expect(tx).to.emit(uwe, "Transfer").withArgs(ZERO_ADDRESS, user2.address, ONE_ETHER); + await expect(tx).to.emit(uwp, "Transfer").withArgs(user1.address, uwe.address, ONE_ETHER); + expect(await uwe.balanceOf(user1.address)).eq(0); + expect(await uwe.balanceOf(user2.address)).eq(ONE_ETHER); + expect(await uwe.totalSupply()).eq(ONE_ETHER); + }); + it("can deposit 2", async function () { + // 1 bal 1 ts => mint 1:1 + let amt1 = await uwe.calculateDeposit(ONE_ETHER); + expect(amt1).eq(ONE_ETHER); + let amt2 = await uwe.connect(user1).callStatic.deposit(ONE_ETHER, user2.address); + expect(amt2).eq(ONE_ETHER); + let tx = await uwe.connect(user1).deposit(ONE_ETHER, user2.address); + await expect(tx).to.emit(uwe, "DepositMade").withArgs(user1.address, ONE_ETHER, ONE_ETHER); + await expect(tx).to.emit(uwe, "Transfer").withArgs(ZERO_ADDRESS, user2.address, ONE_ETHER); + await expect(tx).to.emit(uwp, "Transfer").withArgs(user1.address, uwe.address, ONE_ETHER); + expect(await uwe.balanceOf(user1.address)).eq(0); + expect(await uwe.balanceOf(user2.address)).eq(ONE_ETHER.mul(2)); + expect(await uwe.totalSupply()).eq(ONE_ETHER.mul(2)); + }); + it("can deposit 3", async function () { + // 4 bal 2 ts => mint 1:2 + await uwp.connect(deployer).transfer(uwe.address, ONE_ETHER.mul(2)) + let amt1 = await uwe.calculateDeposit(ONE_ETHER); + expect(amt1).eq(ONE_ETHER.div(2)); + let amt2 = await uwe.connect(user1).callStatic.deposit(ONE_ETHER, user2.address); + expect(amt2).eq(ONE_ETHER.div(2)); + let tx = await uwe.connect(user1).deposit(ONE_ETHER, user2.address); + await expect(tx).to.emit(uwe, "DepositMade").withArgs(user1.address, ONE_ETHER, ONE_ETHER.div(2)); + await expect(tx).to.emit(uwe, "Transfer").withArgs(ZERO_ADDRESS, user2.address, ONE_ETHER.div(2)); + await expect(tx).to.emit(uwp, "Transfer").withArgs(user1.address, uwe.address, ONE_ETHER); + expect(await uwe.balanceOf(user1.address)).eq(0); + expect(await uwe.balanceOf(user2.address)).eq(ONE_ETHER.mul(5).div(2)); + expect(await uwe.totalSupply()).eq(ONE_ETHER.mul(5).div(2)); + }); + it("can deposit 4", async function () { + // 5 bal 2.5 ts => mint 1:2 + // 1% mint fee + let issueFee = ONE_ETHER.div(100); + let invIssueFee = ONE_ETHER.div(100).mul(99); + await uwe.connect(governor).setIssueFee(issueFee, user3.address); + let amt1 = await uwe.calculateDeposit(ONE_ETHER); + expect(amt1).eq(ONE_ETHER.div(2).mul(invIssueFee).div(ONE_ETHER)); + let amt2 = await uwe.connect(user1).callStatic.deposit(ONE_ETHER, user2.address); + expect(amt2).eq(ONE_ETHER.div(2).mul(invIssueFee).div(ONE_ETHER)); + let tx = await uwe.connect(user1).deposit(ONE_ETHER, user2.address); + await expect(tx).to.emit(uwe, "DepositMade").withArgs(user1.address, ONE_ETHER, ONE_ETHER.div(2).mul(invIssueFee).div(ONE_ETHER)); + await expect(tx).to.emit(uwe, "Transfer").withArgs(ZERO_ADDRESS, user2.address, ONE_ETHER.div(2).mul(invIssueFee).div(ONE_ETHER)); + await expect(tx).to.emit(uwe, "Transfer").withArgs(ZERO_ADDRESS, user3.address, ONE_ETHER.div(2).mul(issueFee).div(ONE_ETHER)); + await expect(tx).to.emit(uwp, "Transfer").withArgs(user1.address, uwe.address, ONE_ETHER); + expect(await uwe.balanceOf(user1.address)).eq(0); + expect(await uwe.balanceOf(user2.address)).eq(ONE_ETHER.mul(5).div(2).add(ONE_ETHER.div(2).mul(invIssueFee).div(ONE_ETHER))); + expect(await uwe.balanceOf(user3.address)).eq(ONE_ETHER.div(2).mul(issueFee).div(ONE_ETHER)); + expect(await uwe.totalSupply()).eq(ONE_ETHER.mul(6).div(2)); + }); + }); + + describe("withdraw", function () { + before("redeploy", async function () { + uwe = (await deployContract(deployer, artifacts.UnderwritingEquity, [governor.address, uwp.address])) as UnderwritingEquity; + }); + it("can withdraw 1", async function () { + // 0 bal 0 ts => redeem 1:1 + let amt1 = await uwe.calculateWithdraw(0); + expect(amt1).eq(0); + let amt2 = await uwe.connect(user1).callStatic.withdraw(0, user2.address); + expect(amt2).eq(0); + let tx = await uwe.connect(user1).withdraw(0, user2.address); + await expect(tx).to.emit(uwe, "WithdrawMade").withArgs(user1.address, 0, 0); + await expect(tx).to.emit(uwe, "Transfer").withArgs(user1.address, ZERO_ADDRESS, 0); + await expect(tx).to.emit(uwp, "Transfer").withArgs(uwe.address, user2.address, 0); + expect(await uwe.balanceOf(user1.address)).eq(0); + expect(await uwe.balanceOf(user2.address)).eq(0); + expect(await uwe.totalSupply()).eq(0); + }); + it("cannot withdraw while paused", async function () { + await uwe.connect(governor).setPause(false, true, false); + await expect(uwe.connect(user1).withdraw(0, user1.address)).to.be.revertedWith("withdraw is paused"); + await uwe.connect(governor).setPause(false, false, false); + }); + it("cannot withdraw more than balance", async function () { + await uwp.connect(user1).approve(uwe.address, ONE_ETHER.mul(1000)); + await uwe.connect(user1).deposit(ONE_ETHER.mul(5), user1.address); + await expect(uwe.calculateWithdraw(ONE_ETHER.mul(5).add(1))).to.be.revertedWith("withdraw amount exceeds supply"); + await expect(uwe.withdraw(ONE_ETHER.mul(5).add(1), user2.address)).to.be.revertedWith("ERC20: burn amount exceeds balance"); + }); + it("can withdraw 2", async function () { + // 5 bal 5 ts => redeem 1:1 + let amt1 = await uwe.calculateWithdraw(ONE_ETHER); + expect(amt1).eq(ONE_ETHER); + let amt2 = await uwe.connect(user1).callStatic.withdraw(ONE_ETHER, user2.address); + expect(amt2).eq(ONE_ETHER); + let tx = await uwe.connect(user1).withdraw(ONE_ETHER, user2.address); + await expect(tx).to.emit(uwe, "WithdrawMade").withArgs(user1.address, ONE_ETHER, ONE_ETHER); + await expect(tx).to.emit(uwe, "Transfer").withArgs(user1.address, ZERO_ADDRESS, ONE_ETHER); + await expect(tx).to.emit(uwp, "Transfer").withArgs(uwe.address, user2.address, ONE_ETHER); + expect(await uwe.balanceOf(user1.address)).eq(ONE_ETHER.mul(4)); + expect(await uwe.balanceOf(user2.address)).eq(0); + expect(await uwe.totalSupply()).eq(ONE_ETHER.mul(4)); + }); + it("can withdraw 3", async function () { + // 8 bal 4 ts => redeem 2:1 + await uwp.connect(deployer).transfer(uwe.address, ONE_ETHER.mul(4)); + let amt1 = await uwe.calculateWithdraw(ONE_ETHER); + expect(amt1).eq(ONE_ETHER.mul(2)); + let amt2 = await uwe.connect(user1).callStatic.withdraw(ONE_ETHER, user2.address); + expect(amt2).eq(ONE_ETHER.mul(2)); + let tx = await uwe.connect(user1).withdraw(ONE_ETHER, user2.address); + await expect(tx).to.emit(uwe, "WithdrawMade").withArgs(user1.address, ONE_ETHER.mul(2), ONE_ETHER); + await expect(tx).to.emit(uwe, "Transfer").withArgs(user1.address, ZERO_ADDRESS, ONE_ETHER); + await expect(tx).to.emit(uwp, "Transfer").withArgs(uwe.address, user2.address, ONE_ETHER.mul(2)); + expect(await uwe.balanceOf(user1.address)).eq(ONE_ETHER.mul(3)); + expect(await uwe.balanceOf(user2.address)).eq(0); + expect(await uwe.totalSupply()).eq(ONE_ETHER.mul(3)); + }); + }); + + describe("burn", function () { + it("cannot burn more than balance", async function () { + let bal = await uwe.balanceOf(user1.address); + await expect(uwe.connect(user1).burn(bal.add(1))).to.be.revertedWith("ERC20: burn amount exceeds balance"); + }); + it("can burn", async function () { + let bal1 = await uwe.balanceOf(user1.address); + let ts1 = await uwe.totalSupply(); + let burnAmount = bal1.div(3); + expect(burnAmount).gt(0); + let tx = await uwe.connect(user1).burn(burnAmount); + await expect(tx).to.emit(uwe, "Transfer").withArgs(user1.address, ZERO_ADDRESS, burnAmount); + let bal2 = await uwe.balanceOf(user1.address); + let ts2 = await uwe.totalSupply(); + expect(bal1.sub(bal2)).eq(burnAmount); + expect(ts1.sub(ts2)).eq(burnAmount); + }); + }); + + describe("lend", function () { + it("cannot be called by non governor", async function () { + await expect(uwe.connect(user1).lend(0, user1.address)).to.be.revertedWith("!governance"); + }); + it("cannot be called while paused", async function () { + await uwe.connect(governor).setPause(false, false, true); + await expect(uwe.connect(governor).lend(0, user1.address)).to.be.revertedWith("lend is paused"); + await uwe.connect(governor).setPause(false, false, false); + }); + it("cannot lend more than balance", async function () { + let bal = await uwp.balanceOf(uwe.address); + await expect(uwe.connect(governor).lend(bal.add(1), user1.address)).to.be.revertedWith("ERC20: transfer amount exceeds balance"); + }); + it("can lend", async function () { + let bal11 = await uwp.balanceOf(uwe.address); + let bal12 = await uwp.balanceOf(user3.address); + let lendAmount = bal11.div(3); + expect(lendAmount).gt(0); + let tx = await uwe.connect(governor).lend(lendAmount, user3.address); + await expect(tx).to.emit(uwe, "UwpLoaned").withArgs(lendAmount, user3.address); + await expect(tx).to.emit(uwp, "Transfer").withArgs(uwe.address, user3.address, lendAmount); + let bal21 = await uwp.balanceOf(uwe.address); + let bal22 = await uwp.balanceOf(user3.address); + expect(bal11.sub(bal21)).eq(lendAmount); + expect(bal22.sub(bal12)).eq(lendAmount); + }); + }); + + describe("rescueTokens", function () { + it("cannot be called by non governor", async function () { + await expect(uwe.connect(user1).rescueTokens([], user1.address)).to.be.revertedWith("!governance") + }); + it("cannot rescue uwp", async function () { + await expect(uwe.connect(governor).rescueTokens([uwp.address], user1.address)).to.be.revertedWith("cannot rescue uwp") + }); + it("can rescue tokens", async function () { + await dai.connect(deployer).transfer(uwe.address, ONE_ETHER.mul(100)); + await weth.connect(deployer).transfer(uwe.address, ONE_ETHER); + await uwe.connect(governor).rescueTokens([dai.address, weth.address], user1.address); + expect(await dai.balanceOf(uwe.address)).eq(0); + expect(await weth.balanceOf(uwe.address)).eq(0); + expect(await dai.balanceOf(user1.address)).eq(ONE_ETHER.mul(100)); + expect(await weth.balanceOf(user1.address)).eq(ONE_ETHER); + }); + }); + + describe("setUwp", function () { + it("cannot be called by non governor", async function () { + await expect(uwe.connect(user1).setUwp(dai.address)).to.be.revertedWith("!governance") + }); + it("reverts if zero address uwp", async function () { + await expect(uwe.connect(governor).setUwp(ZERO_ADDRESS)).to.be.revertedWith("zero address uwp") + }); + it("can be called by governor", async function () { + let tx = await uwe.connect(governor).setUwp(uwp2.address); + await expect(tx).to.emit(uwe, "UwpSet").withArgs(uwp2.address); + expect(await uwe.underwritingPool()).eq(uwp2.address); + }); + it("edge case - zero uwp bal", async function () { + // deposits 1:1 + expect(await uwe.calculateDeposit(ONE_ETHER)).eq(ONE_ETHER); + await uwp2.connect(deployer).approve(uwe.address, ethers.constants.MaxUint256); + expect(await uwe.connect(deployer).callStatic.deposit(ONE_ETHER, deployer.address)).eq(ONE_ETHER); + // withdraws any:0 + expect(await uwe.calculateWithdraw(ONE_ETHER)).eq(0); + expect(await uwe.connect(user1).callStatic.withdraw(ONE_ETHER, user1.address)).eq(0); + }); + it("edge case - governance converts uwp and deposits", async function () { + await uwp2.transfer(uwe.address, ONE_ETHER); + // 1:2 + expect(await uwe.calculateDeposit(ONE_ETHER)).eq(ONE_ETHER.mul(2)); + expect(await uwe.connect(deployer).callStatic.deposit(ONE_ETHER, deployer.address)).eq(ONE_ETHER.mul(2)); + expect(await uwe.calculateWithdraw(ONE_ETHER)).eq(ONE_ETHER.div(2)); + expect(await uwe.connect(user1).callStatic.withdraw(ONE_ETHER, user1.address)).eq(ONE_ETHER.div(2)); + }); + it("can rescue old uwp", async function () { + let bale = await uwp.balanceOf(uwe.address); + let bal1 = await uwp.balanceOf(user3.address); + let tx = await uwe.connect(governor).rescueTokens([uwp.address], user3.address); + await expect(tx).to.emit(uwp, "Transfer").withArgs(uwe.address, user3.address, bale); + let bal2 = await uwp.balanceOf(user3.address); + expect(bal2.sub(bal1)).eq(bale); + expect(await uwp.balanceOf(uwe.address)).eq(0); + }); + }); +}); diff --git a/test/native/UnderwritingLockVoting.test.ts b/test/native/UnderwritingLockVoting.test.ts new file mode 100644 index 00000000..50e82fcd --- /dev/null +++ b/test/native/UnderwritingLockVoting.test.ts @@ -0,0 +1,1596 @@ +import { ethers, waffle, upgrades } from "hardhat"; +const { deployContract, solidity } = waffle; +import { MockProvider } from "ethereum-waffle"; +const provider: MockProvider = waffle.provider; +import { BigNumber as BN, constants, Wallet } from "ethers"; +import chai from "chai"; +const { expect } = chai; +chai.use(solidity); +import { import_artifacts, ArtifactImports } from "../utilities/artifact_importer"; +import { UnderwritingLocker, UnderwritingLockVoting, Registry, MockErc20PermitWithBurn, GaugeController } from "../../typechain"; +import { expectDeployed } from "../utilities/expectDeployed"; +import { expectClose } from "./../utilities/math"; + +/******************* + GLOBAL CONSTANTS +*******************/ +const ZERO = BN.from("0"); +const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000"; +const ONE_ETHER = BN.from("1000000000000000000"); +const ONE_MILLION_ETHER = ONE_ETHER.mul(1000000); +const ONE_YEAR = 31536000; // in seconds +const ONE_MONTH = ONE_YEAR / 12; +const ONE_WEEK = 604800; // in seconds +const DEPOSIT_AMOUNT = ONE_ETHER; +const SCALE_FACTOR = ONE_ETHER; +const ONE_PERCENT = ONE_ETHER.div(100); +const ONE_HUNDRED_PERCENT = ONE_ETHER; +const CUSTOM_GAS_LIMIT = 6000000; + +describe("UnderwritingLockVoting", function () { + const [deployer, governor, revenueRouter, voter1, voter2, delegate1, updater, bribeController, anon] = provider.getWallets(); + + /*************************** + VARIABLE DECLARATIONS + ***************************/ + let token: MockErc20PermitWithBurn; + let registry: Registry; + let underwritingLocker: UnderwritingLocker; + let gaugeController: GaugeController; + let voting: UnderwritingLockVoting; + let artifacts: ArtifactImports; + let snapshot: BN; + + before(async function () { + artifacts = await import_artifacts(); + snapshot = await provider.send("evm_snapshot", []); + await deployer.sendTransaction({to:deployer.address}); // for some reason this helps solidity-coverage + + // Deploy $UWE, and mint 1M $UWE to deployer + token = (await deployContract(deployer, artifacts.MockERC20PermitWithBurn, ["Underwriting Equity - Solace Native", "UWE", ONE_MILLION_ETHER, 18])) as MockErc20PermitWithBurn; + + // Deploy registry + registry = (await deployContract(deployer, artifacts.Registry, [governor.address])) as Registry; + }); + + after(async function () { + await provider.send("evm_revert", [snapshot]); + }); + + describe("deployment", function () { + it("reverts if zero address governance", async function () { + await expect(deployContract(deployer, artifacts.UnderwritingLockVoting, [ZERO_ADDRESS, registry.address])).to.be.revertedWith("zero address governance"); + }); + it("reverts if zero address registry", async function () { + await expect(deployContract(deployer, artifacts.UnderwritingLockVoting, [governor.address, ZERO_ADDRESS])).to.be.revertedWith('ZeroAddressInput("registry")'); + }); + it("reverts if zero address revenueRouter in Registry", async function () { + await expect(deployContract(deployer, artifacts.UnderwritingLockVoting, [governor.address, registry.address])).to.be.revertedWith('ZeroAddressInput("revenueRouter")'); + await registry.connect(governor).set(["revenueRouter"], [revenueRouter.address]); + }); + it("reverts if zero address underwritingLocker in Registry", async function () { + await expect(deployContract(deployer, artifacts.UnderwritingLockVoting, [governor.address, registry.address])).to.be.revertedWith('ZeroAddressInput("underwritingLocker")'); + await registry.connect(governor).set(["uwe"], [token.address]); + underwritingLocker = (await deployContract(deployer, artifacts.UnderwritingLocker, [governor.address, registry.address])) as UnderwritingLocker; + await expectDeployed(underwritingLocker.address); + await registry.connect(governor).set(["underwritingLocker"], [underwritingLocker.address]); + }); + it("reverts if zero address gaugeController in Registry", async function () { + await expect(deployContract(deployer, artifacts.UnderwritingLockVoting, [governor.address, registry.address])).to.be.revertedWith('ZeroAddressInput("gaugeController")'); + gaugeController = (await deployContract(deployer, artifacts.GaugeController, [governor.address, token.address])) as GaugeController; + await registry.connect(governor).set(["gaugeController"], [gaugeController.address]); + }); + it("deploys", async function () { + voting = (await deployContract(deployer, artifacts.UnderwritingLockVoting, [governor.address, registry.address])) as UnderwritingLockVoting; + await expectDeployed(voting.address); + }); + it("initializes properly", async function () { + expect(await voting.revenueRouter()).eq(revenueRouter.address); + expect(await voting.underwritingLocker()).eq(underwritingLocker.address); + expect(await voting.gaugeController()).eq(gaugeController.address); + expect(await voting.registry()).eq(registry.address); + expect(await voting.updater()).eq(ZERO_ADDRESS); + expect(await voting.bribeController()).eq(ZERO_ADDRESS); + expect(await voting.lastTimePremiumsCharged()).eq(0); + expect(await voting.isVotingOpen()).eq(false); + expect(await gaugeController.getVoteCount(voting.address, voter1.address)).eq(0) + expect(await gaugeController.getVotersCount(voting.address)).eq(0) + }); + it("getEpochStartTimestamp gets current timestamp rounded down to a multiple of WEEK ", async function () { + const CURRENT_TIME = (await provider.getBlock('latest')).timestamp; + const EXPECTED_EPOCH_START_TIME = BN.from(CURRENT_TIME).div(ONE_WEEK).mul(ONE_WEEK) + expect(await voting.getEpochStartTimestamp()).eq(EXPECTED_EPOCH_START_TIME) + }); + it("getEpochEndTimestamp() == getEpochStartTimestamp() + ONE_WEEK ", async function () { + expect(await voting.getEpochEndTimestamp()).eq((await voting.getEpochStartTimestamp()).add(ONE_WEEK)) + }); + it("getEpochStartTimestamp() should be equivalent to gaugeController ", async function () { + expect(await voting.getEpochStartTimestamp()).eq(await gaugeController.getEpochStartTimestamp()) + }); + it("getEpochEndTimestamp() should be equivalent to gaugeController ", async function () { + expect(await voting.getEpochEndTimestamp()).eq(await gaugeController.getEpochEndTimestamp()) + }); + it("getVotePower should return 0 for a non-lock owner", async function () { + expect(await voting.getVotePower(voter1.address)).eq(0) + }); + it("getVotes should return empty array for non-voter", async function () { + expect(await voting.getVotes(voter1.address)).deep.eq([]) + }); + it("chargePremiums should revert", async function () { + await expect(voting.connect(governor).chargePremiums()).to.be.revertedWith("GaugeWeightsNotYetUpdated") + }); + }); + + describe("governance", () => { + it("starts with the correct governor", async () => { + expect(await voting.governance()).to.equal(governor.address); + }); + it("rejects setting new governance by non governor", async () => { + await expect(voting.connect(voter1).setPendingGovernance(voter1.address)).to.be.revertedWith("!governance"); + }); + it("can set new governance", async () => { + let tx = await voting.connect(governor).setPendingGovernance(deployer.address); + await expect(tx).to.emit(voting, "GovernancePending").withArgs(deployer.address); + expect(await voting.governance()).to.equal(governor.address); + expect(await voting.pendingGovernance()).to.equal(deployer.address); + }); + it("rejects governance transfer by non governor", async () => { + await expect(voting.connect(voter1).acceptGovernance()).to.be.revertedWith("!pending governance"); + }); + it("can transfer governance", async () => { + let tx = await voting.connect(deployer).acceptGovernance(); + await expect(tx) + .to.emit(voting, "GovernanceTransferred") + .withArgs(governor.address, deployer.address); + expect(await voting.governance()).to.equal(deployer.address); + await voting.connect(deployer).setPendingGovernance(governor.address); + await voting.connect(governor).acceptGovernance(); + }); + }); + + describe("setRegistry", () => { + let registry2: Registry; + const RANDOM_ADDRESS_1 = ethers.Wallet.createRandom().connect(provider).address; + const RANDOM_ADDRESS_2 = ethers.Wallet.createRandom().connect(provider).address; + const RANDOM_ADDRESS_3 = ethers.Wallet.createRandom().connect(provider).address; + + before(async function () { + registry2 = (await deployContract(deployer, artifacts.Registry, [governor.address])) as Registry; + }); + it("reverts if not governor", async function () { + await expect(voting.connect(voter1).setRegistry(registry2.address)).to.be.revertedWith("!governance"); + }) + it("reverts if zero address registry", async function () { + await expect(voting.connect(governor).setRegistry(ZERO_ADDRESS, {gasLimit:1000000})).to.be.revertedWith('ZeroAddressInput("registry")'); + }); + it("reverts if zero address revenueRouter in Registry", async function () { + await expect(voting.connect(governor).setRegistry(registry2.address, {gasLimit:1000000})).to.be.revertedWith('ZeroAddressInput("revenueRouter")'); + await registry2.connect(governor).set(["revenueRouter"], [RANDOM_ADDRESS_1]); + }); + it("reverts if zero address underwritingLocker in Registry", async function () { + await expect(voting.connect(governor).setRegistry(registry2.address, {gasLimit:1000000})).to.be.revertedWith('ZeroAddressInput("underwritingLocker")'); + await registry2.connect(governor).set(["underwritingLocker"], [RANDOM_ADDRESS_2]); + }) + it("reverts if zero address gaugeController in Registry", async function () { + await expect(voting.connect(governor).setRegistry(registry2.address, {gasLimit:1000000})).to.be.revertedWith('ZeroAddressInput("gaugeController")'); + await registry2.connect(governor).set(["gaugeController"], [RANDOM_ADDRESS_3]); + }); + it("sets registry", async function () { + const tx = await voting.connect(governor).setRegistry(registry2.address); + await expect(tx).to.emit(voting, "RegistrySet").withArgs(registry2.address); + }); + it("copies Registry addresses to own state variables", async function () { + expect(await voting.registry()).eq(registry2.address); + expect(await voting.revenueRouter()).eq(RANDOM_ADDRESS_1); + expect(await voting.underwritingLocker()).eq(RANDOM_ADDRESS_2); + expect(await voting.gaugeController()).eq(RANDOM_ADDRESS_3); + }); + after(async function () { + await voting.connect(governor).setRegistry(registry.address); + }); + }); + + describe("setDelegate", () => { + // Create two locks for voter1: lockID 1 => 1yr, lockID 2 => 2yr + // and two locks for voter 2: lockID 3 => 3yr, lockID 4 => 4yr + before(async function () { + const CURRENT_TIME = (await provider.getBlock('latest')).timestamp; + await token.connect(deployer).transfer(voter1.address, ONE_ETHER.mul(100000)) + await token.connect(deployer).transfer(voter2.address, ONE_ETHER.mul(100000)) + await token.connect(voter1).approve(underwritingLocker.address, constants.MaxUint256) + await token.connect(voter2).approve(underwritingLocker.address, constants.MaxUint256) + await underwritingLocker.connect(voter1).createLock(voter1.address, DEPOSIT_AMOUNT, CURRENT_TIME + ONE_YEAR); + await underwritingLocker.connect(voter1).createLock(voter1.address, DEPOSIT_AMOUNT, CURRENT_TIME + 2 * ONE_YEAR); + await underwritingLocker.connect(voter2).createLock(voter2.address, DEPOSIT_AMOUNT, CURRENT_TIME + 3 * ONE_YEAR); + await underwritingLocker.connect(voter2).createLock(voter2.address, DEPOSIT_AMOUNT, CURRENT_TIME + 4 * ONE_YEAR); + expect(await voting.delegateOf(voter1.address)).eq(ZERO_ADDRESS) + }); + it("owner can set delegate", async function () { + expect(await voting.getVotingDelegatorsOf(delegate1.address)).deep.eq([]) + const tx = await voting.connect(voter1).setDelegate(delegate1.address); + await expect(tx).to.emit(voting, "DelegateSet").withArgs(voter1.address, delegate1.address); + expect(await voting.delegateOf(voter1.address)).eq(delegate1.address) + expect(await voting.delegateOf(voter2.address)).eq(ZERO_ADDRESS) + expect(await voting.getVotingDelegatorsOf(delegate1.address)).deep.eq([voter1.address]) + }) + it("getVotingDelegatorsOf can show multiple delegators", async function () { + await voting.connect(voter2).setDelegate(delegate1.address); + expect(await voting.getVotingDelegatorsOf(delegate1.address)).deep.eq([voter1.address, voter2.address]) + await voting.connect(voter2).setDelegate(ZERO_ADDRESS); + expect(await voting.getVotingDelegatorsOf(delegate1.address)).deep.eq([voter1.address]) + }) + }); + + describe("setUpdater", () => { + it("non governor cannot setUpdater", async () => { + await expect(voting.connect(voter1).setUpdater(updater.address)).to.be.revertedWith("!governance"); + }); + it("can set updater", async () => { + const tx = await voting.connect(governor).setUpdater(updater.address); + await expect(tx).to.emit(voting, "UpdaterSet").withArgs(updater.address); + expect(await voting.updater()).eq(updater.address) + }); + }); + + describe("setBribeController", () => { + it("non governor cannot setBribeController", async () => { + await expect(voting.connect(voter1).setBribeController()).to.be.revertedWith("!governance"); + }); + it("will revert if bribeController not set in Registry", async () => { + await expect(voting.connect(governor).setBribeController()).to.be.revertedWith('ZeroAddressInput("bribeController")'); + }); + it("can setBribeController", async () => { + await registry.connect(governor).set(["bribeController"], [bribeController.address]) + const tx = await voting.connect(governor).setBribeController(); + await expect(tx).to.emit(voting, "BribeControllerSet").withArgs(bribeController.address); + expect(await voting.bribeController()).eq(bribeController.address) + }); + }); + + /******************* + STATE SUMMARY + *******************/ + /** + * There are four locks owned: + * lockID 1 => 1e18 locked for 1 yr, owned by voter1, managed by delegate1 + * lockID 2 => 1e18 locked for 2 yrs, owned by voter1, managed by delegate1 + * lockID 3 => 1e18 locked for 3 yrs, owned by voter2 + * lockID 4 => 1e18 locked for 4 yrs, owned by voter2 + */ + + describe("getVotePower() sanity check", () => { + it("should return appropriate values", async function () { + const ONE_YEAR_LOCK_ID = 1; + const TWO_YEAR_LOCK_ID = 2; + const THREE_YEAR_LOCK_ID = 3; + const FOUR_YEAR_LOCK_ID = 4; + expectClose(await underwritingLocker.timeLeft(ONE_YEAR_LOCK_ID), ONE_YEAR, 1e15) + expectClose(await underwritingLocker.timeLeft(TWO_YEAR_LOCK_ID), 2 * ONE_YEAR, 1e15) + expectClose(await underwritingLocker.timeLeft(THREE_YEAR_LOCK_ID), 3 * ONE_YEAR, 1e15) + expectClose(await underwritingLocker.timeLeft(FOUR_YEAR_LOCK_ID), 4 * ONE_YEAR, 1e15) + // Expect 1-yr lock multiplier = sqrt(12) / sqrt(6) = sqrt(2) + const EXPECTED_LOCK_MULTIPLIER_ONE_YEAR = sqrt(SCALE_FACTOR.mul(SCALE_FACTOR).mul(2)); + // Expect 2-yr lock multiplier = sqrt(24) / sqrt(6) = 2 + const EXPECTED_LOCK_MULTIPLIER_TWO_YEAR = SCALE_FACTOR.mul(2); + // Expect 3-yr lock multiplier = sqrt(36) / sqrt(6) = sqrt(6) + const EXPECTED_LOCK_MULTIPLIER_THREE_YEAR = sqrt(SCALE_FACTOR.mul(SCALE_FACTOR).mul(6)); + // Expect 4-yr lock multiplier = sqrt(48) / sqrt(6) = sqrt(8) + const EXPECTED_LOCK_MULTIPLIER_FOUR_YEAR = sqrt(SCALE_FACTOR.mul(SCALE_FACTOR).mul(8)); + expectClose(await underwritingLocker.getLockMultiplier(ONE_YEAR_LOCK_ID), EXPECTED_LOCK_MULTIPLIER_ONE_YEAR, 1e15) + expectClose(await underwritingLocker.getLockMultiplier(TWO_YEAR_LOCK_ID), EXPECTED_LOCK_MULTIPLIER_TWO_YEAR, 1e15) + expectClose(await underwritingLocker.getLockMultiplier(THREE_YEAR_LOCK_ID), EXPECTED_LOCK_MULTIPLIER_THREE_YEAR, 1e15) + expectClose(await underwritingLocker.getLockMultiplier(FOUR_YEAR_LOCK_ID), EXPECTED_LOCK_MULTIPLIER_FOUR_YEAR, 1e15) + const EXPECTED_VOTE_POWER_ONE_YEAR_LOCK = EXPECTED_LOCK_MULTIPLIER_ONE_YEAR.mul(DEPOSIT_AMOUNT).div(SCALE_FACTOR) + const EXPECTED_VOTE_POWER_TWO_YEAR_LOCK = EXPECTED_LOCK_MULTIPLIER_TWO_YEAR.mul(DEPOSIT_AMOUNT).div(SCALE_FACTOR) + const EXPECTED_VOTE_POWER_THREE_YEAR_LOCK = EXPECTED_LOCK_MULTIPLIER_THREE_YEAR.mul(DEPOSIT_AMOUNT).div(SCALE_FACTOR) + const EXPECTED_VOTE_POWER_FOUR_YEAR_LOCK = EXPECTED_LOCK_MULTIPLIER_FOUR_YEAR.mul(DEPOSIT_AMOUNT).div(SCALE_FACTOR) + expectClose(await voting.getVotePower(voter1.address), EXPECTED_VOTE_POWER_ONE_YEAR_LOCK.add(EXPECTED_VOTE_POWER_TWO_YEAR_LOCK), 1e15); + expectClose(await voting.getVotePower(voter2.address), EXPECTED_VOTE_POWER_THREE_YEAR_LOCK.add(EXPECTED_VOTE_POWER_FOUR_YEAR_LOCK), 1e15); + }); + }); + + describe("cacheLastProcessedVotePower()", () => { + it("should revert if called by non gaugeController", async function () { + await expect(voting.connect(governor).cacheLastProcessedVotePower(voter1.address, 1)).to.be.revertedWith("NotGaugeController") + }); + }); + + describe("gaugeController.removeTokenholder", () => { + it("rejects setting new governance by non governor", async () => { + await expect(gaugeController.connect(voter1).removeTokenholder(voter1.address)).to.be.revertedWith("!governance"); + }); + it("cannot remove address, that has not previously been added as voting contract", async () => { + await expect(gaugeController.connect(governor).removeTokenholder(deployer.address)).to.be.revertedWith("TokenholderNotPresent"); + }); + it("can remove voting contract", async () => { + await gaugeController.connect(governor).addTokenholder(voter1.address); + let tx = await gaugeController.connect(governor).removeTokenholder(voter1.address); + await expect(tx).to.emit(gaugeController, "TokenholderRemoved").withArgs(voter1.address); + }); + }); + + describe("gaugeController.setLeverageFactor", () => { + it("non governor cannot setLeverageFactor", async () => { + await expect(gaugeController.connect(voter1).setLeverageFactor(ONE_HUNDRED_PERCENT)).to.be.revertedWith("!governance"); + }); + it("can set new leverage factor", async () => { + let tx = await gaugeController.connect(governor).setLeverageFactor(ONE_HUNDRED_PERCENT.mul(2)); + await expect(tx).to.emit(gaugeController, "LeverageFactorSet").withArgs(ONE_HUNDRED_PERCENT.mul(2)); + expect(await gaugeController.leverageFactor()).eq(ONE_HUNDRED_PERCENT.mul(2)) + await gaugeController.connect(governor).setLeverageFactor(ONE_HUNDRED_PERCENT) + }); + }); + + describe("gaugeController.setToken", () => { + it("non governor cannot setToken", async () => { + await expect(gaugeController.connect(voter1).setToken(voter1.address)).to.be.revertedWith("!governance"); + }); + it("can set new token", async () => { + let tx = await gaugeController.connect(governor).setToken(voter1.address); + await expect(tx).to.emit(gaugeController, "TokenSet").withArgs(voter1.address); + expect(await gaugeController.token()).eq(voter1.address) + await gaugeController.connect(governor).setToken(token.address) + }); + }); + + describe("gaugeController.setUpdater", () => { + it("non governor cannot setUpdater", async () => { + await expect(gaugeController.connect(voter1).setUpdater(updater.address)).to.be.revertedWith("!governance"); + }); + it("can set updater", async () => { + let tx = await gaugeController.connect(governor).setUpdater(updater.address); + await expect(tx).to.emit(gaugeController, "UpdaterSet").withArgs(updater.address); + expect(await gaugeController.updater()).eq(updater.address) + }); + }); + + /********************* + INTENTION STATEMENT + *********************/ + // voter1 will vote for gaugeID 1 with 100% of vote power + + describe("basic vote() scenario", () => { + let LAST_RECORDED_VOTE_POWER: BN; // To transport VOTE_POWER value from one unit test to another. + + it("vote() and voteMultiple() should throw if gauge weights have not been processed", async function () { + await expect(voting.connect(voter1).vote(voter1.address, 1, 10000)).to.be.revertedWith("LastEpochPremiumsNotCharged"); + await expect(voting.connect(voter1).voteMultiple(voter1.address, [1, 2], [10000, 10000])).to.be.revertedWith("LastEpochPremiumsNotCharged"); + }); + it("updateGaugeWeights() should revert if non governor or updater", async function () { + await expect(gaugeController.connect(voter1).updateGaugeWeights()).to.be.revertedWith("NotUpdaterNorGovernance"); + }); + it("chargePremiums() should revert if non governor or updater", async function () { + await expect(voting.connect(voter1).chargePremiums()).to.be.revertedWith("NotUpdaterNorGovernance"); + }); + it("chargePremiums() should revert if gauge weights have not been updated", async function () { + await expect(voting.connect(governor).chargePremiums()).to.be.revertedWith("GaugeWeightsNotYetUpdated"); + }); + it("updateGaugeWeights() should succeed", async function () { + const EPOCH_START_TIME = await voting.getEpochStartTimestamp(); + const tx = await gaugeController.connect(governor).updateGaugeWeights({gasLimit: CUSTOM_GAS_LIMIT}); + await expect(tx).to.emit(gaugeController, "GaugeWeightsUpdated").withArgs(EPOCH_START_TIME); + expect(await gaugeController.lastTimeGaugeWeightsUpdated()).eq(EPOCH_START_TIME) + expect(await gaugeController.getVotePowerSum()).eq(0) + }); + it("updateGaugeWeights() should revert if attempted again in the same epoch", async function () { + await expect(gaugeController.connect(governor).updateGaugeWeights()).to.be.revertedWith("GaugeWeightsAlreadyUpdated"); + }); + it("isVotingOpen() should return false at this point", async function () { + expect(await voting.isVotingOpen()).eq(false); + }); + it("vote() and voteMultiple() should throw if premiums have not been charged", async function () { + await expect(voting.connect(voter1).vote(voter1.address, 1, 10000)).to.be.revertedWith("LastEpochPremiumsNotCharged"); + await expect(voting.connect(voter1).voteMultiple(voter1.address, [1, 2], [10000, 10000])).to.be.revertedWith("LastEpochPremiumsNotCharged"); + }); + it("chargePremiums() should revert before tokenholder added to gaugeController()", async function () { + await expect(voting.connect(governor).chargePremiums()).to.be.revertedWith("NoTokenholdersAdded"); + await gaugeController.connect(governor).addTokenholder(underwritingLocker.address); + }); + it("chargePremiums() should succeed", async function () { + const EPOCH_START_TIME = await voting.getEpochStartTimestamp(); + const tx = await voting.connect(governor).chargePremiums(); + await expect(tx).to.emit(voting, "AllPremiumsCharged").withArgs(EPOCH_START_TIME); + expect(await voting.lastTimePremiumsCharged()).eq(EPOCH_START_TIME) + }); + it("isVotingOpen() should return true at this point", async function () { + expect(await voting.isVotingOpen()).eq(true); + }); + it("chargePremiums() should revert if attempted again in the same epoch", async function () { + await expect(voting.connect(governor).chargePremiums()).to.be.revertedWith("LastEpochPremiumsAlreadyProcessed"); + }); + it("non-owner or non-delegate cannot vote() or voteMultiple()", async function () { + await expect(voting.connect(anon).vote(voter1.address, 1, 1)).to.be.revertedWith("NotOwnerNorDelegate()"); + await expect(voting.connect(anon).voteMultiple(voter1.address, [1, 2], [10000, 10000])).to.be.revertedWith("NotOwnerNorDelegate"); + }); + it("cannot vote() or voteMultiple() for gauge that has not been added", async function () { + await expect(voting.connect(voter1).vote(voter1.address, 1, 10000)).to.be.revertedWith("GaugeIDNotExist"); + await expect(voting.connect(voter1).voteMultiple(voter1.address, [1, 2], [10000, 10000])).to.be.revertedWith("GaugeIDNotExist"); + }); + it("cannot vote() or voteMultiple() for gaugeID 0", async function () { + await expect(voting.connect(voter1).vote(voter1.address, 0, 10000)).to.be.revertedWith("CannotVoteForGaugeID0"); + await expect(voting.connect(voter1).voteMultiple(voter1.address, [0, 1], [10000, 10000])).to.be.revertedWith("CannotVoteForGaugeID0"); + }); + it("non-governor cannot add gauge", async function () { + await expect(gaugeController.connect(voter1).addGauge("gauge1", ONE_PERCENT)).to.be.revertedWith("!governance"); + }); + it("governor can add gauge", async function () { + const tx = await gaugeController.connect(governor).addGauge("gauge1", ONE_PERCENT); + await expect(tx).to.emit(gaugeController, "GaugeAdded").withArgs(1, ONE_PERCENT, "gauge1"); + expect(await gaugeController.totalGauges()).eq(1) + expect(await gaugeController.getGaugeName(1)).eq("gauge1") + expect(await gaugeController.isGaugeActive(1)).eq(true) + expect(await gaugeController.getRateOnLineOfGauge(1)).eq(ONE_PERCENT) + }); + it("non governor cannot setRateOnLine", async () => { + await expect(gaugeController.connect(voter1).setRateOnLine([1], [1])).to.be.revertedWith("!governance"); + }); + it("cannot setRateOnLine of non-existent gauge", async () => { + await expect(gaugeController.connect(governor).setRateOnLine([2], [1])).to.be.reverted; + }); + it("cannot setRateOnLine with mismatching arrays", async () => { + await expect(gaugeController.connect(governor).setRateOnLine([2, 0], [1])).to.be.revertedWith("ArrayArgumentsLengthMismatch"); + }); + it("can set setRateOnLine", async () => { + let tx = await gaugeController.connect(governor).setRateOnLine([1], [1]); + await expect(tx).to.emit(gaugeController, "RateOnLineSet").withArgs(1, 1); + expect(await gaugeController.getRateOnLineOfGauge(1)).eq(1) + await gaugeController.connect(governor).setRateOnLine([1], [ONE_PERCENT]); + }); + it("cannot vote() or voteMultiple() before voting contract added to gaugeController", async function () { + await expect(voting.connect(voter1).vote(voter1.address, 1, 10000)).to.be.revertedWith("NotVotingContract"); + await expect(voting.connect(voter1).voteMultiple(voter1.address, [1, 1], [10000, 10000])).to.be.revertedWith("NotVotingContract"); + await gaugeController.connect(governor).addVotingContract(voting.address); + }); + it("non governor cannot remove voting contract", async () => { + await expect(gaugeController.connect(voter1).removeVotingContract(voter1.address)).to.be.revertedWith("!governance"); + }); + it("cannot remove address, that has not previously been added as voting contract", async () => { + await expect(gaugeController.connect(governor).removeVotingContract(deployer.address)).to.be.revertedWith("VotingContractNotAdded"); + }); + it("can remove voting contract", async () => { + const tx = await gaugeController.connect(governor).removeVotingContract(voting.address); + await expect(tx).to.emit(gaugeController, "VotingContractRemoved").withArgs(voting.address); + await gaugeController.connect(governor).addVotingContract(voting.address); + }); + it("no premiums should have been collected at this point", async function () { + expect(await token.balanceOf(revenueRouter.address)).eq(0) + }); + it("non-governor cannot pause gauge", async function () { + await expect(gaugeController.connect(voter1).pauseGauge(1)).to.be.revertedWith("!governance"); + }); + it("governor can pause gauge", async function () { + const tx = await gaugeController.connect(governor).pauseGauge(1); + await expect(tx).to.emit(gaugeController, "GaugePaused").withArgs(1, "gauge1"); + expect(await gaugeController.totalGauges()).eq(1) + expect(await gaugeController.getNumPausedGauges()).eq(1) + }); + it("non-governor cannot repause gauge", async function () { + await expect(gaugeController.connect(governor).pauseGauge(1)).to.be.revertedWith("GaugeAlreadyPaused(1)"); + }); + it("neither voter nor delegate can vote() or voteMultiple() while gauge is paused", async function () { + await expect(voting.connect(voter1).vote(voter1.address, 1, 10000)).to.be.revertedWith("GaugeIDPaused"); + await expect(voting.connect(voter1).voteMultiple(voter1.address, [1, 1], [10000, 10000])).to.be.revertedWith("GaugeIDPaused"); + await gaugeController.connect(governor).unpauseGauge(1); + }); + it("non-governor cannot re-unpause gauge", async function () { + await expect(gaugeController.connect(governor).unpauseGauge(1)).to.be.revertedWith("GaugeAlreadyUnpaused(1)"); + }); + it("non-governor cannot unpause gaugeID 0", async function () { + await expect(gaugeController.connect(governor).unpauseGauge(0)).to.be.revertedWith("CannotUnpauseGaugeID0"); + }); + it("non lockowner cannot vote", async function () { + await expect(voting.connect(anon).vote(anon.address, 1, 10000)).to.be.revertedWith("VoterHasNoLocks"); + await expect(voting.connect(anon).voteMultiple(anon.address, [1, 1], [10000, 10000])).to.be.revertedWith("VoterHasNoLocks"); + }); + it("cannot vote with BPS > 10000", async function () { + await expect(voting.connect(voter1).vote(voter1.address, 1, 10001)).to.be.revertedWith("SingleVotePowerBPSOver10000"); + await expect(voting.connect(voter1).voteMultiple(voter1.address, [1, 2], [1, 10001])).to.be.revertedWith("SingleVotePowerBPSOver10000"); + }); + it("lock-owner can vote", async function () { + const GAUGE_ID = 1; + const tx = await voting.connect(voter1).vote(voter1.address, GAUGE_ID, 10000) + await expect(tx).to.emit(voting, "VoteAdded").withArgs(voter1.address, GAUGE_ID, 10000); + }); + it("delegate can change vote", async function () { + const GAUGE_ID = 1; + expect(await voting.delegateOf(voter1.address)).eq(delegate1.address) + const tx = await voting.connect(delegate1).vote(voter1.address, GAUGE_ID, 10000) + await expect(tx).to.emit(voting, "VoteChanged").withArgs(voter1.address, GAUGE_ID, 10000, 10000); + }); + it("bribeController can change vote", async function () { + const GAUGE_ID = 1; + const tx = await voting.connect(bribeController).vote(voter1.address, GAUGE_ID, 10000) + await expect(tx).to.emit(voting, "VoteChanged").withArgs(voter1.address, GAUGE_ID, 10000, 10000); + }); + it("sanity check of getVotes and gauge weights", async function () { + const GAUGE_ID = BN.from("1") + const EXPECTED_VOTEPOWERBPS = BN.from("10000") + const votes = await voting.getVotes(voter1.address) + expect(votes.length).eq(1) + expect(votes[0].gaugeID).eq(GAUGE_ID) + expect(votes[0].votePowerBPS).eq(EXPECTED_VOTEPOWERBPS) + expect(await voting.getVotes(voter1.address)).deep.eq([[GAUGE_ID, EXPECTED_VOTEPOWERBPS]]) + expect(await gaugeController.getGaugeWeight(1)).eq(ZERO) + expect(await gaugeController.getAllGaugeWeights()).deep.eq([ZERO, ZERO]); + expect(await gaugeController.getVotePowerSum()).eq(ZERO) + expect(await gaugeController.getVoteCount(voting.address, voter1.address)).eq(1) + expect(await gaugeController.getVotersCount(voting.address)).eq(1) + }); + it("updateGaugeWeights() called by updater should succeed in the next epoch", async function () { + const CURRENT_TIME = (await provider.getBlock('latest')).timestamp; + await provider.send("evm_mine", [CURRENT_TIME + ONE_WEEK]); + const tx = await gaugeController.connect(updater).updateGaugeWeights({gasLimit: CUSTOM_GAS_LIMIT}); + const EPOCH_START_TIME = await voting.getEpochStartTimestamp(); + const VOTE_POWER = await voting.getVotePower(voter1.address); + await expect(tx).to.emit(gaugeController, "GaugeWeightsUpdated").withArgs(EPOCH_START_TIME); + LAST_RECORDED_VOTE_POWER = VOTE_POWER; + }); + it("sanity check of gauge weights", async function () { + expect(await gaugeController.getGaugeWeight(1)).eq(ONE_HUNDRED_PERCENT) + expect(await gaugeController.getAllGaugeWeights()).deep.eq([ZERO, ONE_HUNDRED_PERCENT]); + expect(await gaugeController.getVotePowerSum()).eq(LAST_RECORDED_VOTE_POWER) + }); + it("cannot vote or voteMultiple, between processVotes() and chargePremiums() for the same epoch", async function () { + expect(await voting.isVotingOpen()).eq(false) + await expect(voting.connect(voter1).vote(voter1.address, 1, 1)).to.be.revertedWith("LastEpochPremiumsNotCharged"); + await expect(voting.connect(delegate1).voteMultiple(voter1.address, [1, 2], [10000, 10000])).to.be.revertedWith("LastEpochPremiumsNotCharged"); + }); + it("chargePremiums() should revert before underwritingLocker.sol call setVotingContract()", async function () { + await expect(voting.connect(governor).chargePremiums()).to.be.revertedWith("NotVotingContract"); + }); + it("chargePremiums() call by updater should succeed in the next epoch, provided allowance granted by underwritingLocker", async function () { + await registry.connect(governor).set(["underwritingLockVoting"],[voting.address]); + await underwritingLocker.connect(governor).setVotingContract(); + const OLD_VOTER_LOCKED_AMOUNT = await getTotalLockedAmount(voter1.address) + const OLD_UNDERWRITING_LOCKER_BALANCE = await token.balanceOf(underwritingLocker.address); + + const tx = await voting.connect(updater).chargePremiums(); + const EPOCH_START_TIME = await voting.getEpochStartTimestamp(); + const NEW_VOTER_LOCKED_AMOUNT = await getTotalLockedAmount(voter1.address) + const NEW_UNDERWRITING_LOCKER_BALANCE = await token.balanceOf(underwritingLocker.address); + const EXPECTED_PREMIUM = await getExpectedPremium(voter1.address, OLD_UNDERWRITING_LOCKER_BALANCE, LAST_RECORDED_VOTE_POWER) + await expect(tx).to.emit(voting, "AllPremiumsCharged").withArgs(EPOCH_START_TIME); + expect(await token.balanceOf(revenueRouter.address)).eq(EXPECTED_PREMIUM); + expect(NEW_VOTER_LOCKED_AMOUNT.sub(OLD_VOTER_LOCKED_AMOUNT)).eq(EXPECTED_PREMIUM.mul(-1)); + expect(NEW_UNDERWRITING_LOCKER_BALANCE.sub(OLD_UNDERWRITING_LOCKER_BALANCE)).eq(EXPECTED_PREMIUM.mul(-1)); + expect(await voting.isVotingOpen()).eq(true) + }); + }); + + /********** + LESSONS + **********/ + /** + * No vote can occur, gaugeController.updateGaugeWeights() and underwritingLockVoting.chargePremiums() has been completed for the last epoch, even at initialization. + * + * GaugeController.sol requires the following setup: + * i.) Deployed with correct must be deployed with correct token variable. + * ii.) gaugeController.addVotingContract() called to add UnderwritingLockVesting.sol. + * iii.) gaugeController.addTokenholder() called to add UnderwritingLocker.sol + * + * Successful call of UnderwritingLocker.setVotingContract() + * i.) underwritingLockVoting must be added as a registry entry key + * ii.) underwritingLocker must have approved underwritingLockVoting.sol as a spender for its balance of $UWE. + */ + + /******************* + STATE SUMMARY + *******************/ + /** + * voter1: + * - gauge1 with 100% vote power + * - delegate is delegate1 + * - Own lockID 1 (1e18 initial deposit, locked for 1 yr) + * - Own lockID 2 (1e18 initial deposit, locked for 2 yr) + * + * voter2: + * - no votes + * - no delegates + * - Own lockID 3 (1e18 initial deposit, locked for 3 yr) + * - Own lockID 4 (1e18 initial deposit, locked for 4 yr) + * + * There is 1 gauge + * gaugeID 1 => "gauge1" => 100% weight + * + * Votes and premiums have been processed for the last epoch + */ + + /********************** + INTENTION STATEMENT + **********************/ + /** + * We will add 2 more gauges, and create 1 more lock + * - gaugeID 2 => 2% ROL + * - gaugeID 3 => 5% ROL + * - Create lockID 5 for voter1, but burn this lock after voting (but before updateGaugeWeights called). + * + * voter1 => will vote 50% for gauge1 (we will pause this gauge after), and 50% for gauge2 + * voter2 => will vote 40% for gauge2, 30% for gauge3, leave 30% unallocated + */ + + describe("basic voteMultiple() scenario, with epoch length set to 2 weeks", () => { + let LAST_RECORDED_VOTE_POWER_1: BN; + let LAST_RECORDED_VOTE_POWER_2: BN; + + // Create new gauges and lock + before(async function () { + const CURRENT_TIME = (await provider.getBlock('latest')).timestamp; + await gaugeController.connect(governor).setEpochLengthInWeeks(2) + await underwritingLocker.connect(voter1).createLock(voter1.address, DEPOSIT_AMOUNT, CURRENT_TIME + 4 * ONE_YEAR) + await gaugeController.connect(governor).addGauge("gauge2", ONE_PERCENT.mul(2)) + await gaugeController.connect(governor).addGauge("gauge3", ONE_PERCENT.mul(5)) + }); + it("should revert if provide mismatching array inputs", async function () { + await expect(voting.connect(voter1).voteMultiple(voter1.address, [1, 2], [1])).to.be.revertedWith("ArrayArgumentsLengthMismatch"); + }); + it("should revert if provide total vote power >10000", async function () { + await expect(voting.connect(voter1).voteMultiple(voter1.address, [1, 2, 3, 1, 1], [5000, 4000, 3000, 4000, 6000])).to.be.revertedWith("TotalVotePowerBPSOver10000"); + }); + it("delegate should be able to voteMultiple()", async function () { + const GAUGE_ID_1 = 1 + const VOTE_POWER_BPS_1 = 5000 + const GAUGE_ID_2 = 2 + const VOTE_POWER_BPS_2 = 5000 + const tx = await voting.connect(delegate1).voteMultiple(voter1.address, [GAUGE_ID_1, GAUGE_ID_2], [VOTE_POWER_BPS_1, VOTE_POWER_BPS_2]); + await expect(tx).to.emit(voting, "VoteChanged").withArgs(voter1.address, GAUGE_ID_1, VOTE_POWER_BPS_1, 10000); + await expect(tx).to.emit(voting, "VoteAdded").withArgs(voter1.address, GAUGE_ID_2, VOTE_POWER_BPS_2); + + // Add edge conditions + await gaugeController.connect(governor).pauseGauge(1) + await underwritingLocker.connect(voter1).withdraw(5, voter1.address); + }); + it("owner should be able to voteMultiple()", async function () { + const GAUGE_ID_1 = 2 + const VOTE_POWER_BPS_1 = 4000 + const GAUGE_ID_2 = 3 + const VOTE_POWER_BPS_2 = 3000 + const tx = await voting.connect(voter2).voteMultiple(voter2.address, [GAUGE_ID_1, GAUGE_ID_2], [VOTE_POWER_BPS_1, VOTE_POWER_BPS_2]); + await expect(tx).to.emit(voting, "VoteAdded").withArgs(voter2.address, GAUGE_ID_1, VOTE_POWER_BPS_1); + await expect(tx).to.emit(voting, "VoteAdded").withArgs(voter2.address, GAUGE_ID_2, VOTE_POWER_BPS_2); + }); + it("voter should not be able to add additional vote such that total used voting power BPS > 10000", async function () { + await expect(voting.connect(voter1).vote(voter1.address, 3, 1)).to.be.revertedWith("TotalVotePowerBPSOver10000"); + }); + it("voter cannot use vote to remove a non-existent vote", async function () { + await expect(voting.connect(voter1).vote(voter1.address, 3, 0)).to.be.revertedWith("EnumerableMap: nonexistent key"); + }); + it("cannot call updateGaugeWeights() before epoch passes", async function () { + await expect(gaugeController.connect(governor).updateGaugeWeights()).to.be.revertedWith("GaugeWeightsAlreadyUpdated"); + }); + it("cannot call chargePremiums() before epoch passes", async function () { + const CURRENT_TIME = (await provider.getBlock('latest')).timestamp; + await provider.send("evm_mine", [CURRENT_TIME + ONE_WEEK]); + await expect(voting.connect(governor).chargePremiums()).to.be.revertedWith("LastEpochPremiumsAlreadyProcessed"); + }); + it("can updateGaugeWeights() in the next epoch", async function () { + const CURRENT_TIME = (await provider.getBlock('latest')).timestamp; + await provider.send("evm_mine", [CURRENT_TIME + ONE_WEEK]); + await expect(voting.connect(governor).chargePremiums()).to.be.revertedWith("GaugeWeightsNotYetUpdated"); + const EPOCH_START_TIME = await voting.getEpochStartTimestamp(); + + const tx = await gaugeController.connect(governor).updateGaugeWeights({gasLimit: CUSTOM_GAS_LIMIT}) + await expect(tx).to.emit(gaugeController, "GaugeWeightsUpdated").withArgs(EPOCH_START_TIME); + LAST_RECORDED_VOTE_POWER_1 = await voting.getVotePower(voter1.address) + LAST_RECORDED_VOTE_POWER_2 = await voting.getVotePower(voter2.address) + + expect (await gaugeController.lastTimeGaugeWeightsUpdated()).eq(EPOCH_START_TIME) + expect (await voting.isVotingOpen()).eq(false) + await expect(voting.connect(voter1).vote(voter1.address, 1, 1)).to.be.revertedWith("LastEpochPremiumsNotCharged") + }); + it("sanity check of gaugeWeights", async function () { + // 50% votePower from voter1 + 40% votePower from voter2 + const VOTE_POWER_GAUGE_2 = (LAST_RECORDED_VOTE_POWER_1.div(2)).add(LAST_RECORDED_VOTE_POWER_2.mul(4).div(10)) + // 30% votePower from voter2 + const VOTE_POWER_GAUGE_3 = LAST_RECORDED_VOTE_POWER_2.mul(3).div(10) + + const EXPECTED_TOTAL_VOTE_POWER = VOTE_POWER_GAUGE_2.add(VOTE_POWER_GAUGE_3) + expectClose(await gaugeController.getVotePowerSum(), EXPECTED_TOTAL_VOTE_POWER, 1e14) + const EXPECTED_GAUGE_2_WEIGHT = SCALE_FACTOR.mul(VOTE_POWER_GAUGE_2).div(EXPECTED_TOTAL_VOTE_POWER) + const EXPECTED_GAUGE_3_WEIGHT = SCALE_FACTOR.mul(VOTE_POWER_GAUGE_3).div(EXPECTED_TOTAL_VOTE_POWER) + expect(await gaugeController.getGaugeWeight(1)).eq(0) // Paused gauge + expectClose(await gaugeController.getGaugeWeight(2), EXPECTED_GAUGE_2_WEIGHT, 1e14) + expectClose(await gaugeController.getGaugeWeight(3), EXPECTED_GAUGE_3_WEIGHT, 1e14) + expect(await gaugeController.getAllGaugeWeights()).deep.eq([ZERO, ZERO, EXPECTED_GAUGE_2_WEIGHT, EXPECTED_GAUGE_3_WEIGHT]); + }); + it("sanity check of relevant gaugeController view functions", async function () { + expect(await gaugeController.totalGauges()).eq(3) + expect(await gaugeController.getNumActiveGauges()).eq(2) + expect(await gaugeController.getNumPausedGauges()).eq(1) + const voters = await gaugeController.getVoters(voting.address); + expect(voters.includes(voter1.address)).eq(true) + expect(voters.includes(voter2.address)).eq(true) + const votes_1 = await gaugeController.getVotes(voting.address, voter1.address) + const votes_2 = await gaugeController.getVotes(voting.address, voter2.address) + expect(votes_1[0].gaugeID).eq(1) + expect(votes_1[0].votePowerBPS).eq(5000) + expect(votes_1[1].gaugeID).eq(2) + expect(votes_1[1].votePowerBPS).eq(5000) + expect(votes_1.length).eq(2) + expect(votes_2[0].gaugeID).eq(2) + expect(votes_2[0].votePowerBPS).eq(4000) + expect(votes_2[1].gaugeID).eq(3) + expect(votes_2[1].votePowerBPS).eq(3000) + expect(votes_2.length).eq(2) + }) + it("can chargePremiums() in the next epoch", async function () { + const OLD_VOTER1_LOCKED_AMOUNT = await getTotalLockedAmount(voter1.address) + const OLD_VOTER2_LOCKED_AMOUNT = await getTotalLockedAmount(voter2.address) + const OLD_UNDERWRITING_LOCKER_BALANCE = await token.balanceOf(underwritingLocker.address); + const OLD_REVENUE_ROUTER_BALANCE = await token.balanceOf(revenueRouter.address); + + const tx = await voting.connect(governor).chargePremiums(); + const EPOCH_START_TIME = await voting.getEpochStartTimestamp() + await expect(tx).to.emit(voting, "AllPremiumsCharged").withArgs(EPOCH_START_TIME) + + const NEW_VOTER1_LOCKED_AMOUNT = await getTotalLockedAmount(voter1.address) + const NEW_VOTER2_LOCKED_AMOUNT = await getTotalLockedAmount(voter2.address) + const NEW_UNDERWRITING_LOCKER_BALANCE = await token.balanceOf(underwritingLocker.address); + const NEW_REVENUE_ROUTER_BALANCE = await token.balanceOf(revenueRouter.address); + const EXPECTED_PREMIUM_VOTER1 = await getExpectedPremium(voter1.address, OLD_UNDERWRITING_LOCKER_BALANCE, LAST_RECORDED_VOTE_POWER_1) + const EXPECTED_PREMIUM_VOTER2 = await getExpectedPremium(voter2.address, OLD_UNDERWRITING_LOCKER_BALANCE, LAST_RECORDED_VOTE_POWER_2) + const EXPECTED_TOTAL_PREMIUM = EXPECTED_PREMIUM_VOTER1.add(EXPECTED_PREMIUM_VOTER2) + + expect(NEW_REVENUE_ROUTER_BALANCE.sub(OLD_REVENUE_ROUTER_BALANCE)).eq(EXPECTED_TOTAL_PREMIUM); + expectClose(NEW_VOTER1_LOCKED_AMOUNT.sub(OLD_VOTER1_LOCKED_AMOUNT),EXPECTED_PREMIUM_VOTER1.mul(-1), 1e15); + expectClose(NEW_VOTER2_LOCKED_AMOUNT.sub(OLD_VOTER2_LOCKED_AMOUNT), EXPECTED_PREMIUM_VOTER2.mul(-1), 1e15); + expectClose(NEW_UNDERWRITING_LOCKER_BALANCE.sub(OLD_UNDERWRITING_LOCKER_BALANCE), EXPECTED_TOTAL_PREMIUM.mul(-1), 1e15); + expect(await voting.isVotingOpen()).eq(true) + await expect(gaugeController.connect(governor).updateGaugeWeights()).to.be.revertedWith("GaugeWeightsAlreadyUpdated") + await expect(voting.connect(governor).chargePremiums()).to.be.revertedWith("LastEpochPremiumsAlreadyProcessed") + expect(await gaugeController.lastTimeGaugeWeightsUpdated()).eq(EPOCH_START_TIME) + expect(await voting.lastTimePremiumsCharged()).eq(EPOCH_START_TIME) + }); + after(async function () { + await gaugeController.connect(governor).setEpochLengthInWeeks(1) + }); + }); + + /******************* + STATE SUMMARY + *******************/ + /** + * voter1: + * - votes: gauge1 (50%), gauge2 (50%) + * - delegate is delegate1 + * - Own lockID 1 (1e18 initial deposit, locked for 1 yr) + * - Own lockID 2 (1e18 initial deposit, locked for 2 yr) + * + * voter2: + * - votes: gauge2 (40%), gauge3 (30%) + * - no delegates + * - Own lockID 3 (1e18 initial deposit, locked for 3 yr) + * - Own lockID 4 (1e18 initial deposit, locked for 4 yr) + * + * There are 3 gauges + * - gauge1 is paused + * + * LockID 5 is burned + */ + + /********************** + INTENTION STATEMENT + **********************/ + /** + * We will unpause gaugeID 1 + * Delegate 1 will remove voter1's vote for gauge2 + * Voter 2 will remove their vote for gauge 3 + */ + + describe("basic removeVote() scenario", () => { + let LAST_RECORDED_VOTE_POWER_1: BN; + let LAST_RECORDED_VOTE_POWER_2: BN; + + before(async function () { + await gaugeController.connect(governor).unpauseGauge(1) + }); + it("should revert if non-owner or non-delegate attempts to removeVote()", async function () { + await expect(voting.connect(anon).removeVote(voter1.address, 2)).to.be.revertedWith("NotOwnerNorDelegate"); + }); + it("should revert if attempt to removeVote() for non-existent gaugeID", async function () { + await expect(voting.connect(voter1).removeVote(voter1.address, 4)).to.be.revertedWith("GaugeIDNotExist"); + }); + it("should revert if attempt to removeVote() for non-existent vote", async function () { + await expect(voting.connect(voter1).removeVote(voter1.address, 3)).to.be.revertedWith("EnumerableMap: nonexistent key"); + }); + it("delegate can removeVote()", async function () { + const GAUGE_ID = 2 + const tx = await voting.connect(delegate1).removeVote(voter1.address, GAUGE_ID); + await expect(tx).to.emit(voting, "VoteRemoved").withArgs(voter1.address, GAUGE_ID); + }) + it("owner can removeVote()", async function () { + const GAUGE_ID = 2 + const tx = await voting.connect(voter2).removeVote(voter2.address, GAUGE_ID); + await expect(tx).to.emit(voting, "VoteRemoved").withArgs(voter2.address, GAUGE_ID); + }) + it("can removeVote() while gauge paused", async function () { + const GAUGE_ID = 2 + await voting.connect(voter2).vote(voter2.address, 2, 4000) + await gaugeController.connect(governor).pauseGauge(2) + const tx = await voting.connect(voter2).removeVote(voter2.address, GAUGE_ID); + await expect(tx).to.emit(voting, "VoteRemoved").withArgs(voter2.address, GAUGE_ID); + await gaugeController.connect(governor).unpauseGauge(2) + }) + it("updateGaugeWeight() updates gauge weights as expected in the next epoch", async function () { + const CURRENT_TIME = (await provider.getBlock('latest')).timestamp; + await provider.send("evm_mine", [CURRENT_TIME + ONE_WEEK]); + await expect(voting.connect(governor).chargePremiums()).to.be.revertedWith("GaugeWeightsNotYetUpdated"); + const EPOCH_START_TIME = await voting.getEpochStartTimestamp(); + + let counter = 0; + while (true) { + counter += 1; + const tx = await gaugeController.connect(governor).updateGaugeWeights({gasLimit: CUSTOM_GAS_LIMIT}) + + if ((await gaugeController.lastTimeGaugeWeightsUpdated()).lt(EPOCH_START_TIME)) { + await expect(tx).to.emit(gaugeController, "IncompleteGaugeUpdate"); + continue; + } else { + await expect(tx).to.emit(gaugeController, "GaugeWeightsUpdated").withArgs(EPOCH_START_TIME); + break; + } + } + console.log(`Required ${counter} iterations of updateGaugeWeights()`) + + LAST_RECORDED_VOTE_POWER_1 = await voting.getVotePower(voter1.address) + LAST_RECORDED_VOTE_POWER_2 = await voting.getVotePower(voter2.address) + + expect (await gaugeController.lastTimeGaugeWeightsUpdated()).eq(EPOCH_START_TIME) + expect (await voting.isVotingOpen()).eq(false) + await expect(voting.connect(voter1).vote(voter1.address, 1, 1)).to.be.revertedWith("LastEpochPremiumsNotCharged") + }) + it("sanity check of gaugeWeights", async function () { + // 50% votePower from voter1 + const VOTE_POWER_GAUGE_1 = LAST_RECORDED_VOTE_POWER_1.div(2) + // 30% votePower from voter2 + const VOTE_POWER_GAUGE_3 = LAST_RECORDED_VOTE_POWER_2.mul(3).div(10) + + const EXPECTED_TOTAL_VOTE_POWER = VOTE_POWER_GAUGE_1.add(VOTE_POWER_GAUGE_3) + expectClose(await gaugeController.getVotePowerSum(), EXPECTED_TOTAL_VOTE_POWER, 1e14) + const EXPECTED_GAUGE_1_WEIGHT = SCALE_FACTOR.mul(VOTE_POWER_GAUGE_1).div(EXPECTED_TOTAL_VOTE_POWER) + const EXPECTED_GAUGE_3_WEIGHT = SCALE_FACTOR.mul(VOTE_POWER_GAUGE_3).div(EXPECTED_TOTAL_VOTE_POWER) + expectClose(await gaugeController.getGaugeWeight(1), EXPECTED_GAUGE_1_WEIGHT, 1e14) + expect(await gaugeController.getGaugeWeight(2)).eq(0) // No votes + expectClose(await gaugeController.getGaugeWeight(3), EXPECTED_GAUGE_3_WEIGHT, 1e14) + }); + it("sanity check of relevant gaugeController view functions", async function () { + expect(await gaugeController.totalGauges()).eq(3) + expect(await gaugeController.getNumActiveGauges()).eq(3) + expect(await gaugeController.getNumPausedGauges()).eq(0) + const votes_1 = await gaugeController.getVotes(voting.address, voter1.address) + const votes_2 = await gaugeController.getVotes(voting.address, voter2.address) + expect(votes_1[0].gaugeID).eq(1) + expect(votes_1[0].votePowerBPS).eq(5000) + expect(votes_1.length).eq(1) + expect(votes_2[0].gaugeID).eq(3) + expect(votes_2[0].votePowerBPS).eq(3000) + expect(votes_2.length).eq(1) + }) + it("chargePremium() charges premiums as expected", async function () { + const OLD_VOTER1_LOCKED_AMOUNT = await getTotalLockedAmount(voter1.address) + const OLD_VOTER2_LOCKED_AMOUNT = await getTotalLockedAmount(voter2.address) + const OLD_UNDERWRITING_LOCKER_BALANCE = await token.balanceOf(underwritingLocker.address); + const OLD_REVENUE_ROUTER_BALANCE = await token.balanceOf(revenueRouter.address); + + const tx = await voting.connect(governor).chargePremiums(); + const EPOCH_START_TIME = await voting.getEpochStartTimestamp() + await expect(tx).to.emit(voting, "AllPremiumsCharged").withArgs(EPOCH_START_TIME) + + const NEW_VOTER1_LOCKED_AMOUNT = await getTotalLockedAmount(voter1.address) + const NEW_VOTER2_LOCKED_AMOUNT = await getTotalLockedAmount(voter2.address) + const NEW_UNDERWRITING_LOCKER_BALANCE = await token.balanceOf(underwritingLocker.address); + const NEW_REVENUE_ROUTER_BALANCE = await token.balanceOf(revenueRouter.address); + const EXPECTED_PREMIUM_VOTER1 = await getExpectedPremium(voter1.address, OLD_UNDERWRITING_LOCKER_BALANCE, LAST_RECORDED_VOTE_POWER_1) + const EXPECTED_PREMIUM_VOTER2 = await getExpectedPremium(voter2.address, OLD_UNDERWRITING_LOCKER_BALANCE, LAST_RECORDED_VOTE_POWER_2) + const EXPECTED_TOTAL_PREMIUM = EXPECTED_PREMIUM_VOTER1.add(EXPECTED_PREMIUM_VOTER2) + + expectClose(NEW_REVENUE_ROUTER_BALANCE.sub(OLD_REVENUE_ROUTER_BALANCE), EXPECTED_TOTAL_PREMIUM, 1e15); + expectClose(NEW_VOTER1_LOCKED_AMOUNT.sub(OLD_VOTER1_LOCKED_AMOUNT), EXPECTED_PREMIUM_VOTER1.mul(-1), 1e15); + expectClose(NEW_VOTER2_LOCKED_AMOUNT.sub(OLD_VOTER2_LOCKED_AMOUNT), EXPECTED_PREMIUM_VOTER2.mul(-1), 1e15); + expectClose(NEW_UNDERWRITING_LOCKER_BALANCE.sub(OLD_UNDERWRITING_LOCKER_BALANCE), EXPECTED_TOTAL_PREMIUM.mul(-1), 1e15); + expect(await voting.isVotingOpen()).eq(true) + await expect(gaugeController.connect(governor).updateGaugeWeights()).to.be.revertedWith("GaugeWeightsAlreadyUpdated") + await expect(voting.connect(governor).chargePremiums()).to.be.revertedWith("LastEpochPremiumsAlreadyProcessed") + expect(await gaugeController.lastTimeGaugeWeightsUpdated()).eq(EPOCH_START_TIME) + expect(await voting.lastTimePremiumsCharged()).eq(EPOCH_START_TIME) + }) + }); + + describe("voteForMultipleVoters and removeVotesForMultipleVoters", () => { + before(async function () { + await voting.connect(voter2).setDelegate(delegate1.address) + }); + it("should revert if non-delegate attempts to voteForMultipleVoters", async function () { + await expect(voting.connect(governor).voteForMultipleVoters([voter1.address, voter2.address], [2], [1])).to.be.revertedWith("NotOwnerNorDelegate"); + }); + it("should revert if non-delegate attempts to removeVotesForMultipleVoters", async function () { + await expect(voting.connect(governor).removeVotesForMultipleVoters([voter1.address, voter2.address], [2])).to.be.revertedWith("NotOwnerNorDelegate"); + }); + it("delegate can voteForMultipleVoters()", async function () { + const tx = await voting.connect(delegate1).voteForMultipleVoters([voter1.address, voter2.address], [2], [1]); + await expect(tx).to.emit(voting, "VoteAdded").withArgs(voter1.address, 2, 1); + await expect(tx).to.emit(voting, "VoteAdded").withArgs(voter2.address, 2, 1); + }) + it("delegate can removeVotesForMultipleVoters()", async function () { + const tx = await voting.connect(delegate1).removeVotesForMultipleVoters([voter1.address, voter2.address], [2]); + await expect(tx).to.emit(voting, "VoteRemoved").withArgs(voter1.address, 2); + await expect(tx).to.emit(voting, "VoteRemoved").withArgs(voter1.address, 2); + }) + after(async function () { + await voting.connect(voter1).vote(voter1.address, 2, 5000) + await voting.connect(voter2).vote(voter2.address, 2, 4000) + await voting.connect(voter2).setDelegate(ZERO_ADDRESS) + }); + }); + + /******************* + STATE SUMMARY + *******************/ + /** + * voter1: + * - votes: gauge1 (50%) + * - delegate is delegate1 + * - Own lockID 1 (1e18 initial deposit, locked for 1 yr) + * - Own lockID 2 (1e18 initial deposit, locked for 2 yr) + * + * voter2: + * - votes: gauge3 (30%) + * - no delegates + * - Own lockID 3 (1e18 initial deposit, locked for 3 yr) + * - Own lockID 4 (1e18 initial deposit, locked for 4 yr) + * + * There are 3 gauges + * - gauge1: 1% ROL + * - gauge2: 2% ROL + * - gauge3: 5% ROL + * + * LockID 5 is burned + */ + + /********************** + INTENTION STATEMENT + **********************/ + /** + * We will re-add the votes that were deleted in the last block (voter1 and voter2 votes for gauge2) + * We will then removeVoteMultiple() for all of voter1 and voter2 votes + * We will create 2 more gauges (for a total of 5) + * We will create 100 locks of maximum duration for 100 new voters, and distribute their votes equally amongst gauges 1-5 + */ + + describe("removeVoteMultiple() and stress test with 100 votes", () => { + let LAST_RECORDED_VOTE_POWER_N: BN; + let RANDOM_VOTER: Wallet + + before(async function () { + const CURRENT_TIME = (await provider.getBlock('latest')).timestamp; + await voting.connect(voter1).vote(voter1.address, 2, 5000); + await voting.connect(voter2).vote(voter2.address, 2, 4000); + await gaugeController.connect(governor).addGauge("gauge4", ONE_PERCENT) + await gaugeController.connect(governor).addGauge("gauge5", ONE_PERCENT) + for (let i = 0; i < 100; i++) { + RANDOM_VOTER = ethers.Wallet.createRandom().connect(provider); + await token.connect(deployer).transfer(RANDOM_VOTER.address, ONE_ETHER) // gas money + // Can't createLock in parallel or else nonce re-use issue lol + await underwritingLocker.connect(voter1).createLock(RANDOM_VOTER.address, DEPOSIT_AMOUNT, CURRENT_TIME + 4 * ONE_YEAR) + await deployer.sendTransaction({to: RANDOM_VOTER.address, value: ONE_ETHER.div(10)}) + await voting.connect(RANDOM_VOTER).vote( + RANDOM_VOTER.address, + i < 20 ? 1 : + i < 40 ? 2 : + i < 60 ? 3 : + i < 80 ? 4 : + 5 + , + 10000 + ) + } + expect(await underwritingLocker.totalNumLocks()).eq(105) + }); + it("should revert if non-owner or non-delegate attempts to removeVoteMultiple()", async function () { + await expect(voting.connect(anon).removeVoteMultiple(voter1.address, [1, 2])).to.be.revertedWith("NotOwnerNorDelegate"); + }); + it("should revert if attempt to removeVoteMultiple() for non-existent lockID", async function () { + await expect(voting.connect(voter1).removeVoteMultiple(voter1.address, [5, 1])).to.be.revertedWith("EnumerableMap: nonexistent key"); + }); + it("delegate can removeVoteMultiple()", async function () { + const tx = await voting.connect(delegate1).removeVoteMultiple(voter1.address, [1, 2]); + await expect(tx).to.emit(voting, "VoteRemoved").withArgs(voter1.address, 1); + await expect(tx).to.emit(voting, "VoteRemoved").withArgs(voter1.address, 2); + }) + it("voter can removeVoteMultiple()", async function () { + const tx = await voting.connect(voter2).removeVoteMultiple(voter2.address, [2, 3]); + await expect(tx).to.emit(voting, "VoteRemoved").withArgs(voter2.address, 2); + await expect(tx).to.emit(voting, "VoteRemoved").withArgs(voter2.address, 3); + }) + it("updateGaugeWeight() updates gauge weights as expected in the next epoch", async function () { + const CURRENT_TIME = (await provider.getBlock('latest')).timestamp; + await provider.send("evm_mine", [CURRENT_TIME + ONE_WEEK]); + await expect(voting.connect(governor).chargePremiums()).to.be.revertedWith("GaugeWeightsNotYetUpdated"); + const EPOCH_START_TIME = await voting.getEpochStartTimestamp(); + + let counter = 0; + while (true) { + counter += 1; + const tx = await gaugeController.connect(governor).updateGaugeWeights({gasLimit: CUSTOM_GAS_LIMIT}) + + if ((await gaugeController.lastTimeGaugeWeightsUpdated()).lt(EPOCH_START_TIME)) { + await expect(tx).to.emit(gaugeController, "IncompleteGaugeUpdate"); + continue; + } else { + await expect(tx).to.emit(gaugeController, "GaugeWeightsUpdated").withArgs(EPOCH_START_TIME); + break; + } + } + console.log(`Required ${counter} iterations of updateGaugeWeights()`) + + LAST_RECORDED_VOTE_POWER_N = await voting.getVotePower(RANDOM_VOTER.address) + expect (await gaugeController.lastTimeGaugeWeightsUpdated()).eq(EPOCH_START_TIME) + expect (await voting.isVotingOpen()).eq(false) + await expect(voting.connect(voter1).vote(voter1.address, 1, 1)).to.be.revertedWith("LastEpochPremiumsNotCharged") + + const TOTAL_RECORDED_VOTE_POWER = LAST_RECORDED_VOTE_POWER_N.mul(100) + // Don't expect exact equality because different votes processed at different timestamp + expectClose(await gaugeController.getVotePowerSum(), TOTAL_RECORDED_VOTE_POWER, 1e14); + expectClose(await gaugeController.getGaugeWeight(1), ONE_HUNDRED_PERCENT.div(5), 1e14); + expectClose(await gaugeController.getGaugeWeight(2), ONE_HUNDRED_PERCENT.div(5), 1e14); + expectClose(await gaugeController.getGaugeWeight(3), ONE_HUNDRED_PERCENT.div(5), 1e14); + expectClose(await gaugeController.getGaugeWeight(4), ONE_HUNDRED_PERCENT.div(5), 1e14); + expectClose(await gaugeController.getGaugeWeight(5), ONE_HUNDRED_PERCENT.div(5), 1e14); + }) + it("chargePremium() charges premiums as expected", async function () { + const OLD_VOTER_LOCKED_AMOUNT = await getTotalLockedAmount(RANDOM_VOTER.address) + const OLD_UNDERWRITING_LOCKER_BALANCE = await token.balanceOf(underwritingLocker.address); + const OLD_REVENUE_ROUTER_BALANCE = await token.balanceOf(revenueRouter.address); + + const EPOCH_START_TIME = await voting.getEpochStartTimestamp() + + let counter = 0; + while (true) { + counter += 1; + const tx = await voting.connect(governor).chargePremiums({gasLimit: CUSTOM_GAS_LIMIT}) + + if ((await voting.lastTimePremiumsCharged()).lt(EPOCH_START_TIME)) { + await expect(tx).to.emit(voting, "IncompletePremiumsCharge"); + continue; + } else { + await expect(tx).to.emit(voting, "AllPremiumsCharged").withArgs(EPOCH_START_TIME); + break; + } + } + console.log(`Required ${counter} iterations of chargePremiums()`) + + const NEW_VOTER_LOCKED_AMOUNT = await getTotalLockedAmount(RANDOM_VOTER.address) + const NEW_UNDERWRITING_LOCKER_BALANCE = await token.balanceOf(underwritingLocker.address); + const NEW_REVENUE_ROUTER_BALANCE = await token.balanceOf(revenueRouter.address); + const EXPECTED_PREMIUM = await getExpectedPremium(RANDOM_VOTER.address, OLD_UNDERWRITING_LOCKER_BALANCE, LAST_RECORDED_VOTE_POWER_N) + const EXPECTED_PREMIUM_UNIT = await getExpectedUnitPremium(RANDOM_VOTER.address, OLD_UNDERWRITING_LOCKER_BALANCE, LAST_RECORDED_VOTE_POWER_N); + const EXPECTED_TOTAL_PREMIUM = EXPECTED_PREMIUM_UNIT.mul(200) // 20*1 + 20*1 + 20*1 + 20*2 + 20*5 + + expectClose(NEW_REVENUE_ROUTER_BALANCE.sub(OLD_REVENUE_ROUTER_BALANCE), EXPECTED_TOTAL_PREMIUM, 1e15); + expectClose(NEW_VOTER_LOCKED_AMOUNT.sub(OLD_VOTER_LOCKED_AMOUNT), EXPECTED_PREMIUM.mul(-1), 1e15); + expectClose(NEW_UNDERWRITING_LOCKER_BALANCE.sub(OLD_UNDERWRITING_LOCKER_BALANCE), EXPECTED_TOTAL_PREMIUM.mul(-1), 1e15); + expect(await voting.isVotingOpen()).eq(true) + await expect(gaugeController.connect(governor).updateGaugeWeights()).to.be.revertedWith("GaugeWeightsAlreadyUpdated") + await expect(voting.connect(governor).chargePremiums()).to.be.revertedWith("LastEpochPremiumsAlreadyProcessed") + expect(await gaugeController.lastTimeGaugeWeightsUpdated()).eq(EPOCH_START_TIME) + expect(await voting.lastTimePremiumsCharged()).eq(EPOCH_START_TIME) + }) + }); + + describe("edge case - total vote power BPS cannot > 10000", () => { + it("should revert if total vote power BPS > 10000", async function () { + await voting.connect(voter1).voteMultiple(voter1.address, [1, 2], [5000, 5000]) + await expect(voting.connect(voter1).voteMultiple(voter1.address, [2, 3, 4], [0, 2500, 2501])).to.be.revertedWith("TotalVotePowerBPSOver10000") + await voting.connect(voter1).removeVoteMultiple(voter1.address, [1, 2]) + }); + }); + + /********** + LESSONS + **********/ + /** + * We can get through ~80 new votes with updateGaugeWeights() call with 6M gas limit, and about ~140 with chargePremiums() call with 6M gas limit + * We need to checkpoint before the getVotePower() call, I need to investigate why this can be 50-100K for a view call. + */ + + /******************* + STATE SUMMARY + *******************/ + /** + * voter1: + * - no votes + * - delegate is delegate1 + * - Own lockID 1 (1e18 initial deposit, locked for 1 yr) + * - Own lockID 2 (1e18 initial deposit, locked for 2 yr) + * + * voter2: + * - no votes + * - no delegates + * - Own lockID 3 (1e18 initial deposit, locked for 3 yr) + * - Own lockID 4 (1e18 initial deposit, locked for 4 yr) + * + * There are 5 gauges + * - gauge1: 1% ROL + * - gauge2: 2% ROL + * - gauge3: 5% ROL + * - gauge4: 1% ROL + * - gauge5: 1% ROL + * + * LockID 5 is burned + */ + + /********************** + INTENTION STATEMENT + **********************/ + /** + * We will test the system at a larger scale + * We currently have 100 voters with 1 lock each + * + * Let's add another 5 gauges. + * Let's add the votes of another 100 voters with 1 max-duration lock each, and distribute them equally among these 5 new gauges. + * + * Let's also add another 10 voters, with 10 max-duration locks each, equally distributed among the 10 gauges. + * + * Let's then create another 100 voter who will vote for gauge 1, then lose their voting power after voting (but before vote processing). + * + * I want to test if the system can revert with a out-of-gas error with i.) lots of locks to iterate through, ii.) lot of voters to remove + */ + + describe("edge case - DDOS scenario with max locks", () => { + let LAST_RECORDED_VOTE_POWER_N: BN; + let SAVED_RANDOM_VOTER: Wallet + + before(async function () { + const CURRENT_TIME = (await provider.getBlock('latest')).timestamp; + + // Create 5 new gauges + await gaugeController.connect(governor).addGauge("gauge6", ONE_PERCENT) + await gaugeController.connect(governor).addGauge("gauge7", ONE_PERCENT) + await gaugeController.connect(governor).addGauge("gauge8", ONE_PERCENT) + await gaugeController.connect(governor).addGauge("gauge9", ONE_PERCENT) + await gaugeController.connect(governor).addGauge("gauge10", ONE_PERCENT) + + // Create 100 voters with 1 max-duration locks each, each equally distributed among gauges 6 - 10. + for (let i = 0; i < 100; i++) { + const RANDOM_VOTER = ethers.Wallet.createRandom().connect(provider); + SAVED_RANDOM_VOTER = RANDOM_VOTER; + await token.connect(deployer).transfer(RANDOM_VOTER.address, ONE_ETHER) // gas money + // Can't createLock in parallel or else nonce re-use issue lol + await underwritingLocker.connect(voter1).createLock(RANDOM_VOTER.address, DEPOSIT_AMOUNT, CURRENT_TIME + 4 * ONE_YEAR) + await deployer.sendTransaction({to: RANDOM_VOTER.address, value: ONE_ETHER.div(10)}) + await voting.connect(RANDOM_VOTER).vote( + RANDOM_VOTER.address, + i < 20 ? 6 : + i < 40 ? 7 : + i < 60 ? 8 : + i < 80 ? 9 : + 10 + , + 10000 + ) + } + expect(await underwritingLocker.totalNumLocks()).eq(205) + + // Create 10 voters with 10 max-duration locks each, each equally distributed among gauges 1 - 10. + for (let i = 0; i < 10; i++) { + const RANDOM_VOTER = ethers.Wallet.createRandom().connect(provider); + await token.connect(deployer).transfer(RANDOM_VOTER.address, ONE_ETHER) // gas money + // Create 10 locks each + for (let j = 0; j < 10; j++) { + await underwritingLocker.connect(voter1).createLock(RANDOM_VOTER.address, DEPOSIT_AMOUNT, CURRENT_TIME + 4 * ONE_YEAR) + } + await deployer.sendTransaction({to: RANDOM_VOTER.address, value: ONE_ETHER.div(10)}) + await voting.connect(RANDOM_VOTER).voteMultiple( + RANDOM_VOTER.address, + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + [1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000], + ) + } + expect(await underwritingLocker.totalNumLocks()).eq(305) + + // Create 100 voters with 1 max-duration locks each, all voting for gauge1, all of whom votes will be removed + // removeVote() will clean the _voters array, _votersToRemove array will fill only with voters who lose all voting + // power after voting + for (let i = 0; i < 100; i++) { + const RANDOM_VOTER = ethers.Wallet.createRandom().connect(provider); + await token.connect(deployer).transfer(RANDOM_VOTER.address, ONE_ETHER) // gas money + // Can't createLock in parallel or else nonce re-use issue lol + await underwritingLocker.connect(voter1).createLock(RANDOM_VOTER.address, DEPOSIT_AMOUNT, CURRENT_TIME + 4 * ONE_YEAR) + await deployer.sendTransaction({to: RANDOM_VOTER.address, value: ONE_ETHER.div(10)}) + await voting.connect(RANDOM_VOTER).vote(RANDOM_VOTER.address, 1, 10000) + await underwritingLocker.connect(RANDOM_VOTER).withdraw(306 + i, RANDOM_VOTER.address) // Lose voting power + } + expect(await underwritingLocker.totalNumLocks()).eq(405) + }); + it("updateGaugeWeight() updates gauge weights as expected in the next epoch", async function () { + const CURRENT_TIME = (await provider.getBlock('latest')).timestamp; + await provider.send("evm_mine", [CURRENT_TIME + ONE_WEEK]); + await expect(voting.connect(governor).chargePremiums()).to.be.revertedWith("GaugeWeightsNotYetUpdated"); + const EPOCH_START_TIME = await voting.getEpochStartTimestamp(); + + let counter = 0; + while (true) { + counter += 1; + const tx = await gaugeController.connect(governor).updateGaugeWeights({gasLimit: CUSTOM_GAS_LIMIT}) + + if ((await gaugeController.lastTimeGaugeWeightsUpdated()).lt(EPOCH_START_TIME)) { + await expect(tx).to.emit(gaugeController, "IncompleteGaugeUpdate"); + continue; + } else { + await expect(tx).to.emit(gaugeController, "GaugeWeightsUpdated").withArgs(EPOCH_START_TIME); + break; + } + } + console.log(`Required ${counter} iterations of updateGaugeWeights()`) + + LAST_RECORDED_VOTE_POWER_N = await voting.getVotePower(SAVED_RANDOM_VOTER.address) + expect (await gaugeController.lastTimeGaugeWeightsUpdated()).eq(EPOCH_START_TIME) + expect (await voting.isVotingOpen()).eq(false) + await expect(voting.connect(voter1).vote(voter1.address, 1, 1)).to.be.revertedWith("LastEpochPremiumsNotCharged") + + const EXPECTED_TOTAL_RECORDED_VOTE_POWER = LAST_RECORDED_VOTE_POWER_N.mul(300) + // Accept 5% error - because first 100 votes from 1 week back + expect(await gaugeController.getVotePowerSum()).gte(EXPECTED_TOTAL_RECORDED_VOTE_POWER.mul(95).div(100)) + expect(await gaugeController.getVotePowerSum()).lte(EXPECTED_TOTAL_RECORDED_VOTE_POWER.mul(105).div(100)) + expectClose(await gaugeController.getGaugeWeight(1), ONE_HUNDRED_PERCENT.div(10), 2e14); + expectClose(await gaugeController.getGaugeWeight(2), ONE_HUNDRED_PERCENT.div(10), 2e14); + expectClose(await gaugeController.getGaugeWeight(3), ONE_HUNDRED_PERCENT.div(10), 2e14); + expectClose(await gaugeController.getGaugeWeight(4), ONE_HUNDRED_PERCENT.div(10), 2e14); + expectClose(await gaugeController.getGaugeWeight(5), ONE_HUNDRED_PERCENT.div(10), 2e14); + expectClose(await gaugeController.getGaugeWeight(6), ONE_HUNDRED_PERCENT.div(10), 2e14); + expectClose(await gaugeController.getGaugeWeight(7), ONE_HUNDRED_PERCENT.div(10), 2e14); + expectClose(await gaugeController.getGaugeWeight(8), ONE_HUNDRED_PERCENT.div(10), 2e14); + expectClose(await gaugeController.getGaugeWeight(9), ONE_HUNDRED_PERCENT.div(10), 2e14); + expectClose(await gaugeController.getGaugeWeight(10), ONE_HUNDRED_PERCENT.div(10), 2e14); + }) + it("chargePremium() charges premiums as expected", async function () { + const OLD_VOTER_LOCKED_AMOUNT = await getTotalLockedAmount(SAVED_RANDOM_VOTER.address) + const OLD_UNDERWRITING_LOCKER_BALANCE = await token.balanceOf(underwritingLocker.address); + const OLD_REVENUE_ROUTER_BALANCE = await token.balanceOf(revenueRouter.address); + + const EPOCH_START_TIME = await voting.getEpochStartTimestamp() + + let counter = 0; + while (true) { + counter += 1; + const tx = await voting.connect(governor).chargePremiums({gasLimit: CUSTOM_GAS_LIMIT}) + + if ((await voting.lastTimePremiumsCharged()).lt(EPOCH_START_TIME)) { + await expect(tx).to.emit(voting, "IncompletePremiumsCharge"); + continue; + } else { + await expect(tx).to.emit(voting, "AllPremiumsCharged").withArgs(EPOCH_START_TIME); + break; + } + } + console.log(`Required ${counter} iterations of chargePremiums()`) + + const NEW_VOTER_LOCKED_AMOUNT = await getTotalLockedAmount(SAVED_RANDOM_VOTER.address) + const NEW_UNDERWRITING_LOCKER_BALANCE = await token.balanceOf(underwritingLocker.address); + const NEW_REVENUE_ROUTER_BALANCE = await token.balanceOf(revenueRouter.address); + const EXPECTED_PREMIUM = await getExpectedPremium(SAVED_RANDOM_VOTER.address, OLD_UNDERWRITING_LOCKER_BALANCE, LAST_RECORDED_VOTE_POWER_N) + const EXPECTED_PREMIUM_UNIT = await getExpectedUnitPremium(SAVED_RANDOM_VOTER.address, OLD_UNDERWRITING_LOCKER_BALANCE, LAST_RECORDED_VOTE_POWER_N); + const EXPECTED_TOTAL_PREMIUM = EXPECTED_PREMIUM_UNIT.mul(450) + // 8*20 + 2*20 + 20*5 = 300 for single lock voters + // 10 * (8 + 2 + 5) = 10 * 15 for 10-lock voters + + expectClose(NEW_REVENUE_ROUTER_BALANCE.sub(OLD_REVENUE_ROUTER_BALANCE), EXPECTED_TOTAL_PREMIUM, 1e15); + expectClose(NEW_VOTER_LOCKED_AMOUNT.sub(OLD_VOTER_LOCKED_AMOUNT), EXPECTED_PREMIUM.mul(-1), 1e15); + expectClose(NEW_UNDERWRITING_LOCKER_BALANCE.sub(OLD_UNDERWRITING_LOCKER_BALANCE), EXPECTED_TOTAL_PREMIUM.mul(-1), 1e15); + expect(await voting.isVotingOpen()).eq(true) + await expect(gaugeController.connect(governor).updateGaugeWeights()).to.be.revertedWith("GaugeWeightsAlreadyUpdated") + await expect(voting.connect(governor).chargePremiums()).to.be.revertedWith("LastEpochPremiumsAlreadyProcessed") + expect(await gaugeController.lastTimeGaugeWeightsUpdated()).eq(EPOCH_START_TIME) + expect(await voting.lastTimePremiumsCharged()).eq(EPOCH_START_TIME) + }) + }); + + /********** + LESSONS + **********/ + /** + * Need to cap locks for one person - otherwise getVotePower() is an unbounded loop and anyone can deadlock the contract + * by creating more than 500+ locks. 1 voter with 50 locks => ~750K gas to getVotePower() + * + * Uniswap implementation of sqrt is inefficient - sqrt(6 * 1e18) requiring 35 iterations of Babylonian method => ~30K gas + * Alternate implementation with bitwise operations = ~700 gas = 40x more efficient. Swapping this implementation of sqrt + * allows us to process slightly more than 100 new one-lock voters in a 6M gas call. + * + * Arbitrary cap of 10 locks => ~150K gas for updateGaugeWeights(). getVotePower() is an external call to UnderwritingLockVoting + * And we want to keep layer between locks and votes, hence GaugeController should not need any methods from IUnderwritingLock. + * + * Balance need to protect against DDOS possibility, against desire to run simple scenarios in a single run. + * Mmm, when the system scales, who cares about simple scenarios. Should underweigh the convenience of simple unit tests + * for durability in scale. Let's make it clear that the updateGaugeWeight() function is intended to be run + * in a while-loop with custom gas limit of 6M each call. + * + * I'm not as concerned with DDOS from having unbounded number of votes - we can save progress between vote iteration + * done in the updateGaugeWeights() function body. We cannot save progress between lock iterations done in an external call. + * + * In terms of DDOS from removing empty voters - it costs ~10K gas for each voter, and we can save progress between iterations. So not an issue. + * + * We need need to test for DDOS from unbounded amount of votes + * + */ + + /******************* + STATE SUMMARY + *******************/ + /** + * voter1: + * - no votes + * - delegate is delegate1 + * - Own lockID 1 (1e18 initial deposit, locked for 1 yr) + * - Own lockID 2 (1e18 initial deposit, locked for 2 yr) + * + * voter2: + * - no votes + * - no delegates + * - Own lockID 3 (1e18 initial deposit, locked for 3 yr) + * - Own lockID 4 (1e18 initial deposit, locked for 4 yr) + * + * There are 10 gauges + * - gauge1: 1% ROL + * - gauge2: 2% ROL + * - gauge3: 5% ROL + * - gauge4: 1% ROL + * - gauge5: 1% ROL + * - gauge6: 1% ROL + * - gauge7: 1% ROL + * - gauge8: 1% ROL + * - gauge9: 1% ROL + * - gauge10: 1% ROL + * + * LockIDs 5, 306-405 are burned + * + * There are 200 voters with 1 max-duration lock, with votes equally distributed amongst the 10 gauges + * There are 10 voters with 10 max-duration locks each, equally distributed among the 10 gauges + */ + + /********************** + INTENTION STATEMENT + **********************/ + /** + * We will add 90 gauges, for a total of 100 + * We will add 10 voters, with 10 max-duration locks each, who equally distribute their votes among the 100 gauges + * + * I want to test how the system does with a larger number of gauges + */ + + describe("edge case - DDOS scenario with 100 gauges", () => { + let LAST_RECORDED_VOTE_POWER_N: BN; + let SAVED_RANDOM_VOTER: Wallet + + before(async function () { + const CURRENT_TIME = (await provider.getBlock('latest')).timestamp; + + // Create 90 new gauges + for (let i = 0; i < 90; i++) { + await gaugeController.connect(governor).addGauge(`gauge${i+11}`, ONE_PERCENT) + } + + const VOTEPOWERBPS_ARRAY = [] + const GAUGEID_ARRAY = [] + + for (let i = 0; i < 100; i++) { + GAUGEID_ARRAY.push(i + 1) + VOTEPOWERBPS_ARRAY.push(100) + } + + // Create 10 voters with 10 max-duration locks each, each equally distributed among gauges 1 - 100. + for (let i = 0; i < 10; i++) { + const RANDOM_VOTER = ethers.Wallet.createRandom().connect(provider); + SAVED_RANDOM_VOTER = RANDOM_VOTER; + await token.connect(deployer).transfer(RANDOM_VOTER.address, ONE_ETHER) // gas money + // Create 10 locks each + for (let j = 0; j < 10; j++) { + await underwritingLocker.connect(voter1).createLock(RANDOM_VOTER.address, DEPOSIT_AMOUNT, CURRENT_TIME + 4 * ONE_YEAR) + } + await deployer.sendTransaction({to: RANDOM_VOTER.address, value: ONE_ETHER.div(10)}) + await voting.connect(RANDOM_VOTER).voteMultiple( + RANDOM_VOTER.address, + GAUGEID_ARRAY, + VOTEPOWERBPS_ARRAY, + ) + } + expect(await underwritingLocker.totalNumLocks()).eq(505) + }); + it("updateGaugeWeight() updates gauge weights as expected in the next epoch", async function () { + const CURRENT_TIME = (await provider.getBlock('latest')).timestamp; + await provider.send("evm_mine", [CURRENT_TIME + ONE_WEEK]); + await expect(voting.connect(governor).chargePremiums()).to.be.revertedWith("GaugeWeightsNotYetUpdated"); + const EPOCH_START_TIME = await voting.getEpochStartTimestamp(); + + let counter = 0; + while (true) { + counter += 1; + const tx = await gaugeController.connect(governor).updateGaugeWeights({gasLimit: CUSTOM_GAS_LIMIT}) + + if ((await gaugeController.lastTimeGaugeWeightsUpdated()).lt(EPOCH_START_TIME)) { + await expect(tx).to.emit(gaugeController, "IncompleteGaugeUpdate"); + continue; + } else { + await expect(tx).to.emit(gaugeController, "GaugeWeightsUpdated").withArgs(EPOCH_START_TIME); + break; + } + } + console.log(`Required ${counter} iterations of updateGaugeWeights()`) + + LAST_RECORDED_VOTE_POWER_N = await voting.getVotePower(SAVED_RANDOM_VOTER.address) + expect (await gaugeController.lastTimeGaugeWeightsUpdated()).eq(EPOCH_START_TIME) + expect (await voting.isVotingOpen()).eq(false) + await expect(voting.connect(voter1).vote(voter1.address, 1, 1)).to.be.revertedWith("LastEpochPremiumsNotCharged") + + // SAVED_RANDOM_VOTER here has 10 locks - has 10x the unit votePower + // So we should have 200 1-lock users + 20 10-lock users => 400 unit votePower + // So we have 400/10 = 40 of SAVED_RANDOM_VOTER votePower + + // Accept 5% error - because first 100 votes from 1 week back + // expect(await gaugeController.getVotePowerSum()).gte(EXPECTED_TOTAL_RECORDED_VOTE_POWER.mul(95).div(100)) + // expect(await gaugeController.getVotePowerSum()).lte(EXPECTED_TOTAL_RECORDED_VOTE_POWER.mul(105).div(100)) + + // 400 units + // 200 voters with 200 units => 20 units to each of first 10 gauges + // 10 voters with 100 units => 10 units to each of first 10 gauges + // 10 voters with 100 units => 1 unit to each gauge + // But time decay of vote power + + const OG_GAUGE_WEIGHT = await gaugeController.getGaugeWeight(1); + expectClose(await gaugeController.getGaugeWeight(2), OG_GAUGE_WEIGHT, 2e14); + expectClose(await gaugeController.getGaugeWeight(3), OG_GAUGE_WEIGHT, 2e14); + expectClose(await gaugeController.getGaugeWeight(4), OG_GAUGE_WEIGHT, 2e14); + expectClose(await gaugeController.getGaugeWeight(5), OG_GAUGE_WEIGHT, 2e14); + expectClose(await gaugeController.getGaugeWeight(6), OG_GAUGE_WEIGHT, 2e14); + expectClose(await gaugeController.getGaugeWeight(7), OG_GAUGE_WEIGHT, 2e14); + expectClose(await gaugeController.getGaugeWeight(8), OG_GAUGE_WEIGHT, 2e14); + expectClose(await gaugeController.getGaugeWeight(9), OG_GAUGE_WEIGHT, 2e14); + expectClose(await gaugeController.getGaugeWeight(10), OG_GAUGE_WEIGHT, 2e14); + + for (let i = 11; i < 101; i++) { + expectClose(await gaugeController.getGaugeWeight(i), (ONE_HUNDRED_PERCENT.sub(OG_GAUGE_WEIGHT.mul(10))).div(90), 2e14); + } + }) + it("chargePremium() charges premiums as expected", async function () { + const OLD_VOTER_LOCKED_AMOUNT = await getTotalLockedAmount(SAVED_RANDOM_VOTER.address) + const OLD_UNDERWRITING_LOCKER_BALANCE = await token.balanceOf(underwritingLocker.address); + const OLD_REVENUE_ROUTER_BALANCE = await token.balanceOf(revenueRouter.address); + + const EPOCH_START_TIME = await voting.getEpochStartTimestamp() + + let counter = 0; + while (true) { + counter += 1; + const tx = await voting.connect(governor).chargePremiums({gasLimit: CUSTOM_GAS_LIMIT}) + + if ((await voting.lastTimePremiumsCharged()).lt(EPOCH_START_TIME)) { + await expect(tx).to.emit(voting, "IncompletePremiumsCharge"); + continue; + } else { + await expect(tx).to.emit(voting, "AllPremiumsCharged").withArgs(EPOCH_START_TIME); + break; + } + } + console.log(`Required ${counter} iterations of chargePremiums()`) + + // const NEW_VOTER_LOCKED_AMOUNT = await getTotalLockedAmount(SAVED_RANDOM_VOTER.address) + // const NEW_UNDERWRITING_LOCKER_BALANCE = await token.balanceOf(underwritingLocker.address); + // const NEW_REVENUE_ROUTER_BALANCE = await token.balanceOf(revenueRouter.address); + // const EXPECTED_PREMIUM = await getExpectedPremium(SAVED_RANDOM_VOTER.address, OLD_UNDERWRITING_LOCKER_BALANCE, LAST_RECORDED_VOTE_POWER_N) + // const EXPECTED_PREMIUM_UNIT = await getExpectedUnitPremium(SAVED_RANDOM_VOTER.address, OLD_UNDERWRITING_LOCKER_BALANCE, LAST_RECORDED_VOTE_POWER_N); + // const EXPECTED_TOTAL_PREMIUM = EXPECTED_PREMIUM_UNIT.mul(450) + // // 8*20 + 2*20 + 20*5 = 300 for single lock voters + // // 10 * (8 + 2 + 5) = 10 * 15 for 10-lock voters + + // expectClose(NEW_REVENUE_ROUTER_BALANCE.sub(OLD_REVENUE_ROUTER_BALANCE), EXPECTED_TOTAL_PREMIUM, 1e15); + // expectClose(NEW_VOTER_LOCKED_AMOUNT.sub(OLD_VOTER_LOCKED_AMOUNT), EXPECTED_PREMIUM.mul(-1), 1e15); + // expectClose(NEW_UNDERWRITING_LOCKER_BALANCE.sub(OLD_UNDERWRITING_LOCKER_BALANCE), EXPECTED_TOTAL_PREMIUM.mul(-1), 1e15); + expect(await voting.isVotingOpen()).eq(true) + await expect(gaugeController.connect(governor).updateGaugeWeights()).to.be.revertedWith("GaugeWeightsAlreadyUpdated") + await expect(voting.connect(governor).chargePremiums()).to.be.revertedWith("LastEpochPremiumsAlreadyProcessed") + expect(await gaugeController.lastTimeGaugeWeightsUpdated()).eq(EPOCH_START_TIME) + expect(await voting.lastTimePremiumsCharged()).eq(EPOCH_START_TIME) + }) + }); + + /******************* + STATE SUMMARY + *******************/ + /** + * voter1: + * - no votes + * - delegate is delegate1 + * - Own lockID 1 (1e18 initial deposit, locked for 1 yr) + * - Own lockID 2 (1e18 initial deposit, locked for 2 yr) + * + * voter2: + * - no votes + * - no delegates + * - Own lockID 3 (1e18 initial deposit, locked for 3 yr) + * - Own lockID 4 (1e18 initial deposit, locked for 4 yr) + * + * There are 100 gauges + * - gauge1: 1% ROL + * - gauge2: 2% ROL + * - gauge3: 5% ROL + * - gauge4: 1% ROL + * - gauges 5-100: 1% ROL + * + * LockIDs 5, 306-405 are burned + * + * There are 200 voters with 1 max-duration lock, with votes equally distributed amongst the first 10 gauges + * There are 10 voters with 10 max-duration locks each, equally distributed among the first 10 gauges + * There are another 10 voters with 10 max-duration locks each, equally distributed among the 100 gauges + */ + + /****************** + HELPER CLOSURES + ******************/ + + async function getTotalLockedAmount(owner: string): Promise { + const lockIDs = await underwritingLocker.getAllLockIDsOf(owner); + let totalLockedAmount = ZERO; + for (let i = 0; i < lockIDs.length; i++) { + totalLockedAmount = totalLockedAmount.add((await underwritingLocker.locks(lockIDs[i])).amount); + } + return totalLockedAmount; + } + + async function getExpectedPremium(VOTER_ADDRESS: string, UWE_BALANCE: BN, LAST_RECORDED_VOTE_POWER: BN): Promise { + // GLOBAL_MULTIPLIER = INSURANCE_CAPACITY * INDIVIDUAL_VOTE_POWER / TOTAL_VOTE_POWER + // = LEVERAGE_FACTOR * UWE_BALANCE_OF_UNDERWRITINGLOCKER * INDIVIDUAL_VOTE_POWER / TOTAL_VOTE_POWER + const LEVERAGE_FACTOR = await gaugeController.leverageFactor(); + const GLOBAL_NUMERATOR = LEVERAGE_FACTOR.mul(UWE_BALANCE).mul(LAST_RECORDED_VOTE_POWER); + const VOTE_POWER_SUM = await gaugeController.getVotePowerSum(); + const GLOBAL_DENOMINATOR = VOTE_POWER_SUM + + // SCALE ROL => WEEK / (YEAR * 1e18) + // SCALE BPS => (1 / 10000) + // SCALE LEVERAGE FACTOR => (1 / 10000) + const SCALING_NUMERATOR = await gaugeController.getEpochLength(); + const SCALING_DENOMINATOR = SCALE_FACTOR.mul(ONE_YEAR).mul(10000).mul(ONE_ETHER) + + // TOTAL_PREMIUM = GLOBAL_MULTIPLIER * SUM(ROL_GAUGE * ROL_WEIGHT) + let ACCUMULATOR = ZERO + const votes = await gaugeController.getVotes(voting.address, VOTER_ADDRESS) + + for (let i = 0; i < votes.length; i++) { + const {gaugeID, votePowerBPS} = votes[i] + const ANNUAL_ROL = await gaugeController.getRateOnLineOfGauge(gaugeID); + ACCUMULATOR = ACCUMULATOR.add(ANNUAL_ROL.mul(votePowerBPS)); + } + + return ACCUMULATOR.mul(GLOBAL_NUMERATOR).mul(SCALING_NUMERATOR).div(GLOBAL_DENOMINATOR).div(SCALING_DENOMINATOR) + } + + async function getExpectedUnitPremium(VOTER_ADDRESS: string, UWE_BALANCE: BN, LAST_RECORDED_VOTE_POWER: BN): Promise { + // GLOBAL_MULTIPLIER = INSURANCE_CAPACITY * INDIVIDUAL_VOTE_POWER / TOTAL_VOTE_POWER + // = LEVERAGE_FACTOR * UWE_BALANCE_OF_UNDERWRITINGLOCKER * INDIVIDUAL_VOTE_POWER / TOTAL_VOTE_POWER + const LEVERAGE_FACTOR = await gaugeController.leverageFactor(); + const GLOBAL_NUMERATOR = LEVERAGE_FACTOR.mul(UWE_BALANCE).mul(LAST_RECORDED_VOTE_POWER); + const VOTE_POWER_SUM = await gaugeController.getVotePowerSum(); + const GLOBAL_DENOMINATOR = VOTE_POWER_SUM + + // SCALE ROL => WEEK / (YEAR * 1e18) + // SCALE BPS => (1 / 10000) + // SCALE LEVERAGE FACTOR => (1 / 10000) + const SCALING_NUMERATOR = await gaugeController.getEpochLength(); + const SCALING_DENOMINATOR = SCALE_FACTOR.mul(ONE_YEAR).mul(10000).mul(ONE_ETHER) + + // TOTAL_PREMIUM = GLOBAL_MULTIPLIER * SUM(ROL_GAUGE * ROL_WEIGHT) + + const ACCUMULATOR = ONE_PERCENT.mul(10000) + return ACCUMULATOR.mul(GLOBAL_NUMERATOR).mul(SCALING_NUMERATOR).div(GLOBAL_DENOMINATOR).div(SCALING_DENOMINATOR) + } + + function sqrt(x: BN) { + const ONE = BN.from(1); + const TWO = BN.from(2); + let z = x.add(ONE).div(TWO); + let y = x; + while (z.sub(y).isNegative()) { + y = z; + z = x.div(z).add(z).div(TWO); + } + return y; + } + +}); diff --git a/test/native/UnderwritingLocker.test.ts b/test/native/UnderwritingLocker.test.ts new file mode 100644 index 00000000..aebaf97e --- /dev/null +++ b/test/native/UnderwritingLocker.test.ts @@ -0,0 +1,2040 @@ +import { ethers, waffle } from "hardhat"; +const { deployContract, solidity } = waffle; +import { MockProvider } from "ethereum-waffle"; +const provider: MockProvider = waffle.provider; +import { BigNumber as BN, constants, BigNumberish, Wallet } from "ethers"; +import chai from "chai"; +const { expect } = chai; +chai.use(solidity); +import { import_artifacts, ArtifactImports } from "../utilities/artifact_importer"; +import { MockErc20PermitWithBurn, UnderwritingLocker, Registry, MockUnderwritingLockListener } from "../../typechain"; +import { expectDeployed } from "../utilities/expectDeployed"; +import { expectClose } from "./../utilities/math"; +import { getERC20PermitSignature } from "../utilities/getERC20PermitSignature"; + +/******************* + STYLE GUIDE +*******************/ +// Capitalised snake case for `primitive` type variables +// Camel case for objects and arrays +// Prefer 'const' over 'let' when possible + +/******************* + GLOBAL CONSTANTS +*******************/ +const ZERO = BN.from("0"); +const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000"; +const BURN_ADDRESS = "0x0000000000000000000000000000000000000000"; +const ONE_ETHER = BN.from("1000000000000000000"); +const ONE_MILLION_ETHER = ONE_ETHER.mul(1000000); +const ONE_YEAR = 31536000; // in seconds +const ONE_MONTH = ONE_YEAR / 12; +const ONE_WEEK = 604800; // in seconds +const DEADLINE = constants.MaxUint256; +const DEPOSIT_AMOUNT = ONE_ETHER; +const WITHDRAW_AMOUNT = ONE_ETHER; +const FUNDING_RATE = ONE_ETHER.div(10); +const ONE_HUNDRED_PERCENT = ONE_ETHER; +const SCALE_FACTOR = ONE_ETHER; + +describe("UnderwritingLocker", function () { + const [deployer, governor, user1, user2, user3] = provider.getWallets(); + + /*************************** + VARIABLE DECLARATIONS + ***************************/ + let token: MockErc20PermitWithBurn; + let registry: Registry; + let underwritingLocker: UnderwritingLocker; + let listener: MockUnderwritingLockListener; + let artifacts: ArtifactImports; + let snapshot: BN; + + before(async function () { + artifacts = await import_artifacts(); + snapshot = await provider.send("evm_snapshot", []); + await deployer.sendTransaction({to:deployer.address}); // for some reason this helps solidity-coverage + + // Deploy $UWE, and mint 1M $UWE to deployer + token = (await deployContract(deployer, artifacts.MockERC20PermitWithBurn, ["Underwriting Equity - Solace Native", "UWE", ONE_MILLION_ETHER, 18])) as MockErc20PermitWithBurn; + + // Deploy registry + registry = (await deployContract(deployer, artifacts.Registry, [governor.address])) as Registry; + + // Deploy listener + listener = (await deployContract(deployer, artifacts.MockUnderwritingLockListener)) as MockUnderwritingLockListener; + }); + + after(async function () { + await provider.send("evm_revert", [snapshot]); + }); + + describe("deployment", function () { + it("reverts if zero address governance", async function () { + await expect(deployContract(deployer, artifacts.UnderwritingLocker, [ZERO_ADDRESS, registry.address])).to.be.revertedWith("zero address governance"); + }); + it("reverts if zero address registry", async function () { + await expect(deployContract(deployer, artifacts.UnderwritingLocker, [governor.address, ZERO_ADDRESS], {gasLimit:10000000})).to.be.revertedWith('ZeroAddressInput("registry")'); + }); + it("reverts if zero address uwe in Registry", async function () { + await expect(deployContract(deployer, artifacts.UnderwritingLocker, [governor.address, registry.address])).to.be.revertedWith('ZeroAddressInput("uwe")'); + await registry.connect(governor).set(["uwe"], [token.address]); + }); + it("deploys", async function () { + underwritingLocker = (await deployContract(deployer, artifacts.UnderwritingLocker, [governor.address, registry.address])) as UnderwritingLocker; + await expectDeployed(underwritingLocker.address); + }); + it("initializes properly", async function () { + expect(await underwritingLocker.name()).eq("Underwriting Lock"); + expect(await underwritingLocker.symbol()).eq("UnderwritingLock"); + expect(await underwritingLocker.token()).eq(token.address); + expect(await underwritingLocker.votingContract()).eq(ZERO_ADDRESS); + expect(await underwritingLocker.registry()).eq(registry.address); + expect(await underwritingLocker.totalNumLocks()).eq(0); + expect(await underwritingLocker.fundingRate()).eq(0); + expect(await underwritingLocker.MIN_LOCK_DURATION()).eq(ONE_YEAR / 2); + expect(await underwritingLocker.MAX_LOCK_DURATION()).eq(4 * ONE_YEAR); + expect(await underwritingLocker.MAX_NUM_LOCKS()).eq(10); + expect(await underwritingLocker.totalStakedBalance(user1.address)).eq(0); + expect(await underwritingLocker.getLockListeners()).deep.eq([]); + expect(await underwritingLocker.balanceOf(user1.address)).eq(0); + expect(await underwritingLocker.totalSupply()).eq(0); + + await expect(underwritingLocker.locks(0)).to.be.revertedWith("query for nonexistent token"); + await expect(underwritingLocker.isLocked(0)).to.be.revertedWith("query for nonexistent token"); + await expect(underwritingLocker.timeLeft(0)).to.be.revertedWith("query for nonexistent token"); + await expect(underwritingLocker.getWithdrawAmount(0)).to.be.revertedWith("query for nonexistent token"); + await expect(underwritingLocker.getWithdrawInPartAmount(0, 0)).to.be.revertedWith("query for nonexistent token"); + await expect(underwritingLocker.getBurnOnWithdrawAmount(0)).to.be.revertedWith("query for nonexistent token"); + await expect(underwritingLocker.getBurnOnWithdrawInPartAmount(0, 0)).to.be.revertedWith("query for nonexistent token"); + await expect(underwritingLocker.getLockMultiplier(0)).to.be.revertedWith("query for nonexistent token"); + }); + }); + + describe("governance", () => { + it("starts with the correct governor", async () => { + expect(await underwritingLocker.governance()).to.equal(governor.address); + }); + + it("rejects setting new governance by non governor", async () => { + await expect(underwritingLocker.connect(user1).setPendingGovernance(user1.address)).to.be.revertedWith("!governance"); + }); + + it("can set new governance", async () => { + let tx = await underwritingLocker.connect(governor).setPendingGovernance(deployer.address); + await expect(tx).to.emit(underwritingLocker, "GovernancePending").withArgs(deployer.address); + expect(await underwritingLocker.governance()).to.equal(governor.address); + expect(await underwritingLocker.pendingGovernance()).to.equal(deployer.address); + }); + + it("rejects governance transfer by non governor", async () => { + await expect(underwritingLocker.connect(user1).acceptGovernance()).to.be.revertedWith("!pending governance"); + }); + + it("can transfer governance", async () => { + let tx = await underwritingLocker.connect(deployer).acceptGovernance(); + await expect(tx) + .to.emit(underwritingLocker, "GovernanceTransferred") + .withArgs(governor.address, deployer.address); + expect(await underwritingLocker.governance()).to.equal(deployer.address); + await underwritingLocker.connect(deployer).setPendingGovernance(governor.address); + await underwritingLocker.connect(governor).acceptGovernance(); + }); + }); + + describe("addLockListener & removeLockListener", () => { + it("non governor cannot add or remove listener", async function () { + await expect(underwritingLocker.connect(user1).addLockListener(user1.address)).to.be.revertedWith("!governance"); + await expect(underwritingLocker.connect(user1).removeLockListener(user1.address)).to.be.revertedWith("!governance"); + }); + it("governor can add a listener", async function () { + expect(await underwritingLocker.getLockListeners()).deep.eq([]); + const tx = await underwritingLocker.connect(governor).addLockListener(listener.address); + await expect(tx).to.emit(underwritingLocker, "LockListenerAdded").withArgs(listener.address); + expect(await underwritingLocker.getLockListeners()).deep.eq([listener.address]); + }); + it("governor can remove a listener", async function () { + const add_tx = await underwritingLocker.connect(governor).addLockListener(user1.address); + await expect(add_tx).to.emit(underwritingLocker, "LockListenerAdded").withArgs(user1.address); + expect(await underwritingLocker.getLockListeners()).deep.eq([listener.address, user1.address]); + + const remove_tx = await underwritingLocker.connect(governor).removeLockListener(user1.address); + await expect(remove_tx).to.emit(underwritingLocker, "LockListenerRemoved").withArgs(user1.address); + expect(await underwritingLocker.getLockListeners()).deep.eq([listener.address]); + }); + }); + + describe("setVotingContract", () => { + it("non governor cannot set voting contract approval", async function () { + await expect(underwritingLocker.connect(user1).setVotingContract()).to.be.revertedWith("!governance"); + }); + it("non governor cannot set voting contract if not set in Registry", async function () { + await expect(underwritingLocker.connect(governor).setVotingContract({gasLimit:1000000})).to.be.revertedWith('ZeroAddressInput("underwritingLockVoting")'); + }); + it("governor can set voting contract", async function () { + const RANDOM_ADDRESS = ethers.Wallet.createRandom().connect(provider).address; + await registry.connect(governor).set(["underwritingLockVoting"], [RANDOM_ADDRESS]); + const tx = await underwritingLocker.connect(governor).setVotingContract(); + await expect(tx).to.emit(token, "Approval").withArgs(underwritingLocker.address, RANDOM_ADDRESS, constants.MaxUint256); + await expect(tx).to.emit(underwritingLocker, "VotingContractSet").withArgs(RANDOM_ADDRESS); + expect(await token.allowance(underwritingLocker.address, RANDOM_ADDRESS)).eq(constants.MaxUint256); + expect(await underwritingLocker.votingContract()).eq(RANDOM_ADDRESS); + }); + it("old approval revoked when new voting contract set", async function () { + const OLD_VOTING_CONTRACT_ADDRESS = await underwritingLocker.votingContract(); + const RANDOM_ADDRESS = ethers.Wallet.createRandom().connect(provider).address; + await registry.connect(governor).set(["underwritingLockVoting"], [RANDOM_ADDRESS]); + const tx = await underwritingLocker.connect(governor).setVotingContract(); + await expect(tx).to.emit(token, "Approval").withArgs(underwritingLocker.address, OLD_VOTING_CONTRACT_ADDRESS, 0); + await expect(tx).to.emit(token, "Approval").withArgs(underwritingLocker.address, RANDOM_ADDRESS, constants.MaxUint256); + await expect(tx).to.emit(underwritingLocker, "VotingContractSet").withArgs(RANDOM_ADDRESS); + expect(await token.allowance(underwritingLocker.address, OLD_VOTING_CONTRACT_ADDRESS)).eq(0); + expect(await token.allowance(underwritingLocker.address, RANDOM_ADDRESS)).eq(constants.MaxUint256); + }); + }); + + describe("setFundingRate", () => { + it("non governor cannot set voting contract approval", async function () { + await expect(underwritingLocker.connect(user1).setFundingRate(FUNDING_RATE)).to.be.revertedWith("!governance"); + }); + it("cannot set funding rate above 100%", async function () { + await expect(underwritingLocker.connect(governor).setFundingRate(ONE_HUNDRED_PERCENT.mul(2))).to.be.revertedWith("FundingRateAboveOne"); + }); + it("governor can set funding rate", async function () { + const tx = await underwritingLocker.connect(governor).setFundingRate(FUNDING_RATE); + await expect(tx).to.emit(underwritingLocker, "FundingRateSet").withArgs(FUNDING_RATE); + expect(await underwritingLocker.fundingRate()).eq(FUNDING_RATE); + }); + }); + + describe("setRegistry", () => { + let registry2: Registry; + const RANDOM_ADDRESS = ethers.Wallet.createRandom().connect(provider).address; + + before(async function () { + registry2 = (await deployContract(deployer, artifacts.Registry, [governor.address])) as Registry; + }); + it("reverts if not governor", async function () { + await expect(underwritingLocker.connect(user1).setRegistry(registry2.address)).to.be.revertedWith("!governance"); + }) + it("reverts if zero address registry", async function () { + await expect(underwritingLocker.connect(governor).setRegistry(ZERO_ADDRESS, {gasLimit:1000000})).to.be.revertedWith('ZeroAddressInput("registry")'); + }); + it("reverts if zero address uwe in Registry", async function () { + await expect(underwritingLocker.connect(governor).setRegistry(registry2.address, {gasLimit:1000000})).to.be.revertedWith('ZeroAddressInput("uwe")'); + await registry2.connect(governor).set(["uwe"], [RANDOM_ADDRESS]); + }); + it("sets registry", async function () { + const tx = await underwritingLocker.connect(governor).setRegistry(registry2.address); + await expect(tx).to.emit(underwritingLocker, "RegistrySet").withArgs(registry2.address); + }); + it("copies Registry addresses to own state variables", async function () { + expect(await underwritingLocker.registry()).eq(registry2.address); + expect(await underwritingLocker.token()).eq(RANDOM_ADDRESS); + }); + after(async function () { + await underwritingLocker.connect(governor).setRegistry(registry.address); + }); + }); + + describe("createLock", function () { + it("cannot create lock with no balance", async function () { + await expect(underwritingLocker.connect(user1).createLock(user1.address, 1, 0)).to.be.revertedWith("ERC20: transfer amount exceeds balance"); + }); + it("cannot create lock with no allowance", async function () { + await token.connect(deployer).transfer(user1.address, ONE_ETHER.mul(100)); + await expect(underwritingLocker.connect(user1).createLock(user1.address, 1, 0)).to.be.revertedWith("ERC20: transfer amount exceeds allowance"); + await token.connect(user1).approve(underwritingLocker.address, constants.MaxUint256); + }); + it("cannot create lock below minimum duration", async function () { + const CURRENT_TIME = (await provider.getBlock('latest')).timestamp; + await expect(underwritingLocker.connect(user1).createLock(user1.address, 1, CURRENT_TIME)).to.be.revertedWith("LockTimeTooShort"); + }); + it("cannot create lock above maximum duration", async function () { + const CURRENT_TIME = (await provider.getBlock('latest')).timestamp; + await expect(underwritingLocker.connect(user1).createLock(user1.address, 1, CURRENT_TIME + 4 * ONE_YEAR + 100)).to.be.revertedWith("LockTimeTooLong"); + }); + it("cannot create lock with 0 deposit", async function () { + const CURRENT_TIME = (await provider.getBlock('latest')).timestamp; + await expect(underwritingLocker.connect(user1).createLock(user1.address, 0, CURRENT_TIME + ONE_YEAR)).to.be.revertedWith("CannotCreateEmptyLock"); + }); + it("can create a lock, and listener notified", async function () { + const oldGlobalState = await getGlobalState(); + const oldUserState = await getUserState(user1); + const {timestamp: CURRENT_TIME, number: CURRENT_BLOCK} = await provider.getBlock('latest') + + const tx = await underwritingLocker.connect(user1).createLock(user1.address, DEPOSIT_AMOUNT, CURRENT_TIME + ONE_YEAR); + const LOCK_ID = await underwritingLocker.totalNumLocks(); + expect(LOCK_ID).eq(1); + await expect(tx).to.emit(underwritingLocker, "LockCreated").withArgs(LOCK_ID); + await expect(tx).to.emit(underwritingLocker, "Transfer").withArgs(ZERO_ADDRESS, user1.address, LOCK_ID) + + const newGlobalState = await getGlobalState(); + const newUserState = await getUserState(user1); + const globalStateChange = getGlobalStateChange(newGlobalState, oldGlobalState); + const userStateChange = getUserStateChange(newUserState, oldUserState); + expect(globalStateChange.totalNumLocks.eq(1)); + expect(globalStateChange.totalStakedAmount.eq(DEPOSIT_AMOUNT)); + expect(globalStateChange.totalSupply).eq(1) + expect(userStateChange.lockedTokenAmount).eq(DEPOSIT_AMOUNT); + expect(userStateChange.numOfLocks).eq(1); + expect(userStateChange.tokenAmountInWallet).eq(DEPOSIT_AMOUNT.mul(-1)); + + const lock = await underwritingLocker.locks(LOCK_ID); + expect(lock.amount).eq(DEPOSIT_AMOUNT); + expect(lock.end).eq(CURRENT_TIME + ONE_YEAR); + expect(await underwritingLocker.ownerOf(LOCK_ID)).eq(user1.address); + expect(await underwritingLocker.isLocked(LOCK_ID)).eq(true); + expect(await underwritingLocker.timeLeft(LOCK_ID)).eq(ONE_YEAR - 1); // 1s seems to have passed in Hardhat environment at this point, from our initial query for CURRENT_TIME + + const listenerUpdate = await listener.lastUpdate(); + expect(listenerUpdate.blocknum).eq(CURRENT_BLOCK + 1); + expect(listenerUpdate.caller).eq(underwritingLocker.address); + expect(listenerUpdate.lockID).eq(LOCK_ID); + expect(listenerUpdate.oldOwner).eq(ZERO_ADDRESS); + expect(listenerUpdate.newOwner).eq(user1.address); + expect(listenerUpdate.oldLock.amount).eq(0); + expect(listenerUpdate.oldLock.end).eq(0); + expect(listenerUpdate.newLock.amount).eq(lock.amount); + expect(listenerUpdate.newLock.end).eq(lock.end); + }); + }); + + /******************* + STATE SUMMARY + *******************/ + /** + * There are one lock: + * i.) lockID 1 => One-year lock held by user1, with 1e18 token locked + */ + + describe("createLockSigned", function () { + it("cannot create lock with no balance", async function () { + const { v, r, s } = await getERC20PermitSignature(user2, underwritingLocker, token, DEPOSIT_AMOUNT, DEADLINE); + await expect(underwritingLocker.connect(user2).createLockSigned(DEPOSIT_AMOUNT, 0, DEADLINE, v, r, s)).to.be.revertedWith("ERC20: transfer amount exceeds balance"); + }); + it("cannot deposit with invalid permit", async function () { + const { v, r, s } = await getERC20PermitSignature(user2, underwritingLocker, token, DEPOSIT_AMOUNT, DEADLINE); + await expect(underwritingLocker.connect(user2).createLockSigned(2, 0, DEADLINE, v, r, s)).to.be.revertedWith("ERC20Permit: invalid signature"); + }); + it("cannot create lock below minimum duration", async function () { + const { v, r, s } = await getERC20PermitSignature(user1, underwritingLocker, token, DEPOSIT_AMOUNT, DEADLINE); + const CURRENT_TIME = (await provider.getBlock('latest')).timestamp; + await expect(underwritingLocker.connect(user1).createLockSigned(DEPOSIT_AMOUNT, CURRENT_TIME, DEADLINE, v, r, s)).to.be.revertedWith("LockTimeTooShort"); + }); + it("cannot create lock above maximum duration", async function () { + const { v, r, s } = await getERC20PermitSignature(user1, underwritingLocker, token, DEPOSIT_AMOUNT, DEADLINE); + const CURRENT_TIME = (await provider.getBlock('latest')).timestamp; + await expect(underwritingLocker.connect(user1).createLockSigned(DEPOSIT_AMOUNT, CURRENT_TIME + 4 * ONE_YEAR + 100, DEADLINE, v, r, s)).to.be.revertedWith("LockTimeTooLong"); + }); + it("can create a lock, and listener alerted", async function () { + const oldGlobalState = await getGlobalState(); + const oldUserState = await getUserState(user1); + const {timestamp: CURRENT_TIME, number: CURRENT_BLOCK} = await provider.getBlock('latest') + + const { v, r, s } = await getERC20PermitSignature(user1, underwritingLocker, token, DEPOSIT_AMOUNT, DEADLINE); + const tx = await underwritingLocker.connect(user1).createLockSigned(DEPOSIT_AMOUNT, CURRENT_TIME + ONE_YEAR, DEADLINE, v, r, s); + const LOCK_ID = await underwritingLocker.totalNumLocks(); + expect(LOCK_ID).eq(2); + await expect(tx).to.emit(underwritingLocker, "LockCreated").withArgs(LOCK_ID); + await expect(tx).to.emit(underwritingLocker, "Transfer").withArgs(ZERO_ADDRESS, user1.address, LOCK_ID) + + const newGlobalState = await getGlobalState(); + const newUserState = await getUserState(user1); + const globalStateChange = getGlobalStateChange(newGlobalState, oldGlobalState); + const userStateChange = getUserStateChange(newUserState, oldUserState); + expect(globalStateChange.totalNumLocks.eq(1)); + expect(globalStateChange.totalStakedAmount.eq(DEPOSIT_AMOUNT)); + expect(globalStateChange.totalSupply).eq(1) + expect(userStateChange.lockedTokenAmount).eq(DEPOSIT_AMOUNT); + expect(userStateChange.numOfLocks).eq(1); + expect(userStateChange.tokenAmountInWallet).eq(DEPOSIT_AMOUNT.mul(-1)); + + const lock = await underwritingLocker.locks(LOCK_ID); + expect(lock.amount).eq(DEPOSIT_AMOUNT); + expect(lock.end).eq(CURRENT_TIME + ONE_YEAR); + expect(await underwritingLocker.ownerOf(LOCK_ID)).eq(user1.address); + expect(await underwritingLocker.isLocked(LOCK_ID)).eq(true); + expectClose(await underwritingLocker.timeLeft(LOCK_ID), ONE_YEAR - 1, 1e15); // 1s seems to have passed in Hardhat environment at this point, from our initial query for CURRENT_TIME + + const listenerUpdate = await listener.lastUpdate(); + expect(listenerUpdate.blocknum).eq(CURRENT_BLOCK + 1); + expect(listenerUpdate.caller).eq(underwritingLocker.address); + expect(listenerUpdate.lockID).eq(LOCK_ID); + expect(listenerUpdate.oldOwner).eq(ZERO_ADDRESS); + expect(listenerUpdate.newOwner).eq(user1.address); + expect(listenerUpdate.oldLock.amount).eq(0); + expect(listenerUpdate.oldLock.end).eq(0); + expect(listenerUpdate.newLock.amount).eq(lock.amount); + expect(listenerUpdate.newLock.end).eq(lock.end); + }); + }); + + /******************* + STATE SUMMARY + *******************/ + /** + * There are two locks: + * i.) lockID 1 => One-year lock held by user1, with 1e18 token locked + * ii.) lockID 2 => One-year lock held by user1, with 1e18 token locked + */ + + describe("increaseAmount", function () { + it("cannot deposit with no allowance", async function () { + await expect(underwritingLocker.connect(user1).increaseAmount(1, 1)).to.be.revertedWith("ERC20: transfer amount exceeds allowance"); + }); + it("cannot deposit to non existant lock", async function () { + await token.connect(user1).approve(underwritingLocker.address, constants.MaxUint256); // Creating permit in createLockSigned reduced allowance, and token transfer afterwards reduced allowance to 0. + await expect(underwritingLocker.connect(user1).increaseAmount(999, 1)).to.be.revertedWith("ERC721: owner query for nonexistent token"); + }); + it("can increaseAmount, and listener notified", async function () { + const LOCK_ID = 1; + const oldGlobalState = await getGlobalState(); + const oldUserState = await getUserState(user1); + const oldLockState = await getLockState(LOCK_ID); + const {number: CURRENT_BLOCK} = await provider.getBlock('latest') + + // Deposit 1e18 additional tokens into lockID 1 + let tx = await underwritingLocker.connect(user1).increaseAmount(LOCK_ID, DEPOSIT_AMOUNT); + const newGlobalState = await getGlobalState(); + const newUserState = await getUserState(user1); + const newLockState = await getLockState(LOCK_ID); + await expect(tx).to.emit(underwritingLocker, "LockUpdated").withArgs(LOCK_ID, oldLockState.amount.add(DEPOSIT_AMOUNT), oldLockState.end); + await expect(tx).to.emit(underwritingLocker, "LockIncreased").withArgs(LOCK_ID, oldLockState.amount.add(DEPOSIT_AMOUNT), DEPOSIT_AMOUNT); + + const globalStateChange = getGlobalStateChange(newGlobalState, oldGlobalState); + const userStateChange = getUserStateChange(newUserState, oldUserState); + const lockStateChange = getLockStateChange(newLockState, oldLockState); + expect(globalStateChange.totalNumLocks.eq(0)); + expect(globalStateChange.totalStakedAmount.eq(DEPOSIT_AMOUNT)); + expect(globalStateChange.totalSupply).eq(0) + expect(userStateChange.lockedTokenAmount).eq(DEPOSIT_AMOUNT); + expect(userStateChange.numOfLocks).eq(0); + expect(userStateChange.tokenAmountInWallet).eq(DEPOSIT_AMOUNT.mul(-1)); + expect(lockStateChange.amount).eq(DEPOSIT_AMOUNT); + expect(lockStateChange.end).eq(0); + expect(oldLockState.isLocked).eq(newLockState.isLocked) + + const listenerUpdate = await listener.lastUpdate(); + expect(listenerUpdate.blocknum).eq(CURRENT_BLOCK + 1); + expect(listenerUpdate.caller).eq(underwritingLocker.address); + expect(listenerUpdate.lockID).eq(LOCK_ID); + expect(listenerUpdate.oldOwner).eq(user1.address); + expect(listenerUpdate.newOwner).eq(user1.address); + expect(listenerUpdate.oldLock.amount).eq(oldLockState.amount); + expect(listenerUpdate.oldLock.end).eq(oldLockState.end); + expect(listenerUpdate.newLock.amount).eq(newLockState.amount); + expect(listenerUpdate.newLock.end).eq(newLockState.end); + }); + }); + + /******************* + STATE SUMMARY + *******************/ + /** + * There are two locks: + * i.) lockID 1 => One-year lock held by user1, with 2e18 token locked + * ii.) lockID 2 => One-year lock held by user1, with 1e18 token locked + */ + + describe("increaseAmountSigned", function () { + it("cannot increaseAmountSigned with no balance", async function () { + const { v, r, s } = await getERC20PermitSignature(user2, underwritingLocker, token, DEPOSIT_AMOUNT, DEADLINE); + await expect(underwritingLocker.connect(user2).createLockSigned(DEPOSIT_AMOUNT, 0, DEADLINE, v, r, s)).to.be.revertedWith("ERC20: transfer amount exceeds balance"); + }); + it("cannot increaseAmountSigned with invalid permit", async function () { + const { v, r, s } = await getERC20PermitSignature(user1, underwritingLocker, token, DEPOSIT_AMOUNT, DEADLINE); + await expect(underwritingLocker.connect(user1).createLockSigned(2, 0, DEADLINE, v, r, s)).to.be.revertedWith("ERC20Permit: invalid signature"); + }); + it("cannot increaseAmountSigned to non existant lock", async function () { + const { v, r, s } = await getERC20PermitSignature(user1, underwritingLocker, token, DEPOSIT_AMOUNT, DEADLINE); + await expect(underwritingLocker.connect(user1).increaseAmountSigned(999, DEPOSIT_AMOUNT, DEADLINE, v, r, s)).to.be.revertedWith("ERC721: owner query for nonexistent token"); + }); + it("can increaseAmountSigned, and listener notified", async function () { + const LOCK_ID = 2; + const oldGlobalState = await getGlobalState(); + const oldUserState = await getUserState(user1); + const oldLockState = await getLockState(LOCK_ID); + const {number: CURRENT_BLOCK} = await provider.getBlock('latest') + + // Deposit 1e18 additional tokens into lockID 2 + const { v, r, s } = await getERC20PermitSignature(user1, underwritingLocker, token, DEPOSIT_AMOUNT, DEADLINE); + let tx = await underwritingLocker.connect(user1).increaseAmountSigned(LOCK_ID, DEPOSIT_AMOUNT, DEADLINE, v, r, s); + const newGlobalState = await getGlobalState(); + const newUserState = await getUserState(user1); + const newLockState = await getLockState(LOCK_ID); + await expect(tx).to.emit(underwritingLocker, "LockUpdated").withArgs(LOCK_ID, oldLockState.amount.add(DEPOSIT_AMOUNT), oldLockState.end); + await expect(tx).to.emit(underwritingLocker, "LockIncreased").withArgs(LOCK_ID, oldLockState.amount.add(DEPOSIT_AMOUNT), DEPOSIT_AMOUNT); + + const globalStateChange = getGlobalStateChange(newGlobalState, oldGlobalState); + const userStateChange = getUserStateChange(newUserState, oldUserState); + const lockStateChange = getLockStateChange(newLockState, oldLockState); + expect(globalStateChange.totalNumLocks.eq(0)); + expect(globalStateChange.totalStakedAmount.eq(DEPOSIT_AMOUNT)); + expect(globalStateChange.totalSupply).eq(0) + expect(userStateChange.lockedTokenAmount).eq(DEPOSIT_AMOUNT); + expect(userStateChange.numOfLocks).eq(0); + expect(userStateChange.tokenAmountInWallet).eq(DEPOSIT_AMOUNT.mul(-1)); + expect(lockStateChange.amount).eq(DEPOSIT_AMOUNT); + expect(lockStateChange.end).eq(0); + expect(oldLockState.isLocked).eq(newLockState.isLocked) + + const listenerUpdate = await listener.lastUpdate(); + expect(listenerUpdate.blocknum).eq(CURRENT_BLOCK + 1); + expect(listenerUpdate.caller).eq(underwritingLocker.address); + expect(listenerUpdate.lockID).eq(LOCK_ID); + expect(listenerUpdate.oldOwner).eq(user1.address); + expect(listenerUpdate.newOwner).eq(user1.address); + expect(listenerUpdate.oldLock.amount).eq(oldLockState.amount); + expect(listenerUpdate.oldLock.end).eq(oldLockState.end); + expect(listenerUpdate.newLock.amount).eq(newLockState.amount); + expect(listenerUpdate.newLock.end).eq(newLockState.end); + }); + }); + + /******************* + STATE SUMMARY + *******************/ + /** + * There are two locks: + * i.) lockID 1 => One-year lock held by user1, with 2e18 token locked + * ii.) lockID 2 => One-year lock held by user1, with 2e18 token locked + */ + + describe("increaseAmountMultiple", function () { + it("must provide argument arrays of matching length", async function () { + await expect(underwritingLocker.connect(user1).increaseAmountMultiple([1, 2], [DEPOSIT_AMOUNT])).to.be.revertedWith("ArrayArgumentsLengthMismatch"); + }); + it("cannot deposit to a non-existant lock", async function () { + await expect(underwritingLocker.connect(user1).increaseAmountMultiple([1, 999], [DEPOSIT_AMOUNT, DEPOSIT_AMOUNT])).to.be.revertedWith("ERC721: owner query for nonexistent token"); + }); + it("cannot deposit with no allowance", async function () { + await token.connect(user1).approve(underwritingLocker.address, 0); + await expect(underwritingLocker.connect(user1).increaseAmountMultiple([1, 2], [DEPOSIT_AMOUNT, DEPOSIT_AMOUNT])).to.be.revertedWith("ERC20: transfer amount exceeds allowance"); + await token.connect(user1).approve(underwritingLocker.address, constants.MaxUint256); + }); + it("cannot deposit with no balance", async function () { + await token.connect(user2).approve(underwritingLocker.address, constants.MaxUint256); + await expect(underwritingLocker.connect(user2).increaseAmountMultiple([1, 2], [DEPOSIT_AMOUNT, DEPOSIT_AMOUNT])).to.be.revertedWith("ERC20: transfer amount exceeds balance"); + await token.connect(user2).approve(underwritingLocker.address, 0); + }); + it("can increaseAmountMultiple, and listener notified", async function () { + const LOCK_ID_1 = 1; + const LOCK_ID_2 = 2; + const oldGlobalState = await getGlobalState(); + const oldUserState = await getUserState(user1); + const oldLockState1 = await getLockState(LOCK_ID_1); + const oldLockState2 = await getLockState(LOCK_ID_2); + const {number: CURRENT_BLOCK} = await provider.getBlock('latest') + + // Deposit 1e18 additional tokens into both lockID 1 and lockID2 + await token.connect(user1).approve(underwritingLocker.address, constants.MaxUint256); + let tx = await underwritingLocker.connect(user1).increaseAmountMultiple([LOCK_ID_1, LOCK_ID_2], [DEPOSIT_AMOUNT, DEPOSIT_AMOUNT]); + + const newGlobalState = await getGlobalState(); + const newUserState = await getUserState(user1); + const newLockState1 = await getLockState(LOCK_ID_1); + const newLockState2 = await getLockState(LOCK_ID_2); + await expect(tx).to.emit(underwritingLocker, "LockUpdated").withArgs(LOCK_ID_1, oldLockState1.amount.add(DEPOSIT_AMOUNT), oldLockState1.end); + await expect(tx).to.emit(underwritingLocker, "LockIncreased").withArgs(LOCK_ID_1, oldLockState1.amount.add(DEPOSIT_AMOUNT), DEPOSIT_AMOUNT); + await expect(tx).to.emit(underwritingLocker, "LockUpdated").withArgs(LOCK_ID_2, oldLockState2.amount.add(DEPOSIT_AMOUNT), oldLockState2.end); + await expect(tx).to.emit(underwritingLocker, "LockIncreased").withArgs(LOCK_ID_2, oldLockState2.amount.add(DEPOSIT_AMOUNT), DEPOSIT_AMOUNT); + + const globalStateChange = getGlobalStateChange(newGlobalState, oldGlobalState); + const userStateChange = getUserStateChange(newUserState, oldUserState); + const lockStateChange1 = getLockStateChange(newLockState1, oldLockState1); + const lockStateChange2 = getLockStateChange(newLockState2, oldLockState2); + expect(globalStateChange.totalNumLocks.eq(0)); + expect(globalStateChange.totalStakedAmount.eq(DEPOSIT_AMOUNT.mul(2))); + expect(globalStateChange.totalSupply).eq(0) + expect(userStateChange.lockedTokenAmount).eq(DEPOSIT_AMOUNT.mul(2)); + expect(userStateChange.numOfLocks).eq(0); + expect(userStateChange.tokenAmountInWallet).eq(DEPOSIT_AMOUNT.mul(-2)); + expect(lockStateChange1.amount).eq(DEPOSIT_AMOUNT); + expect(lockStateChange1.end).eq(0); + expect(oldLockState1.isLocked).eq(newLockState2.isLocked) + expect(lockStateChange2.amount).eq(DEPOSIT_AMOUNT); + expect(lockStateChange2.end).eq(0); + expect(oldLockState2.isLocked).eq(newLockState2.isLocked) + + const listenerUpdate = await listener.lastUpdate(); + expect(listenerUpdate.blocknum).eq(CURRENT_BLOCK + 2); + expect(listenerUpdate.caller).eq(underwritingLocker.address); + expect(listenerUpdate.lockID).eq(LOCK_ID_2); + expect(listenerUpdate.oldOwner).eq(user1.address); + expect(listenerUpdate.newOwner).eq(user1.address); + expect(listenerUpdate.oldLock.amount).eq(oldLockState2.amount); + expect(listenerUpdate.oldLock.end).eq(oldLockState2.end); + expect(listenerUpdate.newLock.amount).eq(newLockState2.amount); + expect(listenerUpdate.newLock.end).eq(newLockState2.end); + }); + }); + + /******************* + STATE SUMMARY + *******************/ + /** + * There are two locks: + * i.) lockID 1 => One-year lock held by user1, with 3e18 token locked + * ii.) lockID 2 => One-year lock held by user1, with 3e18 token locked + */ + + describe("extendLock", function () { + it("cannot extend non-existant lock", async function () { + await expect(underwritingLocker.connect(user1).extendLock(999, 1)).to.be.revertedWith("ERC721: operator query for nonexistent token"); + }); + it("non-owned or non-approved cannot extend lock", async function () { + await expect(underwritingLocker.connect(user2).extendLock(1, 1)).to.be.revertedWith("only owner or approved"); + }); + it("cannot extend over four years", async function () { + const CURRENT_TIME = (await provider.getBlock('latest')).timestamp; + await expect(underwritingLocker.connect(user1).extendLock(1, CURRENT_TIME + ONE_YEAR*4 + ONE_WEEK)).to.be.revertedWith("LockTimeTooLong"); + }); + it("cannot reduce lock duration", async function () { + const CURRENT_END = (await underwritingLocker.locks(1)).end; + await expect(underwritingLocker.connect(user1).extendLock(1, CURRENT_END.sub(1))).to.be.revertedWith("LockTimeNotExtended"); + }); + it("owner can extend lock, and listener notified", async function () { + const LOCK_ID = 1; + const EXTENSION_TIME = ONE_WEEK; + const oldLockState = await getLockState(LOCK_ID); + expect(oldLockState.ownerOf).eq(user1.address) + const NEW_END = oldLockState.end.add(EXTENSION_TIME); + const {number: CURRENT_BLOCK} = await provider.getBlock('latest') + + const tx = await underwritingLocker.connect(user1).extendLock(LOCK_ID, NEW_END); + await expect(tx).to.emit(underwritingLocker, "LockUpdated").withArgs(LOCK_ID, oldLockState.amount, NEW_END); + await expect(tx).to.emit(underwritingLocker, "LockExtended").withArgs(LOCK_ID, NEW_END); + + const newLockState = await getLockState(LOCK_ID); + const lockStateChange = getLockStateChange(newLockState, oldLockState); + expect(lockStateChange.amount).eq(0) + expect(lockStateChange.end).eq(EXTENSION_TIME) + + const listenerUpdate = await listener.lastUpdate(); + expect(listenerUpdate.blocknum).eq(CURRENT_BLOCK + 1); + expect(listenerUpdate.caller).eq(underwritingLocker.address); + expect(listenerUpdate.lockID).eq(LOCK_ID); + expect(listenerUpdate.oldOwner).eq(user1.address); + expect(listenerUpdate.newOwner).eq(user1.address); + expect(listenerUpdate.oldLock.amount).eq(oldLockState.amount); + expect(listenerUpdate.oldLock.end).eq(oldLockState.end); + expect(listenerUpdate.newLock.amount).eq(newLockState.amount); + expect(listenerUpdate.newLock.end).eq(newLockState.end); + }); + it("approved can extend, and listener notified", async function () { + const LOCK_ID = 1; + const EXTENSION_TIME = ONE_WEEK; + const oldLockState = await getLockState(LOCK_ID); + expect(oldLockState.ownerOf).not.eq(user2.address) + const NEW_END = oldLockState.end.add(EXTENSION_TIME); + const {number: CURRENT_BLOCK} = await provider.getBlock('latest') + + await underwritingLocker.connect(user1).approve(user2.address, LOCK_ID); + const tx = await underwritingLocker.connect(user1).extendLock(LOCK_ID, NEW_END); + await expect(tx).to.emit(underwritingLocker, "LockUpdated").withArgs(LOCK_ID, oldLockState.amount, NEW_END); + await expect(tx).to.emit(underwritingLocker, "LockExtended").withArgs(LOCK_ID, NEW_END); + + const newLockState = await getLockState(LOCK_ID); + const lockStateChange = getLockStateChange(newLockState, oldLockState); + expect(lockStateChange.amount).eq(0) + expect(lockStateChange.end).eq(EXTENSION_TIME) + + const listenerUpdate = await listener.lastUpdate(); + expect(listenerUpdate.blocknum).eq(CURRENT_BLOCK + 2); + expect(listenerUpdate.caller).eq(underwritingLocker.address); + expect(listenerUpdate.lockID).eq(LOCK_ID); + expect(listenerUpdate.oldOwner).eq(user1.address); + expect(listenerUpdate.newOwner).eq(user1.address); + expect(listenerUpdate.oldLock.amount).eq(oldLockState.amount); + expect(listenerUpdate.oldLock.end).eq(oldLockState.end); + expect(listenerUpdate.newLock.amount).eq(newLockState.amount); + expect(listenerUpdate.newLock.end).eq(newLockState.end); + }); + }); + + /******************* + STATE SUMMARY + *******************/ + /** + * There are two locks: + * i.) lockID 1 => 1yr + 2wk lock held by user1, with 3e18 token locked + * ii.) lockID 2 => 1yr lock held by user1, with 3e18 token locked + */ + + describe("extendLockMultiple", function () { + it("must provide argument arrays of matching length", async function () { + const LOCK_ID_1 = 1; + const LOCK_ID_2 = 2; + const CURRENT_END_1 = (await underwritingLocker.locks(LOCK_ID_1)).end; + const EXTENSION_TIME = ONE_WEEK; + + await expect(underwritingLocker.connect(user1).extendLockMultiple( + [LOCK_ID_1, LOCK_ID_2], + [CURRENT_END_1.add(EXTENSION_TIME)] + )).to.be.revertedWith("ArrayArgumentsLengthMismatch"); + }); + it("cannot extend non-existant lock", async function () { + const LOCK_ID_1 = 1; + const CURRENT_END_1 = (await underwritingLocker.locks(LOCK_ID_1)).end; + const EXTENSION_TIME = ONE_WEEK; + + await expect(underwritingLocker.connect(user1).extendLockMultiple( + [LOCK_ID_1, 999], + [CURRENT_END_1.add(EXTENSION_TIME), CURRENT_END_1.add(EXTENSION_TIME)] + )).to.be.revertedWith("ERC721: operator query for nonexistent token"); + }); + it("non-owned or non-approved cannot extend lock", async function () { + const LOCK_ID_1 = 1; + const LOCK_ID_2 = 2; + const CURRENT_END_1 = (await underwritingLocker.locks(LOCK_ID_1)).end; + const CURRENT_END_2 = (await underwritingLocker.locks(LOCK_ID_2)).end; + const EXTENSION_TIME = ONE_WEEK; + + await expect(underwritingLocker.connect(user3).extendLockMultiple( + [LOCK_ID_1, LOCK_ID_2], + [CURRENT_END_1.add(EXTENSION_TIME), CURRENT_END_2.add(EXTENSION_TIME)] + )).to.be.revertedWith("only owner or approved"); + }); + it("cannot extend over four years", async function () { + const LOCK_ID_1 = 1; + const LOCK_ID_2 = 2; + const CURRENT_TIME = (await provider.getBlock('latest')).timestamp; + + await expect(underwritingLocker.connect(user1).extendLockMultiple( + [LOCK_ID_1, LOCK_ID_2], + [CURRENT_TIME + ONE_YEAR*4 + ONE_WEEK, CURRENT_TIME + ONE_YEAR*4 + ONE_WEEK] + )).to.be.revertedWith("LockTimeTooLong"); + }); + it("cannot reduce lock duration", async function () { + const LOCK_ID_1 = 1; + const LOCK_ID_2 = 2; + const CURRENT_END_1 = (await underwritingLocker.locks(LOCK_ID_1)).end; + const CURRENT_END_2 = (await underwritingLocker.locks(LOCK_ID_2)).end; + + await expect(underwritingLocker.connect(user1).extendLockMultiple( + [LOCK_ID_1, LOCK_ID_2], + [CURRENT_END_1.sub(1), CURRENT_END_2.sub(1)] + )).to.be.revertedWith("LockTimeNotExtended"); + }); + it("owner can extend multiple locks, with listener notified", async function () { + const LOCK_ID_1 = 1; + const LOCK_ID_2 = 2; + const EXTENSION_TIME = ONE_WEEK; + + const oldLockState1 = await getLockState(LOCK_ID_1); + const oldLockState2 = await getLockState(LOCK_ID_2); + expect(oldLockState1.ownerOf).eq(user1.address) + expect(oldLockState2.ownerOf).eq(user1.address) + const NEW_END_1 = oldLockState1.end.add(EXTENSION_TIME); + const NEW_END_2 = oldLockState2.end.add(EXTENSION_TIME); + const {number: CURRENT_BLOCK} = await provider.getBlock('latest') + + const tx = await underwritingLocker.connect(user1).extendLockMultiple( + [LOCK_ID_1, LOCK_ID_2], + [NEW_END_1, NEW_END_2] + ); + await expect(tx).to.emit(underwritingLocker, "LockUpdated").withArgs(LOCK_ID_1, oldLockState1.amount, NEW_END_1); + await expect(tx).to.emit(underwritingLocker, "LockExtended").withArgs(LOCK_ID_1, NEW_END_1); + await expect(tx).to.emit(underwritingLocker, "LockUpdated").withArgs(LOCK_ID_2, oldLockState2.amount, NEW_END_2); + await expect(tx).to.emit(underwritingLocker, "LockExtended").withArgs(LOCK_ID_2, NEW_END_2); + + const newLockState1 = await getLockState(LOCK_ID_1); + const newLockState2 = await getLockState(LOCK_ID_2); + const lockStateChange1 = getLockStateChange(newLockState1, oldLockState1); + const lockStateChange2 = getLockStateChange(newLockState2, oldLockState2); + expect(lockStateChange1.amount).eq(0) + expect(lockStateChange2.amount).eq(0) + expect(lockStateChange1.end).eq(EXTENSION_TIME) + expect(lockStateChange2.end).eq(EXTENSION_TIME) + + const listenerUpdate = await listener.lastUpdate(); + expect(listenerUpdate.blocknum).eq(CURRENT_BLOCK + 1); + expect(listenerUpdate.caller).eq(underwritingLocker.address); + expect(listenerUpdate.lockID).eq(LOCK_ID_2); + expect(listenerUpdate.oldOwner).eq(user1.address); + expect(listenerUpdate.newOwner).eq(user1.address); + expect(listenerUpdate.oldLock.amount).eq(oldLockState2.amount); + expect(listenerUpdate.oldLock.end).eq(oldLockState2.end); + expect(listenerUpdate.newLock.amount).eq(newLockState2.amount); + expect(listenerUpdate.newLock.end).eq(newLockState2.end); + }); + it("approved can extend multiple locks, with listener notified", async function () { + const LOCK_ID_1 = 1; + const LOCK_ID_2 = 2; + const EXTENSION_TIME = ONE_WEEK; + + const oldLockState1 = await getLockState(LOCK_ID_1); + const oldLockState2 = await getLockState(LOCK_ID_2); + expect(oldLockState1.ownerOf).not.eq(user2.address) + expect(oldLockState2.ownerOf).not.eq(user2.address) + const NEW_END_1 = oldLockState1.end.add(EXTENSION_TIME); + const NEW_END_2 = oldLockState2.end.add(EXTENSION_TIME); + const {number: CURRENT_BLOCK} = await provider.getBlock('latest') + + await underwritingLocker.connect(user1).approve(user2.address, LOCK_ID_2); + const tx = await underwritingLocker.connect(user2).extendLockMultiple( + [LOCK_ID_1, LOCK_ID_2], + [NEW_END_1, NEW_END_2] + ); + await expect(tx).to.emit(underwritingLocker, "LockUpdated").withArgs(LOCK_ID_1, oldLockState1.amount, NEW_END_1); + await expect(tx).to.emit(underwritingLocker, "LockExtended").withArgs(LOCK_ID_1, NEW_END_1); + await expect(tx).to.emit(underwritingLocker, "LockUpdated").withArgs(LOCK_ID_2, oldLockState2.amount, NEW_END_2); + await expect(tx).to.emit(underwritingLocker, "LockExtended").withArgs(LOCK_ID_2, NEW_END_2); + + const newLockState1 = await getLockState(LOCK_ID_1); + const newLockState2 = await getLockState(LOCK_ID_2); + const lockStateChange1 = getLockStateChange(newLockState1, oldLockState1); + const lockStateChange2 = getLockStateChange(newLockState2, oldLockState2); + expect(lockStateChange1.amount).eq(0) + expect(lockStateChange2.amount).eq(0) + expect(lockStateChange1.end).eq(EXTENSION_TIME) + expect(lockStateChange2.end).eq(EXTENSION_TIME) + + const listenerUpdate = await listener.lastUpdate(); + expect(listenerUpdate.blocknum).eq(CURRENT_BLOCK + 2); + expect(listenerUpdate.caller).eq(underwritingLocker.address); + expect(listenerUpdate.lockID).eq(LOCK_ID_2); + expect(listenerUpdate.oldOwner).eq(user1.address); + expect(listenerUpdate.newOwner).eq(user1.address); + expect(listenerUpdate.oldLock.amount).eq(oldLockState2.amount); + expect(listenerUpdate.oldLock.end).eq(oldLockState2.end); + expect(listenerUpdate.newLock.amount).eq(newLockState2.amount); + expect(listenerUpdate.newLock.end).eq(newLockState2.end); + }); + + }); + + /******************* + STATE SUMMARY + *******************/ + /** + * There are two locks: + * i.) lockID 1 => 1yr + 4wk lock held by user1, with 3e18 token locked + * ii.) lockID 2 => 1yr + 2wk lock held by user1, with 3e18 token locked + */ + + /********************* + INTENTION STATEMENT + *********************/ + // Before proceeding, let's do a time-skip such that lockID 1 is locked, whereas lockID 2 is unlocked + + describe("Timeskip 1", function () { + it("skips time such that lockID 1 is locked, while lockID 2 is unlocked", async function () { + const LOCK_ID_1 = 1; + const LOCK_ID_2 = 2; + const LOCK_END_2 = (await underwritingLocker.locks(LOCK_ID_2)).end; + await provider.send("evm_mine", [LOCK_END_2.toNumber()]); + expect (await underwritingLocker.isLocked(LOCK_ID_1)).eq(true) + expect (await underwritingLocker.isLocked(LOCK_ID_2)).eq(false) + }); + }); + + /******************* + STATE SUMMARY + *******************/ + /** + * There are two locks: + * i.) lockID 1 => 2wk lock held by user1, with 3e18 token locked + * ii.) lockID 2 => Unlocked lock held by user1, with 3e18 token staked + */ + + describe("uri", function () { + it("cannot get the uri of non existant token", async function () { + await expect(underwritingLocker.tokenURI(999)).to.be.revertedWith("query for nonexistent token"); + }); + it("starts simple", async function () { + expect(await underwritingLocker.baseURI()).eq(""); + expect(await underwritingLocker.tokenURI(1)).eq("1"); + }); + it("non governor cannot set base uri", async function () { + await expect(underwritingLocker.connect(user1).setBaseURI("asdf")).to.be.revertedWith("!governance"); + }); + it("governor can set base uri", async function () { + const baseURI = "https://token.fi/xsLocks?xsLockID="; + const tx = await underwritingLocker.connect(governor).setBaseURI(baseURI); + await expect(tx).to.emit(underwritingLocker, "BaseURISet").withArgs(baseURI); + expect(await underwritingLocker.baseURI()).eq(baseURI); + expect(await underwritingLocker.tokenURI(1)).eq(baseURI.concat("1")); + }); + }); + + describe("lock transfer", function () { + it("can transfer when locked, and listener notified", async function () { + const LOCKED_LOCK_ID = 2; + const {amount: LOCK_AMOUNT, end: LOCK_END} = await underwritingLocker.locks(LOCKED_LOCK_ID); + await underwritingLocker.connect(user1).transfer(user2.address, LOCKED_LOCK_ID); + expect(await underwritingLocker.ownerOf(LOCKED_LOCK_ID)).eq(user2.address); + await underwritingLocker.connect(user2).safeTransfer(user1.address, LOCKED_LOCK_ID); + expect(await underwritingLocker.ownerOf(LOCKED_LOCK_ID)).eq(user1.address); + await underwritingLocker.connect(user1).approve(user2.address, LOCKED_LOCK_ID); + await underwritingLocker.connect(user2).transferFrom(user1.address, user2.address, LOCKED_LOCK_ID); // user2 already approved + expect(await underwritingLocker.ownerOf(LOCKED_LOCK_ID)).eq(user2.address); + await underwritingLocker.connect(user2).approve(user1.address, LOCKED_LOCK_ID); + const {number: CURRENT_BLOCK} = await provider.getBlock('latest') + await underwritingLocker.connect(user1)['safeTransferFrom(address,address,uint256)'](user2.address, user1.address, LOCKED_LOCK_ID); + expect(await underwritingLocker.ownerOf(LOCKED_LOCK_ID)).eq(user1.address); + const listenerUpdate = await listener.lastUpdate(); + expect(listenerUpdate.blocknum).eq(CURRENT_BLOCK + 1); + expect(listenerUpdate.caller).eq(underwritingLocker.address); + expect(listenerUpdate.lockID).eq(LOCKED_LOCK_ID); + expect(listenerUpdate.oldOwner).eq(user2.address); + expect(listenerUpdate.newOwner).eq(user1.address); + expect(listenerUpdate.oldLock.amount).eq(LOCK_AMOUNT); + expect(listenerUpdate.oldLock.end).eq(LOCK_END); + expect(listenerUpdate.newLock.amount).eq(LOCK_AMOUNT); + expect(listenerUpdate.newLock.end).eq(LOCK_END); + }); + it("can transfer when unlocked, and listener notified", async function () { + const UNLOCKED_LOCK_ID = 2; + const {amount: LOCK_AMOUNT, end: LOCK_END} = await underwritingLocker.locks(UNLOCKED_LOCK_ID); + await underwritingLocker.connect(user1).transfer(user2.address, UNLOCKED_LOCK_ID); + expect(await underwritingLocker.ownerOf(UNLOCKED_LOCK_ID)).eq(user2.address); + await underwritingLocker.connect(user2).safeTransfer(user1.address, UNLOCKED_LOCK_ID); + expect(await underwritingLocker.ownerOf(UNLOCKED_LOCK_ID)).eq(user1.address); + await underwritingLocker.connect(user1).approve(user2.address, UNLOCKED_LOCK_ID); + await underwritingLocker.connect(user2).transferFrom(user1.address, user2.address, UNLOCKED_LOCK_ID); // user2 already approved + expect(await underwritingLocker.ownerOf(UNLOCKED_LOCK_ID)).eq(user2.address); + await underwritingLocker.connect(user2).approve(user1.address, UNLOCKED_LOCK_ID); + const {number: CURRENT_BLOCK} = await provider.getBlock('latest') + await underwritingLocker.connect(user1)['safeTransferFrom(address,address,uint256)'](user2.address, user1.address, UNLOCKED_LOCK_ID); + expect(await underwritingLocker.ownerOf(UNLOCKED_LOCK_ID)).eq(user1.address); + const listenerUpdate = await listener.lastUpdate(); + expect(listenerUpdate.blocknum).eq(CURRENT_BLOCK + 1); + expect(listenerUpdate.caller).eq(underwritingLocker.address); + expect(listenerUpdate.lockID).eq(UNLOCKED_LOCK_ID); + expect(listenerUpdate.oldOwner).eq(user2.address); + expect(listenerUpdate.newOwner).eq(user1.address); + expect(listenerUpdate.oldLock.amount).eq(LOCK_AMOUNT); + expect(listenerUpdate.oldLock.end).eq(LOCK_END); + expect(listenerUpdate.newLock.amount).eq(LOCK_AMOUNT); + expect(listenerUpdate.newLock.end).eq(LOCK_END); + }); + }); + + describe("sanity check for view functions for individual locks", function () { + it("should not be able to query nonexistent lockIDs", async function () { + await expect(underwritingLocker.ownerOf(999)).to.be.revertedWith("ERC721: owner query for nonexistent token"); + await expect(underwritingLocker.locks(999)).to.be.revertedWith("query for nonexistent token"); + await expect(underwritingLocker.isLocked(999)).to.be.revertedWith("query for nonexistent token"); + await expect(underwritingLocker.timeLeft(999)).to.be.revertedWith("query for nonexistent token"); + await expect(underwritingLocker.getWithdrawAmount(999)).to.be.revertedWith("query for nonexistent token"); + await expect(underwritingLocker.getWithdrawInPartAmount(999, 0)).to.be.revertedWith("query for nonexistent token"); + await expect(underwritingLocker.getBurnOnWithdrawAmount(999)).to.be.revertedWith("query for nonexistent token"); + await expect(underwritingLocker.getBurnOnWithdrawInPartAmount(999, 0)).to.be.revertedWith("query for nonexistent token"); + await expect(underwritingLocker.getLockMultiplier(999)).to.be.revertedWith("query for nonexistent token"); + }); + it("should return appropriate values for locked lock", async function () { + const LOCKED_LOCK_ID = 1; + const lockState = await getLockState(LOCKED_LOCK_ID); + + expect(await lockState.isLocked).eq(true); + expect(await lockState.timeLeft).above(0); + + /************************************************ + ALTER HERE IF WITHDRAWAL BURN FORMULA CHANGES + ************************************************/ + + const TIME_LEFT_IN_MONTHS_SCALED = SCALE_FACTOR.mul(lockState.timeLeft).div(ONE_MONTH); + const EXPECTED_LOCK_MULTIPLIER = SCALE_FACTOR.mul(sqrt(TIME_LEFT_IN_MONTHS_SCALED)).div(sqrt(SCALE_FACTOR.mul(6))) + expect(EXPECTED_LOCK_MULTIPLIER).eq(await underwritingLocker.getLockMultiplier(LOCKED_LOCK_ID)) + + // ( 1 / (1 + lock_multiplier) ) * (1 - funding_rate) + const EXPECTED_EARLY_WITHDRAW_MULTIPLIER_NUMERATOR = SCALE_FACTOR; + const EXPECTED_EARLY_WITHDRAW_MULTIPLIER_DENOMINATOR = EXPECTED_LOCK_MULTIPLIER.add(SCALE_FACTOR); + const EXPECTED_WITHDRAW_MULTIPLIER_AFTER_FUNDING_NUMERATOR = ONE_HUNDRED_PERCENT.sub(FUNDING_RATE) + const EXPECTED_WITHDRAW_MULTIPLIER_AFTER_FUNDING_DENOMINATOR = SCALE_FACTOR + + const EXPECTED_WITHDRAW_AMOUNT = lockState.amount + .mul(EXPECTED_EARLY_WITHDRAW_MULTIPLIER_NUMERATOR) + .mul(EXPECTED_WITHDRAW_MULTIPLIER_AFTER_FUNDING_NUMERATOR) + .div(EXPECTED_EARLY_WITHDRAW_MULTIPLIER_DENOMINATOR) + .div(EXPECTED_WITHDRAW_MULTIPLIER_AFTER_FUNDING_DENOMINATOR) + + expect(await underwritingLocker.getWithdrawAmount(LOCKED_LOCK_ID)).eq(EXPECTED_WITHDRAW_AMOUNT); + expect(await underwritingLocker.getBurnOnWithdrawAmount(LOCKED_LOCK_ID)).eq(lockState.amount.sub(EXPECTED_WITHDRAW_AMOUNT)); + + const EXPECTED_WITHDRAW_IN_PART_AMOUNT = WITHDRAW_AMOUNT + .mul(EXPECTED_EARLY_WITHDRAW_MULTIPLIER_NUMERATOR) + .mul(EXPECTED_WITHDRAW_MULTIPLIER_AFTER_FUNDING_NUMERATOR) + .div(EXPECTED_EARLY_WITHDRAW_MULTIPLIER_DENOMINATOR) + .div(EXPECTED_WITHDRAW_MULTIPLIER_AFTER_FUNDING_DENOMINATOR) + + expect(await underwritingLocker.getWithdrawInPartAmount(LOCKED_LOCK_ID, WITHDRAW_AMOUNT)).eq(EXPECTED_WITHDRAW_IN_PART_AMOUNT); + expect(await underwritingLocker.getBurnOnWithdrawInPartAmount(LOCKED_LOCK_ID, WITHDRAW_AMOUNT)).eq(WITHDRAW_AMOUNT.sub(EXPECTED_WITHDRAW_IN_PART_AMOUNT)); + }); + it("should return appropriate values for unlocked lock", async function () { + const UNLOCKED_LOCK_ID = 2; + const lockState = await getLockState(UNLOCKED_LOCK_ID); + expect(await lockState.isLocked).eq(false); + expect(await lockState.timeLeft).eq(0); + + // Expect withdraw = (1 - funding_rate) * requested_amount + + expect(await underwritingLocker.getLockMultiplier(UNLOCKED_LOCK_ID)).eq(0); + expect(await underwritingLocker.getWithdrawAmount(UNLOCKED_LOCK_ID)).eq(lockState.amount.mul(ONE_HUNDRED_PERCENT.sub(FUNDING_RATE)).div(ONE_HUNDRED_PERCENT)); + expect(await underwritingLocker.getWithdrawInPartAmount(UNLOCKED_LOCK_ID, WITHDRAW_AMOUNT)).eq(WITHDRAW_AMOUNT.mul(ONE_HUNDRED_PERCENT.sub(FUNDING_RATE)).div(ONE_HUNDRED_PERCENT)); + expect(await underwritingLocker.getBurnOnWithdrawAmount(UNLOCKED_LOCK_ID)).eq(lockState.amount.mul(FUNDING_RATE).div(ONE_HUNDRED_PERCENT)); + expect(await underwritingLocker.getBurnOnWithdrawInPartAmount(UNLOCKED_LOCK_ID, WITHDRAW_AMOUNT)).eq(WITHDRAW_AMOUNT.mul(FUNDING_RATE).div(ONE_HUNDRED_PERCENT)); + }); + }); + + describe("withdrawInPart", function () { + it("cannot withdraw non existant token", async function () { + // Error does not indicate non-existant tokenID, however it will revert regardless + await expect(underwritingLocker.connect(user1).withdrawInPart(999, WITHDRAW_AMOUNT, user1.address)).to.be.revertedWith(`ExcessWithdraw`) + }); + it("cannot withdraw more than lock amount", async function () { + const LOCK_ID = 1; + const LOCK_AMOUNT = (await underwritingLocker.locks(1)).amount + await expect(underwritingLocker.connect(user1).withdrawInPart(LOCK_ID, LOCK_AMOUNT.mul(2), user1.address)).to.be.revertedWith(`ExcessWithdraw`) + }); + it("non owner or approved cannot withdraw", async function () { + const LOCK_ID = 1; + await expect(underwritingLocker.connect(user3).withdrawInPart(LOCK_ID, WITHDRAW_AMOUNT, user1.address)).to.be.revertedWith("only owner or approved"); + }); + it("owner can withdraw in part from unlocked lock, and listener notified", async function () { + const UNLOCKED_LOCK_ID = 2; + const oldGlobalState = await getGlobalState(); + const oldUserState = await getUserState(user1); + const oldLockState = await getLockState(UNLOCKED_LOCK_ID); + const {number: CURRENT_BLOCK} = await provider.getBlock('latest') + const ACTUAL_WITHDRAW_AMOUNT = await underwritingLocker.getWithdrawInPartAmount(UNLOCKED_LOCK_ID, WITHDRAW_AMOUNT) + const BURN_AMOUNT = await underwritingLocker.getBurnOnWithdrawInPartAmount(UNLOCKED_LOCK_ID, WITHDRAW_AMOUNT) + + const tx = await underwritingLocker.connect(user1).withdrawInPart(UNLOCKED_LOCK_ID, WITHDRAW_AMOUNT, user1.address); + await expect(tx).to.emit(underwritingLocker, "Withdrawal").withArgs(UNLOCKED_LOCK_ID, WITHDRAW_AMOUNT, ACTUAL_WITHDRAW_AMOUNT, BURN_AMOUNT); + await expect(tx).to.emit(token, "Transfer").withArgs(underwritingLocker.address, BURN_ADDRESS, BURN_AMOUNT); + await expect(tx).to.emit(token, "Transfer").withArgs(underwritingLocker.address, user1.address, ACTUAL_WITHDRAW_AMOUNT); + const newGlobalState = await getGlobalState(); + const newUserState = await getUserState(user1); + const newLockState = await getLockState(UNLOCKED_LOCK_ID); + const globalStateChange = getGlobalStateChange(newGlobalState, oldGlobalState); + const userStateChange = getUserStateChange(newUserState, oldUserState); + const lockStateChange = getLockStateChange(newLockState, oldLockState); + + expect(globalStateChange.totalNumLocks.eq(0)); + expect(globalStateChange.totalStakedAmount.eq(WITHDRAW_AMOUNT)); + expect(globalStateChange.totalSupply).eq(0) + expect(userStateChange.lockedTokenAmount).eq(WITHDRAW_AMOUNT.mul(-1)); + expect(userStateChange.numOfLocks).eq(0); + expect(userStateChange.tokenAmountInWallet).eq(ACTUAL_WITHDRAW_AMOUNT); + expect(lockStateChange.amount).eq(WITHDRAW_AMOUNT.mul(-1)); + expect(lockStateChange.end).eq(0); + expect(lockStateChange.timeLeft).eq(0); + + const listenerUpdate = await listener.lastUpdate(); + expect(listenerUpdate.blocknum).eq(CURRENT_BLOCK + 1); + expect(listenerUpdate.caller).eq(underwritingLocker.address); + expect(listenerUpdate.lockID).eq(UNLOCKED_LOCK_ID); + expect(listenerUpdate.oldOwner).eq(user1.address); + expect(listenerUpdate.newOwner).eq(user1.address); + expect(listenerUpdate.oldLock.amount).eq(oldLockState.amount); + expect(listenerUpdate.oldLock.end).eq(oldLockState.end); + expect(listenerUpdate.newLock.amount).eq(newLockState.amount); + expect(listenerUpdate.newLock.end).eq(newLockState.end); + }); + it("approved can withdraw in part from unlocked lock, and listener notified", async function () { + const UNLOCKED_LOCK_ID = 2; + const oldGlobalState = await getGlobalState(); + const oldUserState = await getUserState(user1); + const oldLockState = await getLockState(UNLOCKED_LOCK_ID); + const {number: CURRENT_BLOCK} = await provider.getBlock('latest') + const ACTUAL_WITHDRAW_AMOUNT = await underwritingLocker.getWithdrawInPartAmount(UNLOCKED_LOCK_ID, WITHDRAW_AMOUNT) + const BURN_AMOUNT = await underwritingLocker.getBurnOnWithdrawInPartAmount(UNLOCKED_LOCK_ID, WITHDRAW_AMOUNT) + + await underwritingLocker.connect(user1).approve(user2.address, UNLOCKED_LOCK_ID); + const tx = await underwritingLocker.connect(user2).withdrawInPart(UNLOCKED_LOCK_ID, WITHDRAW_AMOUNT, user1.address); + await expect(tx).to.emit(underwritingLocker, "Withdrawal").withArgs(UNLOCKED_LOCK_ID, WITHDRAW_AMOUNT, ACTUAL_WITHDRAW_AMOUNT, BURN_AMOUNT); + await expect(tx).to.emit(token, "Transfer").withArgs(underwritingLocker.address, BURN_ADDRESS, BURN_AMOUNT); + await expect(tx).to.emit(token, "Transfer").withArgs(underwritingLocker.address, user1.address, ACTUAL_WITHDRAW_AMOUNT); + + const newGlobalState = await getGlobalState(); + const newUserState = await getUserState(user1); + const newLockState = await getLockState(UNLOCKED_LOCK_ID); + const globalStateChange = getGlobalStateChange(newGlobalState, oldGlobalState); + const userStateChange = getUserStateChange(newUserState, oldUserState); + const lockStateChange = getLockStateChange(newLockState, oldLockState); + + expect(globalStateChange.totalNumLocks.eq(0)); + expect(globalStateChange.totalStakedAmount.eq(WITHDRAW_AMOUNT)); + expect(globalStateChange.totalSupply).eq(0) + expect(userStateChange.lockedTokenAmount).eq(WITHDRAW_AMOUNT.mul(-1)); + expect(userStateChange.numOfLocks).eq(0); + expect(userStateChange.tokenAmountInWallet).eq(ACTUAL_WITHDRAW_AMOUNT); + expect(lockStateChange.amount).eq(WITHDRAW_AMOUNT.mul(-1)); + expect(lockStateChange.end).eq(0); + expect(lockStateChange.timeLeft).eq(0); + + const listenerUpdate = await listener.lastUpdate(); + expect(listenerUpdate.blocknum).eq(CURRENT_BLOCK + 2); + expect(listenerUpdate.caller).eq(underwritingLocker.address); + expect(listenerUpdate.lockID).eq(UNLOCKED_LOCK_ID); + expect(listenerUpdate.oldOwner).eq(user1.address); + expect(listenerUpdate.newOwner).eq(user1.address); + expect(listenerUpdate.oldLock.amount).eq(oldLockState.amount); + expect(listenerUpdate.oldLock.end).eq(oldLockState.end); + expect(listenerUpdate.newLock.amount).eq(newLockState.amount); + expect(listenerUpdate.newLock.end).eq(newLockState.end); + }); + it("owner can withdraw in part from locked lock with penalty, and listener notified", async function () { + const LOCKED_LOCK_ID = 1; + const oldGlobalState = await getGlobalState(); + const oldUserState = await getUserState(user1); + const oldLockState = await getLockState(LOCKED_LOCK_ID); + const {number: CURRENT_BLOCK} = await provider.getBlock('latest') + + const tx = await underwritingLocker.connect(user1).withdrawInPart(LOCKED_LOCK_ID, WITHDRAW_AMOUNT, user1.address); + // Need to calculate ACTUAL_WITHDRAW_AMOUNT and BURN_AMOUNT after tx executed, transaction uses block finalization timestamp? + const ACTUAL_WITHDRAW_AMOUNT = await underwritingLocker.getWithdrawInPartAmount(LOCKED_LOCK_ID, WITHDRAW_AMOUNT) + const BURN_AMOUNT = await underwritingLocker.getBurnOnWithdrawInPartAmount(LOCKED_LOCK_ID, WITHDRAW_AMOUNT) + await expect(tx).to.emit(underwritingLocker, "EarlyWithdrawal").withArgs(LOCKED_LOCK_ID, WITHDRAW_AMOUNT, ACTUAL_WITHDRAW_AMOUNT, BURN_AMOUNT); + await expect(tx).to.emit(token, "Transfer").withArgs(underwritingLocker.address, BURN_ADDRESS, BURN_AMOUNT); + await expect(tx).to.emit(token, "Transfer").withArgs(underwritingLocker.address, user1.address, ACTUAL_WITHDRAW_AMOUNT); + + const newGlobalState = await getGlobalState(); + const newUserState = await getUserState(user1); + const newLockState = await getLockState(LOCKED_LOCK_ID); + const globalStateChange = getGlobalStateChange(newGlobalState, oldGlobalState); + const userStateChange = getUserStateChange(newUserState, oldUserState); + const lockStateChange = getLockStateChange(newLockState, oldLockState); + + expect(globalStateChange.totalNumLocks.eq(0)); + expect(globalStateChange.totalStakedAmount.eq(WITHDRAW_AMOUNT)); + expect(globalStateChange.totalSupply).eq(0) + expect(userStateChange.lockedTokenAmount).eq(WITHDRAW_AMOUNT.mul(-1)); + expect(userStateChange.numOfLocks).eq(0); + expect(userStateChange.tokenAmountInWallet).eq(ACTUAL_WITHDRAW_AMOUNT); + expect(lockStateChange.amount).eq(WITHDRAW_AMOUNT.mul(-1)); + expect(lockStateChange.end).eq(0); + + const listenerUpdate = await listener.lastUpdate(); + expect(listenerUpdate.blocknum).eq(CURRENT_BLOCK + 1); + expect(listenerUpdate.caller).eq(underwritingLocker.address); + expect(listenerUpdate.lockID).eq(LOCKED_LOCK_ID); + expect(listenerUpdate.oldOwner).eq(user1.address); + expect(listenerUpdate.newOwner).eq(user1.address); + expect(listenerUpdate.oldLock.amount).eq(oldLockState.amount); + expect(listenerUpdate.oldLock.end).eq(oldLockState.end); + expect(listenerUpdate.newLock.amount).eq(newLockState.amount); + expect(listenerUpdate.newLock.end).eq(newLockState.end); + }); + it("approved can withdraw in part from locked lock with penalty, and listener notified", async function () { + const LOCKED_LOCK_ID = 1; + const oldGlobalState = await getGlobalState(); + const oldUserState = await getUserState(user1); + const oldLockState = await getLockState(LOCKED_LOCK_ID); + const {number: CURRENT_BLOCK} = await provider.getBlock('latest') + + await underwritingLocker.connect(user1).approve(user2.address, LOCKED_LOCK_ID); + const tx = await underwritingLocker.connect(user2).withdrawInPart(LOCKED_LOCK_ID, WITHDRAW_AMOUNT, user1.address); + const ACTUAL_WITHDRAW_AMOUNT = await underwritingLocker.getWithdrawInPartAmount(LOCKED_LOCK_ID, WITHDRAW_AMOUNT) + const BURN_AMOUNT = await underwritingLocker.getBurnOnWithdrawInPartAmount(LOCKED_LOCK_ID, WITHDRAW_AMOUNT) + await expect(tx).to.emit(underwritingLocker, "EarlyWithdrawal").withArgs(LOCKED_LOCK_ID, WITHDRAW_AMOUNT, ACTUAL_WITHDRAW_AMOUNT, BURN_AMOUNT); + await expect(tx).to.emit(token, "Transfer").withArgs(underwritingLocker.address, BURN_ADDRESS, BURN_AMOUNT); + await expect(tx).to.emit(token, "Transfer").withArgs(underwritingLocker.address, user1.address, ACTUAL_WITHDRAW_AMOUNT); + + const newGlobalState = await getGlobalState(); + const newUserState = await getUserState(user1); + const newLockState = await getLockState(LOCKED_LOCK_ID); + const globalStateChange = getGlobalStateChange(newGlobalState, oldGlobalState); + const userStateChange = getUserStateChange(newUserState, oldUserState); + const lockStateChange = getLockStateChange(newLockState, oldLockState); + + expect(globalStateChange.totalNumLocks.eq(0)); + expect(globalStateChange.totalStakedAmount.eq(WITHDRAW_AMOUNT)); + expect(globalStateChange.totalSupply).eq(0) + expect(userStateChange.lockedTokenAmount).eq(WITHDRAW_AMOUNT.mul(-1)); + expect(userStateChange.numOfLocks).eq(0); + expect(userStateChange.tokenAmountInWallet).eq(ACTUAL_WITHDRAW_AMOUNT); + expect(lockStateChange.amount).eq(WITHDRAW_AMOUNT.mul(-1)); + expect(lockStateChange.end).eq(0); + + const listenerUpdate = await listener.lastUpdate(); + expect(listenerUpdate.blocknum).eq(CURRENT_BLOCK + 2); + expect(listenerUpdate.caller).eq(underwritingLocker.address); + expect(listenerUpdate.lockID).eq(LOCKED_LOCK_ID); + expect(listenerUpdate.oldOwner).eq(user1.address); + expect(listenerUpdate.newOwner).eq(user1.address); + expect(listenerUpdate.oldLock.amount).eq(oldLockState.amount); + expect(listenerUpdate.oldLock.end).eq(oldLockState.end); + expect(listenerUpdate.newLock.amount).eq(newLockState.amount); + expect(listenerUpdate.newLock.end).eq(newLockState.end); + }); + }); + + /******************* + STATE SUMMARY + *******************/ + /** + * There are two locks: + * i.) lockID 1 => 2wk lock held by user1, with 1e18 token locked + * ii.) lockID 2 => Unlocked lock held by user1, with 1e18 token staked + */ + + describe("withdrawInPartMultiple", function () { + // Deposit 4e18 token into each lockID + before(async function () { + await underwritingLocker.connect(user1).increaseAmountMultiple([1, 2], [DEPOSIT_AMOUNT.mul(2), DEPOSIT_AMOUNT.mul(2)]) + }); + it("must provide argument arrays of matching length", async function () { + const LOCK_ID_1 = 1; + const LOCK_ID_2 = 2; + + await expect(underwritingLocker.connect(user1).withdrawInPartMultiple( + [LOCK_ID_1, LOCK_ID_2], + [WITHDRAW_AMOUNT], + user1.address + )).to.be.revertedWith("ArrayArgumentsLengthMismatch"); + }); + it("cannot withdraw non existant token", async function () { + const NON_EXISTENT_LOCK_ID = 999; + const LOCK_ID_1 = 1; + // Error does not indicate non-existant tokenID, however it will revert regardless + await expect(underwritingLocker.connect(user1).withdrawInPartMultiple( + [LOCK_ID_1, NON_EXISTENT_LOCK_ID], + [WITHDRAW_AMOUNT, WITHDRAW_AMOUNT], + user1.address + )).to.be.revertedWith("ERC721: operator query for nonexistent token"); + }); + it("cannot withdraw more than lock amount", async function () { + const LOCK_ID_1 = 1; + const LOCK_ID_2 = 2; + const LOCK_AMOUNT_2 = (await underwritingLocker.locks(2)).amount + await expect(underwritingLocker.connect(user1).withdrawInPartMultiple( + [LOCK_ID_1, LOCK_ID_2], + [WITHDRAW_AMOUNT, LOCK_AMOUNT_2.mul(2)], + user1.address + )).to.be.revertedWith(`ExcessWithdraw()`); + }); + it("non owner or approved cannot withdraw", async function () { + const LOCK_ID_1 = 1; + const LOCK_ID_2 = 2; + await expect(underwritingLocker.connect(user3).withdrawInPartMultiple( + [LOCK_ID_1, LOCK_ID_2], + [WITHDRAW_AMOUNT, WITHDRAW_AMOUNT], + user1.address + )).to.be.revertedWith("NotOwnerNorApproved"); + }); + it("owner can withdraw in part from multiple locks, and listener notified", async function () { + const LOCKED_LOCK_ID = 1; + const UNLOCKED_LOCK_ID = 2; + const oldGlobalState = await getGlobalState(); + const oldUserState = await getUserState(user1); + const oldLockState_Locked = await getLockState(LOCKED_LOCK_ID); + const oldLockState_Unlocked = await getLockState(UNLOCKED_LOCK_ID); + const oldUWETotalSupply = await token.totalSupply() + const {number: CURRENT_BLOCK} = await provider.getBlock('latest') + + const tx = await underwritingLocker.connect(user1).withdrawInPartMultiple( + [LOCKED_LOCK_ID, UNLOCKED_LOCK_ID], + [WITHDRAW_AMOUNT, WITHDRAW_AMOUNT], + user1.address + ) + + const ACTUAL_WITHDRAW_AMOUNT_UNLOCKED = await underwritingLocker.getWithdrawInPartAmount(UNLOCKED_LOCK_ID, WITHDRAW_AMOUNT) + const BURN_AMOUNT_UNLOCKED = await underwritingLocker.getBurnOnWithdrawInPartAmount(UNLOCKED_LOCK_ID, WITHDRAW_AMOUNT) + const ACTUAL_WITHDRAW_AMOUNT_LOCKED = await underwritingLocker.getWithdrawInPartAmount(LOCKED_LOCK_ID, WITHDRAW_AMOUNT) + const BURN_AMOUNT_LOCKED = await underwritingLocker.getBurnOnWithdrawInPartAmount(LOCKED_LOCK_ID, WITHDRAW_AMOUNT) + await expect(tx).to.emit(underwritingLocker, "Withdrawal").withArgs(UNLOCKED_LOCK_ID, WITHDRAW_AMOUNT, ACTUAL_WITHDRAW_AMOUNT_UNLOCKED, BURN_AMOUNT_UNLOCKED); + await expect(tx).to.emit(underwritingLocker, "EarlyWithdrawal").withArgs(LOCKED_LOCK_ID, WITHDRAW_AMOUNT, ACTUAL_WITHDRAW_AMOUNT_LOCKED, BURN_AMOUNT_LOCKED); + await expect(tx).to.emit(token, "Transfer").withArgs(underwritingLocker.address, BURN_ADDRESS, BURN_AMOUNT_UNLOCKED.add(BURN_AMOUNT_LOCKED)); + await expect(tx).to.emit(token, "Transfer").withArgs(underwritingLocker.address, user1.address, ACTUAL_WITHDRAW_AMOUNT_UNLOCKED.add(ACTUAL_WITHDRAW_AMOUNT_LOCKED)); + + const newGlobalState = await getGlobalState(); + const newUserState = await getUserState(user1); + const newLockState_Locked = await getLockState(LOCKED_LOCK_ID); + const newLockState_Unlocked = await getLockState(UNLOCKED_LOCK_ID); + const newUWETotalSupply = await token.totalSupply() + const globalStateChange = getGlobalStateChange(newGlobalState, oldGlobalState); + const userStateChange = getUserStateChange(newUserState, oldUserState); + const lockStateChange_Locked = getLockStateChange(newLockState_Locked, oldLockState_Locked); + const lockStateChange_Unlocked = getLockStateChange(newLockState_Unlocked, oldLockState_Unlocked); + const UWETotalSupplyChange = newUWETotalSupply.sub(oldUWETotalSupply) + + expect(globalStateChange.totalNumLocks.eq(0)); + expect(globalStateChange.totalStakedAmount.eq(WITHDRAW_AMOUNT.mul(2))); + expect(globalStateChange.totalSupply).eq(0) + expect(userStateChange.lockedTokenAmount).eq(WITHDRAW_AMOUNT.mul(-2)); + expect(userStateChange.numOfLocks).eq(0); + expect(userStateChange.tokenAmountInWallet).eq(ACTUAL_WITHDRAW_AMOUNT_LOCKED.add(ACTUAL_WITHDRAW_AMOUNT_UNLOCKED)); + expect(lockStateChange_Locked.amount).eq(WITHDRAW_AMOUNT.mul(-1)); + expect(lockStateChange_Locked.end).eq(0); + expect(lockStateChange_Unlocked.amount).eq(WITHDRAW_AMOUNT.mul(-1)); + expect(lockStateChange_Unlocked.end).eq(0); + expect(UWETotalSupplyChange).eq((BURN_AMOUNT_LOCKED.add(BURN_AMOUNT_UNLOCKED)).mul(-1)) + + const listenerUpdate = await listener.lastUpdate(); + expect(listenerUpdate.blocknum).eq(CURRENT_BLOCK + 1); + expect(listenerUpdate.caller).eq(underwritingLocker.address); + expect(listenerUpdate.lockID).eq(UNLOCKED_LOCK_ID); + expect(listenerUpdate.oldOwner).eq(user1.address); + expect(listenerUpdate.newOwner).eq(user1.address); + expect(listenerUpdate.oldLock.amount).eq(oldLockState_Unlocked.amount); + expect(listenerUpdate.oldLock.end).eq(oldLockState_Unlocked.end); + expect(listenerUpdate.newLock.amount).eq(newLockState_Unlocked.amount); + expect(listenerUpdate.newLock.end).eq(newLockState_Unlocked.end); + }); + it("approved can withdraw in part from multiple locks, and listener notified", async function () { + const LOCKED_LOCK_ID = 1; + const UNLOCKED_LOCK_ID = 2; + const oldGlobalState = await getGlobalState(); + const oldUserState = await getUserState(user1); + const oldLockState_Locked = await getLockState(LOCKED_LOCK_ID); + const oldLockState_Unlocked = await getLockState(UNLOCKED_LOCK_ID); + const oldUWETotalSupply = await token.totalSupply() + const {number: CURRENT_BLOCK} = await provider.getBlock('latest'); + + await underwritingLocker.connect(user1).setApprovalForAll(user2.address, true) + const tx = await underwritingLocker.connect(user2).withdrawInPartMultiple( + [LOCKED_LOCK_ID, UNLOCKED_LOCK_ID], + [WITHDRAW_AMOUNT, WITHDRAW_AMOUNT], + user1.address + ) + + const ACTUAL_WITHDRAW_AMOUNT_UNLOCKED = await underwritingLocker.getWithdrawInPartAmount(UNLOCKED_LOCK_ID, WITHDRAW_AMOUNT) + const BURN_AMOUNT_UNLOCKED = await underwritingLocker.getBurnOnWithdrawInPartAmount(UNLOCKED_LOCK_ID, WITHDRAW_AMOUNT) + const ACTUAL_WITHDRAW_AMOUNT_LOCKED = await underwritingLocker.getWithdrawInPartAmount(LOCKED_LOCK_ID, WITHDRAW_AMOUNT) + const BURN_AMOUNT_LOCKED = await underwritingLocker.getBurnOnWithdrawInPartAmount(LOCKED_LOCK_ID, WITHDRAW_AMOUNT) + await expect(tx).to.emit(underwritingLocker, "Withdrawal").withArgs(UNLOCKED_LOCK_ID, WITHDRAW_AMOUNT, ACTUAL_WITHDRAW_AMOUNT_UNLOCKED, BURN_AMOUNT_UNLOCKED); + await expect(tx).to.emit(underwritingLocker, "EarlyWithdrawal").withArgs(LOCKED_LOCK_ID, WITHDRAW_AMOUNT, ACTUAL_WITHDRAW_AMOUNT_LOCKED, BURN_AMOUNT_LOCKED); + await expect(tx).to.emit(token, "Transfer").withArgs(underwritingLocker.address, BURN_ADDRESS, BURN_AMOUNT_UNLOCKED.add(BURN_AMOUNT_LOCKED)); + await expect(tx).to.emit(token, "Transfer").withArgs(underwritingLocker.address, user1.address, ACTUAL_WITHDRAW_AMOUNT_UNLOCKED.add(ACTUAL_WITHDRAW_AMOUNT_LOCKED)); + + const newGlobalState = await getGlobalState(); + const newUserState = await getUserState(user1); + const newLockState_Locked = await getLockState(LOCKED_LOCK_ID); + const newLockState_Unlocked = await getLockState(UNLOCKED_LOCK_ID); + const newUWETotalSupply = await token.totalSupply() + const globalStateChange = getGlobalStateChange(newGlobalState, oldGlobalState); + const userStateChange = getUserStateChange(newUserState, oldUserState); + const lockStateChange_Locked = getLockStateChange(newLockState_Locked, oldLockState_Locked); + const lockStateChange_Unlocked = getLockStateChange(newLockState_Unlocked, oldLockState_Unlocked); + const UWETotalSupplyChange = newUWETotalSupply.sub(oldUWETotalSupply) + + expect(globalStateChange.totalNumLocks.eq(0)); + expect(globalStateChange.totalStakedAmount.eq(WITHDRAW_AMOUNT.mul(2))); + expect(globalStateChange.totalSupply).eq(0) + expect(userStateChange.lockedTokenAmount).eq(WITHDRAW_AMOUNT.mul(-2)); + expect(userStateChange.numOfLocks).eq(0); + expect(userStateChange.tokenAmountInWallet).eq(ACTUAL_WITHDRAW_AMOUNT_UNLOCKED.add(ACTUAL_WITHDRAW_AMOUNT_LOCKED)); + expect(lockStateChange_Locked.amount).eq(WITHDRAW_AMOUNT.mul(-1)); + expect(lockStateChange_Locked.end).eq(0); + expect(lockStateChange_Unlocked.amount).eq(WITHDRAW_AMOUNT.mul(-1)); + expect(lockStateChange_Unlocked.end).eq(0); + expect(UWETotalSupplyChange).eq((BURN_AMOUNT_LOCKED.add(BURN_AMOUNT_UNLOCKED)).mul(-1)) + + const listenerUpdate = await listener.lastUpdate(); + expect(listenerUpdate.blocknum).eq(CURRENT_BLOCK + 2); + expect(listenerUpdate.caller).eq(underwritingLocker.address); + expect(listenerUpdate.lockID).eq(UNLOCKED_LOCK_ID); + expect(listenerUpdate.oldOwner).eq(user1.address); + expect(listenerUpdate.newOwner).eq(user1.address); + expect(listenerUpdate.oldLock.amount).eq(oldLockState_Unlocked.amount); + expect(listenerUpdate.oldLock.end).eq(oldLockState_Unlocked.end); + expect(listenerUpdate.newLock.amount).eq(newLockState_Unlocked.amount); + expect(listenerUpdate.newLock.end).eq(newLockState_Unlocked.end); + }); + }); + + /******************* + STATE SUMMARY + *******************/ + /** + * There are two locks: + * i.) lockID 1 => 2wk lock held by user1, with 1e18 token locked + * ii.) lockID 2 => Unlocked lock held by user1, with 1e18 token staked + */ + + describe("withdraw", function () { + + /** + * Skip time forward, and create two more locks such that: + * + * lockID 1 => Unlocked lock held by user1, with 1e18 token staked + * lockID 2 => Unlocked lock held by user1, with 1e18 token staked + * lockID 3 => Locked (1yr) lock held by user1, with 1e18 token staked + * lockID 4 => Locked (1yr) lock held by user1, with 1e18 token staked + */ + // + + before(async function () { + const CURRENT_TIME = (await provider.getBlock('latest')).timestamp; + await provider.send("evm_mine", [CURRENT_TIME + 2 * ONE_WEEK]); + expect(await underwritingLocker.isLocked(1)).eq(false) + expect(await underwritingLocker.isLocked(2)).eq(false) + await underwritingLocker.connect(user1).createLock(user1.address, DEPOSIT_AMOUNT, CURRENT_TIME + ONE_YEAR); + await underwritingLocker.connect(user1).createLock(user1.address, DEPOSIT_AMOUNT, CURRENT_TIME + ONE_YEAR); + }); + it("cannot withdraw non existant token", async function () { + const NON_EXISTENT_LOCK_ID = 999; + // Error does not indicate non-existant tokenID, however it will revert regardless + await expect(underwritingLocker.connect(user1).withdraw(999, user1.address)).to.be.revertedWith("ERC721: operator query for nonexistent token") + }); + it("non owner or approved cannot withdraw", async function () { + const LOCK_ID = 1; + await expect(underwritingLocker.connect(user3).withdraw(LOCK_ID, user3.address)).to.be.revertedWith("only owner or approved"); + }); + it("owner can withdraw from unlocked lock, and listener notified", async function () { + const UNLOCKED_LOCK_ID = 1; + const oldGlobalState = await getGlobalState(); + const oldUserState = await getUserState(user1); + const oldLockState = await getLockState(UNLOCKED_LOCK_ID); + const {number: CURRENT_BLOCK} = await provider.getBlock('latest') + const LOCK_AMOUNT = oldLockState.amount; + + const ACTUAL_WITHDRAW_AMOUNT = await underwritingLocker.getWithdrawAmount(UNLOCKED_LOCK_ID) + const BURN_AMOUNT = await underwritingLocker.getBurnOnWithdrawAmount(UNLOCKED_LOCK_ID) + const tx = await underwritingLocker.connect(user1).withdraw(UNLOCKED_LOCK_ID, user1.address); + await expect(tx).to.emit(underwritingLocker, "Withdrawal").withArgs(UNLOCKED_LOCK_ID, WITHDRAW_AMOUNT, ACTUAL_WITHDRAW_AMOUNT, BURN_AMOUNT); + await expect(tx).to.emit(token, "Transfer").withArgs(underwritingLocker.address, BURN_ADDRESS, BURN_AMOUNT); + await expect(tx).to.emit(token, "Transfer").withArgs(underwritingLocker.address, user1.address, ACTUAL_WITHDRAW_AMOUNT); + + const newGlobalState = await getGlobalState(); + const newUserState = await getUserState(user1); + const globalStateChange = getGlobalStateChange(newGlobalState, oldGlobalState); + const userStateChange = getUserStateChange(newUserState, oldUserState); + expect(globalStateChange.totalNumLocks.eq(0)); + expect(globalStateChange.totalStakedAmount.eq(LOCK_AMOUNT)); + expect(globalStateChange.totalSupply).eq(-1) + expect(userStateChange.lockedTokenAmount).eq(LOCK_AMOUNT.mul(-1)); + expect(userStateChange.numOfLocks).eq(-1); + expect(userStateChange.tokenAmountInWallet).eq(ACTUAL_WITHDRAW_AMOUNT); + await expect(underwritingLocker.locks(UNLOCKED_LOCK_ID)).to.be.revertedWith("query for nonexistent token") + await expect(underwritingLocker.timeLeft(UNLOCKED_LOCK_ID)).to.be.revertedWith("query for nonexistent token") + await expect(underwritingLocker.isLocked(UNLOCKED_LOCK_ID)).to.be.revertedWith("query for nonexistent token") + await expect(underwritingLocker.ownerOf(UNLOCKED_LOCK_ID)).to.be.revertedWith("ERC721: owner query for nonexistent token") + + const listenerUpdate = await listener.lastUpdate(); + expect(listenerUpdate.blocknum).eq(CURRENT_BLOCK + 1); + expect(listenerUpdate.caller).eq(underwritingLocker.address); + expect(listenerUpdate.lockID).eq(UNLOCKED_LOCK_ID); + expect(listenerUpdate.oldOwner).eq(user1.address); + expect(listenerUpdate.newOwner).eq(ZERO_ADDRESS); + expect(listenerUpdate.oldLock.amount).eq(oldLockState.amount); + expect(listenerUpdate.oldLock.end).eq(oldLockState.end); + expect(listenerUpdate.newLock.amount).eq(ZERO); + expect(listenerUpdate.newLock.end).eq(ZERO); + }); + it("approved can withdraw from unlocked lock, and listener notified", async function () { + const UNLOCKED_LOCK_ID = 2; + const oldGlobalState = await getGlobalState(); + const oldUserState = await getUserState(user1); + const oldLockState = await getLockState(UNLOCKED_LOCK_ID); + const {number: CURRENT_BLOCK} = await provider.getBlock('latest') + const LOCK_AMOUNT = oldLockState.amount; + const oldUWETotalSupply = await token.totalSupply() + + await underwritingLocker.connect(user1).approve(user2.address, UNLOCKED_LOCK_ID); + const ACTUAL_WITHDRAW_AMOUNT = await underwritingLocker.getWithdrawAmount(UNLOCKED_LOCK_ID) + const BURN_AMOUNT = await underwritingLocker.getBurnOnWithdrawAmount(UNLOCKED_LOCK_ID) + const tx = await underwritingLocker.connect(user2).withdraw(UNLOCKED_LOCK_ID, user1.address); + await expect(tx).to.emit(underwritingLocker, "Withdrawal").withArgs(UNLOCKED_LOCK_ID, WITHDRAW_AMOUNT, ACTUAL_WITHDRAW_AMOUNT, BURN_AMOUNT); + await expect(tx).to.emit(token, "Transfer").withArgs(underwritingLocker.address, BURN_ADDRESS, BURN_AMOUNT); + await expect(tx).to.emit(token, "Transfer").withArgs(underwritingLocker.address, user1.address, ACTUAL_WITHDRAW_AMOUNT); + + const newGlobalState = await getGlobalState(); + const newUserState = await getUserState(user1); + const newUWETotalSupply = await token.totalSupply() + const globalStateChange = getGlobalStateChange(newGlobalState, oldGlobalState); + const userStateChange = getUserStateChange(newUserState, oldUserState); + const UWETotalSupplyChange = newUWETotalSupply.sub(oldUWETotalSupply) + + expect(globalStateChange.totalNumLocks.eq(0)); + expect(globalStateChange.totalStakedAmount.eq(LOCK_AMOUNT)); + expect(globalStateChange.totalSupply).eq(-1) + expect(userStateChange.lockedTokenAmount).eq(LOCK_AMOUNT.mul(-1)); + expect(userStateChange.numOfLocks).eq(-1); + expect(userStateChange.tokenAmountInWallet).eq(ACTUAL_WITHDRAW_AMOUNT); + expect(UWETotalSupplyChange).eq(BURN_AMOUNT.mul(-1)) + await expect(underwritingLocker.locks(UNLOCKED_LOCK_ID)).to.be.revertedWith("query for nonexistent token") + await expect(underwritingLocker.timeLeft(UNLOCKED_LOCK_ID)).to.be.revertedWith("query for nonexistent token") + await expect(underwritingLocker.isLocked(UNLOCKED_LOCK_ID)).to.be.revertedWith("query for nonexistent token") + await expect(underwritingLocker.ownerOf(UNLOCKED_LOCK_ID)).to.be.revertedWith("ERC721: owner query for nonexistent token") + + const listenerUpdate = await listener.lastUpdate(); + expect(listenerUpdate.blocknum).eq(CURRENT_BLOCK + 2); + expect(listenerUpdate.caller).eq(underwritingLocker.address); + expect(listenerUpdate.lockID).eq(UNLOCKED_LOCK_ID); + expect(listenerUpdate.oldOwner).eq(user1.address); + expect(listenerUpdate.newOwner).eq(ZERO_ADDRESS); + expect(listenerUpdate.oldLock.amount).eq(oldLockState.amount); + expect(listenerUpdate.oldLock.end).eq(oldLockState.end); + expect(listenerUpdate.newLock.amount).eq(ZERO); + expect(listenerUpdate.newLock.end).eq(ZERO); + }); + it("owner can withdraw from locked lock with penalty, and listener notified", async function () { + const LOCKED_LOCK_ID = 3; + const oldGlobalState = await getGlobalState(); + const oldUserState = await getUserState(user1); + const oldLockState = await getLockState(LOCKED_LOCK_ID); + const oldUWETotalSupply = await token.totalSupply() + const {number: CURRENT_BLOCK} = await provider.getBlock('latest') + const LOCK_AMOUNT = oldLockState.amount; + + const ACTUAL_WITHDRAW_AMOUNT = await underwritingLocker.getWithdrawAmount(LOCKED_LOCK_ID) + const BURN_AMOUNT = await underwritingLocker.getBurnOnWithdrawAmount(LOCKED_LOCK_ID) + const tx = await underwritingLocker.connect(user1).withdraw(LOCKED_LOCK_ID, user1.address); + + // Cannot get exact match to Withdrawal event parameters, because queries getWithdrawAmount and getBurnOnWithdrawAmount + // are done at time `x`, however the timestamp for the mutator call withdraw is done at time `x + 1` + // We cannot do `getWithdrawAmount` and `getBurnOnWithdrawAmount` queries at time `x + 1` because the lock doesn't exist at this time + // Unless there is a way to simulate these queries at `x + 1`, then bring time back to `x` for withdraw call to be done at `x+1` + // So we need to rely on i.) Testing of exact event parameters in earlier tests, ii.) Accept approximate result for results of desired events + await expect(tx).to.emit(underwritingLocker, "EarlyWithdrawal") + + const newGlobalState = await getGlobalState(); + const newUserState = await getUserState(user1); + const newUWETotalSupply = await token.totalSupply() + const globalStateChange = getGlobalStateChange(newGlobalState, oldGlobalState); + const userStateChange = getUserStateChange(newUserState, oldUserState); + const UWETotalSupplyChange = newUWETotalSupply.sub(oldUWETotalSupply) + + expect(globalStateChange.totalNumLocks.eq(0)); + expect(globalStateChange.totalStakedAmount.eq(LOCK_AMOUNT)); + expect(globalStateChange.totalSupply).eq(-1) + expect(userStateChange.lockedTokenAmount).eq(LOCK_AMOUNT.mul(-1)); + expect(userStateChange.numOfLocks).eq(-1); + expectClose(userStateChange.tokenAmountInWallet, ACTUAL_WITHDRAW_AMOUNT, 1e15); + expectClose(UWETotalSupplyChange, BURN_AMOUNT.mul(-1), 1e15); + await expect(underwritingLocker.locks(LOCKED_LOCK_ID)).to.be.revertedWith("query for nonexistent token") + await expect(underwritingLocker.timeLeft(LOCKED_LOCK_ID)).to.be.revertedWith("query for nonexistent token") + await expect(underwritingLocker.isLocked(LOCKED_LOCK_ID)).to.be.revertedWith("query for nonexistent token") + await expect(underwritingLocker.ownerOf(LOCKED_LOCK_ID)).to.be.revertedWith("ERC721: owner query for nonexistent token") + + const listenerUpdate = await listener.lastUpdate(); + expect(listenerUpdate.blocknum).eq(CURRENT_BLOCK + 1); + expect(listenerUpdate.caller).eq(underwritingLocker.address); + expect(listenerUpdate.lockID).eq(LOCKED_LOCK_ID); + expect(listenerUpdate.oldOwner).eq(user1.address); + expect(listenerUpdate.newOwner).eq(ZERO_ADDRESS); + expect(listenerUpdate.oldLock.amount).eq(oldLockState.amount); + expect(listenerUpdate.oldLock.end).eq(oldLockState.end); + expect(listenerUpdate.newLock.amount).eq(ZERO); + expect(listenerUpdate.newLock.end).eq(ZERO); + }); + it("approved can withdraw from locked lock with penalty, and listener notified", async function () { + const LOCKED_LOCK_ID = 4; + const oldGlobalState = await getGlobalState(); + const oldUserState = await getUserState(user1); + const oldLockState = await getLockState(LOCKED_LOCK_ID); + const oldUWETotalSupply = await token.totalSupply() + const {number: CURRENT_BLOCK} = await provider.getBlock('latest') + const LOCK_AMOUNT = oldLockState.amount; + + await underwritingLocker.connect(user1).approve(user2.address, LOCKED_LOCK_ID); + + const ACTUAL_WITHDRAW_AMOUNT = await underwritingLocker.getWithdrawAmount(LOCKED_LOCK_ID) + const BURN_AMOUNT = await underwritingLocker.getBurnOnWithdrawAmount(LOCKED_LOCK_ID) + const tx = await underwritingLocker.connect(user2).withdraw(LOCKED_LOCK_ID, user1.address); + await expect(tx).to.emit(underwritingLocker, "EarlyWithdrawal") + + const newGlobalState = await getGlobalState(); + const newUserState = await getUserState(user1); + const newUWETotalSupply = await token.totalSupply() + const globalStateChange = getGlobalStateChange(newGlobalState, oldGlobalState); + const userStateChange = getUserStateChange(newUserState, oldUserState); + const UWETotalSupplyChange = newUWETotalSupply.sub(oldUWETotalSupply) + + expect(globalStateChange.totalNumLocks.eq(0)); + expect(globalStateChange.totalStakedAmount.eq(LOCK_AMOUNT)); + expect(globalStateChange.totalSupply).eq(-1) + expect(userStateChange.lockedTokenAmount).eq(LOCK_AMOUNT.mul(-1)); + expect(userStateChange.numOfLocks).eq(-1); + expectClose(userStateChange.tokenAmountInWallet, ACTUAL_WITHDRAW_AMOUNT, 1e15); + expectClose(UWETotalSupplyChange, BURN_AMOUNT.mul(-1), 1e15); + await expect(underwritingLocker.locks(LOCKED_LOCK_ID)).to.be.revertedWith("query for nonexistent token") + await expect(underwritingLocker.timeLeft(LOCKED_LOCK_ID)).to.be.revertedWith("query for nonexistent token") + await expect(underwritingLocker.isLocked(LOCKED_LOCK_ID)).to.be.revertedWith("query for nonexistent token") + await expect(underwritingLocker.ownerOf(LOCKED_LOCK_ID)).to.be.revertedWith("ERC721: owner query for nonexistent token") + + const listenerUpdate = await listener.lastUpdate(); + expect(listenerUpdate.blocknum).eq(CURRENT_BLOCK + 2); + expect(listenerUpdate.caller).eq(underwritingLocker.address); + expect(listenerUpdate.lockID).eq(LOCKED_LOCK_ID); + expect(listenerUpdate.oldOwner).eq(user1.address); + expect(listenerUpdate.newOwner).eq(ZERO_ADDRESS); + expect(listenerUpdate.oldLock.amount).eq(oldLockState.amount); + expect(listenerUpdate.oldLock.end).eq(oldLockState.end); + expect(listenerUpdate.newLock.amount).eq(ZERO); + expect(listenerUpdate.newLock.end).eq(ZERO); + }); + }); + + /******************* + STATE SUMMARY + *******************/ + /** + * All locks have been burned, however the current lockIDs have been used previously and cannot be used again: + * 1, 2, 3, 4 + */ + + describe("withdrawMultiple", function () { + /** + * Create 4 locks - 2 locked and 2 unlocked: + * + * lockID 5 -> unlocked + * lockID 6 -> locked + * lockID 7 -> unlocked + * lockID 8 -> locked + */ + before(async function () { + const CURRENT_TIME = (await provider.getBlock('latest')).timestamp; + await underwritingLocker.connect(user1).createLock(user1.address, DEPOSIT_AMOUNT, CURRENT_TIME + 6 * ONE_MONTH + 10); + await underwritingLocker.connect(user1).createLock(user1.address, DEPOSIT_AMOUNT, CURRENT_TIME + 2 * ONE_YEAR); + await underwritingLocker.connect(user1).createLock(user1.address, DEPOSIT_AMOUNT, CURRENT_TIME + 6 * ONE_MONTH + 10); + await underwritingLocker.connect(user1).createLock(user1.address, DEPOSIT_AMOUNT, CURRENT_TIME + 2 * ONE_YEAR); + await provider.send("evm_mine", [CURRENT_TIME + 6 * ONE_MONTH + ONE_WEEK]); + expect(await underwritingLocker.isLocked(5)).eq(false) + expect(await underwritingLocker.isLocked(6)).eq(true) + expect(await underwritingLocker.isLocked(7)).eq(false) + expect(await underwritingLocker.isLocked(8)).eq(true) + }); + it("cannot withdraw non existant token", async function () { + const NON_EXISTENT_LOCK_ID = 999; + const UNLOCKED_LOCK_ID = 5; + await expect(underwritingLocker.connect(user1).withdrawMultiple( + [UNLOCKED_LOCK_ID, NON_EXISTENT_LOCK_ID], + user1.address + )).to.be.revertedWith("ERC721: operator query for nonexistent token"); + }); + it("non owner or approved cannot withdraw", async function () { + const UNLOCKED_LOCK_ID = 5; + const LOCKED_LOCK_ID = 6; + await expect(underwritingLocker.connect(user3).withdrawMultiple( + [UNLOCKED_LOCK_ID, LOCKED_LOCK_ID], + user1.address + )).to.be.revertedWith("NotOwnerNorApproved"); + }); + it("owner can withdraw from multiple locks, and listener notified", async function () { + const UNLOCKED_LOCK_ID = 5; + const LOCKED_LOCK_ID = 6; + const oldGlobalState = await getGlobalState(); + const oldUserState = await getUserState(user1); + const oldLockState = await getLockState(LOCKED_LOCK_ID); + const oldUWETotalSupply = await token.totalSupply() + const {number: CURRENT_BLOCK} = await provider.getBlock('latest') + const LOCK_AMOUNT = oldLockState.amount + + const ACTUAL_WITHDRAW_AMOUNT_LOCKED = await underwritingLocker.getWithdrawAmount(LOCKED_LOCK_ID) + const BURN_AMOUNT_LOCKED = await underwritingLocker.getBurnOnWithdrawAmount(LOCKED_LOCK_ID) + const ACTUAL_WITHDRAW_AMOUNT_UNLOCKED = await underwritingLocker.getWithdrawAmount(UNLOCKED_LOCK_ID) + const BURN_AMOUNT_UNLOCKED = await underwritingLocker.getBurnOnWithdrawAmount(UNLOCKED_LOCK_ID) + const tx = underwritingLocker.connect(user1).withdrawMultiple( + [UNLOCKED_LOCK_ID, LOCKED_LOCK_ID], + user1.address + ) + await expect(tx).to.emit(underwritingLocker, "Withdrawal") + await expect(tx).to.emit(underwritingLocker, "EarlyWithdrawal") + + const newGlobalState = await getGlobalState(); + const newUserState = await getUserState(user1); + const newUWETotalSupply = await token.totalSupply() + const globalStateChange = getGlobalStateChange(newGlobalState, oldGlobalState); + const userStateChange = getUserStateChange(newUserState, oldUserState); + const UWETotalSupplyChange = newUWETotalSupply.sub(oldUWETotalSupply) + + expect(globalStateChange.totalNumLocks.eq(0)); + expect(globalStateChange.totalStakedAmount.eq(LOCK_AMOUNT)); + expect(globalStateChange.totalSupply).eq(-2) + expect(userStateChange.lockedTokenAmount).eq(LOCK_AMOUNT.mul(-2)); + expect(userStateChange.numOfLocks).eq(-2); + expectClose(userStateChange.tokenAmountInWallet, ACTUAL_WITHDRAW_AMOUNT_LOCKED.add(ACTUAL_WITHDRAW_AMOUNT_UNLOCKED), 1e15) + expectClose(UWETotalSupplyChange, (BURN_AMOUNT_LOCKED.add(BURN_AMOUNT_UNLOCKED)).mul(-1), 1e15) + + await expect(underwritingLocker.locks(UNLOCKED_LOCK_ID)).to.be.revertedWith("query for nonexistent token") + await expect(underwritingLocker.timeLeft(UNLOCKED_LOCK_ID)).to.be.revertedWith("query for nonexistent token") + await expect(underwritingLocker.isLocked(UNLOCKED_LOCK_ID)).to.be.revertedWith("query for nonexistent token") + await expect(underwritingLocker.ownerOf(UNLOCKED_LOCK_ID)).to.be.revertedWith("ERC721: owner query for nonexistent token") + await expect(underwritingLocker.locks(LOCKED_LOCK_ID)).to.be.revertedWith("query for nonexistent token") + await expect(underwritingLocker.timeLeft(LOCKED_LOCK_ID)).to.be.revertedWith("query for nonexistent token") + await expect(underwritingLocker.isLocked(LOCKED_LOCK_ID)).to.be.revertedWith("query for nonexistent token") + await expect(underwritingLocker.ownerOf(LOCKED_LOCK_ID)).to.be.revertedWith("ERC721: owner query for nonexistent token") + + const listenerUpdate = await listener.lastUpdate(); + expect(listenerUpdate.blocknum).eq(CURRENT_BLOCK + 1); + expect(listenerUpdate.caller).eq(underwritingLocker.address); + expect(listenerUpdate.lockID).eq(LOCKED_LOCK_ID); + expect(listenerUpdate.oldOwner).eq(user1.address); + expect(listenerUpdate.newOwner).eq(ZERO_ADDRESS); + expect(listenerUpdate.oldLock.amount).eq(oldLockState.amount); + expect(listenerUpdate.oldLock.end).eq(oldLockState.end); + expect(listenerUpdate.newLock.amount).eq(ZERO); + expect(listenerUpdate.newLock.end).eq(ZERO); + }); + it("approved can withdraw from multiple locks, and listener notified", async function () { + const UNLOCKED_LOCK_ID = 7; + const LOCKED_LOCK_ID = 8; + const oldGlobalState = await getGlobalState(); + const oldUserState = await getUserState(user1); + const oldLockState = await getLockState(LOCKED_LOCK_ID); + const oldUWETotalSupply = await token.totalSupply() + const {number: CURRENT_BLOCK} = await provider.getBlock('latest') + const LOCK_AMOUNT = oldLockState.amount + + await underwritingLocker.connect(user1).setApprovalForAll(user2.address, true) + const ACTUAL_WITHDRAW_AMOUNT_LOCKED = await underwritingLocker.getWithdrawAmount(LOCKED_LOCK_ID) + const BURN_AMOUNT_LOCKED = await underwritingLocker.getBurnOnWithdrawAmount(LOCKED_LOCK_ID) + const ACTUAL_WITHDRAW_AMOUNT_UNLOCKED = await underwritingLocker.getWithdrawAmount(UNLOCKED_LOCK_ID) + const BURN_AMOUNT_UNLOCKED = await underwritingLocker.getBurnOnWithdrawAmount(UNLOCKED_LOCK_ID) + const tx = underwritingLocker.connect(user2).withdrawMultiple( + [UNLOCKED_LOCK_ID, LOCKED_LOCK_ID], + user1.address + ) + await expect(tx).to.emit(underwritingLocker, "Withdrawal"); + await expect(tx).to.emit(underwritingLocker, "EarlyWithdrawal"); + + const newGlobalState = await getGlobalState(); + const newUserState = await getUserState(user1); + const newUWETotalSupply = await token.totalSupply() + const globalStateChange = getGlobalStateChange(newGlobalState, oldGlobalState); + const userStateChange = getUserStateChange(newUserState, oldUserState); + const UWETotalSupplyChange = newUWETotalSupply.sub(oldUWETotalSupply) + + expect(globalStateChange.totalNumLocks.eq(0)); + expect(globalStateChange.totalStakedAmount.eq(LOCK_AMOUNT)); + expect(globalStateChange.totalSupply).eq(-2) + expect(userStateChange.lockedTokenAmount).eq(LOCK_AMOUNT.mul(-2)); + expect(userStateChange.numOfLocks).eq(-2); + expectClose(userStateChange.tokenAmountInWallet, ACTUAL_WITHDRAW_AMOUNT_LOCKED.add(ACTUAL_WITHDRAW_AMOUNT_UNLOCKED), 1e15) + expectClose(UWETotalSupplyChange, (BURN_AMOUNT_LOCKED.add(BURN_AMOUNT_UNLOCKED)).mul(-1), 1e15) + + await expect(underwritingLocker.locks(UNLOCKED_LOCK_ID)).to.be.revertedWith("query for nonexistent token") + await expect(underwritingLocker.timeLeft(UNLOCKED_LOCK_ID)).to.be.revertedWith("query for nonexistent token") + await expect(underwritingLocker.isLocked(UNLOCKED_LOCK_ID)).to.be.revertedWith("query for nonexistent token") + await expect(underwritingLocker.ownerOf(UNLOCKED_LOCK_ID)).to.be.revertedWith("ERC721: owner query for nonexistent token") + await expect(underwritingLocker.locks(LOCKED_LOCK_ID)).to.be.revertedWith("query for nonexistent token") + await expect(underwritingLocker.timeLeft(LOCKED_LOCK_ID)).to.be.revertedWith("query for nonexistent token") + await expect(underwritingLocker.isLocked(LOCKED_LOCK_ID)).to.be.revertedWith("query for nonexistent token") + await expect(underwritingLocker.ownerOf(LOCKED_LOCK_ID)).to.be.revertedWith("ERC721: owner query for nonexistent token") + + const listenerUpdate = await listener.lastUpdate(); + expect(listenerUpdate.blocknum).eq(CURRENT_BLOCK + 2); + expect(listenerUpdate.caller).eq(underwritingLocker.address); + expect(listenerUpdate.lockID).eq(LOCKED_LOCK_ID); + expect(listenerUpdate.oldOwner).eq(user1.address); + expect(listenerUpdate.newOwner).eq(ZERO_ADDRESS); + expect(listenerUpdate.oldLock.amount).eq(oldLockState.amount); + expect(listenerUpdate.oldLock.end).eq(oldLockState.end); + expect(listenerUpdate.newLock.amount).eq(ZERO); + expect(listenerUpdate.newLock.end).eq(ZERO); + }); + }); + + /******************* + STATE SUMMARY + *******************/ + /** + * All locks have been burned, however the current lockIDs have been used previously and cannot be used again: + * 1, 2, 3, 4, 5, 6, 7, 8 + */ + + describe("further sanity checks of funding rate mechanism", function () { + /** + * Create 2 more locks - 1 minimum-period lock (6 months) and 1 maximum-period lock (4 years) + * + * lockID 9 -> 6-month lock + * lockID 10 -> 4-yr lock + */ + before(async function () { + const CURRENT_TIME = (await provider.getBlock('latest')).timestamp; + await underwritingLocker.connect(user1).createLock(user1.address, DEPOSIT_AMOUNT, CURRENT_TIME + 6 * ONE_MONTH + 2); + await underwritingLocker.connect(user1).createLock(user1.address, DEPOSIT_AMOUNT, CURRENT_TIME + 4 * ONE_YEAR); + }); + + it("should return appropriate values for minimum-period lock", async function () { + const LOCK_ID = 9; + const lockState = await getLockState(LOCK_ID); + + expect(lockState.isLocked).eq(true); + expectClose(lockState.timeLeft, BN.from(6).mul(ONE_MONTH), 1e15) + + // Expect multiplier for minimum-period lock to be 1.0x + const EXPECTED_LOCK_MULTIPLIER = ONE_HUNDRED_PERCENT; + expectClose(await underwritingLocker.getLockMultiplier(LOCK_ID), EXPECTED_LOCK_MULTIPLIER, 1e15) + + // ( 1 / (1 + lock_multiplier) ) * (1 - funding_rate) + const EXPECTED_EARLY_WITHDRAW_MULTIPLIER_NUMERATOR = SCALE_FACTOR; + const EXPECTED_EARLY_WITHDRAW_MULTIPLIER_DENOMINATOR = EXPECTED_LOCK_MULTIPLIER.add(SCALE_FACTOR); + const EXPECTED_WITHDRAW_MULTIPLIER_AFTER_FUNDING_NUMERATOR = ONE_HUNDRED_PERCENT.sub(FUNDING_RATE) + const EXPECTED_WITHDRAW_MULTIPLIER_AFTER_FUNDING_DENOMINATOR = SCALE_FACTOR + + const EXPECTED_WITHDRAW_AMOUNT = lockState.amount + .mul(EXPECTED_EARLY_WITHDRAW_MULTIPLIER_NUMERATOR) + .mul(EXPECTED_WITHDRAW_MULTIPLIER_AFTER_FUNDING_NUMERATOR) + .div(EXPECTED_EARLY_WITHDRAW_MULTIPLIER_DENOMINATOR) + .div(EXPECTED_WITHDRAW_MULTIPLIER_AFTER_FUNDING_DENOMINATOR) + + expect(await underwritingLocker.getWithdrawAmount(LOCK_ID)).eq(EXPECTED_WITHDRAW_AMOUNT); + expect(await underwritingLocker.getBurnOnWithdrawAmount(LOCK_ID)).eq(lockState.amount.sub(EXPECTED_WITHDRAW_AMOUNT)); + + const EXPECTED_WITHDRAW_IN_PART_AMOUNT = WITHDRAW_AMOUNT + .mul(EXPECTED_EARLY_WITHDRAW_MULTIPLIER_NUMERATOR) + .mul(EXPECTED_WITHDRAW_MULTIPLIER_AFTER_FUNDING_NUMERATOR) + .div(EXPECTED_EARLY_WITHDRAW_MULTIPLIER_DENOMINATOR) + .div(EXPECTED_WITHDRAW_MULTIPLIER_AFTER_FUNDING_DENOMINATOR) + + expect(await underwritingLocker.getWithdrawInPartAmount(LOCK_ID, WITHDRAW_AMOUNT)).eq(EXPECTED_WITHDRAW_IN_PART_AMOUNT); + expect(await underwritingLocker.getBurnOnWithdrawInPartAmount(LOCK_ID, WITHDRAW_AMOUNT)).eq(WITHDRAW_AMOUNT.sub(EXPECTED_WITHDRAW_IN_PART_AMOUNT)); + + // Expect ~45% to be returned on withdraw at minimum lock period + expectClose(await underwritingLocker.getWithdrawInPartAmount(LOCK_ID, WITHDRAW_AMOUNT), WITHDRAW_AMOUNT.mul(45).div(100), 1e15) + }); + it("should return appropriate values for maximum-period lock", async function () { + const LOCK_ID = 10; + const lockState = await getLockState(LOCK_ID); + + expect(lockState.isLocked).eq(true); + expectClose(lockState.timeLeft, BN.from(4).mul(ONE_YEAR), 1e15) + + // Expect multiplier for maximum-period lock to be sqrt(8) = 2.83x + const EXPECTED_LOCK_MULTIPLIER = sqrt(SCALE_FACTOR.mul(SCALE_FACTOR).mul(8)); + expectClose(await underwritingLocker.getLockMultiplier(LOCK_ID), EXPECTED_LOCK_MULTIPLIER, 1e15) + + // ( 1 / (1 + lock_multiplier) ) * (1 - funding_rate) + const EXPECTED_EARLY_WITHDRAW_MULTIPLIER_NUMERATOR = SCALE_FACTOR; + const EXPECTED_EARLY_WITHDRAW_MULTIPLIER_DENOMINATOR = EXPECTED_LOCK_MULTIPLIER.add(SCALE_FACTOR); + const EXPECTED_WITHDRAW_MULTIPLIER_AFTER_FUNDING_NUMERATOR = ONE_HUNDRED_PERCENT.sub(FUNDING_RATE) + const EXPECTED_WITHDRAW_MULTIPLIER_AFTER_FUNDING_DENOMINATOR = SCALE_FACTOR + + const EXPECTED_WITHDRAW_AMOUNT = lockState.amount + .mul(EXPECTED_EARLY_WITHDRAW_MULTIPLIER_NUMERATOR) + .mul(EXPECTED_WITHDRAW_MULTIPLIER_AFTER_FUNDING_NUMERATOR) + .div(EXPECTED_EARLY_WITHDRAW_MULTIPLIER_DENOMINATOR) + .div(EXPECTED_WITHDRAW_MULTIPLIER_AFTER_FUNDING_DENOMINATOR) + + expectClose(await underwritingLocker.getWithdrawAmount(LOCK_ID), EXPECTED_WITHDRAW_AMOUNT, 1e15); + expectClose(await underwritingLocker.getBurnOnWithdrawAmount(LOCK_ID), lockState.amount.sub(EXPECTED_WITHDRAW_AMOUNT), 1e15); + + const EXPECTED_WITHDRAW_IN_PART_AMOUNT = WITHDRAW_AMOUNT + .mul(EXPECTED_EARLY_WITHDRAW_MULTIPLIER_NUMERATOR) + .mul(EXPECTED_WITHDRAW_MULTIPLIER_AFTER_FUNDING_NUMERATOR) + .div(EXPECTED_EARLY_WITHDRAW_MULTIPLIER_DENOMINATOR) + .div(EXPECTED_WITHDRAW_MULTIPLIER_AFTER_FUNDING_DENOMINATOR) + + expectClose(await underwritingLocker.getWithdrawInPartAmount(LOCK_ID, WITHDRAW_AMOUNT), EXPECTED_WITHDRAW_IN_PART_AMOUNT, 1e15); + expectClose(await underwritingLocker.getBurnOnWithdrawInPartAmount(LOCK_ID, WITHDRAW_AMOUNT), WITHDRAW_AMOUNT.sub(EXPECTED_WITHDRAW_IN_PART_AMOUNT), 1e15); + + // Expect ~23.5% to be returned on withdraw at maximum lock period + expectClose(await underwritingLocker.getWithdrawInPartAmount(LOCK_ID, WITHDRAW_AMOUNT), WITHDRAW_AMOUNT.mul(235).div(1000), 1e15) + }); + }); + + /******************* + STATE SUMMARY + *******************/ + /** + * The following locks have been burned, and the IDs cannot be used again: + * 1, 2, 3, 4, 5, 6, 7, 8 + * + * The following locks exist: + * lockID 9 -> 6-month lock, 1e18 deposit + * lockID 10 -> 4-yr lock, 1e18 deposit + */ + + describe("chargePremium", function () { + const votingContractProxy = ethers.Wallet.createRandom().connect(provider); + + it("will revert if called by non voting-contract", async function () { + await expect(underwritingLocker.connect(governor).chargePremium(1, 1)).to.be.revertedWith("NotVotingContract"); + }); + it("will revert if attempt to charge more premium than exists in the lock", async function () { + await registry.connect(governor).set(["underwritingLockVoting"], [votingContractProxy.address]) + await underwritingLocker.connect(governor).setVotingContract() + expect(await underwritingLocker.votingContract()).eq(votingContractProxy.address) + await expect(underwritingLocker.connect(votingContractProxy).chargePremium(9, DEPOSIT_AMOUNT.mul(2))).to.be.reverted; + }); + it("premium can be charged", async function () { + const LOCK_ID = 9; + const PREMIUM_AMOUNT = DEPOSIT_AMOUNT.div(2) + const oldLockState = await getLockState(LOCK_ID) + + await user1.sendTransaction({to: votingContractProxy.address, value: ONE_ETHER}) // Send gas money + const tx = await underwritingLocker.connect(votingContractProxy).chargePremium(9, PREMIUM_AMOUNT) + const newLockState = await getLockState(LOCK_ID) + const lockStateChange = await getLockStateChange(newLockState, oldLockState) + expect(lockStateChange.amount).eq(PREMIUM_AMOUNT.mul(-1)) + }); + it("if attempt to charge premium for non-existent lock, call will succeed but state will not change", async function () { + const LOCK_ID = 1; + const oldGlobalState = await getGlobalState() + const oldUserState = await getUserState(user1) + const tx = await underwritingLocker.connect(votingContractProxy).chargePremium(LOCK_ID, 1) + expect(await underwritingLocker.exists(LOCK_ID)).eq(false) + const newGlobalState = await getGlobalState() + const newUserState = await getUserState(user1) + const globalStateChange = getGlobalStateChange(newGlobalState, oldGlobalState) + const userStateChange = getUserStateChange(newUserState, oldUserState) + expect(globalStateChange.totalNumLocks).eq(0) + expect(globalStateChange.totalSupply).eq(0) + expect(globalStateChange.totalStakedAmount).eq(0) + expect(userStateChange.tokenAmountInWallet).eq(0) + expect(userStateChange.lockedTokenAmount).eq(0) + expect(userStateChange.numOfLocks).eq(0) + }); + }); + + /******************* + STATE SUMMARY + *******************/ + /** + * The following locks have been burned, and the IDs cannot be used again: + * 1, 2, 3, 4, 5, 6, 7, 8 + * + * The following locks exist: + * lockID 9 -> 6-month lock, 5e17 deposit + * lockID 10 -> 4-yr lock, 1e18 deposit + */ + + describe("getAllLockIDsOf", function () { + it("should return all expected locks", async function () { + const LOCK_ID_1 = BN.from("9"); + const LOCK_ID_2 = BN.from("10"); + expect(await underwritingLocker.getAllLockIDsOf(user1.address)).deep.eq([LOCK_ID_1, LOCK_ID_2]); + }); + it("should return empty array for non-owner", async function () { + expect(await underwritingLocker.getAllLockIDsOf(governor.address)).deep.eq([]); + }); + }); + + describe("Invariant - user cannot have more than 10 active locks", function () { + it("user cannot have more than 10 active locks", async function () { + const CURRENT_TIME = (await provider.getBlock('latest')).timestamp; + await underwritingLocker.connect(user1).createLock(user1.address, DEPOSIT_AMOUNT, CURRENT_TIME + 4 * ONE_YEAR); + await underwritingLocker.connect(user1).createLock(user1.address, DEPOSIT_AMOUNT, CURRENT_TIME + 4 * ONE_YEAR); + await underwritingLocker.connect(user1).createLock(user1.address, DEPOSIT_AMOUNT, CURRENT_TIME + 4 * ONE_YEAR); + await underwritingLocker.connect(user1).createLock(user1.address, DEPOSIT_AMOUNT, CURRENT_TIME + 4 * ONE_YEAR); + await underwritingLocker.connect(user1).createLock(user1.address, DEPOSIT_AMOUNT, CURRENT_TIME + 4 * ONE_YEAR); + await underwritingLocker.connect(user1).createLock(user1.address, DEPOSIT_AMOUNT, CURRENT_TIME + 4 * ONE_YEAR); + await underwritingLocker.connect(user1).createLock(user1.address, DEPOSIT_AMOUNT, CURRENT_TIME + 4 * ONE_YEAR); + await underwritingLocker.connect(user1).createLock(user1.address, DEPOSIT_AMOUNT, CURRENT_TIME + 4 * ONE_YEAR); + expect(await underwritingLocker.balanceOf(user1.address)).eq(10) + await expect(underwritingLocker.connect(user1).createLock(user1.address, DEPOSIT_AMOUNT, CURRENT_TIME + 4 * ONE_YEAR)).to.be.revertedWith("CreatedMaxLocks") + }); + }); + + /******************* + STATE SUMMARY + *******************/ + /** + * The following locks have been burned, and the IDs cannot be used again: + * 1, 2, 3, 4, 5, 6, 7, 8 + * + * The following locks exist: + * lockID 9 -> 6-month lock, 5e17 deposit + * lockID 10 -> 4-yr lock, 1e18 deposit + * lockID 11 -> 4-yr lock, 1e18 deposit + * lockID 12 -> 4-yr lock, 1e18 deposit + * lockID 13 -> 4-yr lock, 1e18 deposit + * lockID 14 -> 4-yr lock, 1e18 deposit + * lockID 15 -> 4-yr lock, 1e18 deposit + * lockID 16 -> 4-yr lock, 1e18 deposit + * lockID 17 -> 4-yr lock, 1e18 deposit + * lockID 18 -> 4-yr lock, 1e18 deposit + */ + + /****************** + HELPER CLOSURES + ******************/ + + interface GlobalState { + totalNumLocks: BN; + totalSupply: BN; + totalStakedAmount: BN; + } + + interface UserState { + tokenAmountInWallet: BN; + lockedTokenAmount: BN; + numOfLocks: BN; + } + + interface LockState { + amount: BN; + end: BN; + timeLeft: BN; + isLocked: boolean; + ownerOf: string; + } + + interface LockStateChange { + amount: BN; + end: BN; + timeLeft: BN; + } + + async function getGlobalState(): Promise { + return { + totalNumLocks: await underwritingLocker.totalNumLocks(), + totalSupply: await underwritingLocker.totalSupply(), + totalStakedAmount: await token.balanceOf(underwritingLocker.address) + } + } + + async function getUserState(user: Wallet): Promise { + return { + tokenAmountInWallet: await token.balanceOf(user.address), + lockedTokenAmount: await underwritingLocker.totalStakedBalance(user.address), + numOfLocks: await underwritingLocker.balanceOf(user.address) + } + } + + async function getLockState(lockID: BigNumberish): Promise { + try { + const lock = await underwritingLocker.locks(lockID); + + return { + amount: lock.amount, + end: lock.end, + timeLeft: await underwritingLocker.timeLeft(lockID), + isLocked: await underwritingLocker.isLocked(lockID), + ownerOf: await underwritingLocker.ownerOf(lockID) + } + } catch { + return { + amount: ZERO, + end: ZERO, + timeLeft: ZERO, + isLocked: false, + ownerOf: ZERO_ADDRESS + } + } + } + + function getGlobalStateChange(newGlobalState: GlobalState, oldGlobalState: GlobalState): GlobalState { + return { + totalNumLocks: newGlobalState.totalNumLocks.sub(oldGlobalState.totalNumLocks), + totalSupply: newGlobalState.totalSupply.sub(oldGlobalState.totalSupply), + totalStakedAmount: newGlobalState.totalStakedAmount.sub(oldGlobalState.totalStakedAmount) + } + } + + function getUserStateChange(newUserState: UserState, oldUserState: UserState): UserState { + return { + tokenAmountInWallet: newUserState.tokenAmountInWallet.sub(oldUserState.tokenAmountInWallet), + lockedTokenAmount: newUserState.lockedTokenAmount.sub(oldUserState.lockedTokenAmount), + numOfLocks: newUserState.numOfLocks.sub(oldUserState.numOfLocks) + } + } + + function getLockStateChange(newLockState: LockState, oldLockState: LockState): LockStateChange { + return { + amount: newLockState.amount.sub(oldLockState.amount), + end: newLockState.end.sub(oldLockState.end), + timeLeft: newLockState.timeLeft.sub(oldLockState.timeLeft) + } + } + + // https://github.com/ethers-io/ethers.js/issues/1182 + function sqrt(x: BN) { + const ONE = BN.from(1); + const TWO = BN.from(2); + let z = x.add(ONE).div(TWO); + let y = x; + while (z.sub(y).isNegative()) { + y = z; + z = x.div(z).add(z).div(TWO); + } + return y; + } +}); diff --git a/test/native/UnderwritingPool.test.ts b/test/native/UnderwritingPool.test.ts new file mode 100644 index 00000000..e83575a4 --- /dev/null +++ b/test/native/UnderwritingPool.test.ts @@ -0,0 +1,507 @@ +import chai from "chai"; +import { ethers, waffle } from "hardhat"; +const { expect } = chai; +const { deployContract, solidity } = waffle; +import { BigNumber as BN, Wallet } from "ethers"; +const provider = waffle.provider; +chai.use(solidity); + +import { import_artifacts, ArtifactImports } from "../utilities/artifact_importer"; +import { UnderwritingPool, FluxMegaOracle, MockFluxPriceFeed, MockErc20, MockErc20Decimals } from "../../typechain"; +import { expectDeployed } from "../utilities/expectDeployed"; + +const name = "Solace Native Underwriting Pool"; +const symbol = "UWP"; +const decimals = 18; + +const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000"; +const ETH_ADDRESS = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; +const ONE_USDC = BN.from("1000000"); +const ONE_ETHER = BN.from("1000000000000000000"); +const ONE_NEAR = BN.from("1000000000000000000000000"); +const EIGHT_DECIMALS = BN.from("100000000"); + +describe("UnderwritingPool", function () { + let uwp: UnderwritingPool; + let oracle: FluxMegaOracle; + let dai: MockErc20; + let usdc: MockErc20; + let weth: MockErc20; + let near: MockErc20; + let uni: MockErc20; + let comp: MockErc20; + let daiPriceFeed: MockFluxPriceFeed; + let ethPriceFeed: MockFluxPriceFeed; + let nearPriceFeed: MockFluxPriceFeed; + let usdcPriceFeed: MockFluxPriceFeed; + + const [deployer, governor, user1, user2, user3] = provider.getWallets(); + let artifacts: ArtifactImports; + let snapshot: BN; + + before(async function () { + artifacts = await import_artifacts(); + snapshot = await provider.send("evm_snapshot", []); + await deployer.sendTransaction({to:deployer.address}); // for some reason this helps solidity-coverage + + // deploy tokens + dai = (await deployContract(deployer, artifacts.MockERC20, ["Dai Stablecoin", "DAI", ONE_ETHER.mul(1000000)])) as MockErc20; + weth = (await deployContract(deployer, artifacts.MockERC20, ["Wrapped Ether", "WETH", ONE_ETHER.mul(1000000)])) as MockErc20; + near = (await deployContract(deployer, artifacts.MockERC20Decimals, ["Near", "NEAR", ONE_NEAR.mul(1000000), 24])) as MockErc20Decimals; + usdc = (await deployContract(deployer, artifacts.MockERC20Decimals, ["USD Coin", "USDC", ONE_USDC.mul(1000000), 24])) as MockErc20Decimals; + uni = (await deployContract(deployer, artifacts.MockERC20, ["Uniswap", "UNI", ONE_ETHER.mul(1000000)])) as MockErc20; + comp = (await deployContract(deployer, artifacts.MockERC20, ["Compound", "COMP", ONE_ETHER.mul(1000000)])) as MockErc20; + + // deploy price feeds + daiPriceFeed = (await deployContract(deployer, artifacts.MockFluxPriceFeed, [governor.address])) as MockFluxPriceFeed; + await daiPriceFeed.connect(governor).setAnswer(EIGHT_DECIMALS.mul(1)); + usdcPriceFeed = (await deployContract(deployer, artifacts.MockFluxPriceFeed, [governor.address])) as MockFluxPriceFeed; + await usdcPriceFeed.connect(governor).setAnswer(EIGHT_DECIMALS.mul(1)); + ethPriceFeed = (await deployContract(deployer, artifacts.MockFluxPriceFeed, [governor.address])) as MockFluxPriceFeed; + await ethPriceFeed.connect(governor).setAnswer(EIGHT_DECIMALS.mul(1300)); + nearPriceFeed = (await deployContract(deployer, artifacts.MockFluxPriceFeed, [governor.address])) as MockFluxPriceFeed; + await nearPriceFeed.connect(governor).setAnswer(EIGHT_DECIMALS.mul(4)); + + // deploy oracle + oracle = (await deployContract(deployer, artifacts.FluxMegaOracle, [governor.address])) as FluxMegaOracle; + await oracle.connect(governor).addPriceFeeds([ + { token: dai.address, priceFeed: daiPriceFeed.address, tokenDecimals: 18, priceFeedDecimals: 8 }, + { token: weth.address, priceFeed: ethPriceFeed.address, tokenDecimals: 18, priceFeedDecimals: 8 }, + { token: near.address, priceFeed: nearPriceFeed.address, tokenDecimals: 24, priceFeedDecimals: 8 }, + { token: usdc.address, priceFeed: usdcPriceFeed.address, tokenDecimals: 6, priceFeedDecimals: 8 }, + ]); + }); + + after(async function () { + await provider.send("evm_revert", [snapshot]); + }); + + describe("deployment", function () { + it("reverts if zero governance", async function () { + await expect(deployContract(deployer, artifacts.UnderwritingPool, [ZERO_ADDRESS])).to.be.revertedWith("zero address governance"); + }); + it("deploys", async function () { + uwp = (await deployContract(deployer, artifacts.UnderwritingPool, [governor.address])) as UnderwritingPool; + await expectDeployed(uwp.address); + }); + it("initializes correctly", async function () { + expect(await uwp.name()).eq(name); + expect(await uwp.symbol()).eq(symbol); + expect(await uwp.decimals()).eq(decimals); + expect(await uwp.issueFee()).eq(0); + expect(await uwp.issueFeeTo()).eq(ZERO_ADDRESS); + expect(await uwp.valueOfPool()).eq(0); + expect(await uwp.isPaused()).eq(false); + expect(await uwp.valueOfShares(0)).eq(0); + expect(await uwp.valueOfHolder(user1.address)).eq(0); + await expect(uwp.valueOfShares(1)).to.be.revertedWith("shares exceeds supply"); + }); + }); + + describe("setting tokens", function () { + it("starts with no tokens", async function () { + expect(await uwp.tokensLength()).eq(0); + await expect(uwp.tokenList(0)).to.be.revertedWith("index out of bounds"); + let data1 = await uwp.tokenData(dai.address); + expect(data1.token).eq(ZERO_ADDRESS); + expect(data1.oracle).eq(ZERO_ADDRESS); + expect(data1.min).eq(0); + expect(data1.max).eq(0); + }); + it("non governance cannot add tokens", async function () { + await expect(uwp.connect(user1).addTokensToPool([])).to.be.revertedWith("!governance"); + }); + it("governance can add tokens", async function () { + let tx1 = await uwp.connect(governor).addTokensToPool([ + { token: dai.address, oracle: oracle.address, min: 0, max: 1 }, + { token: weth.address, oracle: oracle.address, min: 2, max: 3 }, + ]); + await expect(tx1).to.emit(uwp, "TokenAdded").withArgs(dai.address); + await expect(tx1).to.emit(uwp, "TokenAdded").withArgs(weth.address); + let data11 = await uwp.tokenData(dai.address); + expect(data11.token).eq(dai.address); + expect(data11.oracle).eq(oracle.address); + expect(data11.min).eq(0); + expect(data11.max).eq(1); + let data12 = await uwp.tokenData(weth.address); + expect(data12.token).eq(weth.address); + expect(data12.oracle).eq(oracle.address); + expect(data12.min).eq(2); + expect(data12.max).eq(3); + let data21 = await uwp.tokenList(0); + expect(data21.token).eq(dai.address); + expect(data21.oracle).eq(oracle.address); + expect(data21.min).eq(0); + expect(data21.max).eq(1); + let data22 = await uwp.tokenList(1); + expect(data22.token).eq(weth.address); + expect(data22.oracle).eq(oracle.address); + expect(data22.min).eq(2); + expect(data22.max).eq(3); + expect(await uwp.tokensLength()).eq(2); + await expect(uwp.tokenList(2)).to.be.revertedWith("index out of bounds"); + + let tx2 = await uwp.connect(governor).addTokensToPool([ + { token: weth.address, oracle: oracle.address, min: 4, max: 5 }, + { token: near.address, oracle: oracle.address, min: 6, max: 7 }, + ]); + await expect(tx2).to.emit(uwp, "TokenAdded").withArgs(weth.address); + await expect(tx2).to.emit(uwp, "TokenAdded").withArgs(near.address); + let data13 = await uwp.tokenData(weth.address); + expect(data13.token).eq(weth.address); + expect(data13.oracle).eq(oracle.address); + expect(data13.min).eq(4); + expect(data13.max).eq(5); + let data14 = await uwp.tokenData(near.address); + expect(data14.token).eq(near.address); + expect(data14.oracle).eq(oracle.address); + expect(data14.min).eq(6); + expect(data14.max).eq(7); + let data23 = await uwp.tokenList(1); + expect(data23.token).eq(weth.address); + expect(data23.oracle).eq(oracle.address); + expect(data23.min).eq(4); + expect(data23.max).eq(5); + let data24 = await uwp.tokenList(2); + expect(data24.token).eq(near.address); + expect(data24.oracle).eq(oracle.address); + expect(data24.min).eq(6); + expect(data24.max).eq(7); + expect(await uwp.tokensLength()).eq(3); + await expect(uwp.tokenList(3)).to.be.revertedWith("index out of bounds"); + + await uwp.connect(governor).addTokensToPool([]); + let tx3 = await uwp.connect(governor).addTokensToPool([ + { token: weth.address, oracle: oracle.address, min: 4, max: 5 }, + { token: near.address, oracle: oracle.address, min: 6, max: 7 }, + ]); + await expect(tx3).to.emit(uwp, "TokenAdded").withArgs(weth.address); + await expect(tx3).to.emit(uwp, "TokenAdded").withArgs(near.address); + expect(await uwp.tokensLength()).eq(3); + + expect(await uwp.valueOfPool()).eq(0); + }); + it("non governance cannot remove tokens", async function () { + await expect(uwp.connect(user1).removeTokensFromPool([])).to.be.revertedWith("!governance"); + }); + it("governance can remove tokens", async function () { + let tx = await uwp.connect(governor).removeTokensFromPool([near.address, dai.address, usdc.address]); + await expect(tx).to.emit(uwp, "TokenRemoved").withArgs(dai.address); + await expect(tx).to.emit(uwp, "TokenRemoved").withArgs(near.address); + let data1 = await uwp.tokenData(dai.address); + expect(data1.token).eq(ZERO_ADDRESS); + expect(data1.oracle).eq(ZERO_ADDRESS); + expect(data1.min).eq(0); + expect(data1.max).eq(0); + let data2 = await uwp.tokenData(near.address); + expect(data2.token).eq(ZERO_ADDRESS); + expect(data2.oracle).eq(ZERO_ADDRESS); + expect(data2.min).eq(0); + expect(data2.max).eq(0); + let data3 = await uwp.tokenData(weth.address); + expect(data3.token).eq(weth.address); + expect(data3.oracle).eq(oracle.address); + expect(data3.min).eq(4); + expect(data3.max).eq(5); + let data4 = await uwp.tokenList(0); + expect(data4.token).eq(weth.address); + expect(data4.oracle).eq(oracle.address); + expect(data4.min).eq(4); + expect(data4.max).eq(5); + expect(await uwp.tokensLength()).eq(1); + await expect(uwp.tokenList(1)).to.be.revertedWith("index out of bounds"); + + await uwp.connect(governor).removeTokensFromPool([]); + await uwp.connect(governor).removeTokensFromPool([near.address, dai.address, usdc.address]); + expect(await uwp.tokensLength()).eq(1); + + expect(await uwp.valueOfPool()).eq(0); + }); + }); + + describe("issueFee", function () { + it("starts zero", async function () { + expect(await uwp.issueFee()).eq(0); + expect(await uwp.issueFeeTo()).eq(ZERO_ADDRESS); + }); + it("cannot be set by non governance", async function () { + await expect(uwp.connect(user1).setIssueFee(0, ZERO_ADDRESS)).to.be.revertedWith("!governance"); + }); + it("set has safety checks", async function () { + await expect(uwp.connect(governor).setIssueFee(ONE_ETHER.add(1), ZERO_ADDRESS)).to.be.revertedWith("invalid issue fee"); + await expect(uwp.connect(governor).setIssueFee(ONE_ETHER, ZERO_ADDRESS)).to.be.revertedWith("invalid issue fee to"); + }); + it("can be set by governance", async function () { + let tx = await uwp.connect(governor).setIssueFee(1, governor.address); + await expect(tx).to.emit(uwp, "IssueFeeSet").withArgs(1, governor.address); + expect(await uwp.issueFee()).eq(1); + expect(await uwp.issueFeeTo()).eq(governor.address); + await uwp.connect(governor).setIssueFee(0, ZERO_ADDRESS); + }); + }); + + describe("issue", function () { + it("cannot deposit mismatched args", async function () { + await expect(uwp.connect(user1).calculateIssue([dai.address], [1,2])).to.be.revertedWith("length mismatch"); + await expect(uwp.connect(user1).issue([dai.address], [1,2], user1.address)).to.be.revertedWith("length mismatch"); + }); + it("cannot deposit token not in pool", async function () { + await expect(uwp.connect(user1).calculateIssue([dai.address], [1])).to.be.revertedWith("token not in pool"); + await expect(uwp.connect(user1).issue([dai.address], [1], user1.address)).to.be.revertedWith("token not in pool"); + }); + it("cannot deposit with insufficient balance", async function () { + await expect(uwp.connect(user1).issue([weth.address], [1], user1.address)).to.be.revertedWith("ERC20: transfer amount exceeds balance"); + await weth.transfer(user1.address, ONE_ETHER.mul(1000)); + await dai.transfer(user1.address, ONE_ETHER.mul(100000)); + await near.transfer(user1.address, ONE_NEAR.mul(10000)); + }); + it("cannot deposit with insufficient approval", async function () { + await expect(uwp.connect(user1).issue([weth.address], [1], user1.address)).to.be.revertedWith("ERC20: transfer amount exceeds allowance"); + await weth.connect(user1).approve(uwp.address, ethers.constants.MaxUint256); + await dai.connect(user1).approve(uwp.address, ethers.constants.MaxUint256); + await near.connect(user1).approve(uwp.address, ethers.constants.MaxUint256); + }); + it("cannot deposit below min", async function () { + await uwp.connect(governor).addTokensToPool([ + { token: weth.address, oracle: oracle.address, min: ONE_ETHER.mul(1300), max: ONE_ETHER.mul(13000) }, // measured in USD, so 1-10 ETH + { token: dai.address, oracle: oracle.address, min: ONE_ETHER.mul(1000), max: ONE_ETHER.mul(10000) }, + { token: usdc.address, oracle: oracle.address, min: 0, max: ONE_ETHER.mul(10000) }, + { token: near.address, oracle: oracle.address, min: 0, max: ONE_ETHER.mul(10000) }, // measured in USD, so 0-2500 NEAR + ]); + await expect(uwp.connect(user1).calculateIssue([dai.address], [ONE_ETHER.mul(999)])).to.be.revertedWith("deposit too small"); + await expect(uwp.connect(user1).issue([dai.address], [ONE_ETHER.mul(999)], user1.address)).to.be.revertedWith("deposit too small"); + await expect(uwp.connect(user1).calculateIssue([weth.address], [ONE_ETHER.mul(999).div(1000)])).to.be.revertedWith("deposit too small"); + await expect(uwp.connect(user1).issue([weth.address], [ONE_ETHER.mul(999).div(1000)], user1.address)).to.be.revertedWith("deposit too small"); + }); + it("cannot deposit above max", async function () { + await expect(uwp.connect(user1).calculateIssue([dai.address], [ONE_ETHER.mul(10001)])).to.be.revertedWith("deposit too large"); + await expect(uwp.connect(user1).issue([dai.address], [ONE_ETHER.mul(10001)], user1.address)).to.be.revertedWith("deposit too large"); + await expect(uwp.connect(user1).calculateIssue([weth.address], [ONE_ETHER.mul(10001).div(1000)])).to.be.revertedWith("deposit too large"); + await expect(uwp.connect(user1).issue([weth.address], [ONE_ETHER.mul(10001).div(1000)], user1.address)).to.be.revertedWith("deposit too large"); + }); + it("can deposit empty", async function () { + let amount = await uwp.connect(user1).calculateIssue([], []); + expect(amount).eq(0); + let tx = await uwp.connect(user1).issue([], [], user2.address); + await expect(tx).to.emit(uwp, "IssueMade").withArgs(user1.address, 0); + await expect(tx).to.emit(uwp, "Transfer").withArgs(ZERO_ADDRESS, user2.address, 0); + expect(await uwp.balanceOf(user1.address)).eq(0); + expect(await uwp.balanceOf(user2.address)).eq(0); + expect(await uwp.totalSupply()).eq(0); + expect(await uwp.valueOfPool()).eq(0); + expect(await uwp.valueOfShares(0)).eq(0); + expect(await uwp.valueOfHolder(user1.address)).eq(0); + }); + it("can deposit zero", async function () { + let amount = await uwp.connect(user1).calculateIssue([usdc.address], [0]); + expect(amount).eq(0); + let tx = await uwp.connect(user1).issue([usdc.address], [0], user2.address); + await expect(tx).to.emit(uwp, "IssueMade").withArgs(user1.address, 0); + await expect(tx).to.emit(usdc, "Transfer").withArgs(user1.address, uwp.address, 0); + await expect(tx).to.emit(uwp, "Transfer").withArgs(ZERO_ADDRESS, user2.address, 0); + expect(await uwp.balanceOf(user1.address)).eq(0); + expect(await uwp.balanceOf(user2.address)).eq(0); + expect(await uwp.totalSupply()).eq(0); + expect(await uwp.valueOfPool()).eq(0); + expect(await uwp.valueOfShares(0)).eq(0); + expect(await uwp.valueOfHolder(user1.address)).eq(0); + }); + it("can deposit 1", async function () { + // first deposit + let amount1 = await uwp.connect(user1).calculateIssue([dai.address], [ONE_ETHER.mul(1000)]); + expect(amount1).eq(ONE_ETHER.mul(1000)) + let amount = await uwp.connect(user1).callStatic.issue([dai.address], [ONE_ETHER.mul(1000)], user2.address); + expect(amount).eq(ONE_ETHER.mul(1000)); + let tx = await uwp.connect(user1).issue([dai.address], [ONE_ETHER.mul(1000)], user2.address); + await expect(tx).to.emit(uwp, "IssueMade").withArgs(user1.address, ONE_ETHER.mul(1000)); + await expect(tx).to.emit(dai, "Transfer").withArgs(user1.address, uwp.address, ONE_ETHER.mul(1000)); + await expect(tx).to.emit(uwp, "Transfer").withArgs(ZERO_ADDRESS, user2.address, ONE_ETHER.mul(1000)); + expect(await uwp.balanceOf(user1.address)).eq(0); + expect(await uwp.balanceOf(user2.address)).eq(ONE_ETHER.mul(1000)); + expect(await uwp.totalSupply()).eq(ONE_ETHER.mul(1000)); + expect(await uwp.valueOfPool()).eq(ONE_ETHER.mul(1000)); + expect(await uwp.valueOfShares(ONE_ETHER)).eq(ONE_ETHER); + expect(await uwp.valueOfHolder(user1.address)).eq(0); + expect(await uwp.valueOfHolder(user2.address)).eq(ONE_ETHER.mul(1000)); + await expect(uwp.valueOfShares(ONE_ETHER.mul(1000).add(1))).to.be.revertedWith("shares exceeds supply"); + }); + it("can deposit 2", async function () { + // another deposit + let amount1 = await uwp.connect(user1).calculateIssue([dai.address], [ONE_ETHER.mul(1000)]); + expect(amount1).eq(ONE_ETHER.mul(1000)); + let amount = await uwp.connect(user1).callStatic.issue([dai.address], [ONE_ETHER.mul(1000)], user2.address); + expect(amount).eq(ONE_ETHER.mul(1000)); + let tx = await uwp.connect(user1).issue([dai.address], [ONE_ETHER.mul(1000)], user2.address); + await expect(tx).to.emit(uwp, "IssueMade").withArgs(user1.address, ONE_ETHER.mul(1000)); + await expect(tx).to.emit(dai, "Transfer").withArgs(user1.address, uwp.address, ONE_ETHER.mul(1000)); + await expect(tx).to.emit(uwp, "Transfer").withArgs(ZERO_ADDRESS, user2.address, ONE_ETHER.mul(1000)); + expect(await uwp.balanceOf(user1.address)).eq(0); + expect(await uwp.balanceOf(user2.address)).eq(ONE_ETHER.mul(2000)); + expect(await uwp.totalSupply()).eq(ONE_ETHER.mul(2000)); + expect(await uwp.valueOfPool()).eq(ONE_ETHER.mul(2000)); + expect(await uwp.valueOfShares(ONE_ETHER)).eq(ONE_ETHER); + expect(await uwp.valueOfHolder(user1.address)).eq(0); + expect(await uwp.valueOfHolder(user2.address)).eq(ONE_ETHER.mul(2000)); + await expect(uwp.valueOfShares(ONE_ETHER.mul(2000).add(1))).to.be.revertedWith("shares exceeds supply"); + }); + it("can deposit 3", async function () { + // multi deposit + let amount1 = await uwp.connect(user1).calculateIssue([dai.address, weth.address], [ONE_ETHER.mul(1000), ONE_ETHER]); + expect(amount1).eq(ONE_ETHER.mul(2300)); + let amount = await uwp.connect(user1).callStatic.issue([dai.address, weth.address], [ONE_ETHER.mul(1000), ONE_ETHER], user2.address); + expect(amount).eq(ONE_ETHER.mul(2300)); + let tx = await uwp.connect(user1).issue([dai.address, weth.address], [ONE_ETHER.mul(1000), ONE_ETHER], user2.address); + await expect(tx).to.emit(uwp, "IssueMade").withArgs(user1.address, ONE_ETHER.mul(2300)); + await expect(tx).to.emit(dai, "Transfer").withArgs(user1.address, uwp.address, ONE_ETHER.mul(1000)); + await expect(tx).to.emit(weth, "Transfer").withArgs(user1.address, uwp.address, ONE_ETHER); + await expect(tx).to.emit(uwp, "Transfer").withArgs(ZERO_ADDRESS, user2.address, ONE_ETHER.mul(2300)); + expect(await uwp.balanceOf(user1.address)).eq(0); + expect(await uwp.balanceOf(user2.address)).eq(ONE_ETHER.mul(4300)); + expect(await uwp.totalSupply()).eq(ONE_ETHER.mul(4300)); + expect(await uwp.valueOfPool()).eq(ONE_ETHER.mul(4300)); + expect(await uwp.valueOfShares(ONE_ETHER)).eq(ONE_ETHER); + expect(await uwp.valueOfHolder(user1.address)).eq(0); + expect(await uwp.valueOfHolder(user2.address)).eq(ONE_ETHER.mul(4300)); + await expect(uwp.valueOfShares(ONE_ETHER.mul(4300).add(1))).to.be.revertedWith("shares exceeds supply"); + }); + it("can deposit 4", async function () { + // with issue fee + await uwp.connect(governor).setIssueFee(ONE_ETHER.div(100), user3.address); + let amount1 = await uwp.connect(user1).calculateIssue([dai.address], [ONE_ETHER.mul(1000)]); + expect(amount1).eq(ONE_ETHER.mul(990)); + let amount = await uwp.connect(user1).callStatic.issue([dai.address], [ONE_ETHER.mul(1000)], user2.address); + expect(amount).eq(ONE_ETHER.mul(990)); + let tx = await uwp.connect(user1).issue([dai.address], [ONE_ETHER.mul(1000)], user2.address); + await expect(tx).to.emit(uwp, "IssueMade").withArgs(user1.address, ONE_ETHER.mul(990)); + await expect(tx).to.emit(dai, "Transfer").withArgs(user1.address, uwp.address, ONE_ETHER.mul(1000)); + await expect(tx).to.emit(uwp, "Transfer").withArgs(ZERO_ADDRESS, user2.address, ONE_ETHER.mul(990)); + await expect(tx).to.emit(uwp, "Transfer").withArgs(ZERO_ADDRESS, user3.address, ONE_ETHER.mul(10)); + expect(await uwp.balanceOf(user1.address)).eq(0); + expect(await uwp.balanceOf(user2.address)).eq(ONE_ETHER.mul(5290)); + expect(await uwp.balanceOf(user3.address)).eq(ONE_ETHER.mul(10)); + expect(await uwp.totalSupply()).eq(ONE_ETHER.mul(5300)); + expect(await uwp.valueOfPool()).eq(ONE_ETHER.mul(5300)); + expect(await uwp.valueOfShares(ONE_ETHER)).eq(ONE_ETHER); + expect(await uwp.valueOfHolder(user1.address)).eq(0); + expect(await uwp.valueOfHolder(user2.address)).eq(ONE_ETHER.mul(5290)); + await expect(uwp.valueOfShares(ONE_ETHER.mul(5300).add(1))).to.be.revertedWith("shares exceeds supply"); + }); + it("cannot deposit above max pt 2", async function () { + await expect(uwp.connect(user1).calculateIssue([dai.address], [ONE_ETHER.mul(6001)])).to.be.revertedWith("deposit too large"); + await expect(uwp.connect(user1).issue([dai.address], [ONE_ETHER.mul(6001)], user1.address)).to.be.revertedWith("deposit too large"); + await expect(uwp.connect(user1).calculateIssue([weth.address], [ONE_ETHER.mul(9001).div(1000)])).to.be.revertedWith("deposit too large"); + await expect(uwp.connect(user1).issue([weth.address], [ONE_ETHER.mul(9001).div(1000)], user1.address)).to.be.revertedWith("deposit too large"); + }); + it("value of pool changes with oracle answers", async function () { + expect(await uwp.valueOfPool()).eq(ONE_ETHER.mul(5300)); + await ethPriceFeed.connect(governor).setAnswer(EIGHT_DECIMALS.mul(1400)); + expect(await uwp.valueOfPool()).eq(ONE_ETHER.mul(5400)); + expect(await uwp.valueOfShares(ONE_ETHER)).eq(ONE_ETHER.mul(5400).div(5300)); + expect(await uwp.valueOfHolder(user1.address)).eq(0); + expect(await uwp.valueOfHolder(user2.address)).eq(ONE_ETHER.mul(5400).mul(await uwp.balanceOf(user2.address)).div(await uwp.totalSupply())); + await expect(uwp.valueOfShares(ONE_ETHER.mul(5300).add(1))).to.be.revertedWith("shares exceeds supply"); + }); + it("can deposit 5", async function () { + // at value per share != 1 + await uwp.connect(governor).setIssueFee(0, ZERO_ADDRESS); + let amount1 = await uwp.connect(user1).calculateIssue([near.address], [ONE_NEAR.mul(1000)]); + expect(amount1).eq(ONE_ETHER.mul(1000).mul(4).mul(5300).div(5400)); + let amount = await uwp.connect(user1).callStatic.issue([near.address], [ONE_NEAR.mul(1000)], user2.address); + expect(amount).eq(ONE_ETHER.mul(1000).mul(4).mul(5300).div(5400)); + let tx = await uwp.connect(user1).issue([near.address], [ONE_NEAR.mul(1000)], user2.address); + await expect(tx).to.emit(uwp, "IssueMade").withArgs(user1.address, ONE_ETHER.mul(1000).mul(4).mul(5300).div(5400)); + await expect(tx).to.emit(near, "Transfer").withArgs(user1.address, uwp.address, ONE_NEAR.mul(1000)); + await expect(tx).to.emit(uwp, "Transfer").withArgs(ZERO_ADDRESS, user2.address, ONE_ETHER.mul(1000).mul(4).mul(5300).div(5400)); + expect(await uwp.balanceOf(user1.address)).eq(0); + expect(await uwp.balanceOf(user2.address)).eq(ONE_ETHER.mul(5290).add(ONE_ETHER.mul(1000).mul(4).mul(5300).div(5400))); + expect(await uwp.totalSupply()).eq(ONE_ETHER.mul(5300).add(ONE_ETHER.mul(1000).mul(4).mul(5300).div(5400))); + expect(await uwp.valueOfPool()).eq(ONE_ETHER.mul(9400)); + expect(await uwp.valueOfShares(ONE_ETHER)).eq(ONE_ETHER.mul(5400).div(5300)); + expect(await uwp.valueOfHolder(user1.address)).eq(0); + expect(await uwp.valueOfHolder(user2.address)).eq(ONE_ETHER.mul(9400).mul(await uwp.balanceOf(user2.address)).div(await uwp.totalSupply())); + }); + }); + + describe("redeem", function () { + it("cannot redeem more than balance", async function () { + let ts = await uwp.totalSupply(); + await expect(uwp.connect(user2).calculateRedeem(ts.add(1))).to.be.revertedWith("redeem amount exceeds supply"); + let bal = await uwp.balanceOf(user2.address); + await expect(uwp.connect(user2).redeem(bal.add(1), user3.address)).to.be.revertedWith("ERC20: burn amount exceeds balance"); + }); + it("can redeem", async function () { + let tokens = [weth, dai, usdc, near]; + let bals = await Promise.all(tokens.map(token => token.balanceOf(uwp.address))); + let bal = await uwp.balanceOf(user2.address); + let ts = await uwp.totalSupply(); + let redeemAmount = ONE_ETHER.mul(1000); + // static + let amounts1 = await uwp.connect(user2).calculateRedeem(redeemAmount); + let amounts = await uwp.connect(user2).callStatic.redeem(redeemAmount, user3.address); + for(var i = 0; i < tokens.length; ++i) { + let expectedAmount = bals[i].mul(redeemAmount).div(ts); + expect(amounts1[i]).eq(expectedAmount); + expect(amounts[i]).eq(expectedAmount); + } + // real + let tx = await uwp.connect(user2).redeem(redeemAmount, user3.address); + await expect(tx).to.emit(uwp, "RedeemMade").withArgs(user2.address, redeemAmount); + await expect(tx).to.emit(uwp, "Transfer").withArgs(user2.address, ZERO_ADDRESS, redeemAmount); + for(var i = 0; i < tokens.length; ++i) { + let expectedAmount = bals[i].mul(redeemAmount).div(ts); + await expect(tx).to.emit(tokens[i], "Transfer").withArgs(uwp.address, user3.address, expectedAmount); + expect(await tokens[i].balanceOf(user3.address)).eq(expectedAmount); + } + expect(await uwp.balanceOf(user2.address)).eq(bal.sub(redeemAmount)); + expect(await uwp.totalSupply()).eq(ts.sub(redeemAmount)); + }); + }); + + describe("rescueTokens", function () { + it("cannot be called by non governance", async function () { + await expect(uwp.connect(user1).rescueTokens([], user1.address)).to.be.revertedWith("!governance"); + }); + it("cannot rescue tokens in pool", async function () { + await expect(uwp.connect(governor).rescueTokens([dai.address], user1.address)).to.be.revertedWith("cannot rescue that token"); + }); + it("can rescue tokens", async function () { + await uni.transfer(uwp.address, ONE_ETHER); + await comp.transfer(uwp.address, ONE_ETHER.mul(10)); + let tx = await uwp.connect(governor).rescueTokens([uni.address, comp.address], user1.address); + await expect(tx).to.emit(uni, "Transfer").withArgs(uwp.address, user1.address, ONE_ETHER); + await expect(tx).to.emit(comp, "Transfer").withArgs(uwp.address, user1.address, ONE_ETHER.mul(10)); + expect(await uni.balanceOf(uwp.address)).eq(0); + expect(await uni.balanceOf(user1.address)).eq(ONE_ETHER); + expect(await comp.balanceOf(uwp.address)).eq(0); + expect(await comp.balanceOf(user1.address)).eq(ONE_ETHER.mul(10)); + }); + }); + + describe("pause", function () { + it("starts unpaused", async function () { + expect(await uwp.isPaused()).eq(false); + }); + it("cannot be paused by non goveranance", async function () { + await expect(uwp.connect(user1).setPause(true)).to.be.revertedWith("!governance"); + }); + it("can be paused", async function () { + let tx = await uwp.connect(governor).setPause(true); + await expect(tx).to.emit(uwp, "PauseSet").withArgs(true); + expect(await uwp.isPaused()).eq(true); + }); + it("cannot issue while paused", async function () { + await expect(uwp.connect(user1).issue([], [], user1.address)).to.be.revertedWith("issue is paused"); + }); + it("cannot be unpaused by non goveranance", async function () { + await expect(uwp.connect(user1).setPause(false)).to.be.revertedWith("!governance"); + }); + it("can be unpaused", async function () { + let tx = await uwp.connect(governor).setPause(false); + await expect(tx).to.emit(uwp, "PauseSet").withArgs(false); + expect(await uwp.isPaused()).eq(false); + }); + it("can issue after unpause", async function () { + await uwp.connect(user1).issue([], [], user2.address); + }); + }) +}); diff --git a/test/utilities/artifact_importer.ts b/test/utilities/artifact_importer.ts index 6332a7a8..42f31362 100644 --- a/test/utilities/artifact_importer.ts +++ b/test/utilities/artifact_importer.ts @@ -74,6 +74,7 @@ export async function import_artifacts() { if(!artifacts.ERC20) artifacts.ERC20 = await tryImport(`../../artifacts/@openzeppelin/contracts/token/ERC20/ERC20.sol/ERC20.json`); artifacts.MockERC20 = await tryImport(`${artifact_dir}/mocks/MockERC20.sol/MockERC20.json`); artifacts.MockERC20Permit = await tryImport(`${artifact_dir}/mocks/MockERC20Permit.sol/MockERC20Permit.json`); + artifacts.MockERC20PermitWithBurn = await tryImport(`${artifact_dir}/mocks/MockERC20PermitWithBurn.sol/MockERC20PermitWithBurn.json`); artifacts.MockERC20Decimals = await tryImport(`${artifact_dir}/mocks/MockERC20Decimals.sol/MockERC20Decimals.json`); artifacts.MockERC721 = await tryImport(`${artifact_dir}/mocks/MockERC721.sol/MockERC721.json`); artifacts.MockERC721Initializable = await tryImport(`${artifact_dir}/mocks/MockERC721Initializable.sol/MockERC721Initializable.json`); @@ -91,6 +92,7 @@ export async function import_artifacts() { artifacts.RiskStrategyFactory = await tryImport(`${artifact_dir}/RiskStrategyFactory.sol/RiskStrategyFactory.json`); artifacts.RiskStrategy = await tryImport(`${artifact_dir}/RiskStrategy.sol/RiskStrategy.json`); artifacts.MockRiskStrategy = await tryImport(`${artifact_dir}/mocks/MockRiskStrategy.sol/MockRiskStrategy.json`); + artifacts.MockFluxPriceFeed = await tryImport(`${artifact_dir}/mocks/MockFluxPriceFeed.sol/MockFluxPriceFeed.json`); // uniswapv3 imports artifacts.UniswapV3Factory = await tryImport("@uniswap/v3-core/artifacts/contracts/UniswapV3Factory.sol/UniswapV3Factory.json"); @@ -105,11 +107,23 @@ export async function import_artifacts() { // vesting artifacts.TokenVesting = await tryImport(`${artifact_dir}/vesting/TokenVesting.sol/TokenVesting.json`); - + // airdrop contracts artifacts.MerkleDistributor = await tryImport(`${artifact_dir}/airdrop/MerkleDistributor.sol/MerkleDistributor.json`); artifacts.xsLockerExtension = await tryImport(`${artifact_dir}/airdrop/xsLockerExtension.sol/xsLockerExtension.json`); + // native contracts + artifacts.SolaceMegaOracle = await tryImport(`${artifact_dir}/native/SolaceMegaOracle.sol/SolaceMegaOracle.json`); + artifacts.FluxPriceFeed = await tryImport(`${artifact_dir}/interfaces/native/IFluxPriceFeed.sol/IFluxPriceFeed.json`); + artifacts.FluxMegaOracle = await tryImport(`${artifact_dir}/native/FluxMegaOracle.sol/FluxMegaOracle.json`); + artifacts.UnderwritingPool = await tryImport(`${artifact_dir}/native/UnderwritingPool.sol/UnderwritingPool.json`); + artifacts.UnderwritingEquity = await tryImport(`${artifact_dir}/native/UnderwritingEquity.sol/UnderwritingEquity.json`); + artifacts.UnderwritingLocker = await tryImport(`${artifact_dir}/native/UnderwritingLocker.sol/UnderwritingLocker.json`); + artifacts.UnderwritingLockVoting = await tryImport(`${artifact_dir}/native/UnderwritingLockVoting.sol/UnderwritingLockVoting.json`); + artifacts.GaugeController = await tryImport(`${artifact_dir}/native/GaugeController.sol/GaugeController.json`); + artifacts.MockUnderwritingLockListener = await tryImport(`${artifact_dir}/mocks/MockUnderwritingLockListener.sol/MockUnderwritingLockListener.json`); + artifacts.DepositHelper = await tryImport(`${artifact_dir}/native/DepositHelper.sol/DepositHelper.json`); + return artifacts; } diff --git a/test/utils/Deployer.test.ts b/test/utils/Deployer.test.ts index 5fa9b89f..484b70df 100644 --- a/test/utils/Deployer.test.ts +++ b/test/utils/Deployer.test.ts @@ -80,9 +80,6 @@ describe("Deployer", function () { let predictedAddress = await deployerContract.callStatic.deploy(initcode, toBytes32(0)); expect(predictedAddress.length).eq(42); expect(predictedAddress).to.not.equal(ZERO_ADDRESS); - // test no deployment - solace = (await ethers.getContractAt(artifacts.SOLACE.abi, predictedAddress)) as Solace; - await expect(solace.isMinter(governor.address)).to.be.reverted; // test actual deployment let tx = await deployerContract.deploy(initcode, toBytes32(0), {gasLimit: 10000000}); //let gasUsed = (await tx.wait()).gasUsed; @@ -97,9 +94,6 @@ describe("Deployer", function () { expect(predictedAddress.length).eq(42); expect(predictedAddress).to.not.equal(ZERO_ADDRESS); expect(predictedAddress).to.not.equal(solaceAddress); - // test no deployment - solace = (await ethers.getContractAt(artifacts.SOLACE.abi, predictedAddress)) as Solace; - await expect(solace.isMinter(governor.address)).to.be.reverted; // test actual deployment let tx = await deployerContract.deploy(initcode, toBytes32(1), {gasLimit: 10000000}); //let gasUsed = (await tx.wait()).gasUsed; diff --git a/test/vesting/TokenVesting.test.ts b/test/vesting/TokenVesting.test.ts index 5f90283b..8f6dd379 100644 --- a/test/vesting/TokenVesting.test.ts +++ b/test/vesting/TokenVesting.test.ts @@ -33,7 +33,7 @@ const TEN_MILLION_ETHER = BN.from("10000000000000000000000000"); const ONE_MONTH = 2500000; const THREE_YEARS = 94608000 -const VESTING_START = 1638209176 + THREE_YEARS; +const VESTING_START = 1638209176 + THREE_YEARS; // Unix timestamp for initial SOLACE add liquidity transaction - https://etherscan.io/tx/0x71f1de15ee75f414c454aec3612433d0123e44ec5987515fc3566795cd840bc3 // Add three years (arbitrary time) to intended VESTING_START because want to test contract behaviour // before vestingStart, and cannot shift time backwards in Hardhat environment. So need to shift vestingStart forwards. @@ -41,7 +41,7 @@ const VESTING_START = 1638209176 + THREE_YEARS; describe("TokenVesting", function () { const [deployer, governor, investor1, investor2, investor3, randomGreedyPerson, investor1_new_account, SOLACE_rescue_account] = provider.getWallets(); let artifacts: ArtifactImports; - + before(async function () { artifacts = await import_artifacts(); await deployer.sendTransaction({to:deployer.address}); // for some reason this helps solidity-coverage @@ -108,7 +108,7 @@ describe("TokenVesting", function () { // expect(await tokenVesting.pendingGovernance()).to.equal("0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF"); // }); }); - + describe("setTotalInvestorTokens", function () { it("only Governor can call setTotalInvestorTokens", async function () { await expect(tokenVesting.connect(investor1).setTotalInvestorTokens([investor1.address, investor2.address, investor3.address], [ONE_MILLION_ETHER, 0, 0])).to.be.revertedWith("!governance"); @@ -118,7 +118,7 @@ describe("TokenVesting", function () { it("verifies equivalent lengths of 'investors' array and 'SOLACE token amounts' array", async function () { await expect(tokenVesting.connect(governor).setTotalInvestorTokens([investor1.address, investor2.address, investor3.address], [ONE_MILLION_ETHER, 0])).to.be.revertedWith("length mismatch"); }); - it("sets correct total investor token amounts", async function () { + it("sets correct total investor token amounts", async function () { let tx = await tokenVesting.connect(governor).setTotalInvestorTokens([investor1.address, investor2.address, investor3.address], [THREE_HUNDRED_THOUSAND_ETHER, THREE_HUNDRED_THOUSAND_ETHER, THREE_HUNDRED_THOUSAND_ETHER]) expect((await tokenVesting.totalInvestorTokens(investor1.address))).to.equal(THREE_HUNDRED_THOUSAND_ETHER); expect((await tokenVesting.totalInvestorTokens(investor2.address))).to.equal(THREE_HUNDRED_THOUSAND_ETHER); @@ -283,7 +283,7 @@ describe("TokenVesting", function () { await expect(investor3_claim_tx).to.emit(solace, "Transfer").withArgs(tokenVesting.address, investor3.address, claimedTokenAmount); await expect(investor3_claim_tx).to.emit(tokenVesting, "TokensClaimed").withArgs(solace.address, investor3.address, claimedTokenAmount); expect((await tokenVesting.claimedInvestorTokens(investor3.address))).to.equal(claimedTokenAmount.add(preClaimedAmount)); - expect(await solace.balanceOf(investor3.address)).eq(claimedTokenAmount.add(preClaimedAmount)) + expect(await solace.balanceOf(investor3.address)).eq(claimedTokenAmount.add(preClaimedAmount)) }) it("Sanity check redeemedInvestorTokens - should have lower values than totalInvestorTokens for same addresses", async function () { const investor1_claimedTokens = await tokenVesting.claimedInvestorTokens(investor1_new_account.address); @@ -352,7 +352,7 @@ describe("TokenVesting", function () { await expect(investor3_claim_tx).to.emit(solace, "Transfer").withArgs(tokenVesting.address, investor3.address, claimedTokenAmount); await expect(investor3_claim_tx).to.emit(tokenVesting, "TokensClaimed").withArgs(solace.address, investor3.address, claimedTokenAmount); expect((await tokenVesting.claimedInvestorTokens(investor3.address))).to.equal(claimedTokenAmount.add(preClaimedAmount)); - expect(await solace.balanceOf(investor3.address)).eq(claimedTokenAmount.add(preClaimedAmount)) + expect(await solace.balanceOf(investor3.address)).eq(claimedTokenAmount.add(preClaimedAmount)) }) it("Sanity check redeemedInvestorTokens - should be equivalent to totalInvestorTokens for same addresses", async function () { const investor1_claimedTokens = await tokenVesting.claimedInvestorTokens(investor1_new_account.address); @@ -425,8 +425,7 @@ describe("TokenVesting", function () { }) async function getCurrentTimestamp() { - const currentBlockNumber = await provider.getBlockNumber(); - const currentBlock = await provider.getBlock(currentBlockNumber); + const currentBlock = await provider.getBlock("latest"); const currentTimestamp = currentBlock.timestamp; return currentTimestamp -} \ No newline at end of file +}