diff --git a/contracts/ExchangeRates.sol b/contracts/ExchangeRates.sol index a2f37e0b73..03759d99c0 100644 --- a/contracts/ExchangeRates.sol +++ b/contracts/ExchangeRates.sol @@ -22,12 +22,8 @@ contract ExchangeRates is Owned, MixinSystemSettings, IExchangeRates { using SafeDecimalMath for uint; bytes32 public constant CONTRACT_NAME = "ExchangeRates"; - - // Exchange rates and update times stored by currency code, e.g. 'SNX', or 'sUSD' - mapping(bytes32 => mapping(uint => RateAndUpdatedTime)) private _rates; - - // The address of the oracle which pushes rate updates to this contract - address public oracle; + //slither-disable-next-line naming-convention + bytes32 internal constant sUSD = "sUSD"; // Decentralized oracle networks that feed into pricing aggregators mapping(bytes32 => AggregatorV2V3Interface) public aggregators; @@ -37,58 +33,12 @@ contract ExchangeRates is Owned, MixinSystemSettings, IExchangeRates { // List of aggregator keys for convenient iteration bytes32[] public aggregatorKeys; - // Do not allow the oracle to submit times any further forward into the future than this constant. - uint private constant ORACLE_FUTURE_LIMIT = 10 minutes; - - mapping(bytes32 => uint) public currentRoundForRate; - - // // ========== CONSTRUCTOR ========== - constructor( - address _owner, - address _oracle, - address _resolver, - bytes32[] memory _currencyKeys, - uint[] memory _newRates - ) public Owned(_owner) MixinSystemSettings(_resolver) { - require(_currencyKeys.length == _newRates.length, "Currency key length and rate length must match."); - - oracle = _oracle; - - // The sUSD rate is always 1 and is never stale. - _setRate("sUSD", SafeDecimalMath.unit(), now); - - internalUpdateRates(_currencyKeys, _newRates, now); - } - - /* ========== SETTERS ========== */ - - function setOracle(address _oracle) external onlyOwner { - oracle = _oracle; - emit OracleUpdated(oracle); - } + constructor(address _owner, address _resolver) public Owned(_owner) MixinSystemSettings(_resolver) {} /* ========== MUTATIVE FUNCTIONS ========== */ - function updateRates( - bytes32[] calldata currencyKeys, - uint[] calldata newRates, - uint timeSent - ) external onlyOracle returns (bool) { - return internalUpdateRates(currencyKeys, newRates, timeSent); - } - - function deleteRate(bytes32 currencyKey) external onlyOracle { - require(_getRate(currencyKey) > 0, "Rate is zero"); - - delete _rates[currencyKey][currentRoundForRate[currencyKey]]; - - currentRoundForRate[currencyKey]--; - - emit RateDeleted(currencyKey); - } - function addAggregator(bytes32 currencyKey, address aggregatorAddress) external onlyOwner { AggregatorV2V3Interface aggregator = AggregatorV2V3Interface(aggregatorAddress); // This check tries to make sure that a valid aggregator is being added. @@ -288,7 +238,7 @@ contract ExchangeRates is Owned, MixinSystemSettings, IExchangeRates { function rateAndInvalid(bytes32 currencyKey) external view returns (uint rate, bool isInvalid) { RateAndUpdatedTime memory rateAndTime = _getRateAndUpdatedTime(currencyKey); - if (currencyKey == "sUSD") { + if (currencyKey == sUSD) { return (rateAndTime.rate, false); } return ( @@ -314,7 +264,7 @@ contract ExchangeRates is Owned, MixinSystemSettings, IExchangeRates { // do one lookup of the rate & time to minimize gas RateAndUpdatedTime memory rateEntry = _getRateAndUpdatedTime(currencyKeys[i]); rates[i] = rateEntry.rate; - if (!anyRateInvalid && currencyKeys[i] != "sUSD") { + if (!anyRateInvalid && currencyKeys[i] != sUSD) { anyRateInvalid = flagList[i] || _rateIsStaleWithTime(_rateStalePeriod, rateEntry.time); } } @@ -372,52 +322,6 @@ contract ExchangeRates is Owned, MixinSystemSettings, IExchangeRates { } } - function _setRate( - bytes32 currencyKey, - uint256 rate, - uint256 time - ) internal { - // Note: this will effectively start the rounds at 1, which matches Chainlink's Agggregators - currentRoundForRate[currencyKey]++; - - _rates[currencyKey][currentRoundForRate[currencyKey]] = RateAndUpdatedTime({ - rate: uint216(rate), - time: uint40(time) - }); - } - - function internalUpdateRates( - bytes32[] memory currencyKeys, - uint[] memory newRates, - uint timeSent - ) internal returns (bool) { - require(currencyKeys.length == newRates.length, "Currency key array length must match rates array length."); - require(timeSent < (now + ORACLE_FUTURE_LIMIT), "Time is too far into the future"); - - // Loop through each key and perform update. - for (uint i = 0; i < currencyKeys.length; i++) { - bytes32 currencyKey = currencyKeys[i]; - - // Should not set any rate to zero ever, as no asset will ever be - // truely worthless and still valid. In this scenario, we should - // delete the rate and remove it from the system. - require(newRates[i] != 0, "Zero is not a valid rate, please call deleteRate instead."); - require(currencyKey != "sUSD", "Rate of sUSD cannot be updated, it's always UNIT."); - - // We should only update the rate if it's at least the same age as the last rate we've got. - if (timeSent < _getUpdatedTime(currencyKey)) { - continue; - } - - // Ok, go ahead with the update. - _setRate(currencyKey, newRates[i], timeSent); - } - - emit RatesUpdated(currencyKeys, newRates); - - return true; - } - function removeFromArray(bytes32 entry, bytes32[] storage array) internal returns (bool) { for (uint i = 0; i < array.length; i++) { if (array[i] == entry) { @@ -447,60 +351,64 @@ contract ExchangeRates is Owned, MixinSystemSettings, IExchangeRates { } function _getRateAndUpdatedTime(bytes32 currencyKey) internal view returns (RateAndUpdatedTime memory) { - AggregatorV2V3Interface aggregator = aggregators[currencyKey]; - - if (aggregator != AggregatorV2V3Interface(0)) { - // this view from the aggregator is the most gas efficient but it can throw when there's no data, - // so let's call it low-level to suppress any reverts - bytes memory payload = abi.encodeWithSignature("latestRoundData()"); - // solhint-disable avoid-low-level-calls - (bool success, bytes memory returnData) = address(aggregator).staticcall(payload); - - if (success) { - (, int256 answer, , uint256 updatedAt, ) = - abi.decode(returnData, (uint80, int256, uint256, uint256, uint80)); - return - RateAndUpdatedTime({ - rate: uint216(_formatAggregatorAnswer(currencyKey, answer)), - time: uint40(updatedAt) - }); - } + // sUSD rate is 1.0 + if (currencyKey == sUSD) { + return RateAndUpdatedTime({rate: uint216(SafeDecimalMath.unit()), time: 0}); } else { - uint roundId = currentRoundForRate[currencyKey]; - RateAndUpdatedTime memory entry = _rates[currencyKey][roundId]; - - return RateAndUpdatedTime({rate: uint216(entry.rate), time: entry.time}); + AggregatorV2V3Interface aggregator = aggregators[currencyKey]; + if (aggregator != AggregatorV2V3Interface(0)) { + // this view from the aggregator is the most gas efficient but it can throw when there's no data, + // so let's call it low-level to suppress any reverts + bytes memory payload = abi.encodeWithSignature("latestRoundData()"); + // solhint-disable avoid-low-level-calls + // slither-disable-next-line low-level-calls + (bool success, bytes memory returnData) = address(aggregator).staticcall(payload); + + if (success) { + (, int256 answer, , uint256 updatedAt, ) = + abi.decode(returnData, (uint80, int256, uint256, uint256, uint80)); + return + RateAndUpdatedTime({ + rate: uint216(_formatAggregatorAnswer(currencyKey, answer)), + time: uint40(updatedAt) + }); + } // else return defaults, to avoid reverting in views + } // else return defaults, to avoid reverting in views } } function _getCurrentRoundId(bytes32 currencyKey) internal view returns (uint) { + if (currencyKey == sUSD) { + return 0; // no roundIds for sUSD + } AggregatorV2V3Interface aggregator = aggregators[currencyKey]; - if (aggregator != AggregatorV2V3Interface(0)) { return aggregator.latestRound(); - } else { - return currentRoundForRate[currencyKey]; - } + } // else return defaults, to avoid reverting in views } function _getRateAndTimestampAtRound(bytes32 currencyKey, uint roundId) internal view returns (uint rate, uint time) { - AggregatorV2V3Interface aggregator = aggregators[currencyKey]; - - if (aggregator != AggregatorV2V3Interface(0)) { - // this view from the aggregator is the most gas efficient but it can throw when there's no data, - // so let's call it low-level to suppress any reverts - bytes memory payload = abi.encodeWithSignature("getRoundData(uint80)", roundId); - // solhint-disable avoid-low-level-calls - (bool success, bytes memory returnData) = address(aggregator).staticcall(payload); - - if (success) { - (, int256 answer, , uint256 updatedAt, ) = - abi.decode(returnData, (uint80, int256, uint256, uint256, uint80)); - return (_formatAggregatorAnswer(currencyKey, answer), updatedAt); - } + // short circuit sUSD + if (currencyKey == sUSD) { + // sUSD has no rounds, and 0 time is preferrable for "volatility" heuristics + // which are used in atomic swaps and fee reclamation + return (SafeDecimalMath.unit(), 0); } else { - RateAndUpdatedTime memory update = _rates[currencyKey][roundId]; - return (update.rate, update.time); + AggregatorV2V3Interface aggregator = aggregators[currencyKey]; + + if (aggregator != AggregatorV2V3Interface(0)) { + // this view from the aggregator is the most gas efficient but it can throw when there's no data, + // so let's call it low-level to suppress any reverts + bytes memory payload = abi.encodeWithSignature("getRoundData(uint80)", roundId); + // solhint-disable avoid-low-level-calls + (bool success, bytes memory returnData) = address(aggregator).staticcall(payload); + + if (success) { + (, int256 answer, , uint256 updatedAt, ) = + abi.decode(returnData, (uint80, int256, uint256, uint256, uint80)); + return (_formatAggregatorAnswer(currencyKey, answer), updatedAt); + } // else return defaults, to avoid reverting in views + } // else return defaults, to avoid reverting in views } } @@ -542,7 +450,7 @@ contract ExchangeRates is Owned, MixinSystemSettings, IExchangeRates { function _rateIsStale(bytes32 currencyKey, uint _rateStalePeriod) internal view returns (bool) { // sUSD is a special case and is never stale (check before an SLOAD of getRateAndUpdatedTime) - if (currencyKey == "sUSD") return false; + if (currencyKey == sUSD) return false; return _rateIsStaleWithTime(_rateStalePeriod, _getUpdatedTime(currencyKey)); } @@ -553,7 +461,7 @@ contract ExchangeRates is Owned, MixinSystemSettings, IExchangeRates { function _rateIsFlagged(bytes32 currencyKey, FlagsInterface flags) internal view returns (bool) { // sUSD is a special case and is never invalid - if (currencyKey == "sUSD") return false; + if (currencyKey == sUSD) return false; address aggregator = address(aggregators[currencyKey]); // when no aggregator or when the flags haven't been setup if (aggregator == address(0) || flags == FlagsInterface(0)) { @@ -563,25 +471,12 @@ contract ExchangeRates is Owned, MixinSystemSettings, IExchangeRates { } function _notImplemented() internal pure { + // slither-disable-next-line dead-code revert("Cannot be run on this layer"); } - /* ========== MODIFIERS ========== */ - - modifier onlyOracle { - _onlyOracle(); - _; - } - - function _onlyOracle() internal view { - require(msg.sender == oracle, "Only the oracle can perform this action"); - } - /* ========== EVENTS ========== */ - event OracleUpdated(address newOracle); - event RatesUpdated(bytes32[] currencyKeys, uint[] newRates); - event RateDeleted(bytes32 currencyKey); event AggregatorAdded(bytes32 currencyKey, address aggregator); event AggregatorRemoved(bytes32 currencyKey, address aggregator); } diff --git a/contracts/ExchangeRatesWithDexPricing.sol b/contracts/ExchangeRatesWithDexPricing.sol index 1548a61030..b6081da974 100644 --- a/contracts/ExchangeRatesWithDexPricing.sol +++ b/contracts/ExchangeRatesWithDexPricing.sol @@ -10,13 +10,7 @@ contract ExchangeRatesWithDexPricing is ExchangeRates { bytes32 internal constant SETTING_DEX_PRICE_AGGREGATOR = "dexPriceAggregator"; - constructor( - address _owner, - address _oracle, - address _resolver, - bytes32[] memory _currencyKeys, - uint[] memory _newRates - ) public ExchangeRates(_owner, _oracle, _resolver, _currencyKeys, _newRates) {} + constructor(address _owner, address _resolver) public ExchangeRates(_owner, _resolver) {} /* ========== SETTERS ========== */ diff --git a/contracts/FeePool.sol b/contracts/FeePool.sol index 1f58afa1f0..0b0098e812 100644 --- a/contracts/FeePool.sol +++ b/contracts/FeePool.sol @@ -242,9 +242,8 @@ contract FeePool is Owned, Proxyable, LimitedSetup, MixinSystemSettings, IFeePoo /** * @notice The RewardsDistribution contract informs us how many SNX rewards are sent to RewardEscrow to be claimed. */ - function setRewardsToDistribute(uint amount) external { - address rewardsAuthority = address(rewardsDistribution()); - require(messageSender == rewardsAuthority || msg.sender == rewardsAuthority, "Caller is not rewardsAuthority"); + function setRewardsToDistribute(uint amount) external optionalProxy { + require(messageSender == address(rewardsDistribution()), "RewardsDistribution only"); // Add the amount of SNX rewards to distribute on top of any rolling unclaimed amount _recentFeePeriodsStorage(0).rewardsToDistribute = _recentFeePeriodsStorage(0).rewardsToDistribute.add(amount); } diff --git a/contracts/MixinSystemSettings.sol b/contracts/MixinSystemSettings.sol index 213b0d1fb0..7e59eec559 100644 --- a/contracts/MixinSystemSettings.sol +++ b/contracts/MixinSystemSettings.sol @@ -7,6 +7,7 @@ import "./interfaces/IFlexibleStorage.sol"; // https://docs.synthetix.io/contracts/source/contracts/mixinsystemsettings contract MixinSystemSettings is MixinResolver { + // must match the one defined SystemSettingsLib, defined in both places due to sol v0.5 limitations bytes32 internal constant SETTING_CONTRACT_NAME = "SystemSettings"; bytes32 internal constant SETTING_WAITING_PERIOD_SECS = "waitingPeriodSecs"; @@ -34,8 +35,6 @@ contract MixinSystemSettings is MixinResolver { bytes32 internal constant SETTING_WRAPPER_MAX_TOKEN_AMOUNT = "wrapperMaxTokens"; bytes32 internal constant SETTING_WRAPPER_MINT_FEE_RATE = "wrapperMintFeeRate"; bytes32 internal constant SETTING_WRAPPER_BURN_FEE_RATE = "wrapperBurnFeeRate"; - bytes32 internal constant SETTING_MIN_CRATIO = "minCratio"; - bytes32 internal constant SETTING_NEW_COLLATERAL_MANAGER = "newCollateralManager"; bytes32 internal constant SETTING_INTERACTION_DELAY = "interactionDelay"; bytes32 internal constant SETTING_COLLAPSE_FEE_RATE = "collapseFeeRate"; bytes32 internal constant SETTING_ATOMIC_MAX_VOLUME_PER_BLOCK = "atomicMaxVolumePerBlock"; @@ -180,22 +179,6 @@ contract MixinSystemSettings is MixinResolver { ); } - function getMinCratio(address collateral) internal view returns (uint) { - return - flexibleStorage().getUIntValue( - SETTING_CONTRACT_NAME, - keccak256(abi.encodePacked(SETTING_MIN_CRATIO, collateral)) - ); - } - - function getNewCollateralManager(address collateral) internal view returns (address) { - return - flexibleStorage().getAddressValue( - SETTING_CONTRACT_NAME, - keccak256(abi.encodePacked(SETTING_NEW_COLLATERAL_MANAGER, collateral)) - ); - } - function getInteractionDelay(address collateral) internal view returns (uint) { return flexibleStorage().getUIntValue( diff --git a/contracts/SystemSettings.sol b/contracts/SystemSettings.sol index 3386145458..ac754726a4 100644 --- a/contracts/SystemSettings.sol +++ b/contracts/SystemSettings.sol @@ -5,62 +5,28 @@ import "./Owned.sol"; import "./MixinResolver.sol"; import "./MixinSystemSettings.sol"; import "./interfaces/ISystemSettings.sol"; - -// Libraries -import "./SafeDecimalMath.sol"; +import "./SystemSettingsLib.sol"; // https://docs.synthetix.io/contracts/source/contracts/systemsettings contract SystemSettings is Owned, MixinSystemSettings, ISystemSettings { - using SafeMath for uint; - using SafeDecimalMath for uint; - - bytes32 public constant CONTRACT_NAME = "SystemSettings"; - - // No more synths may be issued than the value of SNX backing them. - uint public constant MAX_ISSUANCE_RATIO = 1e18; - - // The fee period must be between 1 day and 60 days. - uint public constant MIN_FEE_PERIOD_DURATION = 1 days; - uint public constant MAX_FEE_PERIOD_DURATION = 60 days; - - uint public constant MAX_TARGET_THRESHOLD = 50; - - uint public constant MAX_LIQUIDATION_RATIO = 1e18; // 100% issuance ratio - - uint public constant MAX_LIQUIDATION_PENALTY = 1e18 / 4; // Max 25% liquidation penalty / bonus - - uint public constant RATIO_FROM_TARGET_BUFFER = 2e18; // 200% - mininimum buffer between issuance ratio and liquidation ratio - - uint public constant MAX_LIQUIDATION_DELAY = 30 days; - uint public constant MIN_LIQUIDATION_DELAY = 1 days; - - // Exchange fee may not exceed 10%. - uint public constant MAX_EXCHANGE_FEE_RATE = 1e18 / 10; - - // Minimum Stake time may not exceed 1 weeks. - uint public constant MAX_MINIMUM_STAKE_TIME = 1 weeks; - - uint public constant MAX_CROSS_DOMAIN_GAS_LIMIT = 8e6; - uint public constant MIN_CROSS_DOMAIN_GAS_LIMIT = 3e6; - - int public constant MAX_WRAPPER_MINT_FEE_RATE = 1e18; - int public constant MAX_WRAPPER_BURN_FEE_RATE = 1e18; - - // Atomic block volume limit is encoded as uint192. - uint public constant MAX_ATOMIC_VOLUME_PER_BLOCK = uint192(-1); - - // TWAP window must be between 1 min and 1 day. - uint public constant MIN_ATOMIC_TWAP_WINDOW = 60; - uint public constant MAX_ATOMIC_TWAP_WINDOW = 86400; - - // Volatility consideration window must be between 1 min and 1 day. - uint public constant MIN_ATOMIC_VOLATILITY_CONSIDERATION_WINDOW = 60; - uint public constant MAX_ATOMIC_VOLATILITY_CONSIDERATION_WINDOW = 86400; + // SystemSettingsLib is a way to split out the setters to reduce contract size + using SystemSettingsLib for IFlexibleStorage; - constructor(address _owner, address _resolver) public Owned(_owner) MixinSystemSettings(_resolver) {} + constructor(address _owner, address _resolver) public Owned(_owner) MixinSystemSettings(_resolver) { + // SETTING_CONTRACT_NAME is defined for the getters in MixinSystemSettings and + // SystemSettingsLib.contractName() is a view into SystemSettingsLib of the contract name + // that's used by the setters. They have to be equal. + require(SETTING_CONTRACT_NAME == SystemSettingsLib.contractName(), "read and write keys not equal"); + } // ========== VIEWS ========== + // backwards compatibility to having CONTRACT_NAME public constant + // solhint-disable-next-line func-name-mixedcase + function CONTRACT_NAME() external view returns (bytes32) { + return SystemSettingsLib.contractName(); + } + // SIP-37 Fee Reclamation // The number of seconds after an exchange is executed that must be waited // before settlement. @@ -180,14 +146,6 @@ contract SystemSettings is Owned, MixinSystemSettings, ISystemSettings { return getWrapperBurnFeeRate(wrapper); } - function minCratio(address collateral) external view returns (uint) { - return getMinCratio(collateral); - } - - function collateralManager(address collateral) external view returns (address) { - return getNewCollateralManager(collateral); - } - function interactionDelay(address collateral) external view returns (uint) { return getInteractionDelay(collateral); } @@ -244,101 +202,67 @@ contract SystemSettings is Owned, MixinSystemSettings, ISystemSettings { external onlyOwner { - require( - _crossDomainMessageGasLimit >= MIN_CROSS_DOMAIN_GAS_LIMIT && - _crossDomainMessageGasLimit <= MAX_CROSS_DOMAIN_GAS_LIMIT, - "Out of range xDomain gasLimit" - ); - flexibleStorage().setUIntValue( - SETTING_CONTRACT_NAME, - _getGasLimitSetting(_gasLimitType), - _crossDomainMessageGasLimit - ); + flexibleStorage().setCrossDomainMessageGasLimit(_getGasLimitSetting(_gasLimitType), _crossDomainMessageGasLimit); emit CrossDomainMessageGasLimitChanged(_gasLimitType, _crossDomainMessageGasLimit); } + function setIssuanceRatio(uint issuanceRatio) external onlyOwner { + flexibleStorage().setIssuanceRatio(SETTING_ISSUANCE_RATIO, issuanceRatio); + emit IssuanceRatioUpdated(issuanceRatio); + } + function setTradingRewardsEnabled(bool _tradingRewardsEnabled) external onlyOwner { - flexibleStorage().setBoolValue(SETTING_CONTRACT_NAME, SETTING_TRADING_REWARDS_ENABLED, _tradingRewardsEnabled); + flexibleStorage().setTradingRewardsEnabled(SETTING_TRADING_REWARDS_ENABLED, _tradingRewardsEnabled); emit TradingRewardsEnabled(_tradingRewardsEnabled); } function setWaitingPeriodSecs(uint _waitingPeriodSecs) external onlyOwner { - flexibleStorage().setUIntValue(SETTING_CONTRACT_NAME, SETTING_WAITING_PERIOD_SECS, _waitingPeriodSecs); + flexibleStorage().setWaitingPeriodSecs(SETTING_WAITING_PERIOD_SECS, _waitingPeriodSecs); emit WaitingPeriodSecsUpdated(_waitingPeriodSecs); } function setPriceDeviationThresholdFactor(uint _priceDeviationThresholdFactor) external onlyOwner { - flexibleStorage().setUIntValue( - SETTING_CONTRACT_NAME, + flexibleStorage().setPriceDeviationThresholdFactor( SETTING_PRICE_DEVIATION_THRESHOLD_FACTOR, _priceDeviationThresholdFactor ); emit PriceDeviationThresholdUpdated(_priceDeviationThresholdFactor); } - function setIssuanceRatio(uint _issuanceRatio) external onlyOwner { - require(_issuanceRatio <= MAX_ISSUANCE_RATIO, "New issuance ratio cannot exceed MAX_ISSUANCE_RATIO"); - flexibleStorage().setUIntValue(SETTING_CONTRACT_NAME, SETTING_ISSUANCE_RATIO, _issuanceRatio); - emit IssuanceRatioUpdated(_issuanceRatio); - } - function setFeePeriodDuration(uint _feePeriodDuration) external onlyOwner { - require(_feePeriodDuration >= MIN_FEE_PERIOD_DURATION, "value < MIN_FEE_PERIOD_DURATION"); - require(_feePeriodDuration <= MAX_FEE_PERIOD_DURATION, "value > MAX_FEE_PERIOD_DURATION"); - - flexibleStorage().setUIntValue(SETTING_CONTRACT_NAME, SETTING_FEE_PERIOD_DURATION, _feePeriodDuration); - + flexibleStorage().setFeePeriodDuration(SETTING_FEE_PERIOD_DURATION, _feePeriodDuration); emit FeePeriodDurationUpdated(_feePeriodDuration); } - function setTargetThreshold(uint _percent) external onlyOwner { - require(_percent <= MAX_TARGET_THRESHOLD, "Threshold too high"); - - uint _targetThreshold = _percent.mul(SafeDecimalMath.unit()).div(100); - - flexibleStorage().setUIntValue(SETTING_CONTRACT_NAME, SETTING_TARGET_THRESHOLD, _targetThreshold); - - emit TargetThresholdUpdated(_targetThreshold); + function setTargetThreshold(uint percent) external onlyOwner { + uint targetThreshold = flexibleStorage().setTargetThreshold(SETTING_TARGET_THRESHOLD, percent); + emit TargetThresholdUpdated(targetThreshold); } function setLiquidationDelay(uint time) external onlyOwner { - require(time <= MAX_LIQUIDATION_DELAY, "Must be less than 30 days"); - require(time >= MIN_LIQUIDATION_DELAY, "Must be greater than 1 day"); - - flexibleStorage().setUIntValue(SETTING_CONTRACT_NAME, SETTING_LIQUIDATION_DELAY, time); - + flexibleStorage().setLiquidationDelay(SETTING_LIQUIDATION_DELAY, time); emit LiquidationDelayUpdated(time); } // The collateral / issuance ratio ( debt / collateral ) is higher when there is less collateral backing their debt // Upper bound liquidationRatio is 1 + penalty (100% + 10% = 110%) to allow collateral value to cover debt and liquidation penalty function setLiquidationRatio(uint _liquidationRatio) external onlyOwner { - require( - _liquidationRatio <= MAX_LIQUIDATION_RATIO.divideDecimal(SafeDecimalMath.unit().add(getLiquidationPenalty())), - "liquidationRatio > MAX_LIQUIDATION_RATIO / (1 + penalty)" + flexibleStorage().setLiquidationRatio( + SETTING_LIQUIDATION_RATIO, + _liquidationRatio, + getLiquidationPenalty(), + getIssuanceRatio() ); - - // MIN_LIQUIDATION_RATIO is a product of target issuance ratio * RATIO_FROM_TARGET_BUFFER - // Ensures that liquidation ratio is set so that there is a buffer between the issuance ratio and liquidation ratio. - uint MIN_LIQUIDATION_RATIO = getIssuanceRatio().multiplyDecimal(RATIO_FROM_TARGET_BUFFER); - require(_liquidationRatio >= MIN_LIQUIDATION_RATIO, "liquidationRatio < MIN_LIQUIDATION_RATIO"); - - flexibleStorage().setUIntValue(SETTING_CONTRACT_NAME, SETTING_LIQUIDATION_RATIO, _liquidationRatio); - emit LiquidationRatioUpdated(_liquidationRatio); } function setLiquidationPenalty(uint penalty) external onlyOwner { - require(penalty <= MAX_LIQUIDATION_PENALTY, "penalty > MAX_LIQUIDATION_PENALTY"); - - flexibleStorage().setUIntValue(SETTING_CONTRACT_NAME, SETTING_LIQUIDATION_PENALTY, penalty); - + flexibleStorage().setLiquidationPenalty(SETTING_LIQUIDATION_PENALTY, penalty); emit LiquidationPenaltyUpdated(penalty); } function setRateStalePeriod(uint period) external onlyOwner { - flexibleStorage().setUIntValue(SETTING_CONTRACT_NAME, SETTING_RATE_STALE_PERIOD, period); - + flexibleStorage().setRateStalePeriod(SETTING_RATE_STALE_PERIOD, period); emit RateStalePeriodUpdated(period); } @@ -346,200 +270,119 @@ contract SystemSettings is Owned, MixinSystemSettings, ISystemSettings { external onlyOwner { - require(synthKeys.length == exchangeFeeRates.length, "Array lengths dont match"); + flexibleStorage().setExchangeFeeRateForSynths(SETTING_EXCHANGE_FEE_RATE, synthKeys, exchangeFeeRates); for (uint i = 0; i < synthKeys.length; i++) { - require(exchangeFeeRates[i] <= MAX_EXCHANGE_FEE_RATE, "MAX_EXCHANGE_FEE_RATE exceeded"); - flexibleStorage().setUIntValue( - SETTING_CONTRACT_NAME, - keccak256(abi.encodePacked(SETTING_EXCHANGE_FEE_RATE, synthKeys[i])), - exchangeFeeRates[i] - ); emit ExchangeFeeUpdated(synthKeys[i], exchangeFeeRates[i]); } } function setMinimumStakeTime(uint _seconds) external onlyOwner { - require(_seconds <= MAX_MINIMUM_STAKE_TIME, "stake time exceed maximum 1 week"); - flexibleStorage().setUIntValue(SETTING_CONTRACT_NAME, SETTING_MINIMUM_STAKE_TIME, _seconds); + flexibleStorage().setMinimumStakeTime(SETTING_MINIMUM_STAKE_TIME, _seconds); emit MinimumStakeTimeUpdated(_seconds); } function setDebtSnapshotStaleTime(uint _seconds) external onlyOwner { - flexibleStorage().setUIntValue(SETTING_CONTRACT_NAME, SETTING_DEBT_SNAPSHOT_STALE_TIME, _seconds); + flexibleStorage().setDebtSnapshotStaleTime(SETTING_DEBT_SNAPSHOT_STALE_TIME, _seconds); emit DebtSnapshotStaleTimeUpdated(_seconds); } function setAggregatorWarningFlags(address _flags) external onlyOwner { - require(_flags != address(0), "Valid address must be given"); - flexibleStorage().setAddressValue(SETTING_CONTRACT_NAME, SETTING_AGGREGATOR_WARNING_FLAGS, _flags); + flexibleStorage().setAggregatorWarningFlags(SETTING_AGGREGATOR_WARNING_FLAGS, _flags); emit AggregatorWarningFlagsUpdated(_flags); } function setEtherWrapperMaxETH(uint _maxETH) external onlyOwner { - flexibleStorage().setUIntValue(SETTING_CONTRACT_NAME, SETTING_ETHER_WRAPPER_MAX_ETH, _maxETH); + flexibleStorage().setEtherWrapperMaxETH(SETTING_ETHER_WRAPPER_MAX_ETH, _maxETH); emit EtherWrapperMaxETHUpdated(_maxETH); } function setEtherWrapperMintFeeRate(uint _rate) external onlyOwner { - require(_rate <= uint(MAX_WRAPPER_MINT_FEE_RATE), "rate > MAX_WRAPPER_MINT_FEE_RATE"); - flexibleStorage().setUIntValue(SETTING_CONTRACT_NAME, SETTING_ETHER_WRAPPER_MINT_FEE_RATE, _rate); + flexibleStorage().setEtherWrapperMintFeeRate(SETTING_ETHER_WRAPPER_MINT_FEE_RATE, _rate); emit EtherWrapperMintFeeRateUpdated(_rate); } function setEtherWrapperBurnFeeRate(uint _rate) external onlyOwner { - require(_rate <= uint(MAX_WRAPPER_BURN_FEE_RATE), "rate > MAX_WRAPPER_BURN_FEE_RATE"); - flexibleStorage().setUIntValue(SETTING_CONTRACT_NAME, SETTING_ETHER_WRAPPER_BURN_FEE_RATE, _rate); + flexibleStorage().setEtherWrapperBurnFeeRate(SETTING_ETHER_WRAPPER_BURN_FEE_RATE, _rate); emit EtherWrapperBurnFeeRateUpdated(_rate); } function setWrapperMaxTokenAmount(address _wrapper, uint _maxTokenAmount) external onlyOwner { - flexibleStorage().setUIntValue( - SETTING_CONTRACT_NAME, - keccak256(abi.encodePacked(SETTING_WRAPPER_MAX_TOKEN_AMOUNT, _wrapper)), - _maxTokenAmount - ); + flexibleStorage().setWrapperMaxTokenAmount(SETTING_WRAPPER_MAX_TOKEN_AMOUNT, _wrapper, _maxTokenAmount); emit WrapperMaxTokenAmountUpdated(_wrapper, _maxTokenAmount); } function setWrapperMintFeeRate(address _wrapper, int _rate) external onlyOwner { - require(_rate <= MAX_WRAPPER_MINT_FEE_RATE, "rate > MAX_WRAPPER_MINT_FEE_RATE"); - require(_rate >= -MAX_WRAPPER_MINT_FEE_RATE, "rate < -MAX_WRAPPER_MINT_FEE_RATE"); - - // if mint rate is negative, burn fee rate should be positive and at least equal in magnitude - // otherwise risk of flash loan attack - if (_rate < 0) { - require(-_rate <= getWrapperBurnFeeRate(_wrapper), "-rate > wrapperBurnFeeRate"); - } - - flexibleStorage().setIntValue( - SETTING_CONTRACT_NAME, - keccak256(abi.encodePacked(SETTING_WRAPPER_MINT_FEE_RATE, _wrapper)), - _rate + flexibleStorage().setWrapperMintFeeRate( + SETTING_WRAPPER_MINT_FEE_RATE, + _wrapper, + _rate, + getWrapperBurnFeeRate(_wrapper) ); emit WrapperMintFeeRateUpdated(_wrapper, _rate); } function setWrapperBurnFeeRate(address _wrapper, int _rate) external onlyOwner { - require(_rate <= MAX_WRAPPER_BURN_FEE_RATE, "rate > MAX_WRAPPER_BURN_FEE_RATE"); - require(_rate >= -MAX_WRAPPER_BURN_FEE_RATE, "rate < -MAX_WRAPPER_BURN_FEE_RATE"); - - // if burn rate is negative, burn fee rate should be negative and at least equal in magnitude - // otherwise risk of flash loan attack - if (_rate < 0) { - require(-_rate <= getWrapperMintFeeRate(_wrapper), "-rate > wrapperMintFeeRate"); - } - - flexibleStorage().setIntValue( - SETTING_CONTRACT_NAME, - keccak256(abi.encodePacked(SETTING_WRAPPER_BURN_FEE_RATE, _wrapper)), - _rate + flexibleStorage().setWrapperBurnFeeRate( + SETTING_WRAPPER_BURN_FEE_RATE, + _wrapper, + _rate, + getWrapperMintFeeRate(_wrapper) ); emit WrapperBurnFeeRateUpdated(_wrapper, _rate); } - function setMinCratio(address _collateral, uint _minCratio) external onlyOwner { - require(_minCratio >= SafeDecimalMath.unit(), "Cratio must be above 1"); - flexibleStorage().setUIntValue( - SETTING_CONTRACT_NAME, - keccak256(abi.encodePacked(SETTING_MIN_CRATIO, _collateral)), - _minCratio - ); - emit MinCratioRatioUpdated(_minCratio); - } - - function setCollateralManager(address _collateral, address _newCollateralManager) external onlyOwner { - flexibleStorage().setAddressValue( - SETTING_CONTRACT_NAME, - keccak256(abi.encodePacked(SETTING_NEW_COLLATERAL_MANAGER, _collateral)), - _newCollateralManager - ); - emit CollateralManagerUpdated(_newCollateralManager); - } - function setInteractionDelay(address _collateral, uint _interactionDelay) external onlyOwner { - require(_interactionDelay <= SafeDecimalMath.unit() * 3600, "Max 1 hour"); - flexibleStorage().setUIntValue( - SETTING_CONTRACT_NAME, - keccak256(abi.encodePacked(SETTING_INTERACTION_DELAY, _collateral)), - _interactionDelay - ); + flexibleStorage().setInteractionDelay(SETTING_INTERACTION_DELAY, _collateral, _interactionDelay); emit InteractionDelayUpdated(_interactionDelay); } function setCollapseFeeRate(address _collateral, uint _collapseFeeRate) external onlyOwner { - flexibleStorage().setUIntValue( - SETTING_CONTRACT_NAME, - keccak256(abi.encodePacked(SETTING_COLLAPSE_FEE_RATE, _collateral)), - _collapseFeeRate - ); + flexibleStorage().setCollapseFeeRate(SETTING_COLLAPSE_FEE_RATE, _collateral, _collapseFeeRate); emit CollapseFeeRateUpdated(_collapseFeeRate); } function setAtomicMaxVolumePerBlock(uint _maxVolume) external onlyOwner { - require(_maxVolume <= MAX_ATOMIC_VOLUME_PER_BLOCK, "Atomic max volume exceed maximum uint192"); - flexibleStorage().setUIntValue(SETTING_CONTRACT_NAME, SETTING_ATOMIC_MAX_VOLUME_PER_BLOCK, _maxVolume); + flexibleStorage().setAtomicMaxVolumePerBlock(SETTING_ATOMIC_MAX_VOLUME_PER_BLOCK, _maxVolume); emit AtomicMaxVolumePerBlockUpdated(_maxVolume); } function setAtomicTwapWindow(uint _window) external onlyOwner { - require(_window >= MIN_ATOMIC_TWAP_WINDOW, "Atomic twap window under minimum 1 min"); - require(_window <= MAX_ATOMIC_TWAP_WINDOW, "Atomic twap window exceed maximum 1 day"); - flexibleStorage().setUIntValue(SETTING_CONTRACT_NAME, SETTING_ATOMIC_TWAP_WINDOW, _window); + flexibleStorage().setAtomicTwapWindow(SETTING_ATOMIC_TWAP_WINDOW, _window); emit AtomicTwapWindowUpdated(_window); } function setAtomicEquivalentForDexPricing(bytes32 _currencyKey, address _equivalent) external onlyOwner { - require(_equivalent != address(0), "Atomic equivalent is 0 address"); - flexibleStorage().setAddressValue( - SETTING_CONTRACT_NAME, - keccak256(abi.encodePacked(SETTING_ATOMIC_EQUIVALENT_FOR_DEX_PRICING, _currencyKey)), + flexibleStorage().setAtomicEquivalentForDexPricing( + SETTING_ATOMIC_EQUIVALENT_FOR_DEX_PRICING, + _currencyKey, _equivalent ); emit AtomicEquivalentForDexPricingUpdated(_currencyKey, _equivalent); } function setAtomicExchangeFeeRate(bytes32 _currencyKey, uint256 _exchangeFeeRate) external onlyOwner { - require(_exchangeFeeRate <= MAX_EXCHANGE_FEE_RATE, "MAX_EXCHANGE_FEE_RATE exceeded"); - flexibleStorage().setUIntValue( - SETTING_CONTRACT_NAME, - keccak256(abi.encodePacked(SETTING_ATOMIC_EXCHANGE_FEE_RATE, _currencyKey)), - _exchangeFeeRate - ); + flexibleStorage().setAtomicExchangeFeeRate(SETTING_ATOMIC_EXCHANGE_FEE_RATE, _currencyKey, _exchangeFeeRate); emit AtomicExchangeFeeUpdated(_currencyKey, _exchangeFeeRate); } function setAtomicPriceBuffer(bytes32 _currencyKey, uint _buffer) external onlyOwner { - flexibleStorage().setUIntValue( - SETTING_CONTRACT_NAME, - keccak256(abi.encodePacked(SETTING_ATOMIC_PRICE_BUFFER, _currencyKey)), - _buffer - ); + flexibleStorage().setAtomicPriceBuffer(SETTING_ATOMIC_PRICE_BUFFER, _currencyKey, _buffer); emit AtomicPriceBufferUpdated(_currencyKey, _buffer); } function setAtomicVolatilityConsiderationWindow(bytes32 _currencyKey, uint _window) external onlyOwner { - if (_window != 0) { - require( - _window >= MIN_ATOMIC_VOLATILITY_CONSIDERATION_WINDOW, - "Atomic volatility consideration window under minimum 1 min" - ); - require( - _window <= MAX_ATOMIC_VOLATILITY_CONSIDERATION_WINDOW, - "Atomic volatility consideration window exceed maximum 1 day" - ); - } - flexibleStorage().setUIntValue( - SETTING_CONTRACT_NAME, - keccak256(abi.encodePacked(SETTING_ATOMIC_VOLATILITY_CONSIDERATION_WINDOW, _currencyKey)), + flexibleStorage().setAtomicVolatilityConsiderationWindow( + SETTING_ATOMIC_VOLATILITY_CONSIDERATION_WINDOW, + _currencyKey, _window ); emit AtomicVolatilityConsiderationWindowUpdated(_currencyKey, _window); } function setAtomicVolatilityUpdateThreshold(bytes32 _currencyKey, uint _threshold) external onlyOwner { - flexibleStorage().setUIntValue( - SETTING_CONTRACT_NAME, - keccak256(abi.encodePacked(SETTING_ATOMIC_VOLATILITY_UPDATE_THRESHOLD, _currencyKey)), + flexibleStorage().setAtomicVolatilityUpdateThreshold( + SETTING_ATOMIC_VOLATILITY_UPDATE_THRESHOLD, + _currencyKey, _threshold ); emit AtomicVolatilityUpdateThresholdUpdated(_currencyKey, _threshold); @@ -547,10 +390,10 @@ contract SystemSettings is Owned, MixinSystemSettings, ISystemSettings { // ========== EVENTS ========== event CrossDomainMessageGasLimitChanged(CrossDomainMessageGasLimits gasLimitType, uint newLimit); + event IssuanceRatioUpdated(uint newRatio); event TradingRewardsEnabled(bool enabled); event WaitingPeriodSecsUpdated(uint waitingPeriodSecs); event PriceDeviationThresholdUpdated(uint threshold); - event IssuanceRatioUpdated(uint newRatio); event FeePeriodDurationUpdated(uint newFeePeriodDuration); event TargetThresholdUpdated(uint newTargetThreshold); event LiquidationDelayUpdated(uint newDelay); @@ -567,8 +410,6 @@ contract SystemSettings is Owned, MixinSystemSettings, ISystemSettings { event WrapperMaxTokenAmountUpdated(address wrapper, uint maxTokenAmount); event WrapperMintFeeRateUpdated(address wrapper, int rate); event WrapperBurnFeeRateUpdated(address wrapper, int rate); - event MinCratioRatioUpdated(uint minCratio); - event CollateralManagerUpdated(address newCollateralManager); event InteractionDelayUpdated(uint interactionDelay); event CollapseFeeRateUpdated(uint collapseFeeRate); event AtomicMaxVolumePerBlockUpdated(uint newMaxVolume); diff --git a/contracts/SystemSettingsLib.sol b/contracts/SystemSettingsLib.sol new file mode 100644 index 0000000000..1a137ea43d --- /dev/null +++ b/contracts/SystemSettingsLib.sol @@ -0,0 +1,422 @@ +pragma solidity ^0.5.16; + +// Internal references +import "./interfaces/IFlexibleStorage.sol"; + +// Libraries +import "./SafeDecimalMath.sol"; + +/// This library is to reduce SystemSettings contract size only and is not really +/// a proper library - so it shares knowledge of implementation details +library SystemSettingsLib { + using SafeMath for uint; + using SafeDecimalMath for uint; + + bytes32 public constant SETTINGS_CONTRACT_NAME = "SystemSettings"; + + // No more synths may be issued than the value of SNX backing them. + uint public constant MAX_ISSUANCE_RATIO = 1e18; + + // The fee period must be between 1 day and 60 days. + uint public constant MIN_FEE_PERIOD_DURATION = 1 days; + uint public constant MAX_FEE_PERIOD_DURATION = 60 days; + + uint public constant MAX_TARGET_THRESHOLD = 50; + + uint public constant MAX_LIQUIDATION_RATIO = 1e18; // 100% issuance ratio + uint public constant RATIO_FROM_TARGET_BUFFER = 2e18; // 200% - mininimum buffer between issuance ratio and liquidation ratio + + uint public constant MAX_LIQUIDATION_PENALTY = 1e18 / 4; // Max 25% liquidation penalty / bonus + + uint public constant MAX_LIQUIDATION_DELAY = 30 days; + uint public constant MIN_LIQUIDATION_DELAY = 1 days; + + // Exchange fee may not exceed 10%. + uint public constant MAX_EXCHANGE_FEE_RATE = 1e18 / 10; + + // Minimum Stake time may not exceed 1 weeks. + uint public constant MAX_MINIMUM_STAKE_TIME = 1 weeks; + + uint public constant MAX_CROSS_DOMAIN_GAS_LIMIT = 8e6; + uint public constant MIN_CROSS_DOMAIN_GAS_LIMIT = 3e6; + + int public constant MAX_WRAPPER_MINT_FEE_RATE = 1e18; + + int public constant MAX_WRAPPER_BURN_FEE_RATE = 1e18; + + // Atomic block volume limit is encoded as uint192. + uint public constant MAX_ATOMIC_VOLUME_PER_BLOCK = uint192(-1); + + // TWAP window must be between 1 min and 1 day. + uint public constant MIN_ATOMIC_TWAP_WINDOW = 60; + uint public constant MAX_ATOMIC_TWAP_WINDOW = 86400; + + // Volatility consideration window must be between 1 min and 1 day. + uint public constant MIN_ATOMIC_VOLATILITY_CONSIDERATION_WINDOW = 60; + uint public constant MAX_ATOMIC_VOLATILITY_CONSIDERATION_WINDOW = 86400; + + // workaround for library not supporting public constants in sol v0.5 + function contractName() external view returns (bytes32) { + return SETTINGS_CONTRACT_NAME; + } + + function setCrossDomainMessageGasLimit( + IFlexibleStorage flexibleStorage, + bytes32 gasLimitSettings, + uint crossDomainMessageGasLimit + ) external { + require( + crossDomainMessageGasLimit >= MIN_CROSS_DOMAIN_GAS_LIMIT && + crossDomainMessageGasLimit <= MAX_CROSS_DOMAIN_GAS_LIMIT, + "Out of range xDomain gasLimit" + ); + flexibleStorage.setUIntValue(SETTINGS_CONTRACT_NAME, gasLimitSettings, crossDomainMessageGasLimit); + } + + function setIssuanceRatio( + IFlexibleStorage flexibleStorage, + bytes32 settingName, + uint issuanceRatio + ) external { + require(issuanceRatio <= MAX_ISSUANCE_RATIO, "New issuance ratio cannot exceed MAX_ISSUANCE_RATIO"); + flexibleStorage.setUIntValue(SETTINGS_CONTRACT_NAME, settingName, issuanceRatio); + } + + function setTradingRewardsEnabled( + IFlexibleStorage flexibleStorage, + bytes32 settingName, + bool _tradingRewardsEnabled + ) external { + flexibleStorage.setBoolValue(SETTINGS_CONTRACT_NAME, settingName, _tradingRewardsEnabled); + } + + function setWaitingPeriodSecs( + IFlexibleStorage flexibleStorage, + bytes32 settingName, + uint _waitingPeriodSecs + ) external { + flexibleStorage.setUIntValue(SETTINGS_CONTRACT_NAME, settingName, _waitingPeriodSecs); + } + + function setPriceDeviationThresholdFactor( + IFlexibleStorage flexibleStorage, + bytes32 settingName, + uint _priceDeviationThresholdFactor + ) external { + flexibleStorage.setUIntValue(SETTINGS_CONTRACT_NAME, settingName, _priceDeviationThresholdFactor); + } + + function setFeePeriodDuration( + IFlexibleStorage flexibleStorage, + bytes32 settingName, + uint _feePeriodDuration + ) external { + require(_feePeriodDuration >= MIN_FEE_PERIOD_DURATION, "value < MIN_FEE_PERIOD_DURATION"); + require(_feePeriodDuration <= MAX_FEE_PERIOD_DURATION, "value > MAX_FEE_PERIOD_DURATION"); + + flexibleStorage.setUIntValue(SETTINGS_CONTRACT_NAME, settingName, _feePeriodDuration); + } + + function setTargetThreshold( + IFlexibleStorage flexibleStorage, + bytes32 settingName, + uint _percent + ) external returns (uint targetThreshold) { + require(_percent <= MAX_TARGET_THRESHOLD, "Threshold too high"); + targetThreshold = _percent.mul(SafeDecimalMath.unit()).div(100); + + flexibleStorage.setUIntValue(SETTINGS_CONTRACT_NAME, settingName, targetThreshold); + } + + function setLiquidationDelay( + IFlexibleStorage flexibleStorage, + bytes32 settingName, + uint time + ) external { + require(time <= MAX_LIQUIDATION_DELAY, "Must be less than 30 days"); + require(time >= MIN_LIQUIDATION_DELAY, "Must be greater than 1 day"); + + flexibleStorage.setUIntValue(SETTINGS_CONTRACT_NAME, settingName, time); + } + + function setLiquidationRatio( + IFlexibleStorage flexibleStorage, + bytes32 settingName, + uint _liquidationRatio, + uint getLiquidationPenalty, + uint getIssuanceRatio + ) external { + require( + _liquidationRatio <= MAX_LIQUIDATION_RATIO.divideDecimal(SafeDecimalMath.unit().add(getLiquidationPenalty)), + "liquidationRatio > MAX_LIQUIDATION_RATIO / (1 + penalty)" + ); + + // MIN_LIQUIDATION_RATIO is a product of target issuance ratio * RATIO_FROM_TARGET_BUFFER + // Ensures that liquidation ratio is set so that there is a buffer between the issuance ratio and liquidation ratio. + uint MIN_LIQUIDATION_RATIO = getIssuanceRatio.multiplyDecimal(RATIO_FROM_TARGET_BUFFER); + require(_liquidationRatio >= MIN_LIQUIDATION_RATIO, "liquidationRatio < MIN_LIQUIDATION_RATIO"); + + flexibleStorage.setUIntValue(SETTINGS_CONTRACT_NAME, settingName, _liquidationRatio); + } + + function setLiquidationPenalty( + IFlexibleStorage flexibleStorage, + bytes32 settingName, + uint penalty + ) external { + require(penalty <= MAX_LIQUIDATION_PENALTY, "penalty > MAX_LIQUIDATION_PENALTY"); + + flexibleStorage.setUIntValue(SETTINGS_CONTRACT_NAME, settingName, penalty); + } + + function setRateStalePeriod( + IFlexibleStorage flexibleStorage, + bytes32 settingName, + uint period + ) external { + flexibleStorage.setUIntValue(SETTINGS_CONTRACT_NAME, settingName, period); + } + + function setExchangeFeeRateForSynths( + IFlexibleStorage flexibleStorage, + bytes32 settingExchangeFeeRate, + bytes32[] calldata synthKeys, + uint256[] calldata exchangeFeeRates + ) external { + require(synthKeys.length == exchangeFeeRates.length, "Array lengths dont match"); + for (uint i = 0; i < synthKeys.length; i++) { + require(exchangeFeeRates[i] <= MAX_EXCHANGE_FEE_RATE, "MAX_EXCHANGE_FEE_RATE exceeded"); + flexibleStorage.setUIntValue( + SETTINGS_CONTRACT_NAME, + keccak256(abi.encodePacked(settingExchangeFeeRate, synthKeys[i])), + exchangeFeeRates[i] + ); + } + } + + function setMinimumStakeTime( + IFlexibleStorage flexibleStorage, + bytes32 settingName, + uint _seconds + ) external { + require(_seconds <= MAX_MINIMUM_STAKE_TIME, "stake time exceed maximum 1 week"); + flexibleStorage.setUIntValue(SETTINGS_CONTRACT_NAME, settingName, _seconds); + } + + function setDebtSnapshotStaleTime( + IFlexibleStorage flexibleStorage, + bytes32 settingName, + uint _seconds + ) external { + flexibleStorage.setUIntValue(SETTINGS_CONTRACT_NAME, settingName, _seconds); + } + + function setAggregatorWarningFlags( + IFlexibleStorage flexibleStorage, + bytes32 settingName, + address _flags + ) external { + require(_flags != address(0), "Valid address must be given"); + flexibleStorage.setAddressValue(SETTINGS_CONTRACT_NAME, settingName, _flags); + } + + function setEtherWrapperMaxETH( + IFlexibleStorage flexibleStorage, + bytes32 settingName, + uint _maxETH + ) external { + flexibleStorage.setUIntValue(SETTINGS_CONTRACT_NAME, settingName, _maxETH); + } + + function setEtherWrapperMintFeeRate( + IFlexibleStorage flexibleStorage, + bytes32 settingName, + uint _rate + ) external { + require(_rate <= uint(MAX_WRAPPER_MINT_FEE_RATE), "rate > MAX_WRAPPER_MINT_FEE_RATE"); + flexibleStorage.setUIntValue(SETTINGS_CONTRACT_NAME, settingName, _rate); + } + + function setEtherWrapperBurnFeeRate( + IFlexibleStorage flexibleStorage, + bytes32 settingName, + uint _rate + ) external { + require(_rate <= uint(MAX_WRAPPER_BURN_FEE_RATE), "rate > MAX_WRAPPER_BURN_FEE_RATE"); + flexibleStorage.setUIntValue(SETTINGS_CONTRACT_NAME, settingName, _rate); + } + + function setWrapperMaxTokenAmount( + IFlexibleStorage flexibleStorage, + bytes32 settingName, + address _wrapper, + uint _maxTokenAmount + ) external { + flexibleStorage.setUIntValue( + SETTINGS_CONTRACT_NAME, + keccak256(abi.encodePacked(settingName, _wrapper)), + _maxTokenAmount + ); + } + + function setWrapperMintFeeRate( + IFlexibleStorage flexibleStorage, + bytes32 settingName, + address _wrapper, + int _rate, + int getWrapperBurnFeeRate + ) external { + require(_rate <= MAX_WRAPPER_MINT_FEE_RATE, "rate > MAX_WRAPPER_MINT_FEE_RATE"); + require(_rate >= -MAX_WRAPPER_MINT_FEE_RATE, "rate < -MAX_WRAPPER_MINT_FEE_RATE"); + + // if mint rate is negative, burn fee rate should be positive and at least equal in magnitude + // otherwise risk of flash loan attack + if (_rate < 0) { + require(-_rate <= getWrapperBurnFeeRate, "-rate > wrapperBurnFeeRate"); + } + + flexibleStorage.setIntValue(SETTINGS_CONTRACT_NAME, keccak256(abi.encodePacked(settingName, _wrapper)), _rate); + } + + function setWrapperBurnFeeRate( + IFlexibleStorage flexibleStorage, + bytes32 settingName, + address _wrapper, + int _rate, + int getWrapperMintFeeRate + ) external { + require(_rate <= MAX_WRAPPER_BURN_FEE_RATE, "rate > MAX_WRAPPER_BURN_FEE_RATE"); + require(_rate >= -MAX_WRAPPER_BURN_FEE_RATE, "rate < -MAX_WRAPPER_BURN_FEE_RATE"); + + // if burn rate is negative, burn fee rate should be negative and at least equal in magnitude + // otherwise risk of flash loan attack + if (_rate < 0) { + require(-_rate <= getWrapperMintFeeRate, "-rate > wrapperMintFeeRate"); + } + + flexibleStorage.setIntValue(SETTINGS_CONTRACT_NAME, keccak256(abi.encodePacked(settingName, _wrapper)), _rate); + } + + function setInteractionDelay( + IFlexibleStorage flexibleStorage, + bytes32 settingName, + address _collateral, + uint _interactionDelay + ) external { + require(_interactionDelay <= SafeDecimalMath.unit() * 3600, "Max 1 hour"); + flexibleStorage.setUIntValue( + SETTINGS_CONTRACT_NAME, + keccak256(abi.encodePacked(settingName, _collateral)), + _interactionDelay + ); + } + + function setCollapseFeeRate( + IFlexibleStorage flexibleStorage, + bytes32 settingName, + address _collateral, + uint _collapseFeeRate + ) external { + flexibleStorage.setUIntValue( + SETTINGS_CONTRACT_NAME, + keccak256(abi.encodePacked(settingName, _collateral)), + _collapseFeeRate + ); + } + + function setAtomicMaxVolumePerBlock( + IFlexibleStorage flexibleStorage, + bytes32 settingName, + uint _maxVolume + ) external { + require(_maxVolume <= MAX_ATOMIC_VOLUME_PER_BLOCK, "Atomic max volume exceed maximum uint192"); + flexibleStorage.setUIntValue(SETTINGS_CONTRACT_NAME, settingName, _maxVolume); + } + + function setAtomicTwapWindow( + IFlexibleStorage flexibleStorage, + bytes32 settingName, + uint _window + ) external { + require(_window >= MIN_ATOMIC_TWAP_WINDOW, "Atomic twap window under minimum 1 min"); + require(_window <= MAX_ATOMIC_TWAP_WINDOW, "Atomic twap window exceed maximum 1 day"); + flexibleStorage.setUIntValue(SETTINGS_CONTRACT_NAME, settingName, _window); + } + + function setAtomicEquivalentForDexPricing( + IFlexibleStorage flexibleStorage, + bytes32 settingName, + bytes32 _currencyKey, + address _equivalent + ) external { + require(_equivalent != address(0), "Atomic equivalent is 0 address"); + flexibleStorage.setAddressValue( + SETTINGS_CONTRACT_NAME, + keccak256(abi.encodePacked(settingName, _currencyKey)), + _equivalent + ); + } + + function setAtomicExchangeFeeRate( + IFlexibleStorage flexibleStorage, + bytes32 settingName, + bytes32 _currencyKey, + uint _exchangeFeeRate + ) external { + require(_exchangeFeeRate <= MAX_EXCHANGE_FEE_RATE, "MAX_EXCHANGE_FEE_RATE exceeded"); + flexibleStorage.setUIntValue( + SETTINGS_CONTRACT_NAME, + keccak256(abi.encodePacked(settingName, _currencyKey)), + _exchangeFeeRate + ); + } + + function setAtomicPriceBuffer( + IFlexibleStorage flexibleStorage, + bytes32 settingName, + bytes32 _currencyKey, + uint _buffer + ) external { + flexibleStorage.setUIntValue( + SETTINGS_CONTRACT_NAME, + keccak256(abi.encodePacked(settingName, _currencyKey)), + _buffer + ); + } + + function setAtomicVolatilityConsiderationWindow( + IFlexibleStorage flexibleStorage, + bytes32 settingName, + bytes32 _currencyKey, + uint _window + ) external { + if (_window != 0) { + require( + _window >= MIN_ATOMIC_VOLATILITY_CONSIDERATION_WINDOW, + "Atomic volatility consideration window under minimum 1 min" + ); + require( + _window <= MAX_ATOMIC_VOLATILITY_CONSIDERATION_WINDOW, + "Atomic volatility consideration window exceed maximum 1 day" + ); + } + flexibleStorage.setUIntValue( + SETTINGS_CONTRACT_NAME, + keccak256(abi.encodePacked(settingName, _currencyKey)), + _window + ); + } + + function setAtomicVolatilityUpdateThreshold( + IFlexibleStorage flexibleStorage, + bytes32 settingName, + bytes32 _currencyKey, + uint _threshold + ) external { + flexibleStorage.setUIntValue( + SETTINGS_CONTRACT_NAME, + keccak256(abi.encodePacked(settingName, _currencyKey)), + _threshold + ); + } +} diff --git a/contracts/interfaces/IExchangeRates.sol b/contracts/interfaces/IExchangeRates.sol index 800e868731..e55b1e87f0 100644 --- a/contracts/interfaces/IExchangeRates.sol +++ b/contracts/interfaces/IExchangeRates.sol @@ -15,8 +15,6 @@ interface IExchangeRates { function anyRateIsInvalid(bytes32[] calldata currencyKeys) external view returns (bool); - function currentRoundForRate(bytes32 currencyKey) external view returns (uint); - function currenciesUsingAggregator(address aggregator) external view returns (bytes32[] memory); function effectiveValue( @@ -71,8 +69,6 @@ interface IExchangeRates { function lastRateUpdateTimes(bytes32 currencyKey) external view returns (uint256); - function oracle() external view returns (address); - function rateAndTimestampAtRound(bytes32 currencyKey, uint roundId) external view returns (uint rate, uint time); function rateAndUpdatedTime(bytes32 currencyKey) external view returns (uint rate, uint time); diff --git a/contracts/interfaces/ISystemSettings.sol b/contracts/interfaces/ISystemSettings.sol index a2f1bf5e89..a108bdbfd8 100644 --- a/contracts/interfaces/ISystemSettings.sol +++ b/contracts/interfaces/ISystemSettings.sol @@ -43,10 +43,6 @@ interface ISystemSettings { function etherWrapperBurnFeeRate() external view returns (uint); - function minCratio(address collateral) external view returns (uint); - - function collateralManager(address collateral) external view returns (address); - function interactionDelay(address collateral) external view returns (uint); function atomicMaxVolumePerBlock() external view returns (uint); diff --git a/contracts/migrations/Migration_Peacock.sol b/contracts/migrations/Migration_Peacock.sol new file mode 100644 index 0000000000..28861e72ae --- /dev/null +++ b/contracts/migrations/Migration_Peacock.sol @@ -0,0 +1,190 @@ + +pragma solidity ^0.5.16; + +import "../BaseMigration.sol"; +import "../AddressResolver.sol"; +import "../Proxy.sol"; +import "../FeePoolEternalStorage.sol"; +import "../FeePoolState.sol"; +import "../RewardEscrow.sol"; +import "../FeePool.sol"; + +interface ISynthetixNamedContract { + // solhint-disable func-name-mixedcase + function CONTRACT_NAME() external view returns (bytes32); +} + +// solhint-disable contract-name-camelcase +contract Migration_Peacock is BaseMigration { + // https://kovan.etherscan.io/address/0x73570075092502472E4b61A7058Df1A4a1DB12f2; + address public constant OWNER = 0x73570075092502472E4b61A7058Df1A4a1DB12f2; + + // ---------------------------- + // EXISTING SYNTHETIX CONTRACTS + // ---------------------------- + + // https://kovan.etherscan.io/address/0x84f87E3636Aa9cC1080c07E6C61aDfDCc23c0db6 + AddressResolver public constant addressresolver_i = AddressResolver(0x84f87E3636Aa9cC1080c07E6C61aDfDCc23c0db6); + // https://kovan.etherscan.io/address/0xc43b833F93C3896472dED3EfF73311f571e38742 + Proxy public constant proxyfeepool_i = Proxy(0xc43b833F93C3896472dED3EfF73311f571e38742); + // https://kovan.etherscan.io/address/0x7bB8B3Cc191600547b9467639aD397c05AF3ce8D + FeePoolEternalStorage public constant feepooleternalstorage_i = FeePoolEternalStorage(0x7bB8B3Cc191600547b9467639aD397c05AF3ce8D); + // https://kovan.etherscan.io/address/0x78b70223d9Fa1a0abE6cD967472Fa04fEf3C7586 + FeePoolState public constant feepoolstate_i = FeePoolState(0x78b70223d9Fa1a0abE6cD967472Fa04fEf3C7586); + // https://kovan.etherscan.io/address/0x8c6680412e914932A9abC02B6c7cbf690e583aFA + RewardEscrow public constant rewardescrow_i = RewardEscrow(0x8c6680412e914932A9abC02B6c7cbf690e583aFA); + // https://kovan.etherscan.io/address/0x288cA161F9382d54dD27803AbF45C78Da95D19b0 + FeePool public constant feepool_i = FeePool(0x288cA161F9382d54dD27803AbF45C78Da95D19b0); + + // ---------------------------------- + // NEW CONTRACTS DEPLOYED TO BE ADDED + // ---------------------------------- + + // https://kovan.etherscan.io/address/0x288cA161F9382d54dD27803AbF45C78Da95D19b0 + address public constant new_FeePool_contract = 0x288cA161F9382d54dD27803AbF45C78Da95D19b0; + + constructor() public BaseMigration(OWNER) {} + + function contractsRequiringOwnership() public pure returns (address[] memory contracts) { + contracts = new address[](6); + contracts[0]= address(addressresolver_i); + contracts[1]= address(proxyfeepool_i); + contracts[2]= address(feepooleternalstorage_i); + contracts[3]= address(feepoolstate_i); + contracts[4]= address(rewardescrow_i); + contracts[5]= address(feepool_i); + } + + function migrate(address currentOwner) external onlyDeployer { + require(owner == currentOwner, "Only the assigned owner can be re-assigned when complete"); + + require(ISynthetixNamedContract(new_FeePool_contract).CONTRACT_NAME() == "FeePool", "Invalid contract supplied for FeePool"); + + // ACCEPT OWNERSHIP for all contracts that require ownership to make changes + acceptAll(); + + // MIGRATION + // Import all new contracts into the address resolver; + addressresolver_importAddresses_0(); + // Rebuild the resolver caches in all MixinResolver contracts - batch 1; + addressresolver_rebuildCaches_1(); + // Ensure the ProxyFeePool contract has the correct FeePool target set; + proxyfeepool_i.setTarget(Proxyable(new_FeePool_contract)); + // Ensure the FeePool contract can write to its EternalStorage; + feepooleternalstorage_i.setAssociatedContract(new_FeePool_contract); + // Ensure the FeePool contract can write to its State; + feepoolstate_i.setFeePool(IFeePool(new_FeePool_contract)); + // Ensure the legacy RewardEscrow contract is connected to the FeePool contract; + rewardescrow_i.setFeePool(IFeePool(new_FeePool_contract)); + // Import fee period from existing fee pool at index 0; + importFeePeriod_0(); + // Import fee period from existing fee pool at index 1; + importFeePeriod_1(); + + // NOMINATE OWNERSHIP back to owner for aforementioned contracts + nominateAll(); + } + + function acceptAll() internal { + address[] memory contracts = contractsRequiringOwnership(); + for (uint i = 0; i < contracts.length; i++) { + Owned(contracts[i]).acceptOwnership(); + } + } + + function nominateAll() internal { + address[] memory contracts = contractsRequiringOwnership(); + for (uint i = 0; i < contracts.length; i++) { + returnOwnership(contracts[i]); + } + } + + + function addressresolver_importAddresses_0() internal { + bytes32[] memory addressresolver_importAddresses_names_0_0 = new bytes32[](1); + addressresolver_importAddresses_names_0_0[0] = bytes32("FeePool"); + address[] memory addressresolver_importAddresses_destinations_0_1 = new address[](1); + addressresolver_importAddresses_destinations_0_1[0] = address(new_FeePool_contract); + addressresolver_i.importAddresses(addressresolver_importAddresses_names_0_0, addressresolver_importAddresses_destinations_0_1); + } + + + function addressresolver_rebuildCaches_1() internal { + MixinResolver[] memory addressresolver_rebuildCaches_destinations_1_0 = new MixinResolver[](20); + addressresolver_rebuildCaches_destinations_1_0[0] = MixinResolver(0x64ac15AB583fFfA6a7401B83E3aA5cf4Ad1aA92A); + addressresolver_rebuildCaches_destinations_1_0[1] = MixinResolver(0x52DCF4f0019E16455621De5f792C5e7BE4cdAA81); + addressresolver_rebuildCaches_destinations_1_0[2] = MixinResolver(0x2Ef87CE145476A895ef2D442d826aED1CFaf5627); + addressresolver_rebuildCaches_destinations_1_0[3] = MixinResolver(0x6B4D3e213e10d9238c1a1A87E493687cc2eb1DD0); + addressresolver_rebuildCaches_destinations_1_0[4] = MixinResolver(0xB98c6031344EB6007e94A8eDbc0ee28C13c66290); + addressresolver_rebuildCaches_destinations_1_0[5] = MixinResolver(0x26b814c9fA4C0512D84373f80d4B92408CD13960); + addressresolver_rebuildCaches_destinations_1_0[6] = MixinResolver(0x880477aE972Ca606cC7D47496E077514e978231B); + addressresolver_rebuildCaches_destinations_1_0[7] = MixinResolver(0x0D9D97E38d19885441f8be74fE88C3294300C866); + addressresolver_rebuildCaches_destinations_1_0[8] = MixinResolver(0x16A5ED828fD7F03B0c3F4E261Ea519112c4fa2f4); + addressresolver_rebuildCaches_destinations_1_0[9] = MixinResolver(0x376684744fb828D67B1659f6D3D754938dc1Ec4b); + addressresolver_rebuildCaches_destinations_1_0[10] = MixinResolver(0x67FbB70d887e8E493611D273E94aD12fE7a7Da4e); + addressresolver_rebuildCaches_destinations_1_0[11] = MixinResolver(0xe2d39AB610fEe4C7FC591003553c7557C880eD04); + addressresolver_rebuildCaches_destinations_1_0[12] = MixinResolver(0x56a8953C03FC8b859140D5C6f7e7f24dD611d419); + addressresolver_rebuildCaches_destinations_1_0[13] = MixinResolver(0xa2aFD3FaA2b69a334DD5493031fa59B7779a3CBf); + addressresolver_rebuildCaches_destinations_1_0[14] = MixinResolver(0x7fA8b2D1F640Ac31f08046d0502147Ed430DdAb2); + addressresolver_rebuildCaches_destinations_1_0[15] = MixinResolver(0x44Af736495544a726ED15CB0EBe2d87a6bCC1832); + addressresolver_rebuildCaches_destinations_1_0[16] = MixinResolver(0xdFd01d828D34982DFE882B9fDC6DC17fcCA33C25); + addressresolver_rebuildCaches_destinations_1_0[17] = MixinResolver(0x5AD5469D8A1Eee2cF7c8B8205CbeD95A032cdff3); + addressresolver_rebuildCaches_destinations_1_0[18] = MixinResolver(0x9712DdCC43F42402acC483e297eeFf650d18D354); + addressresolver_rebuildCaches_destinations_1_0[19] = MixinResolver(new_FeePool_contract); + addressresolver_i.rebuildCaches(addressresolver_rebuildCaches_destinations_1_0); + } + + + function importFeePeriod_0() internal { + // https://kovan.etherscan.io/address/0xE532C9336934DA37aacc0143D07314d7F9D2a8c0; + FeePool existingFeePool = FeePool(0xE532C9336934DA37aacc0143D07314d7F9D2a8c0); + // https://kovan.etherscan.io/address/0x288cA161F9382d54dD27803AbF45C78Da95D19b0; + FeePool newFeePool = FeePool(0x288cA161F9382d54dD27803AbF45C78Da95D19b0); + ( + uint64 feePeriodId_0, + uint64 startingDebtIndex_0, + uint64 startTime_0, + uint feesToDistribute_0, + uint feesClaimed_0, + uint rewardsToDistribute_0, + uint rewardsClaimed_0 + ) = existingFeePool.recentFeePeriods(0); + newFeePool.importFeePeriod( + 0, + feePeriodId_0, + startingDebtIndex_0, + startTime_0, + feesToDistribute_0, + feesClaimed_0, + rewardsToDistribute_0, + rewardsClaimed_0 + ); + } + + + function importFeePeriod_1() internal { + // https://kovan.etherscan.io/address/0xE532C9336934DA37aacc0143D07314d7F9D2a8c0; + FeePool existingFeePool = FeePool(0xE532C9336934DA37aacc0143D07314d7F9D2a8c0); + // https://kovan.etherscan.io/address/0x288cA161F9382d54dD27803AbF45C78Da95D19b0; + FeePool newFeePool = FeePool(0x288cA161F9382d54dD27803AbF45C78Da95D19b0); + ( + uint64 feePeriodId_1, + uint64 startingDebtIndex_1, + uint64 startTime_1, + uint feesToDistribute_1, + uint feesClaimed_1, + uint rewardsToDistribute_1, + uint rewardsClaimed_1 + ) = existingFeePool.recentFeePeriods(1); + newFeePool.importFeePeriod( + 1, + feePeriodId_1, + startingDebtIndex_1, + startTime_1, + feesToDistribute_1, + feesClaimed_1, + rewardsToDistribute_1, + rewardsClaimed_1 + ); + } +} diff --git a/contracts/migrations/Migration_PeacockOptimism.sol b/contracts/migrations/Migration_PeacockOptimism.sol new file mode 100644 index 0000000000..9133ed060c --- /dev/null +++ b/contracts/migrations/Migration_PeacockOptimism.sol @@ -0,0 +1,183 @@ + +pragma solidity ^0.5.16; + +import "../BaseMigration.sol"; +import "../AddressResolver.sol"; +import "../Proxy.sol"; +import "../FeePoolEternalStorage.sol"; +import "../FeePoolState.sol"; +import "../RewardEscrow.sol"; +import "../FeePool.sol"; + +interface ISynthetixNamedContract { + // solhint-disable func-name-mixedcase + function CONTRACT_NAME() external view returns (bytes32); +} + +// solhint-disable contract-name-camelcase +contract Migration_PeacockOptimism is BaseMigration { + // https://kovan-explorer.optimism.io/address/0x73570075092502472E4b61A7058Df1A4a1DB12f2; + address public constant OWNER = 0x73570075092502472E4b61A7058Df1A4a1DB12f2; + + // ---------------------------- + // EXISTING SYNTHETIX CONTRACTS + // ---------------------------- + + // https://kovan-explorer.optimism.io/address/0xb08b62e1cdfd37eCCd69A9ACe67322CCF801b3A6 + AddressResolver public constant addressresolver_i = AddressResolver(0xb08b62e1cdfd37eCCd69A9ACe67322CCF801b3A6); + // https://kovan-explorer.optimism.io/address/0xd8c8887A629F98C56686Be6aEEDAae7f8f75D599 + Proxy public constant proxyfeepool_i = Proxy(0xd8c8887A629F98C56686Be6aEEDAae7f8f75D599); + // https://kovan-explorer.optimism.io/address/0x0A1d3bde7751e92971891FB034AcDE4C271de408 + FeePoolEternalStorage public constant feepooleternalstorage_i = FeePoolEternalStorage(0x0A1d3bde7751e92971891FB034AcDE4C271de408); + // https://kovan-explorer.optimism.io/address/0x2e542fA43A19F3F07230dD125f9f81411141362F + FeePoolState public constant feepoolstate_i = FeePoolState(0x2e542fA43A19F3F07230dD125f9f81411141362F); + // https://kovan-explorer.optimism.io/address/0x9952e42fF92149f48b3b7dee3f921A6DD106F79F + RewardEscrow public constant rewardescrow_i = RewardEscrow(0x9952e42fF92149f48b3b7dee3f921A6DD106F79F); + // https://kovan-explorer.optimism.io/address/0x129fd2f3a799bD156e8c00599760AfC2f0f953dA + FeePool public constant feepool_i = FeePool(0x129fd2f3a799bD156e8c00599760AfC2f0f953dA); + + // ---------------------------------- + // NEW CONTRACTS DEPLOYED TO BE ADDED + // ---------------------------------- + + // https://kovan-explorer.optimism.io/address/0x129fd2f3a799bD156e8c00599760AfC2f0f953dA + address public constant new_FeePool_contract = 0x129fd2f3a799bD156e8c00599760AfC2f0f953dA; + + constructor() public BaseMigration(OWNER) {} + + function contractsRequiringOwnership() public pure returns (address[] memory contracts) { + contracts = new address[](6); + contracts[0]= address(addressresolver_i); + contracts[1]= address(proxyfeepool_i); + contracts[2]= address(feepooleternalstorage_i); + contracts[3]= address(feepoolstate_i); + contracts[4]= address(rewardescrow_i); + contracts[5]= address(feepool_i); + } + + function migrate(address currentOwner) external onlyDeployer { + require(owner == currentOwner, "Only the assigned owner can be re-assigned when complete"); + + require(ISynthetixNamedContract(new_FeePool_contract).CONTRACT_NAME() == "FeePool", "Invalid contract supplied for FeePool"); + + // ACCEPT OWNERSHIP for all contracts that require ownership to make changes + acceptAll(); + + // MIGRATION + // Import all new contracts into the address resolver; + addressresolver_importAddresses_0(); + // Rebuild the resolver caches in all MixinResolver contracts - batch 1; + addressresolver_rebuildCaches_1(); + // Ensure the ProxyFeePool contract has the correct FeePool target set; + proxyfeepool_i.setTarget(Proxyable(new_FeePool_contract)); + // Ensure the FeePool contract can write to its EternalStorage; + feepooleternalstorage_i.setAssociatedContract(new_FeePool_contract); + // Ensure the FeePool contract can write to its State; + feepoolstate_i.setFeePool(IFeePool(new_FeePool_contract)); + // Ensure the legacy RewardEscrow contract is connected to the FeePool contract; + rewardescrow_i.setFeePool(IFeePool(new_FeePool_contract)); + // Import fee period from existing fee pool at index 0; + importFeePeriod_0(); + // Import fee period from existing fee pool at index 1; + importFeePeriod_1(); + + // NOMINATE OWNERSHIP back to owner for aforementioned contracts + nominateAll(); + } + + function acceptAll() internal { + address[] memory contracts = contractsRequiringOwnership(); + for (uint i = 0; i < contracts.length; i++) { + Owned(contracts[i]).acceptOwnership(); + } + } + + function nominateAll() internal { + address[] memory contracts = contractsRequiringOwnership(); + for (uint i = 0; i < contracts.length; i++) { + returnOwnership(contracts[i]); + } + } + + + function addressresolver_importAddresses_0() internal { + bytes32[] memory addressresolver_importAddresses_names_0_0 = new bytes32[](1); + addressresolver_importAddresses_names_0_0[0] = bytes32("FeePool"); + address[] memory addressresolver_importAddresses_destinations_0_1 = new address[](1); + addressresolver_importAddresses_destinations_0_1[0] = address(new_FeePool_contract); + addressresolver_i.importAddresses(addressresolver_importAddresses_names_0_0, addressresolver_importAddresses_destinations_0_1); + } + + + function addressresolver_rebuildCaches_1() internal { + MixinResolver[] memory addressresolver_rebuildCaches_destinations_1_0 = new MixinResolver[](13); + addressresolver_rebuildCaches_destinations_1_0[0] = MixinResolver(0xB613d148E47525478bD8A91eF7Cf2F7F63d81858); + addressresolver_rebuildCaches_destinations_1_0[1] = MixinResolver(0x15e7Aa4Cd2C74750b5DCaC9B8B21B9189552BBaD); + addressresolver_rebuildCaches_destinations_1_0[2] = MixinResolver(0x42d9ac3ebebb9479f24360847350b4F7EADECE50); + addressresolver_rebuildCaches_destinations_1_0[3] = MixinResolver(0xb7469A575b7931532F09AEe2882835A0249064a0); + addressresolver_rebuildCaches_destinations_1_0[4] = MixinResolver(0xD32c1443Dde2d248cE1bE42BacBb65Db0A4aAF10); + addressresolver_rebuildCaches_destinations_1_0[5] = MixinResolver(0x6E6e2e9b7769CbA76aFC1e6CAd795CD3Ce0772a1); + addressresolver_rebuildCaches_destinations_1_0[6] = MixinResolver(0x66C203BcF339460698c48a2B589eBD91de4984E7); + addressresolver_rebuildCaches_destinations_1_0[7] = MixinResolver(0xE73EB48B9E725E563775fF38cb67Ae09bF34c791); + addressresolver_rebuildCaches_destinations_1_0[8] = MixinResolver(0x319D190584248280e3084A4692C6472A8dA5CA26); + addressresolver_rebuildCaches_destinations_1_0[9] = MixinResolver(0x1f99f5CbFC3b5Fd804dCc7F7780148F06423AC70); + addressresolver_rebuildCaches_destinations_1_0[10] = MixinResolver(0xc7960401a5Ca5A201d41Cf6532C7d2803f8D5Ce4); + addressresolver_rebuildCaches_destinations_1_0[11] = MixinResolver(0xD170549da4115c39EC42D6101eAAE5604F26150d); + addressresolver_rebuildCaches_destinations_1_0[12] = MixinResolver(new_FeePool_contract); + addressresolver_i.rebuildCaches(addressresolver_rebuildCaches_destinations_1_0); + } + + + function importFeePeriod_0() internal { + // https://kovan-explorer.optimism.io/address/0x2F737bf6a32bf3AcBef4d5148DA507569204Fb61; + FeePool existingFeePool = FeePool(0x2F737bf6a32bf3AcBef4d5148DA507569204Fb61); + // https://kovan-explorer.optimism.io/address/0x129fd2f3a799bD156e8c00599760AfC2f0f953dA; + FeePool newFeePool = FeePool(0x129fd2f3a799bD156e8c00599760AfC2f0f953dA); + ( + uint64 feePeriodId_0, + uint64 startingDebtIndex_0, + uint64 startTime_0, + uint feesToDistribute_0, + uint feesClaimed_0, + uint rewardsToDistribute_0, + uint rewardsClaimed_0 + ) = existingFeePool.recentFeePeriods(0); + newFeePool.importFeePeriod( + 0, + feePeriodId_0, + startingDebtIndex_0, + startTime_0, + feesToDistribute_0, + feesClaimed_0, + rewardsToDistribute_0, + rewardsClaimed_0 + ); + } + + + function importFeePeriod_1() internal { + // https://kovan-explorer.optimism.io/address/0x2F737bf6a32bf3AcBef4d5148DA507569204Fb61; + FeePool existingFeePool = FeePool(0x2F737bf6a32bf3AcBef4d5148DA507569204Fb61); + // https://kovan-explorer.optimism.io/address/0x129fd2f3a799bD156e8c00599760AfC2f0f953dA; + FeePool newFeePool = FeePool(0x129fd2f3a799bD156e8c00599760AfC2f0f953dA); + ( + uint64 feePeriodId_1, + uint64 startingDebtIndex_1, + uint64 startTime_1, + uint feesToDistribute_1, + uint feesClaimed_1, + uint rewardsToDistribute_1, + uint rewardsClaimed_1 + ) = existingFeePool.recentFeePeriods(1); + newFeePool.importFeePeriod( + 1, + feePeriodId_1, + startingDebtIndex_1, + startTime_1, + feesToDistribute_1, + feesClaimed_1, + rewardsToDistribute_1, + rewardsClaimed_1 + ); + } +} diff --git a/hardhat.config.js b/hardhat.config.js index 8b769f2504..76821c5b95 100644 --- a/hardhat.config.js +++ b/hardhat.config.js @@ -3,6 +3,10 @@ require('dotenv').config(); const path = require('path'); +/// for some weird reason the order of these imports is important: +/// ./hardhat needs to be imported after hardhat-interact (error otherwise) +/// and hardhat-gas-reporter needs to be imported after ./hardhat (otherwise no gas reports) +require('hardhat-interact'); require('./hardhat'); require('@nomiclabs/hardhat-truffle5'); require('@nomiclabs/hardhat-ethers'); @@ -54,6 +58,22 @@ module.exports = { blockGasLimit: 12e6, url: 'http://localhost:8545', }, + mainnet: { + url: process.env.PROVIDER_URL_MAINNET || 'http://localhost:8545', + chainId: 1, + }, + 'mainnet-ovm': { + url: process.env.OVM_PROVIDER_URL || 'https://mainnet.optimism.io/', + chainId: 10, + }, + kovan: { + url: process.env.PROVIDER_URL || 'http://localhost:8545', + chainId: 42, + }, + 'kovan-ovm': { + url: process.env.OVM_PROVIDER_URL || 'https://kovan.optimism.io/', + chainId: 69, + }, }, gasReporter: { enabled: false, @@ -65,5 +85,6 @@ module.exports = { }, mocha: { timeout: 120e3, // 120s + retries: 3, }, }; diff --git a/hardhat/tasks/task-interact.js b/hardhat/tasks/task-interact.js old mode 100755 new mode 100644 index 0eff74d4fb..08acc92613 --- a/hardhat/tasks/task-interact.js +++ b/hardhat/tasks/task-interact.js @@ -1,656 +1,84 @@ +const { subtask } = require('hardhat/config'); const fs = require('fs'); const path = require('path'); -const { types, task } = require('hardhat/config'); -const levenshtein = require('js-levenshtein'); const ethers = require('ethers'); -const inquirer = require('inquirer'); -const autocomplete = require('inquirer-list-search-prompt'); -const { yellow, green, red, cyan, gray } = require('chalk'); -const synthetixPackage = require('../../package.json'); -const synthetix = require('../..'); - -task('interact', 'Interact with a deployed Synthetix instance from the command line') - .addFlag('useFork', 'Use a local fork') - .addFlag('useOvm', 'Use an Optimism chain') - .addOptionalParam('targetNetwork', 'Target the instance deployed in this network', 'mainnet') - .addOptionalParam('gasLimit', 'Max gas to use when signing transactions', 8000000, types.int) - .addOptionalParam('privateKey', 'Private key to use to sign txs') - .addOptionalParam('providerUrl', 'The http provider to use for communicating with the blockchain') - .addOptionalParam('deploymentPath', 'Specify the path to the deployment data directory') - .addOptionalParam('blockTag', 'Specify the block tag to interact at, per ethers.js specification') - .setAction(async (taskArguments, hre) => { - const { useOvm, useFork, deploymentPath, targetNetwork } = taskArguments; - let { providerUrl, gasLimit, privateKey, blockTag } = taskArguments; - // ------------------ - // Default values per network - // ------------------ - - const key = `${targetNetwork}${useOvm ? '-ovm' : ''}`; - const defaults = DEFAULTS[key]; - providerUrl = providerUrl || defaults.providerUrl; - if (useOvm) { - gasLimit = undefined; - } - blockTag = blockTag || 'latest'; - if (!isNaN(blockTag)) { - blockTag = parseInt(blockTag); - } - - // ------------------ - // Setup - // ------------------ - // Wrap Synthetix utils for current network - const { getPathToNetwork, getUsers, getTarget, getSource } = synthetix.wrap({ - network: targetNetwork, - useOvm, - fs, - path, - }); +const synthetix = require('../..'); - // Derive target build path and retrieve deployment artifacts - const file = synthetix.constants.DEPLOYMENT_FILENAME; - let deploymentFilePath; - if (deploymentPath) { - deploymentFilePath = path.join(deploymentPath, file); - } else { - deploymentFilePath = getPathToNetwork({ network: targetNetwork, useOvm, file }); - } - const deploymentData = JSON.parse(fs.readFileSync(deploymentFilePath)); +const { + loadAndCheckRequiredSources, + appendOwnerActionGenerator, +} = require('../../publish/src/util'); + +subtask('interact:load-contracts').setAction(async (args, hre, runSuper) => { + // Wrap Synthetix utils for current network + const { getPathToNetwork, getTarget, getSource } = synthetix.wrap({ + network: hre.network.name, + useOvm: false, + fs, + path, + }); - // Determine private/public keys - let publicKey; - if (useFork) { - if (!privateKey) { - publicKey = getUsers({ user: 'owner' }).address; - } - } - const envPrivateKey = - targetNetwork === 'mainnet' - ? process.env.DEPLOY_PRIVATE_KEY - : process.env.TESTNET_DEPLOY_PRIVATE_KEY; - if (!privateKey && envPrivateKey) { - privateKey = envPrivateKey; - } + // Derive target build path and retrieve deployment artifacts + const file = synthetix.constants.DEPLOYMENT_FILENAME; + const deploymentFilePath = getPathToNetwork({ network: hre.network.name, useOvm: false, file }); - // Determine provider url - if (useFork) { - providerUrl = 'http://localhost:8545'; - } + const deploymentData = JSON.parse(fs.readFileSync(deploymentFilePath)); + const targets = Object.keys(deploymentData.targets); - if (!providerUrl && process.env.PROVIDER_URL) { - const envProviderUrl = process.env.PROVIDER_URL; - if (targetNetwork === 'mainnet' && process.env.PROVIDER_URL_MAINNET) { - providerUrl = process.env.PROVIDER_URL_MAINNET; - } else if (envProviderUrl.includes('infura')) { - providerUrl = process.env.PROVIDER_URL.replace('network', targetNetwork); - } else { - providerUrl = envProviderUrl; - } - } + const contracts = {}; - // Construct provider and signer - const { provider, wallet } = _setupProvider({ - providerUrl, - privateKey, - publicKey, + for (const target of targets) { + const targetData = getTarget({ + contract: target, + network: hre.network.name, + useOvm: false, + deploymentFilePath, }); - // Set up inquirer - inquirer.registerPrompt('autocomplete', autocomplete); - - // Set up cache - const activeContract = {}; - const recentContracts = []; - - // ----------------- - // Start interaction - // ----------------- - - await _printHeader({ - useOvm, - providerUrl, - network: targetNetwork, + const sourceData = getSource({ + contract: targetData.source, + network: hre.network.name, + useOvm: false, deploymentFilePath, - wallet, - blockTag, }); - async function pickContract() { - const targets = Object.keys(deploymentData.targets); - - function prioritizeTarget(itemName) { - targets.splice(targets.indexOf(itemName), 1); - targets.unshift(itemName); - } - - prioritizeTarget('Synthetix'); - - async function searchTargets(matches, query = '') { - return new Promise(resolve => { - resolve(targets.filter(target => target.toLowerCase().includes(query.toLowerCase()))); - }); - } - - const { contractName } = await inquirer.prompt([ - { - type: 'autocomplete', - name: 'contractName', - message: 'Pick a CONTRACT:', - source: (matches, query) => searchTargets(matches, query), - }, - ]); - - const target = await getTarget({ - contract: contractName, - network: targetNetwork, - useOvm, - deploymentPath, - }); - - const source = await getSource({ - contract: target.source, - network: targetNetwork, - useOvm, - deploymentPath, - }); - - activeContract.name = contractName; - activeContract.address = target.address; - if (!recentContracts.some(entry => entry.name === contractName)) { - recentContracts.push({ ...activeContract }); - } - - _printCheatsheet({ activeContract, recentContracts, wallet }); - - const contract = new ethers.Contract(target.address, source.abi, wallet || provider); - if (source.bytecode === '') { - const code = await provider.getCode(target.address, blockTag); - console.log(red(` > No code at ${target.address}, code: ${code}`)); - } - - // ----------------- - // Pick a function - // ----------------- - - async function pickFunction() { - function combineNameAndType(items) { - const combined = []; - if (items && items.length > 0) { - items.map(item => { - if (item.name) combined.push(`${item.type} ${item.name}`); - else combined.push(item.type); - }); - } - - return combined; - } - - function reduceSignature(item) { - const inputs = combineNameAndType(item.inputs); - const inputPart = `${item.name}(${inputs.join(', ')})`; - - const outputs = combineNameAndType(item.outputs); - let outputPart = outputs.length > 0 ? ` returns(${outputs.join(', ')})` : ''; - outputPart = item.stateMutability === 'view' ? ` view${outputPart}` : outputPart; - - return `${inputPart}${outputPart} ${gray(item.signature)}`; - } - - const escItem = '↩ BACK'; - - async function searchAbi(matches, query = '') { - return new Promise(resolve => { - let abiMatches = source.abi.filter(item => { - if (item.name && item.type === 'function') { - return item.name.toLowerCase().includes(query.toLowerCase()); - } - - return false; - }); - - // Sort matches by proximity to query - abiMatches = abiMatches.sort((a, b) => { - const aProximity = levenshtein(a.name, query); - const bProximity = levenshtein(b.name, query); - return aProximity - bProximity; - }); - - const signatures = abiMatches.map(match => reduceSignature(match)); - if (query === '') { - signatures.splice(0, 0, escItem); - } - - resolve(signatures); - }); - } - - // Prompt function to call - const prompt = inquirer.prompt([ - { - type: 'autocomplete', - name: 'abiItemSignature', - message: '>>> Pick a FUNCTION:', - source: (matches, query) => searchAbi(matches, query), - }, - ]); - const { abiItemSignature } = await prompt; - - if (abiItemSignature === escItem) { - prompt.ui.close(); - - await pickContract(); - } - - const abiItemName = abiItemSignature.split('(')[0]; - const abiItem = source.abi.find(item => item.name === abiItemName); - - // ----------------- - // Process inputs - // ----------------- - - // Prompt inputs for function - const inputs = []; - if (abiItem.inputs.length > 0) { - for (const input of abiItem.inputs) { - const name = input.name || input.type; - - let message = name; - - const requiresBytes32Util = input.type.includes('bytes32'); - const isArray = input.type.includes('[]'); - - if (requiresBytes32Util) { - message = `${message} (uses toBytes32${ - isArray ? ' - if array, use ["a","b","c"] syntax' : '' - })`; - } - - const answer = await inquirer.prompt([ - { - type: 'input', - message, - name, - }, - ]); - - let processed = answer[name]; - console.log(gray(' > raw inputs:', processed)); - - if (isArray) { - try { - processed = JSON.parse(processed); - } catch (err) { - console.log(red(`Error parsing array input. Please use the indicated syntax.`)); - - await pickFunction(); - } - } - - if (requiresBytes32Util) { - if (isArray) { - processed = processed.map(item => _bytes32ify(item)); - } else { - processed = _bytes32ify(processed); - } - } - - if (isArray) { - processed = processed.map(value => _boolify(value)); - } else { - processed = _boolify(processed); - } - - console.log( - gray(` > processed inputs (${isArray ? processed.length : '1'}):`, processed) - ); - - inputs.push(processed); - } - } - - // ----------------- - // Call function - // ----------------- - - // Call function - let result, error; - // READ ONLY - if (abiItem.stateMutability === 'view' || abiItem.stateMutability === 'pure') { - console.log(gray(' > Querying...')); - const overrides = { - blockTag, - }; - - try { - result = await contract[abiItemName](...inputs, overrides); - } catch (err) { - error = err; - } - // SEND TX - } else { - const overrides = { - gasLimit, - }; - - let preview; - try { - preview = await contract.populateTransaction[abiItemName](...inputs, overrides); - } catch (err) { - console.log(yellow(`Warning: tx will probably fail!`)); - } - if (preview && preview.data) { - console.log(gray(` > calldata: ${preview.data}`)); - } - - const { confirmation } = await inquirer.prompt([ - { - type: 'confirm', - name: 'confirmation', - message: 'Send transaction?', - }, - ]); - if (!confirmation) { - await pickFunction(); - - return; - } - - console.log(gray(` > Staging transaction... ${new Date()}`)); - const txPromise = contract[abiItemName](...inputs, overrides); - result = await _sendTx({ - txPromise, - }); - - if (result.success) { - console.log(gray(` > Sending transaction... ${result.tx.hash}`)); - result = await _confirmTx({ - tx: result.tx, - provider, - blockTag, - }); - - if (result.success) { - result = result.receipt; - } else { - error = result.error; - } - } else { - error = result.error; - } - } - - function printReturnedValue(value) { - if (ethers.BigNumber.isBigNumber(value)) { - return `${value.toString()} (${ethers.utils.formatEther(value)})`; - } else if (Array.isArray(value)) { - return value.map(item => `${item}`); - } else { - return value; - } - } - - console.log(gray(` > Transaction sent... ${new Date()}`)); - - if (error) { - _logError(error); - } else { - _logReceipt(result, contract); - - if ( - (abiItem.stateMutability === 'view' || abiItem.stateMutability === 'pure') && - result !== undefined - ) { - if (Array.isArray(result) && result.length === 0) { - console.log(gray(` ↪ Call returned no data`)); - } else { - if (abiItem.outputs.length > 1) { - for (let i = 0; i < abiItem.outputs.length; i++) { - const output = abiItem.outputs[i]; - console.log( - cyan(` ↪${output.name}(${output.type}):`), - printReturnedValue(result[i]) - ); - } - } else { - const output = abiItem.outputs[0]; - console.log(cyan(` ↪${output.name}(${output.type}):`), printReturnedValue(result)); - } - } - } - } - - // Call indefinitely - await pickFunction(); - } - - // First function pick - await pickFunction(); - } - - // First contract pick - await pickContract(); - }); - -const DEFAULTS = { - mainnet: {}, - 'mainnet-ovm': { - providerUrl: 'https://mainnet.optimism.io', - }, - kovan: {}, - 'kovan-ovm': { - providerUrl: 'https://kovan.optimism.io', - }, - local: { - providerUrl: 'http://localhost:9545', - }, - 'local-ovm': { - providerUrl: 'http://localhost:8545', - }, - rinkeby: {}, - ropsten: {}, -}; - -async function _printHeader({ - useOvm, - providerUrl, - network, - deploymentFilePath, - wallet, - blockTag, -}) { - console.clear(); - console.log(green(`Interactive Synthetix CLI (v${synthetixPackage.version})`)); - console.log(gray('Please review this information before you interact with the system:')); - console.log( - gray('================================================================================') - ); - console.log( - gray( - `> Provider: ${providerUrl ? `${providerUrl.slice(0, 25)}...` : 'Ethers default provider'}` - ) - ); - console.log(gray(`> Network: ${network}`)); - console.log(gray(`> Gas price: provider default`)); - console.log(gray(`> OVM: ${useOvm}`)); - console.log(gray(`> Block tag: ${blockTag}`)); - console.log(yellow(`> Target deployment: ${path.dirname(deploymentFilePath)}`)); - - if (wallet) { - console.log(yellow(`> Signer: ${wallet.address || wallet}`)); - } else { - console.log(gray('> Read only')); - } - - console.log( - gray('================================================================================') - ); - console.log('\n'); -} - -function _printCheatsheet({ activeContract, recentContracts, wallet }) { - console.log(gray.inverse(`${activeContract.name} => ${activeContract.address}`)); - console.log(gray(` * Signer: ${wallet ? `${wallet.address}` : 'Read only'}`)); - - console.log(gray(' * Recent contracts:')); - for (let i = 0; i < recentContracts.length; i++) { - const contract = recentContracts[i]; - console.log(gray(` ${contract.name}: ${contract.address}`)); - } -} - -function _bytes32ify(value) { - if (ethers.utils.isHexString(value)) { - console.log('isHex'); - return value; - } else { - return synthetix.toBytes32(value); - } -} - -// Avoid 'false' and '0' being interpreted as bool = true -function _boolify(value) { - if (value === 'false' || value === '0') return 0; - return value; -} - -function _logReceipt(receipt, contract) { - console.log(green(' ✅ Success')); - // console.log('receipt', JSON.stringify(receipt, null, 2)); - - // Print tx hash - if (receipt.transactionHash) console.log(gray(` tx hash: ${receipt.transactionHash}`)); - - // Print gas used - if (receipt.gasUsed) { - console.log(gray(` gas used: ${receipt.gasUsed.toString()}`)); - } - - // Print emitted events - if (contract && receipt.logs && receipt.logs.length > 0) { - for (let i = 0; i < receipt.logs.length; i++) { - const log = receipt.logs[i]; - - try { - const parsedLog = contract.interface.parseLog(log); - console.log(gray(` log ${i}:`), cyan(parsedLog.name)); - } catch (err) { - console.log(gray(` log ${i}: unable to decode log - ${JSON.stringify(log)}`)); - } - } + contracts[target] = new ethers.Contract(targetData.address, sourceData.abi, args.provider); } -} -function _logError(error) { - console.log(red(' ❌ Error')); + return { ...contracts, ...(await runSuper(args)) }; +}); - function findReason(error) { - if (typeof error === 'string') { - return error; - } else { - if (error.hasOwnProperty('reason')) { - return error.reason; - } else if (error.hasOwnProperty('error')) { - return findReason(error.error); - } - } - } - - const reason = findReason(error); - if (reason) console.log(red(` Reason: ${reason}`)); +subtask('interact:stage-txn').setAction(async ({ txn, contract, functionSignature, args }, hre) => { + const { getPathToNetwork } = synthetix.wrap({ + network: hre.network.name, + useOvm: false, + fs, + path, + }); - console.log(gray(JSON.stringify(error, null, 2))); -} + // always appending to mainnet owner actions now + const { ownerActions, ownerActionsFile } = loadAndCheckRequiredSources({ + deploymentPath: getPathToNetwork({ network: hre.network.name, useOvm: false }), + network: hre.network.name, + }); -function _setupProvider({ providerUrl, privateKey, publicKey }) { - let provider; - if (providerUrl) { - provider = new ethers.providers.JsonRpcProvider(providerUrl); - } else { - // eslint-disable-next-line new-cap - provider = new ethers.getDefaultProvider(); - } + // append to owner actions if supplied + const appendOwnerAction = appendOwnerActionGenerator({ + ownerActions, + ownerActionsFile, + // 'https://', + }); - let wallet; - if (publicKey) { - wallet = provider.getSigner(publicKey); - wallet.address = publicKey; - } else if (privateKey) { - wallet = new ethers.Wallet(privateKey, provider); - } + const actionName = `${contract.address}.${functionSignature}:${args.join(',')}`; - return { - provider, - wallet: wallet || undefined, + const ownerAction = { + key: actionName, + target: txn.to, + action: actionName, + data: txn.data, }; -} - -async function _sendTx({ txPromise }) { - try { - const tx = await txPromise; - - return { - success: true, - tx, - }; - } catch (error) { - return { - success: false, - error, - }; - } -} - -async function _confirmTx({ tx, provider, blockTag }) { - try { - const receipt = await tx.wait(); - - return { - success: true, - receipt, - }; - } catch (error) { - try { - error.reason = await _getRevertReason({ tx, provider, blockTag }); - - return { - success: false, - error, - }; - } catch (suberror) { - error.error = suberror; - - return { - success: false, - error, - }; - } - } -} - -function _hexToString(hex) { - let str = ''; - const terminator = '**zÛ'; - for (var i = 0; i < hex.length; i += 2) { - str += String.fromCharCode(parseInt(hex.substr(i, 2), 16)); - - if (str.includes(terminator)) { - break; - } - } - - return str.substring(0, str.length - 4); -} - -async function _getRevertReason({ tx, provider, blockTag }) { - const code = (await provider.call(tx, blockTag)).substr(138); - const hex = `0x${code}`; - - if (code.length === '64') { - return ethers.utils.parseBytes32String(hex); - } else { - return _hexToString(hex); - } -} + appendOwnerAction(ownerAction); +}); diff --git a/index.js b/index.js index 4ce101e97a..3d067eb942 100644 --- a/index.js +++ b/index.js @@ -490,7 +490,9 @@ const getUsers = ({ network = 'mainnet', user, useOvm = false } = {}) => { oracle: '0xaC1ED4Fabbd5204E02950D68b6FC8c446AC95362', }), kovan: Object.assign({}, base), - 'kovan-ovm': Object.assign({}, base), + 'kovan-ovm': Object.assign({}, base, { + owner: '0x7509FeAEE952F7dA93f746CF7134CFDE8f249C94', + }), 'mainnet-ovm': Object.assign({}, base, { owner: '0x6d4a64C57612841c2C6745dB2a4E4db34F002D20', }), diff --git a/package-lock.json b/package-lock.json index 29f81add21..637621672f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,6 +5,7 @@ "requires": true, "packages": { "": { + "name": "synthetix", "version": "2.56.1", "license": "MIT", "dependencies": { @@ -55,6 +56,7 @@ "fs-extra": "9.0.1", "hardhat": "2.6.4", "hardhat-gas-reporter": "~1.0.4", + "hardhat-interact": "^0.2.0", "husky": "^4.3.0", "is-ci": "^2.0.0", "lodash.clonedeep": "^4.5.0", @@ -84,12 +86,12 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", - "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz", + "integrity": "sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==", "dev": true, "dependencies": { - "@babel/highlight": "^7.14.5" + "@babel/highlight": "^7.16.0" }, "engines": { "node": ">=6.9.0" @@ -105,12 +107,12 @@ } }, "node_modules/@babel/highlight": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", - "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.0.tgz", + "integrity": "sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.14.5", + "@babel/helper-validator-identifier": "^7.15.7", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, @@ -119,9 +121,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.4.tgz", - "integrity": "sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.5.tgz", + "integrity": "sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA==", "dev": true, "optional": true, "dependencies": { @@ -565,6 +567,13 @@ "node": ">=0.10.0" } }, + "node_modules/@ensdomains/ens/node_modules/require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true, + "optional": true + }, "node_modules/@ensdomains/ens/node_modules/semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", @@ -620,6 +629,13 @@ "node": ">=0.10.0" } }, + "node_modules/@ensdomains/ens/node_modules/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, + "optional": true + }, "node_modules/@ensdomains/ens/node_modules/wrap-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", @@ -765,15 +781,15 @@ "dev": true }, "node_modules/@ethereumjs/block": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/@ethereumjs/block/-/block-3.5.1.tgz", - "integrity": "sha512-MoY9bHKABOBK6BW0v1N1Oc0Cve4x/giX67M3TtrVBUsKQTj2eznLGKpydoitxWSZ+WgKKSVhfRMzbCGRwk7T5w==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/block/-/block-3.6.0.tgz", + "integrity": "sha512-dqLo1LtsLG+Oelu5S5tWUDG0pah3QUwV5TJZy2cm19BXDr4ka/S9XBSgao0i09gTcuPlovlHgcs6d7EZ37urjQ==", "dev": true, "dependencies": { - "@ethereumjs/common": "^2.5.0", - "@ethereumjs/tx": "^3.3.1", - "ethereumjs-util": "^7.1.1", - "merkle-patricia-tree": "^4.2.1" + "@ethereumjs/common": "^2.6.0", + "@ethereumjs/tx": "^3.4.0", + "ethereumjs-util": "^7.1.3", + "merkle-patricia-tree": "^4.2.2" } }, "node_modules/@ethereumjs/block/node_modules/abstract-leveldown": { @@ -955,19 +971,18 @@ } }, "node_modules/@ethereumjs/blockchain": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/@ethereumjs/blockchain/-/blockchain-5.4.2.tgz", - "integrity": "sha512-AOAAwz/lw2lciG9gf5wHi7M/qknraXXnLR66lYgbQ04qfyFC3ZE5x/5rLVm1Vu+kfJLlKrYZTmA0IbOkc7kvgw==", + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/@ethereumjs/blockchain/-/blockchain-5.5.1.tgz", + "integrity": "sha512-JS2jeKxl3tlaa5oXrZ8mGoVBCz6YqsGG350XVNtHAtNZXKk7pU3rH4xzF2ru42fksMMqzFLzKh9l4EQzmNWDqA==", "dev": true, "dependencies": { - "@ethereumjs/block": "^3.5.1", - "@ethereumjs/common": "^2.5.0", + "@ethereumjs/block": "^3.6.0", + "@ethereumjs/common": "^2.6.0", "@ethereumjs/ethash": "^1.1.0", "debug": "^2.2.0", - "ethereumjs-util": "^7.1.1", + "ethereumjs-util": "^7.1.3", "level-mem": "^5.0.1", "lru-cache": "^5.1.1", - "rlp": "^2.2.4", "semaphore-async-await": "^1.5.1" } }, @@ -1136,13 +1151,13 @@ "dev": true }, "node_modules/@ethereumjs/common": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.5.0.tgz", - "integrity": "sha512-DEHjW6e38o+JmB/NO3GZBpW4lpaiBpkFgXF6jLcJ6gETBYpEyaA5nTimsWBUJR3Vmtm/didUEbNjajskugZORg==", + "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, "dependencies": { "crc-32": "^1.2.0", - "ethereumjs-util": "^7.1.1" + "ethereumjs-util": "^7.1.3" } }, "node_modules/@ethereumjs/ethash": { @@ -1159,34 +1174,33 @@ } }, "node_modules/@ethereumjs/tx": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.3.2.tgz", - "integrity": "sha512-6AaJhwg4ucmwTvw/1qLaZUX5miWrwZ4nLOUsKyb/HtzS3BMw/CasKhdi1ims9mBKeK9sOJCH4qGKOBGyJCeeog==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.4.0.tgz", + "integrity": "sha512-WWUwg1PdjHKZZxPPo274ZuPsJCWV3SqATrEKQP1n2DrVYVP1aZIYpo/mFaA0BDoE0tIQmBeimRCEA0Lgil+yYw==", "dev": true, "dependencies": { - "@ethereumjs/common": "^2.5.0", - "ethereumjs-util": "^7.1.2" + "@ethereumjs/common": "^2.6.0", + "ethereumjs-util": "^7.1.3" } }, "node_modules/@ethereumjs/vm": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/@ethereumjs/vm/-/vm-5.5.3.tgz", - "integrity": "sha512-0k5OreWnlgXYs54wohgO11jtGI05GDasj2EYxzuaStxTi15CS3vow5wGYELC1pG9xngE1F/mFmKi/f14XRuDow==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/vm/-/vm-5.6.0.tgz", + "integrity": "sha512-J2m/OgjjiGdWF2P9bj/4LnZQ1zRoZhY8mRNVw/N3tXliGI8ai1sI1mlDPkLpeUUM4vq54gH6n0ZlSpz8U/qlYQ==", "dev": true, "dependencies": { - "@ethereumjs/block": "^3.5.0", - "@ethereumjs/blockchain": "^5.4.1", - "@ethereumjs/common": "^2.5.0", - "@ethereumjs/tx": "^3.3.1", + "@ethereumjs/block": "^3.6.0", + "@ethereumjs/blockchain": "^5.5.0", + "@ethereumjs/common": "^2.6.0", + "@ethereumjs/tx": "^3.4.0", "async-eventemitter": "^0.2.4", "core-js-pure": "^3.0.1", "debug": "^2.2.0", - "ethereumjs-util": "^7.1.1", + "ethereumjs-util": "^7.1.3", "functional-red-black-tree": "^1.0.1", "mcl-wasm": "^0.7.1", - "merkle-patricia-tree": "^4.2.1", - "rustbn.js": "~0.2.0", - "util.promisify": "^1.0.1" + "merkle-patricia-tree": "^4.2.2", + "rustbn.js": "~0.2.0" } }, "node_modules/@ethereumjs/vm/node_modules/abstract-leveldown": { @@ -1725,9 +1739,9 @@ ] }, "node_modules/@ethersproject/networks": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.5.0.tgz", - "integrity": "sha512-KWfP3xOnJeF89Uf/FCJdV1a2aDJe5XTN2N52p4fcQ34QhDqQFkgQKZ39VGtiqUgHcLI8DfT0l9azC3KFTunqtA==", + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.5.1.tgz", + "integrity": "sha512-tYRDM4zZtSUcKnD4UMuAlj7SeXH/k5WC4SP2u1Pn57++JdXHkRu2zwNkgNogZoxHzhm9Q6qqurDBVptHOsW49Q==", "funding": [ { "type": "individual", @@ -2029,9 +2043,9 @@ } }, "node_modules/@ethersproject/web": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.5.0.tgz", - "integrity": "sha512-BEgY0eL5oH4mAo37TNYVrFeHsIXLRxggCRG/ksRIxI2X5uj5IsjGmcNiRN/VirQOlBxcUhCgHhaDLG4m6XAVoA==", + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.5.1.tgz", + "integrity": "sha512-olvLvc1CB12sREc1ROPSHTdFCdvMh0J5GSJYiQg2D0hdD4QmJDy8QYDb1CvoqD/bF1c++aeKv2sR5uduuG9dQg==", "funding": [ { "type": "individual", @@ -2185,9 +2199,9 @@ } }, "node_modules/@nomiclabs/hardhat-ethers": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.0.2.tgz", - "integrity": "sha512-6quxWe8wwS4X5v3Au8q1jOvXYEPkS1Fh+cME5u6AwNdnI4uERvPlVjlgRWzpnb+Rrt1l/cEqiNRH9GlsBMSDQg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.0.3.tgz", + "integrity": "sha512-IJ0gBotVtO7YyLZyHNgbxzskUtFok+JkRlKPo8YELqj1ms9XL6Qm3vsfsGdZr22wnJeVEF5TQPotKuwQk21Dag==", "dev": true, "peerDependencies": { "ethers": "^5.0.0", @@ -2567,6 +2581,29 @@ "integrity": "sha512-H8BSBoKE8EubJa0ONqecA2TviT3TnHeC4NpgnAHSUiuhZoQBfPB4L2P9bs8R6AoTW10Endvh3vc+fomVMIDIYQ==", "dev": true }, + "node_modules/@synthetixio/wei": { + "version": "2.56.3", + "resolved": "https://registry.npmjs.org/@synthetixio/wei/-/wei-2.56.3.tgz", + "integrity": "sha512-eJu5G/z/o6QyCEwe2Ovby/w4zmpoSM/tn0gcMkibzADqNMqM8afBVvSF5YM4whnf3/lWjEfeDFqHI62XnR5wqw==", + "dev": true, + "dependencies": { + "big.js": "6.1.1", + "ethers": "5.4.6" + } + }, + "node_modules/@synthetixio/wei/node_modules/big.js": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-6.1.1.tgz", + "integrity": "sha512-1vObw81a8ylZO5ePrtMay0n018TcftpTA5HFKDaSuiUDBo8biRBtjIobw60OpwuvrGk+FsxKamqN4cnmj/eXdg==", + "dev": true, + "engines": { + "node": "*" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/bigjs" + } + }, "node_modules/@szmarczak/http-timer": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", @@ -2580,9 +2617,9 @@ } }, "node_modules/@truffle/abi-utils": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@truffle/abi-utils/-/abi-utils-0.2.4.tgz", - "integrity": "sha512-ICr5Sger6r5uj2G5GN9Zp9OQDCaCqe2ZyAEyvavDoFB+jX0zZFUCfDnv5jllGRhgzdYJ3mec2390mjUyz9jSZA==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@truffle/abi-utils/-/abi-utils-0.2.5.tgz", + "integrity": "sha512-eKDIn9LqUFP8MnHVohe8ncuza4p9bszz1NtJWc+sr5zUogtmWnnf8Ajyj7JJpNKhLNDVZVbLowVEVxWzSSpMHw==", "dev": true, "optional": true, "dependencies": { @@ -2666,9 +2703,9 @@ } }, "node_modules/@truffle/compile-common": { - "version": "0.7.22", - "resolved": "https://registry.npmjs.org/@truffle/compile-common/-/compile-common-0.7.22.tgz", - "integrity": "sha512-afFKh0Wphn8JrCSjOORKjO8/E1X0EtQv6GpFJpQCAWo3/i4VGcSVKR1rjkknnExtjEGe9PJH/Ym/opGH3pQyDw==", + "version": "0.7.23", + "resolved": "https://registry.npmjs.org/@truffle/compile-common/-/compile-common-0.7.23.tgz", + "integrity": "sha512-LWzeboJ9HmSZVgx5DMmKArOo96V4QZhS/+8beDOfeNT1W4QeKfkuVbAM0R77cXjiLnUsNjjFVXehnco6HiF8ww==", "dev": true, "optional": true, "dependencies": { @@ -2684,19 +2721,20 @@ "optional": true }, "node_modules/@truffle/contract": { - "version": "4.3.38", - "resolved": "https://registry.npmjs.org/@truffle/contract/-/contract-4.3.38.tgz", - "integrity": "sha512-11HL9IJTmd45pVXJvEaRYeyuhf8GmAgRD7bTYBZj2CiMBnt0337Fg7Zz/GuTpUUW2h3fbyTYO4hgOntxdQjZ5A==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@truffle/contract/-/contract-4.4.1.tgz", + "integrity": "sha512-KVpG9alKxdNzWOcRN97crZXXmmnnShq1SkM9hQN2fOckszzrmy6ctOhnZKNAb8tzfHBgODDCmiGQbTqaYizcrA==", "dev": true, "optional": true, "dependencies": { "@ensdomains/ensjs": "^2.0.1", "@truffle/blockchain-utils": "^0.0.31", - "@truffle/contract-schema": "^3.4.3", - "@truffle/debug-utils": "^5.1.18", + "@truffle/contract-schema": "^3.4.4", + "@truffle/debug-utils": "^6.0.2", "@truffle/error": "^0.0.14", "@truffle/interface-adapter": "^0.5.8", "bignumber.js": "^7.2.1", + "debug": "^4.3.1", "ethers": "^4.0.32", "web3": "1.5.3", "web3-core-helpers": "1.5.3", @@ -2706,9 +2744,9 @@ } }, "node_modules/@truffle/contract-schema": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/@truffle/contract-schema/-/contract-schema-3.4.3.tgz", - "integrity": "sha512-pgaTgF4CKIpkqVYZVr2qGTxZZQOkNCWOXW9VQpKvLd4G0SNF2Y1gyhrFbBhoOUtYlbbSty+IEFFHsoAqpqlvpQ==", + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@truffle/contract-schema/-/contract-schema-3.4.4.tgz", + "integrity": "sha512-xWgrm6WRM2jmT04w7dP7aVbS2qyP9XPmH/mybQtFXMjJ/8BZlp0yltC8QOs8sGl6q8Ws7acp19YtRkLdK6SsmQ==", "dev": true, "dependencies": { "ajv": "^6.10.0", @@ -2741,14 +2779,14 @@ "optional": true }, "node_modules/@truffle/contract/node_modules/@truffle/codec": { - "version": "0.11.17", - "resolved": "https://registry.npmjs.org/@truffle/codec/-/codec-0.11.17.tgz", - "integrity": "sha512-WO9D5TVyTf9czqdsfK/qqYeSS//zWcHBgQgSNKPlCDb6koCNLxG5yGbb4P+0bZvTUNS2e2iIdN92QHg00wMbSQ==", + "version": "0.11.21", + "resolved": "https://registry.npmjs.org/@truffle/codec/-/codec-0.11.21.tgz", + "integrity": "sha512-ZDzaEPCUFWmQuFsXA3KzXmU4w4lpxSWZTGUcEDHxn6IqAmL7FY8mmdbR6LQ1wTRAa9oPf84PcehMpTNY47HVcg==", "dev": true, "optional": true, "dependencies": { - "@truffle/abi-utils": "^0.2.4", - "@truffle/compile-common": "^0.7.22", + "@truffle/abi-utils": "^0.2.5", + "@truffle/compile-common": "^0.7.23", "big.js": "^5.2.2", "bn.js": "^5.1.3", "cbor": "^5.1.0", @@ -2763,18 +2801,18 @@ } }, "node_modules/@truffle/contract/node_modules/@truffle/debug-utils": { - "version": "5.1.18", - "resolved": "https://registry.npmjs.org/@truffle/debug-utils/-/debug-utils-5.1.18.tgz", - "integrity": "sha512-QBq1vA/YozksQZGjyA7o482AuT8KW5gvO8VmYM/PIDllCIqDruEZuz4DZ+zpVUPXyVoJycFo+RKnM/TLE1AZRQ==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@truffle/debug-utils/-/debug-utils-6.0.2.tgz", + "integrity": "sha512-gMZ2IHPS9cvWGinUwVMoZedOYJz4sSekUXGC5FQkBnR0XDVriPmuja4rdgXhkA9EFSqZdXu4JAL8IiEHp/1YIw==", "dev": true, "optional": true, "dependencies": { - "@truffle/codec": "^0.11.17", + "@truffle/codec": "^0.11.21", "@trufflesuite/chromafi": "^2.2.2", "bn.js": "^5.1.3", "chalk": "^2.4.2", "debug": "^4.3.1", - "highlightjs-solidity": "^2.0.1" + "highlightjs-solidity": "^2.0.2" } }, "node_modules/@truffle/contract/node_modules/@truffle/error": { @@ -2807,9 +2845,9 @@ } }, "node_modules/@truffle/contract/node_modules/@types/node": { - "version": "12.20.33", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.33.tgz", - "integrity": "sha512-5XmYX2GECSa+CxMYaFsr2mrql71Q4EvHjKS+ox/SiwSdaASMoBIWE6UmZqFO+VX1jIcsYLStI4FFoB6V7FeIYw==", + "version": "12.20.37", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.37.tgz", + "integrity": "sha512-i1KGxqcvJaLQali+WuypQnXwcplhtNtjs66eNsZpp2P2FL/trJJxx/VWsM0YCL2iMoIJrbXje48lvIQAQ4p2ZA==", "dev": true, "optional": true }, @@ -2876,9 +2914,9 @@ } }, "node_modules/@truffle/contract/node_modules/highlightjs-solidity": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/highlightjs-solidity/-/highlightjs-solidity-2.0.1.tgz", - "integrity": "sha512-9YY+HQpXMTrF8HgRByjeQhd21GXAz2ktMPTcs6oWSj5HJR52fgsNoelMOmgigwcpt9j4tu4IVSaWaJB2n2TbvQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/highlightjs-solidity/-/highlightjs-solidity-2.0.2.tgz", + "integrity": "sha512-q0aYUKiZ9MPQg41qx/KpXKaCpqql50qTvmwGYyLFfcjt9AE/+C9CwjVIdJZc7EYj6NGgJuFJ4im1gfgrzUU1fQ==", "dev": true, "optional": true }, @@ -3072,9 +3110,9 @@ } }, "node_modules/@truffle/contract/node_modules/web3-core/node_modules/bignumber.js": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", - "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", + "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", "dev": true, "optional": true, "engines": { @@ -3405,15 +3443,15 @@ } }, "node_modules/@truffle/interface-adapter/node_modules/@types/node": { - "version": "12.20.33", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.33.tgz", - "integrity": "sha512-5XmYX2GECSa+CxMYaFsr2mrql71Q4EvHjKS+ox/SiwSdaASMoBIWE6UmZqFO+VX1jIcsYLStI4FFoB6V7FeIYw==", + "version": "12.20.37", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.37.tgz", + "integrity": "sha512-i1KGxqcvJaLQali+WuypQnXwcplhtNtjs66eNsZpp2P2FL/trJJxx/VWsM0YCL2iMoIJrbXje48lvIQAQ4p2ZA==", "dev": true }, "node_modules/@truffle/interface-adapter/node_modules/bignumber.js": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", - "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", + "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", "dev": true, "engines": { "node": "*" @@ -3937,15 +3975,15 @@ } }, "node_modules/@truffle/provider/node_modules/@types/node": { - "version": "12.20.33", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.33.tgz", - "integrity": "sha512-5XmYX2GECSa+CxMYaFsr2mrql71Q4EvHjKS+ox/SiwSdaASMoBIWE6UmZqFO+VX1jIcsYLStI4FFoB6V7FeIYw==", + "version": "12.20.37", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.37.tgz", + "integrity": "sha512-i1KGxqcvJaLQali+WuypQnXwcplhtNtjs66eNsZpp2P2FL/trJJxx/VWsM0YCL2iMoIJrbXje48lvIQAQ4p2ZA==", "dev": true }, "node_modules/@truffle/provider/node_modules/bignumber.js": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", - "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", + "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", "dev": true, "engines": { "node": "*" @@ -4453,9 +4491,9 @@ } }, "node_modules/@types/chai": { - "version": "4.2.22", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.22.tgz", - "integrity": "sha512-tFfcE+DSTzWAgifkjik9AySNqIyNoYwmR+uecPwwD/XRNfvOjmC/FjCxpiUGDkDVDphPfCUecSQVFw+lN3M3kQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.0.tgz", + "integrity": "sha512-/ceqdqeRraGolFTcfoXNiqjyQhZzbINDngeoAq9GoHa8PPK1yNzTaxWjA6BFWp5Ua9JpXEMSS4s5i9tS0hOJtw==", "dev": true }, "node_modules/@types/concat-stream": { @@ -4522,9 +4560,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "16.11.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.1.tgz", - "integrity": "sha512-PYGcJHL9mwl1Ek3PLiYgyEKtwTMmkMw4vbiyz/ps3pfdRYLVv+SN7qHVAImrjdAXxgluDEw6Ph4lyv+m9UpRmA==" + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.0.tgz", + "integrity": "sha512-eMhwJXc931Ihh4tkU+Y7GiLzT/y/DBNpNtr4yU9O2w3SYBsr9NaOPhQlLKRmoWtI54uNwuo0IOUFQjVOTZYRvw==" }, "node_modules/@types/parse-json": { "version": "4.0.0", @@ -4555,9 +4593,9 @@ } }, "node_modules/@uniswap/token-lists": { - "version": "1.0.0-beta.26", - "resolved": "https://registry.npmjs.org/@uniswap/token-lists/-/token-lists-1.0.0-beta.26.tgz", - "integrity": "sha512-lDeB81CVds2ISqTbANyxgProFtoux4WRJFv9OoFV3NRnn10SYr0kVjgSOuBmbqa8gJorqomQYqOSGksIDQqthw==", + "version": "1.0.0-beta.27", + "resolved": "https://registry.npmjs.org/@uniswap/token-lists/-/token-lists-1.0.0-beta.27.tgz", + "integrity": "sha512-x5hmIniQ9TGqOBCRqfWcmZi/U5kB0qrHMDQ9igs3nMbK0wwmYLraL4owbIwXFGR/co6/lJYJC4K/Gjn4wZY5mQ==", "dev": true, "engines": { "node": ">=10" @@ -4750,6 +4788,12 @@ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", "dev": true }, + "node_modules/abbrev": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", + "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", + "dev": true + }, "node_modules/abi-decoder": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/abi-decoder/-/abi-decoder-2.3.0.tgz", @@ -5216,9 +5260,9 @@ "dev": true }, "node_modules/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, "dependencies": { "safer-buffer": "~2.1.0" @@ -5428,9 +5472,9 @@ "dev": true }, "node_modules/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==", "dependencies": { "safe-buffer": "^5.0.1" } @@ -5560,21 +5604,21 @@ "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" }, "node_modules/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.19.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.1.tgz", + "integrity": "sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA==", "dev": true, "dependencies": { - "bytes": "3.1.0", + "bytes": "3.1.1", "content-type": "~1.0.4", "debug": "2.6.9", "depd": "~1.1.2", - "http-errors": "1.7.2", + "http-errors": "1.8.1", "iconv-lite": "0.4.24", "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" + "qs": "6.9.6", + "raw-body": "2.4.2", + "type-is": "~1.6.18" }, "engines": { "node": ">= 0.8" @@ -5589,28 +5633,6 @@ "ms": "2.0.0" } }, - "node_modules/body-parser/node_modules/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, - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/body-parser/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, "node_modules/body-parser/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -5618,27 +5640,15 @@ "dev": true }, "node_modules/body-parser/node_modules/qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "version": "6.9.6", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz", + "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==", "dev": true, "engines": { "node": ">=0.6" - } - }, - "node_modules/body-parser/node_modules/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==", - "dev": true, - "dependencies": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" }, - "engines": { - "node": ">= 0.8" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/boolbase": { @@ -5665,9 +5675,9 @@ } }, "node_modules/borc/node_modules/bignumber.js": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", - "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", + "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", "dev": true, "engines": { "node": "*" @@ -5883,9 +5893,9 @@ "dev": true }, "node_modules/bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz", + "integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==", "dev": true, "engines": { "node": ">= 0.8" @@ -5914,12 +5924,6 @@ "y18n": "^4.0.0" } }, - "node_modules/cacache/node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, "node_modules/cache-base": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", @@ -6076,9 +6080,9 @@ } }, "node_modules/cbor/node_modules/bignumber.js": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", - "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", + "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", "dev": true, "optional": true, "engines": { @@ -6247,6 +6251,12 @@ "fsevents": "~2.3.2" } }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, "node_modules/chrome-trace-event": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", @@ -6422,9 +6432,9 @@ } }, "node_modules/cli-table": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.6.tgz", - "integrity": "sha512-ZkNZbnZjKERTY5NwC2SeMeLeifSPq/pubeRoTpdr3WchLlnZg6hEgvHkK5zL7KNFdd9PmHN8lxrENUwI3cE8vQ==", + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.11.tgz", + "integrity": "sha512-IqLQi4lO0nIB4tcdTpN4LCB9FI3uqrJZK7RC515EnhZ6qBaglkIgICb1wjeAqpdoOabm1+SuQtkXIPdYC93jhQ==", "dev": true, "dependencies": { "colors": "1.0.3" @@ -6463,6 +6473,58 @@ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==" }, + "node_modules/cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "dependencies": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "node_modules/cliui/node_modules/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, + "engines": { + "node": ">=6" + } + }, + "node_modules/cliui/node_modules/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 + }, + "node_modules/cliui/node_modules/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, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/cliui/node_modules/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, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/clone-response": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", @@ -6641,125 +6703,6 @@ "node": ">=6.0.0" } }, - "node_modules/concurrently/node_modules/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, - "engines": { - "node": ">=6" - } - }, - "node_modules/concurrently/node_modules/cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "dependencies": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "node_modules/concurrently/node_modules/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 - }, - "node_modules/concurrently/node_modules/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, - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/concurrently/node_modules/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, - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/concurrently/node_modules/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, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/concurrently/node_modules/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, - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/concurrently/node_modules/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, - "engines": { - "node": ">=6" - } - }, - "node_modules/concurrently/node_modules/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 - }, - "node_modules/concurrently/node_modules/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, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/concurrently/node_modules/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, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/concurrently/node_modules/supports-color": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", @@ -6772,44 +6715,6 @@ "node": ">=6" } }, - "node_modules/concurrently/node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "node_modules/concurrently/node_modules/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, - "dependencies": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/concurrently/node_modules/yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "dependencies": { - "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" - } - }, "node_modules/console-browserify": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", @@ -6925,9 +6830,9 @@ } }, "node_modules/core-js-pure": { - "version": "3.18.3", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.18.3.tgz", - "integrity": "sha512-qfskyO/KjtbYn09bn1IPkuhHl5PlJ6IzJ9s9sraJ1EqcuGyLGKzhSM1cY0zgyL9hx42eulQLZ6WaeK5ycJCkqw==", + "version": "3.20.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.20.0.tgz", + "integrity": "sha512-qsrbIwWSEEYOM7z616jAVgwhuDDtPLwZSpUsU3vyUkHYqKTf/uwOJBZg2V7lMurYWkpVlaVOxBrfX0Q3ppvjfg==", "dev": true, "hasInstallScript": true, "funding": { @@ -7083,15 +6988,15 @@ } }, "node_modules/css-select": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.1.3.tgz", - "integrity": "sha512-gT3wBNd9Nj49rAbmtFHj1cljIAOLYSX1nZ8CB7TBO3INYckygm5B7LISU/szY//YmdiSLbJvDLOx9VnMVpMBxA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.2.0.tgz", + "integrity": "sha512-6YVG6hsH9yIb/si3Th/is8Pex7qnVHO6t7q7U6TIUnkQASGbS8tnUDBftnPynLNnuUl/r2+PTd0ekiiq7R0zJw==", "dependencies": { "boolbase": "^1.0.0", - "css-what": "^5.0.0", - "domhandler": "^4.2.0", - "domutils": "^2.6.0", - "nth-check": "^2.0.0" + "css-what": "^5.1.0", + "domhandler": "^4.3.0", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" }, "funding": { "url": "https://github.com/sponsors/fb55" @@ -7137,9 +7042,9 @@ } }, "node_modules/date-fns": { - "version": "2.25.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.25.0.tgz", - "integrity": "sha512-ovYRFnTrbGPD4nqaEqescPEv1mNwvt+UTqI3Ay9SzNtey9NZnYu6E2qCcBBgJ6/2VF1zGGygpyTDITqpQQ5e+w==", + "version": "2.27.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.27.0.tgz", + "integrity": "sha512-sj+J0Mo2p2X1e306MHq282WS4/A8Pz/95GIFcsPNMPMZVI3EUrAdSv90al1k+p74WGLCruMXk23bfEDZa71X9Q==", "dev": true, "engines": { "node": ">=0.11" @@ -7156,9 +7061,9 @@ "dev": true }, "node_modules/debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -7457,9 +7362,9 @@ ] }, "node_modules/domhandler": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.2.tgz", - "integrity": "sha512-PzE9aBMsdZO8TK4BnuJwH0QT41wgMbRzuZrHUcpYncEjmQazq8QEaBWgLG7ZyC/DAZKEgglpIA6j4Qn/HmxS3w==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.0.tgz", + "integrity": "sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==", "dependencies": { "domelementtype": "^2.2.0" }, @@ -8293,9 +8198,9 @@ } }, "node_modules/eslint-plugin-node/node_modules/ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.9.tgz", + "integrity": "sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ==", "dev": true, "engines": { "node": ">= 4" @@ -8526,9 +8431,9 @@ } }, "node_modules/esquery/node_modules/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, "engines": { "node": ">=4.0" @@ -8547,9 +8452,9 @@ } }, "node_modules/esrecurse/node_modules/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, "engines": { "node": ">=4.0" @@ -8599,13 +8504,13 @@ "dev": true }, "node_modules/eth-gas-reporter": { - "version": "0.2.22", - "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.22.tgz", - "integrity": "sha512-L1FlC792aTf3j/j+gGzSNlGrXKSxNPXQNk6TnV5NNZ2w3jnQCRyJjDl0zUo25Cq2t90IS5vGdbkwqFQK7Ce+kw==", + "version": "0.2.23", + "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.23.tgz", + "integrity": "sha512-T8KsVakDEupvQxW3MfFfHDfJ7y8zl2+XhyEQk4hZ3qQsAh/FE27BfFHM9UhqNQvrJLz8zVWnPZWNcARwLT/lsA==", "dev": true, "dependencies": { "@ethersproject/abi": "^5.0.0-beta.146", - "@solidity-parser/parser": "^0.12.0", + "@solidity-parser/parser": "^0.14.0", "cli-table3": "^0.5.0", "colors": "^1.1.2", "ethereumjs-util": "6.2.0", @@ -8622,13 +8527,21 @@ }, "peerDependencies": { "@codechecks/client": "^0.1.0" + }, + "peerDependenciesMeta": { + "@codechecks/client": { + "optional": true + } } }, "node_modules/eth-gas-reporter/node_modules/@solidity-parser/parser": { - "version": "0.12.2", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.12.2.tgz", - "integrity": "sha512-d7VS7PxgMosm5NyaiyDJRNID5pK4AWj1l64Dbz0147hJgy5k2C0/ZiKK/9u5c5K+HRUVHmp+RMvGEjGh84oA5Q==", - "dev": true + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.0.tgz", + "integrity": "sha512-cX0JJRcmPtNUJpzD2K7FdA7qQsTOk1UZnFx2k7qAg9ZRvuaH5NBe5IEdBMXGlmf2+FmjhqbygJ26H8l2SV7aKQ==", + "dev": true, + "dependencies": { + "antlr4ts": "^0.5.0-alpha.4" + } }, "node_modules/eth-gas-reporter/node_modules/@types/bn.js": { "version": "4.11.6", @@ -8648,15 +8561,6 @@ "node": ">=6" } }, - "node_modules/eth-gas-reporter/node_modules/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, - "engines": { - "node": ">=6" - } - }, "node_modules/eth-gas-reporter/node_modules/bn.js": { "version": "4.12.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", @@ -8684,17 +8588,6 @@ "fsevents": "~2.1.1" } }, - "node_modules/eth-gas-reporter/node_modules/cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "dependencies": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, "node_modules/eth-gas-reporter/node_modules/debug": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", @@ -8714,12 +8607,6 @@ "node": ">=0.3.1" } }, - "node_modules/eth-gas-reporter/node_modules/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 - }, "node_modules/eth-gas-reporter/node_modules/ethereumjs-util": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.0.tgz", @@ -8978,12 +8865,6 @@ "node": ">= 8" } }, - "node_modules/eth-gas-reporter/node_modules/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 - }, "node_modules/eth-gas-reporter/node_modules/scrypt-js": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz", @@ -9016,32 +8897,6 @@ "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=", "dev": true }, - "node_modules/eth-gas-reporter/node_modules/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, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eth-gas-reporter/node_modules/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, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/eth-gas-reporter/node_modules/strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", @@ -9082,44 +8937,6 @@ "which": "bin/which" } }, - "node_modules/eth-gas-reporter/node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "node_modules/eth-gas-reporter/node_modules/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, - "dependencies": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eth-gas-reporter/node_modules/yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "dependencies": { - "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" - } - }, "node_modules/eth-gas-reporter/node_modules/yargs-unparser": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", @@ -9169,6 +8986,7 @@ "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==", + "deprecated": "Deprecated in favor of '@metamask/eth-sig-util'", "dev": true, "dependencies": { "ethereumjs-abi": "0.6.8", @@ -9883,6 +9701,13 @@ "node": ">=4" } }, + "node_modules/ethereumjs-testrpc/node_modules/require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true, + "optional": true + }, "node_modules/ethereumjs-testrpc/node_modules/shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", @@ -10076,13 +9901,6 @@ "which": "bin/which" } }, - "node_modules/ethereumjs-testrpc/node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true, - "optional": true - }, "node_modules/ethereumjs-testrpc/node_modules/window-size": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", @@ -11016,6 +10834,36 @@ "node": ">= 0.10.0" } }, + "node_modules/express/node_modules/body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "dev": true, + "dependencies": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/node_modules/bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/express/node_modules/cookie": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", @@ -11034,6 +10882,28 @@ "ms": "2.0.0" } }, + "node_modules/express/node_modules/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, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, "node_modules/express/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -11049,12 +10919,42 @@ "node": ">=0.6" } }, + "node_modules/express/node_modules/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==", + "dev": true, + "dependencies": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/express/node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, + "node_modules/express/node_modules/setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "dev": true + }, + "node_modules/express/node_modules/toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, "node_modules/ext": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/ext/-/ext-1.6.0.tgz", @@ -11181,9 +11081,9 @@ "optional": true }, "node_modules/fast-check": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-2.18.0.tgz", - "integrity": "sha512-7KKUw0wtAJOVrJ1DgmFILd9EmeqMLGtfe5HoEtkYZfYIxohm6Zy7zPq1Zl8t6tPL8A3e86YZrheyGg2m5j8cLA==", + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-2.20.0.tgz", + "integrity": "sha512-tFNjLyPnOUg6iimVxOtoWMJOIyybCo7B8gUGm1yv43jDCQ0hlPUn0fmna/XO/n1yPxn/dxQw3+IygPSbMDiiog==", "dev": true, "optional": true, "dependencies": { @@ -11677,9 +11577,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.14.4", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.4.tgz", - "integrity": "sha512-zwGkiSXC1MUJG/qmeIFH2HBJx9u0V46QGUe3YR1fXG8bXQxq7fLj0RjLZQ5nubr9qNJUZrH+xUcwXEoXNpfS+g==", + "version": "1.14.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.6.tgz", + "integrity": "sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A==", "dev": true, "funding": [ { @@ -11701,6 +11601,7 @@ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", "dev": true, + "peer": true, "dependencies": { "is-callable": "^1.1.3" } @@ -11840,6 +11741,15 @@ "node": ">=10" } }, + "node_modules/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, + "dependencies": { + "minipass": "^2.6.0" + } + }, "node_modules/fs-readdir-recursive": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", @@ -13201,9 +13111,9 @@ } }, "node_modules/globby/node_modules/ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.9.tgz", + "integrity": "sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ==", "dev": true, "engines": { "node": ">= 4" @@ -13373,18 +13283,444 @@ } }, "node_modules/hardhat-gas-reporter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.4.tgz", - "integrity": "sha512-G376zKh81G3K9WtDA+SoTLWsoygikH++tD1E7llx+X7J+GbIqfwhDKKgvJjcnEesMrtR9UqQHK02lJuXY1RTxw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.6.tgz", + "integrity": "sha512-LlCEmSx1dZpnxKmODb2hmP5eJ1IAM5It3NnBNTUpBTxn9g9qPPI3JQTxj8AbGEiNc3r6V+w/mXYCmiC8pWvnoQ==", "dev": true, "dependencies": { - "eth-gas-reporter": "^0.2.20", + "array-uniq": "1.0.3", + "eth-gas-reporter": "^0.2.23", "sha1": "^1.1.1" }, "peerDependencies": { "hardhat": "^2.0.2" } }, + "node_modules/hardhat-interact": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/hardhat-interact/-/hardhat-interact-0.2.0.tgz", + "integrity": "sha512-MiqTv3r2zYwdhOdZE9uKprw8Ig/nO5Ww69jhPzFG2wsd7A9CAuSfUYDUUQEi+u6FeosXYkqpgcj1Vj9T49k/zA==", + "dev": true, + "dependencies": { + "@synthetixio/wei": "^2.53.0-alpha2", + "axios": "^0.24.0", + "chalk": "^4.0.0", + "ethers": "^5.5.1", + "lodash": "^4.17.21", + "prompts": "^2.4.2" + }, + "peerDependencies": { + "@nomiclabs/hardhat-ethers": "^2.0.0", + "hardhat": "^2.0.0" + } + }, + "node_modules/hardhat-interact/node_modules/@ethersproject/basex": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.5.0.tgz", + "integrity": "sha512-ZIodwhHpVJ0Y3hUCfUucmxKsWQA5TMnavp5j/UOuDdzZWzJlRmuOjcTMIGgHCYuZmHt36BfiSyQPSRskPxbfaQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/properties": "^5.5.0" + } + }, + "node_modules/hardhat-interact/node_modules/@ethersproject/hdnode": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.5.0.tgz", + "integrity": "sha512-mcSOo9zeUg1L0CoJH7zmxwUG5ggQHU1UrRf8jyTYy6HxdZV+r0PBoL1bxr+JHIPXRzS6u/UW4mEn43y0tmyF8Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@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" + } + }, + "node_modules/hardhat-interact/node_modules/@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==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@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" + } + }, + "node_modules/hardhat-interact/node_modules/@ethersproject/pbkdf2": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.5.0.tgz", + "integrity": "sha512-SaDvQFvXPnz1QGpzr6/HToLifftSXGoXrbpZ6BvoZhmx4bNLHrxDe8MZisuecyOziP1aVEwzC2Hasj+86TgWVg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/sha2": "^5.5.0" + } + }, + "node_modules/hardhat-interact/node_modules/@ethersproject/providers": { + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.5.1.tgz", + "integrity": "sha512-2zdD5sltACDWhjUE12Kucg2PcgM6V2q9JMyVvObtVGnzJu+QSmibbP+BHQyLWZUBfLApx2942+7DC5D+n4wBQQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@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" + } + }, + "node_modules/hardhat-interact/node_modules/@ethersproject/random": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.5.0.tgz", + "integrity": "sha512-egGYZwZ/YIFKMHcoBUo8t3a8Hb/TKYX8BCBoLjudVCZh892welR3jOxgOmb48xznc9bTcMm7Tpwc1gHC1PFNFQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/hardhat-interact/node_modules/@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==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "hash.js": "1.1.7" + } + }, + "node_modules/hardhat-interact/node_modules/@ethersproject/solidity": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.5.0.tgz", + "integrity": "sha512-9NgZs9LhGMj6aCtHXhtmFQ4AN4sth5HuFXVvAQtzmm0jpSCNOTGtrHZJAeYTh7MBjRR8brylWZxBZR9zDStXbw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@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" + } + }, + "node_modules/hardhat-interact/node_modules/@ethersproject/units": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.5.0.tgz", + "integrity": "sha512-7+DpjiZk4v6wrikj+TCyWWa9dXLNU73tSTa7n0TSJDxkYbV3Yf1eRh9ToMLlZtuctNYu9RDNNy2USq3AdqSbag==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/hardhat-interact/node_modules/@ethersproject/wallet": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.5.0.tgz", + "integrity": "sha512-Mlu13hIctSYaZmUOo7r2PhNSd8eaMPVXe1wxrz4w4FCE4tDYBywDH+bAR1Xz2ADyXGwqYMwstzTrtUVIsKDO0Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@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" + } + }, + "node_modules/hardhat-interact/node_modules/@ethersproject/wordlists": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.5.0.tgz", + "integrity": "sha512-bL0UTReWDiaQJJYOC9sh/XcRu/9i2jMrzf8VLRmPKx58ckSlOJiohODkECCO50dtLZHcGU6MLXQ4OOrgBwP77Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@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" + } + }, + "node_modules/hardhat-interact/node_modules/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, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/hardhat-interact/node_modules/axios": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz", + "integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==", + "dev": true, + "dependencies": { + "follow-redirects": "^1.14.4" + } + }, + "node_modules/hardhat-interact/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/hardhat-interact/node_modules/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, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/hardhat-interact/node_modules/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 + }, + "node_modules/hardhat-interact/node_modules/ethers": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.5.2.tgz", + "integrity": "sha512-EF5W+6Wwcu6BqVwpgmyR5U2+L4c1FQzlM/02dkZOugN3KF0cG9bzHZP+TDJglmPm2/IzCEJDT7KBxzayk7SAHw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@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.1", + "@ethersproject/pbkdf2": "5.5.0", + "@ethersproject/properties": "5.5.0", + "@ethersproject/providers": "5.5.1", + "@ethersproject/random": "5.5.0", + "@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" + } + }, + "node_modules/hardhat-interact/node_modules/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/hardhat-interact/node_modules/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/hardhat/node_modules/abstract-leveldown": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.3.0.tgz", @@ -13410,26 +13746,6 @@ "node": ">=6" } }, - "node_modules/hardhat/node_modules/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, - "engines": { - "node": ">=6" - } - }, - "node_modules/hardhat/node_modules/cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "dependencies": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, "node_modules/hardhat/node_modules/commander": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", @@ -13474,12 +13790,6 @@ "node": ">=0.3.1" } }, - "node_modules/hardhat/node_modules/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 - }, "node_modules/hardhat/node_modules/encoding-down": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-6.3.0.tgz", @@ -13861,12 +14171,6 @@ "node": ">= 8" } }, - "node_modules/hardhat/node_modules/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 - }, "node_modules/hardhat/node_modules/resolve": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", @@ -13942,32 +14246,6 @@ "semver": "bin/semver" } }, - "node_modules/hardhat/node_modules/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, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/hardhat/node_modules/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, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/hardhat/node_modules/strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", @@ -14010,44 +14288,6 @@ "which": "bin/which" } }, - "node_modules/hardhat/node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "node_modules/hardhat/node_modules/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, - "dependencies": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/hardhat/node_modules/yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "dependencies": { - "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" - } - }, "node_modules/hardhat/node_modules/yargs-unparser": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", @@ -14062,18 +14302,6 @@ "node": ">=6" } }, - "node_modules/hardhat/node_modules/yargs/node_modules/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, - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -14347,16 +14575,16 @@ "dev": true }, "node_modules/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": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", "dev": true, "dependencies": { "depd": "~1.1.2", "inherits": "2.0.4", - "setprototypeof": "1.1.1", + "setprototypeof": "1.2.0", "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" + "toidentifier": "1.0.1" }, "engines": { "node": ">= 0.6" @@ -15253,9 +15481,9 @@ } }, "node_modules/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, "engines": { "node": ">= 0.4" @@ -15446,12 +15674,12 @@ "optional": true }, "node_modules/is-weakref": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.1.tgz", - "integrity": "sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.0" + "call-bind": "^1.0.2" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -15616,9 +15844,9 @@ "dev": true }, "node_modules/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 }, "node_modules/json-schema-traverse": { @@ -15694,18 +15922,18 @@ } }, "node_modules/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, - "engines": [ - "node >=0.6.0" - ], "dependencies": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", - "json-schema": "0.2.3", + "json-schema": "0.4.0", "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" } }, "node_modules/keccak": { @@ -15749,6 +15977,15 @@ "graceful-fs": "^4.1.9" } }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/lazy-cache": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", @@ -15985,9 +16222,9 @@ } }, "node_modules/lines-and-columns": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, "node_modules/load-json-file": { @@ -16621,21 +16858,21 @@ } }, "node_modules/mime-db": { - "version": "1.50.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz", - "integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==", + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { - "version": "2.1.33", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz", - "integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==", + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", "dev": true, "dependencies": { - "mime-db": "1.50.0" + "mime-db": "1.51.0" }, "engines": { "node": ">= 0.6" @@ -16703,6 +16940,25 @@ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, + "node_modules/minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "node_modules/minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "dev": true, + "dependencies": { + "minipass": "^2.9.0" + } + }, "node_modules/mississippi": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", @@ -16763,12 +17019,12 @@ } }, "node_modules/mnemonist": { - "version": "0.38.4", - "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.4.tgz", - "integrity": "sha512-mflgW0gEWmVLbDDE2gJbOh3+RltTN7CgV9jV25qyCnyLN9FtoltWr7ZtAEDeD9u8W4oFAoolR6fBWieXdn3u8Q==", + "version": "0.38.5", + "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz", + "integrity": "sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==", "dev": true, "dependencies": { - "obliterator": "^1.6.1" + "obliterator": "^2.0.0" } }, "node_modules/mocha": { @@ -16815,15 +17071,6 @@ "url": "https://opencollective.com/mochajs" } }, - "node_modules/mocha/node_modules/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, - "engines": { - "node": ">=6" - } - }, "node_modules/mocha/node_modules/chokidar": { "version": "3.4.2", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.2.tgz", @@ -16845,17 +17092,6 @@ "fsevents": "~2.1.2" } }, - "node_modules/mocha/node_modules/cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "dependencies": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, "node_modules/mocha/node_modules/debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", @@ -16866,12 +17102,6 @@ "ms": "^2.1.1" } }, - "node_modules/mocha/node_modules/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 - }, "node_modules/mocha/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -17023,15 +17253,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mocha/node_modules/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, - "engines": { - "node": ">=6" - } - }, "node_modules/mocha/node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -17053,38 +17274,6 @@ "node": ">=8.10.0" } }, - "node_modules/mocha/node_modules/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 - }, - "node_modules/mocha/node_modules/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, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/mocha/node_modules/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, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/mocha/node_modules/strip-json-comments": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", @@ -17106,105 +17295,6 @@ "node": ">=8" } }, - "node_modules/mocha/node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "node_modules/mocha/node_modules/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, - "dependencies": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/mocha/node_modules/yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "dependencies": { - "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" - } - }, - "node_modules/mocha/node_modules/yargs/node_modules/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, - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/mocha/node_modules/yargs/node_modules/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, - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/mocha/node_modules/yargs/node_modules/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, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/yargs/node_modules/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, - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/mocha/node_modules/yargs/node_modules/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, - "engines": { - "node": ">=4" - } - }, "node_modules/mock-fs": { "version": "4.14.0", "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.14.0.tgz", @@ -17530,9 +17620,9 @@ } }, "node_modules/node-fetch": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz", - "integrity": "sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==", + "version": "2.6.6", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.6.tgz", + "integrity": "sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA==", "dev": true, "dependencies": { "whatwg-url": "^5.0.0" @@ -17660,6 +17750,18 @@ "node": ">=8" } }, + "node_modules/nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, "node_modules/normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -17859,9 +17961,9 @@ } }, "node_modules/object-inspect": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", - "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.1.tgz", + "integrity": "sha512-If7BjFlpkzzBeV1cqgT3OSWT3azyoxDGajR+iGnFBfVV2EWyDyWaZZW2ERDjUaY2QM8i5jI3Sj7mhsM4DDAqWA==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -17953,9 +18055,9 @@ } }, "node_modules/obliterator": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-1.6.1.tgz", - "integrity": "sha512-9WXswnqINnnhOG/5SLimUlzuU1hFJUc8zkwyD59Sd+dPOMf05PmnYG/d6Q7HZ+KmgkZJa1PxRso6QdM3sTNHig==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.1.tgz", + "integrity": "sha512-XnkiCrrBcIZQitJPAI36mrrpEUvatbte8hLcTcQwKA1v9NkCKasSi+UAguLsLDs/out7MoRzAlmz7VXvY6ph6w==", "dev": true }, "node_modules/oboe": { @@ -18574,9 +18676,9 @@ } }, "node_modules/prettier-plugin-solidity/node_modules/prettier": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.4.1.tgz", - "integrity": "sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz", + "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==", "dev": true, "bin": { "prettier": "bin-prettier.js" @@ -18704,9 +18806,9 @@ } }, "node_modules/pretty-quick/node_modules/ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.9.tgz", + "integrity": "sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ==", "dev": true, "engines": { "node": ">= 4" @@ -18859,6 +18961,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -18957,9 +19072,9 @@ } }, "node_modules/qs": { - "version": "6.10.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", - "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.2.tgz", + "integrity": "sha512-mSIdjzqznWgfd4pMii7sHtaYF8rx8861hBO80SraY5GT0XQibWZWJSid0avzHGkDIZLImux2S5mXO0Hfct2QCw==", "dev": true, "dependencies": { "side-channel": "^1.0.4" @@ -19051,13 +19166,13 @@ } }, "node_modules/raw-body": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.1.tgz", - "integrity": "sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz", + "integrity": "sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==", "dev": true, "dependencies": { - "bytes": "3.1.0", - "http-errors": "1.7.3", + "bytes": "3.1.1", + "http-errors": "1.8.1", "iconv-lite": "0.4.24", "unpipe": "1.0.0" }, @@ -19485,11 +19600,10 @@ } }, "node_modules/require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true, - "optional": true + "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 }, "node_modules/resolve": { "version": "1.20.0", @@ -19835,12 +19949,6 @@ "istanbul": "lib/cli.js" } }, - "node_modules/sc-istanbul/node_modules/abbrev": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", - "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", - "dev": true - }, "node_modules/sc-istanbul/node_modules/async": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", @@ -19885,18 +19993,6 @@ "node": ">=0.10.0" } }, - "node_modules/sc-istanbul/node_modules/nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", - "dev": true, - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - } - }, "node_modules/sc-istanbul/node_modules/resolve": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", @@ -20048,12 +20144,43 @@ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, + "node_modules/send/node_modules/http-errors": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", + "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/send/node_modules/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 }, + "node_modules/send/node_modules/setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "dev": true + }, + "node_modules/send/node_modules/toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, "node_modules/sentence-case": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-2.1.1.tgz", @@ -20153,9 +20280,9 @@ "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" }, "node_modules/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 }, "node_modules/sha.js": { @@ -20271,9 +20398,9 @@ } }, "node_modules/signal-exit": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", - "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==" + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", + "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==" }, "node_modules/simple-concat": { "version": "1.0.1", @@ -20304,6 +20431,12 @@ "simple-concat": "^1.0.0" } }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -21098,9 +21231,9 @@ } }, "node_modules/solidity-coverage/node_modules/web3-utils": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.6.0.tgz", - "integrity": "sha512-bgCAWAeQnJF035YTFxrcHJ5mGEfTi/McsjqldZiXRwlHK7L1PyOqvXiQLE053dlzvy1kdAxWl/sSSfLMyNUAXg==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.6.1.tgz", + "integrity": "sha512-RidGKv5kOkcerI6jQqDFDoTllQQqV+rPhTzZHhmbqtFObbYpU93uc+yG1LHivRTQhA6llIx67iudc/vzisgO+w==", "dev": true, "dependencies": { "bn.js": "^4.11.9", @@ -21159,9 +21292,9 @@ } }, "node_modules/source-map-support": { - "version": "0.5.20", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", - "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, "dependencies": { "buffer-from": "^1.0.0", @@ -21216,9 +21349,9 @@ } }, "node_modules/spdx-license-ids": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz", - "integrity": "sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==", + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", + "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==", "dev": true }, "node_modules/split-string": { @@ -21725,12 +21858,6 @@ "xhr-request": "^1.0.1" } }, - "node_modules/swarm-js/node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, "node_modules/swarm-js/node_modules/fs-extra": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", @@ -21742,15 +21869,6 @@ "universalify": "^0.1.0" } }, - "node_modules/swarm-js/node_modules/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, - "dependencies": { - "minipass": "^2.6.0" - } - }, "node_modules/swarm-js/node_modules/get-stream": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", @@ -21803,25 +21921,6 @@ "graceful-fs": "^4.1.6" } }, - "node_modules/swarm-js/node_modules/minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "node_modules/swarm-js/node_modules/minizlib": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", - "dev": true, - "dependencies": { - "minipass": "^2.9.0" - } - }, "node_modules/swarm-js/node_modules/p-cancelable": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", @@ -21840,24 +21939,6 @@ "node": ">=0.10.0" } }, - "node_modules/swarm-js/node_modules/tar": { - "version": "4.4.19", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", - "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", - "dev": true, - "dependencies": { - "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" - }, - "engines": { - "node": ">=4.5" - } - }, "node_modules/swarm-js/node_modules/universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -21967,6 +22048,24 @@ "node": ">=6" } }, + "node_modules/tar": { + "version": "4.4.19", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", + "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", + "dev": true, + "dependencies": { + "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" + }, + "engines": { + "node": ">=4.5" + } + }, "node_modules/terser": { "version": "4.8.0", "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz", @@ -22239,9 +22338,9 @@ } }, "node_modules/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, "engines": { "node": ">=0.6" @@ -22322,9 +22421,9 @@ } }, "node_modules/tsconfig-paths": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz", - "integrity": "sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz", + "integrity": "sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==", "dev": true, "dependencies": { "@types/json5": "^0.0.29", @@ -22452,9 +22551,9 @@ } }, "node_modules/typescript": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", - "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==", + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz", + "integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==", "dev": true, "peer": true, "bin": { @@ -22466,9 +22565,9 @@ } }, "node_modules/uglify-js": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.14.2.tgz", - "integrity": "sha512-rtPMlmcO4agTUfz10CbgJ1k6UAoXM2gWb3GoMPPZB/+/Ackf8lNWk11K4rYi2D0apgoFRLtQOZhb+/iGNJq26A==", + "version": "3.14.5", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.14.5.tgz", + "integrity": "sha512-qZukoSxOG0urUTvjc2ERMTcAy+BiFh3weWAkeurLwjrCba73poHmG3E36XEjd/JGukMzwTL7uCxZiAexj8ppvQ==", "dev": true, "optional": true, "bin": { @@ -22507,9 +22606,9 @@ } }, "node_modules/underscore": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.1.tgz", - "integrity": "sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.2.tgz", + "integrity": "sha512-ekY1NhRzq0B08g4bGuX4wd2jZx5GnKz6mKSqFL4nqBlfyMGiG10gDFhDTMEfYmDL6Jy0FUIZp7wiRB+0BP7J2g==", "dev": true }, "node_modules/union-value": { @@ -22769,6 +22868,7 @@ "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.1.1.tgz", "integrity": "sha512-/s3UsZUrIfa6xDhr7zZhnE9SLQ5RIXyYfiVnMMyMDzOc8WhWN4Nbh36H842OyurKbCDAesZOJaVyvmSl6fhGQw==", "dev": true, + "peer": true, "dependencies": { "call-bind": "^1.0.0", "define-properties": "^1.1.3", @@ -23251,9 +23351,9 @@ } }, "node_modules/web3-bzz/node_modules/@types/node": { - "version": "12.20.33", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.33.tgz", - "integrity": "sha512-5XmYX2GECSa+CxMYaFsr2mrql71Q4EvHjKS+ox/SiwSdaASMoBIWE6UmZqFO+VX1jIcsYLStI4FFoB6V7FeIYw==", + "version": "12.20.37", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.37.tgz", + "integrity": "sha512-i1KGxqcvJaLQali+WuypQnXwcplhtNtjs66eNsZpp2P2FL/trJJxx/VWsM0YCL2iMoIJrbXje48lvIQAQ4p2ZA==", "dev": true }, "node_modules/web3-bzz/node_modules/underscore": { @@ -23281,14 +23381,14 @@ } }, "node_modules/web3-core-helpers": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.6.0.tgz", - "integrity": "sha512-H/IAH/0mrgvad/oxVKiAMC7qDzMrPPe/nRKmJOoIsupRg9/frvL62kZZiHhqVD1HMyyswbQFC69QRl7JqWzvxg==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.6.1.tgz", + "integrity": "sha512-om2PZvK1uoWcgMq6JfcSx3241LEIVF6qi2JuHz2SLKiKEW5UsBUaVx0mNCmcZaiuYQCyOsLS3r33q5AdM+v8ng==", "dev": true, "peer": true, "dependencies": { - "web3-eth-iban": "1.6.0", - "web3-utils": "1.6.0" + "web3-eth-iban": "1.6.1", + "web3-utils": "1.6.1" }, "engines": { "node": ">=8.0.0" @@ -23302,9 +23402,9 @@ "peer": true }, "node_modules/web3-core-helpers/node_modules/web3-utils": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.6.0.tgz", - "integrity": "sha512-bgCAWAeQnJF035YTFxrcHJ5mGEfTi/McsjqldZiXRwlHK7L1PyOqvXiQLE053dlzvy1kdAxWl/sSSfLMyNUAXg==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.6.1.tgz", + "integrity": "sha512-RidGKv5kOkcerI6jQqDFDoTllQQqV+rPhTzZHhmbqtFObbYpU93uc+yG1LHivRTQhA6llIx67iudc/vzisgO+w==", "dev": true, "peer": true, "dependencies": { @@ -23419,9 +23519,9 @@ } }, "node_modules/web3-core-promievent": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.6.0.tgz", - "integrity": "sha512-ZzsevjMXWkhqW9dnVfTfb1OUcK7jKcKPvPIbQ4boJccNgvNZPZKlo8xB4pkAX38n4c59O5mC7Lt/z2QL/M5CeQ==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.6.1.tgz", + "integrity": "sha512-byJ5s2MQxrWdXd27pWFmujfzsTZK4ik8rDgIV1RFDFc+rHZ2nZhq+VWk7t/Nkrj7EaVXncEgTdPEHc18nx+ocQ==", "dev": true, "peer": true, "dependencies": { @@ -23610,15 +23710,15 @@ } }, "node_modules/web3-core/node_modules/@types/node": { - "version": "12.20.33", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.33.tgz", - "integrity": "sha512-5XmYX2GECSa+CxMYaFsr2mrql71Q4EvHjKS+ox/SiwSdaASMoBIWE6UmZqFO+VX1jIcsYLStI4FFoB6V7FeIYw==", + "version": "12.20.37", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.37.tgz", + "integrity": "sha512-i1KGxqcvJaLQali+WuypQnXwcplhtNtjs66eNsZpp2P2FL/trJJxx/VWsM0YCL2iMoIJrbXje48lvIQAQ4p2ZA==", "dev": true }, "node_modules/web3-core/node_modules/bignumber.js": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", - "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", + "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", "dev": true, "engines": { "node": "*" @@ -23718,12 +23818,12 @@ } }, "node_modules/web3-eth-abi": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.6.0.tgz", - "integrity": "sha512-fImomGE9McuTMJLwK8Tp0lTUzXqCkWeMm00qPVIwpJ/h7lCw9UFYV9+4m29wSqW6FF+FIZKwc6UBEf9dlx3orA==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.6.1.tgz", + "integrity": "sha512-svhYrAlXP9XQtV7poWKydwDJq2CaNLMtmKydNXoOBLcQec6yGMP+v20pgrxF2H6wyTK+Qy0E3/5ciPOqC/VuoQ==", "dependencies": { "@ethersproject/abi": "5.0.7", - "web3-utils": "1.6.0" + "web3-utils": "1.6.1" }, "engines": { "node": ">=8.0.0" @@ -23751,9 +23851,9 @@ "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" }, "node_modules/web3-eth-abi/node_modules/web3-utils": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.6.0.tgz", - "integrity": "sha512-bgCAWAeQnJF035YTFxrcHJ5mGEfTi/McsjqldZiXRwlHK7L1PyOqvXiQLE053dlzvy1kdAxWl/sSSfLMyNUAXg==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.6.1.tgz", + "integrity": "sha512-RidGKv5kOkcerI6jQqDFDoTllQQqV+rPhTzZHhmbqtFObbYpU93uc+yG1LHivRTQhA6llIx67iudc/vzisgO+w==", "dependencies": { "bn.js": "^4.11.9", "ethereum-bloom-filters": "^1.0.6", @@ -24142,14 +24242,14 @@ } }, "node_modules/web3-eth-iban": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.6.0.tgz", - "integrity": "sha512-HM/bKBS/e8qg0+Eh7B8C/JVG+GkR4AJty17DKRuwMtrh78YsonPj7GKt99zS4n5sDLFww1Imu/ZIk3+K5uJCjw==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.6.1.tgz", + "integrity": "sha512-91H0jXZnWlOoXmc13O9NuQzcjThnWyAHyDn5Yf7u6mmKOhpJSGF/OHlkbpXt1Y4v2eJdEPaVFa+6i8aRyagE7Q==", "dev": true, "peer": true, "dependencies": { "bn.js": "^4.11.9", - "web3-utils": "1.6.0" + "web3-utils": "1.6.1" }, "engines": { "node": ">=8.0.0" @@ -24163,9 +24263,9 @@ "peer": true }, "node_modules/web3-eth-iban/node_modules/web3-utils": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.6.0.tgz", - "integrity": "sha512-bgCAWAeQnJF035YTFxrcHJ5mGEfTi/McsjqldZiXRwlHK7L1PyOqvXiQLE053dlzvy1kdAxWl/sSSfLMyNUAXg==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.6.1.tgz", + "integrity": "sha512-RidGKv5kOkcerI6jQqDFDoTllQQqV+rPhTzZHhmbqtFObbYpU93uc+yG1LHivRTQhA6llIx67iudc/vzisgO+w==", "dev": true, "peer": true, "dependencies": { @@ -24199,9 +24299,9 @@ } }, "node_modules/web3-eth-personal/node_modules/@types/node": { - "version": "12.20.33", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.33.tgz", - "integrity": "sha512-5XmYX2GECSa+CxMYaFsr2mrql71Q4EvHjKS+ox/SiwSdaASMoBIWE6UmZqFO+VX1jIcsYLStI4FFoB6V7FeIYw==", + "version": "12.20.37", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.37.tgz", + "integrity": "sha512-i1KGxqcvJaLQali+WuypQnXwcplhtNtjs66eNsZpp2P2FL/trJJxx/VWsM0YCL2iMoIJrbXje48lvIQAQ4p2ZA==", "dev": true }, "node_modules/web3-eth-personal/node_modules/bn.js": { @@ -24843,26 +24943,6 @@ "webpack": "4.x.x" } }, - "node_modules/webpack-cli/node_modules/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, - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack-cli/node_modules/cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "dependencies": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, "node_modules/webpack-cli/node_modules/cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -24879,73 +24959,6 @@ "node": ">=4.8" } }, - "node_modules/webpack-cli/node_modules/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 - }, - "node_modules/webpack-cli/node_modules/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, - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack-cli/node_modules/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, - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack-cli/node_modules/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, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/webpack-cli/node_modules/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, - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack-cli/node_modules/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, - "engines": { - "node": ">=6" - } - }, "node_modules/webpack-cli/node_modules/path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", @@ -24955,12 +24968,6 @@ "node": ">=4" } }, - "node_modules/webpack-cli/node_modules/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 - }, "node_modules/webpack-cli/node_modules/semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", @@ -24991,32 +24998,6 @@ "node": ">=0.10.0" } }, - "node_modules/webpack-cli/node_modules/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, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack-cli/node_modules/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, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/webpack-cli/node_modules/supports-color": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", @@ -25041,44 +25022,6 @@ "which": "bin/which" } }, - "node_modules/webpack-cli/node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "node_modules/webpack-cli/node_modules/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, - "dependencies": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack-cli/node_modules/yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "dependencies": { - "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" - } - }, "node_modules/webpack-sources": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", @@ -25333,11 +25276,10 @@ } }, "node_modules/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, - "optional": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true }, "node_modules/which-pm-runs": { "version": "1.0.0", @@ -25417,6 +25359,61 @@ "integrity": "sha512-fU2OcNA/GVAJLLyKUoHkAgIhKb0JoCpSjLC/G2vYKxUjVmQwGbRVeoPJ1a8U4pnVofz4AQV5Y/NEw8oKqxEBtA==", "dev": true }, + "node_modules/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, + "dependencies": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/wrap-ansi/node_modules/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, + "engines": { + "node": ">=6" + } + }, + "node_modules/wrap-ansi/node_modules/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 + }, + "node_modules/wrap-ansi/node_modules/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, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/wrap-ansi/node_modules/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, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -28911,6 +28908,24 @@ "node": ">=6" } }, + "node_modules/yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "dependencies": { + "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" + } + }, "node_modules/yargs-parser": { "version": "13.1.2", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", @@ -28964,17 +28979,6 @@ "node": ">=6" } }, - "node_modules/yargs-unparser/node_modules/cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "dependencies": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, "node_modules/yargs-unparser/node_modules/emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", @@ -29042,12 +29046,6 @@ "node": ">=6" } }, - "node_modules/yargs-unparser/node_modules/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 - }, "node_modules/yargs-unparser/node_modules/string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", @@ -29074,26 +29072,6 @@ "node": ">=6" } }, - "node_modules/yargs-unparser/node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "node_modules/yargs-unparser/node_modules/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, - "dependencies": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/yargs-unparser/node_modules/yargs": { "version": "14.2.3", "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.3.tgz", @@ -29123,6 +29101,108 @@ "decamelize": "^1.2.0" } }, + "node_modules/yargs/node_modules/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, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/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 + }, + "node_modules/yargs/node_modules/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, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/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, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/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, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs/node_modules/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, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/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, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/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, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/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, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", @@ -29147,12 +29227,12 @@ }, "dependencies": { "@babel/code-frame": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", - "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz", + "integrity": "sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==", "dev": true, "requires": { - "@babel/highlight": "^7.14.5" + "@babel/highlight": "^7.16.0" } }, "@babel/helper-validator-identifier": { @@ -29162,20 +29242,20 @@ "dev": true }, "@babel/highlight": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", - "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.0.tgz", + "integrity": "sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.14.5", + "@babel/helper-validator-identifier": "^7.15.7", "chalk": "^2.0.0", "js-tokens": "^4.0.0" } }, "@babel/runtime": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.4.tgz", - "integrity": "sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.5.tgz", + "integrity": "sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA==", "dev": true, "optional": true, "requires": { @@ -29551,6 +29631,13 @@ "dev": true, "optional": 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=", + "dev": true, + "optional": true + }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", @@ -29594,6 +29681,13 @@ "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, + "optional": true + }, "wrap-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", @@ -29726,15 +29820,15 @@ } }, "@ethereumjs/block": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/@ethereumjs/block/-/block-3.5.1.tgz", - "integrity": "sha512-MoY9bHKABOBK6BW0v1N1Oc0Cve4x/giX67M3TtrVBUsKQTj2eznLGKpydoitxWSZ+WgKKSVhfRMzbCGRwk7T5w==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/block/-/block-3.6.0.tgz", + "integrity": "sha512-dqLo1LtsLG+Oelu5S5tWUDG0pah3QUwV5TJZy2cm19BXDr4ka/S9XBSgao0i09gTcuPlovlHgcs6d7EZ37urjQ==", "dev": true, "requires": { - "@ethereumjs/common": "^2.5.0", - "@ethereumjs/tx": "^3.3.1", - "ethereumjs-util": "^7.1.1", - "merkle-patricia-tree": "^4.2.1" + "@ethereumjs/common": "^2.6.0", + "@ethereumjs/tx": "^3.4.0", + "ethereumjs-util": "^7.1.3", + "merkle-patricia-tree": "^4.2.2" }, "dependencies": { "abstract-leveldown": { @@ -29889,19 +29983,18 @@ } }, "@ethereumjs/blockchain": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/@ethereumjs/blockchain/-/blockchain-5.4.2.tgz", - "integrity": "sha512-AOAAwz/lw2lciG9gf5wHi7M/qknraXXnLR66lYgbQ04qfyFC3ZE5x/5rLVm1Vu+kfJLlKrYZTmA0IbOkc7kvgw==", + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/@ethereumjs/blockchain/-/blockchain-5.5.1.tgz", + "integrity": "sha512-JS2jeKxl3tlaa5oXrZ8mGoVBCz6YqsGG350XVNtHAtNZXKk7pU3rH4xzF2ru42fksMMqzFLzKh9l4EQzmNWDqA==", "dev": true, "requires": { - "@ethereumjs/block": "^3.5.1", - "@ethereumjs/common": "^2.5.0", + "@ethereumjs/block": "^3.6.0", + "@ethereumjs/common": "^2.6.0", "@ethereumjs/ethash": "^1.1.0", "debug": "^2.2.0", - "ethereumjs-util": "^7.1.1", + "ethereumjs-util": "^7.1.3", "level-mem": "^5.0.1", "lru-cache": "^5.1.1", - "rlp": "^2.2.4", "semaphore-async-await": "^1.5.1" }, "dependencies": { @@ -30046,13 +30139,13 @@ } }, "@ethereumjs/common": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.5.0.tgz", - "integrity": "sha512-DEHjW6e38o+JmB/NO3GZBpW4lpaiBpkFgXF6jLcJ6gETBYpEyaA5nTimsWBUJR3Vmtm/didUEbNjajskugZORg==", + "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.1" + "ethereumjs-util": "^7.1.3" } }, "@ethereumjs/ethash": { @@ -30069,34 +30162,33 @@ } }, "@ethereumjs/tx": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.3.2.tgz", - "integrity": "sha512-6AaJhwg4ucmwTvw/1qLaZUX5miWrwZ4nLOUsKyb/HtzS3BMw/CasKhdi1ims9mBKeK9sOJCH4qGKOBGyJCeeog==", + "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.5.0", - "ethereumjs-util": "^7.1.2" + "@ethereumjs/common": "^2.6.0", + "ethereumjs-util": "^7.1.3" } }, "@ethereumjs/vm": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/@ethereumjs/vm/-/vm-5.5.3.tgz", - "integrity": "sha512-0k5OreWnlgXYs54wohgO11jtGI05GDasj2EYxzuaStxTi15CS3vow5wGYELC1pG9xngE1F/mFmKi/f14XRuDow==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/vm/-/vm-5.6.0.tgz", + "integrity": "sha512-J2m/OgjjiGdWF2P9bj/4LnZQ1zRoZhY8mRNVw/N3tXliGI8ai1sI1mlDPkLpeUUM4vq54gH6n0ZlSpz8U/qlYQ==", "dev": true, "requires": { - "@ethereumjs/block": "^3.5.0", - "@ethereumjs/blockchain": "^5.4.1", - "@ethereumjs/common": "^2.5.0", - "@ethereumjs/tx": "^3.3.1", + "@ethereumjs/block": "^3.6.0", + "@ethereumjs/blockchain": "^5.5.0", + "@ethereumjs/common": "^2.6.0", + "@ethereumjs/tx": "^3.4.0", "async-eventemitter": "^0.2.4", "core-js-pure": "^3.0.1", "debug": "^2.2.0", - "ethereumjs-util": "^7.1.1", + "ethereumjs-util": "^7.1.3", "functional-red-black-tree": "^1.0.1", "mcl-wasm": "^0.7.1", - "merkle-patricia-tree": "^4.2.1", - "rustbn.js": "~0.2.0", - "util.promisify": "^1.0.1" + "merkle-patricia-tree": "^4.2.2", + "rustbn.js": "~0.2.0" }, "dependencies": { "abstract-leveldown": { @@ -30460,9 +30552,9 @@ "integrity": "sha512-rIY/6WPm7T8n3qS2vuHTUBPdXHl+rGxWxW5okDfo9J4Z0+gRRZT0msvUdIJkE4/HS29GUMziwGaaKO2bWONBrg==" }, "@ethersproject/networks": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.5.0.tgz", - "integrity": "sha512-KWfP3xOnJeF89Uf/FCJdV1a2aDJe5XTN2N52p4fcQ34QhDqQFkgQKZ39VGtiqUgHcLI8DfT0l9azC3KFTunqtA==", + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.5.1.tgz", + "integrity": "sha512-tYRDM4zZtSUcKnD4UMuAlj7SeXH/k5WC4SP2u1Pn57++JdXHkRu2zwNkgNogZoxHzhm9Q6qqurDBVptHOsW49Q==", "requires": { "@ethersproject/logger": "^5.5.0" } @@ -30636,9 +30728,9 @@ } }, "@ethersproject/web": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.5.0.tgz", - "integrity": "sha512-BEgY0eL5oH4mAo37TNYVrFeHsIXLRxggCRG/ksRIxI2X5uj5IsjGmcNiRN/VirQOlBxcUhCgHhaDLG4m6XAVoA==", + "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", @@ -30765,9 +30857,9 @@ } }, "@nomiclabs/hardhat-ethers": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.0.2.tgz", - "integrity": "sha512-6quxWe8wwS4X5v3Au8q1jOvXYEPkS1Fh+cME5u6AwNdnI4uERvPlVjlgRWzpnb+Rrt1l/cEqiNRH9GlsBMSDQg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.0.3.tgz", + "integrity": "sha512-IJ0gBotVtO7YyLZyHNgbxzskUtFok+JkRlKPo8YELqj1ms9XL6Qm3vsfsGdZr22wnJeVEF5TQPotKuwQk21Dag==", "dev": true, "requires": {} }, @@ -31111,6 +31203,24 @@ "integrity": "sha512-H8BSBoKE8EubJa0ONqecA2TviT3TnHeC4NpgnAHSUiuhZoQBfPB4L2P9bs8R6AoTW10Endvh3vc+fomVMIDIYQ==", "dev": true }, + "@synthetixio/wei": { + "version": "2.56.3", + "resolved": "https://registry.npmjs.org/@synthetixio/wei/-/wei-2.56.3.tgz", + "integrity": "sha512-eJu5G/z/o6QyCEwe2Ovby/w4zmpoSM/tn0gcMkibzADqNMqM8afBVvSF5YM4whnf3/lWjEfeDFqHI62XnR5wqw==", + "dev": true, + "requires": { + "big.js": "6.1.1", + "ethers": "5.4.6" + }, + "dependencies": { + "big.js": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-6.1.1.tgz", + "integrity": "sha512-1vObw81a8ylZO5ePrtMay0n018TcftpTA5HFKDaSuiUDBo8biRBtjIobw60OpwuvrGk+FsxKamqN4cnmj/eXdg==", + "dev": true + } + } + }, "@szmarczak/http-timer": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", @@ -31121,9 +31231,9 @@ } }, "@truffle/abi-utils": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@truffle/abi-utils/-/abi-utils-0.2.4.tgz", - "integrity": "sha512-ICr5Sger6r5uj2G5GN9Zp9OQDCaCqe2ZyAEyvavDoFB+jX0zZFUCfDnv5jllGRhgzdYJ3mec2390mjUyz9jSZA==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@truffle/abi-utils/-/abi-utils-0.2.5.tgz", + "integrity": "sha512-eKDIn9LqUFP8MnHVohe8ncuza4p9bszz1NtJWc+sr5zUogtmWnnf8Ajyj7JJpNKhLNDVZVbLowVEVxWzSSpMHw==", "dev": true, "optional": true, "requires": { @@ -31203,9 +31313,9 @@ } }, "@truffle/compile-common": { - "version": "0.7.22", - "resolved": "https://registry.npmjs.org/@truffle/compile-common/-/compile-common-0.7.22.tgz", - "integrity": "sha512-afFKh0Wphn8JrCSjOORKjO8/E1X0EtQv6GpFJpQCAWo3/i4VGcSVKR1rjkknnExtjEGe9PJH/Ym/opGH3pQyDw==", + "version": "0.7.23", + "resolved": "https://registry.npmjs.org/@truffle/compile-common/-/compile-common-0.7.23.tgz", + "integrity": "sha512-LWzeboJ9HmSZVgx5DMmKArOo96V4QZhS/+8beDOfeNT1W4QeKfkuVbAM0R77cXjiLnUsNjjFVXehnco6HiF8ww==", "dev": true, "optional": true, "requires": { @@ -31223,19 +31333,20 @@ } }, "@truffle/contract": { - "version": "4.3.38", - "resolved": "https://registry.npmjs.org/@truffle/contract/-/contract-4.3.38.tgz", - "integrity": "sha512-11HL9IJTmd45pVXJvEaRYeyuhf8GmAgRD7bTYBZj2CiMBnt0337Fg7Zz/GuTpUUW2h3fbyTYO4hgOntxdQjZ5A==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@truffle/contract/-/contract-4.4.1.tgz", + "integrity": "sha512-KVpG9alKxdNzWOcRN97crZXXmmnnShq1SkM9hQN2fOckszzrmy6ctOhnZKNAb8tzfHBgODDCmiGQbTqaYizcrA==", "dev": true, "optional": true, "requires": { "@ensdomains/ensjs": "^2.0.1", "@truffle/blockchain-utils": "^0.0.31", - "@truffle/contract-schema": "^3.4.3", - "@truffle/debug-utils": "^5.1.18", + "@truffle/contract-schema": "^3.4.4", + "@truffle/debug-utils": "^6.0.2", "@truffle/error": "^0.0.14", "@truffle/interface-adapter": "^0.5.8", "bignumber.js": "^7.2.1", + "debug": "^4.3.1", "ethers": "^4.0.32", "web3": "1.5.3", "web3-core-helpers": "1.5.3", @@ -31270,14 +31381,14 @@ "optional": true }, "@truffle/codec": { - "version": "0.11.17", - "resolved": "https://registry.npmjs.org/@truffle/codec/-/codec-0.11.17.tgz", - "integrity": "sha512-WO9D5TVyTf9czqdsfK/qqYeSS//zWcHBgQgSNKPlCDb6koCNLxG5yGbb4P+0bZvTUNS2e2iIdN92QHg00wMbSQ==", + "version": "0.11.21", + "resolved": "https://registry.npmjs.org/@truffle/codec/-/codec-0.11.21.tgz", + "integrity": "sha512-ZDzaEPCUFWmQuFsXA3KzXmU4w4lpxSWZTGUcEDHxn6IqAmL7FY8mmdbR6LQ1wTRAa9oPf84PcehMpTNY47HVcg==", "dev": true, "optional": true, "requires": { - "@truffle/abi-utils": "^0.2.4", - "@truffle/compile-common": "^0.7.22", + "@truffle/abi-utils": "^0.2.5", + "@truffle/compile-common": "^0.7.23", "big.js": "^5.2.2", "bn.js": "^5.1.3", "cbor": "^5.1.0", @@ -31292,18 +31403,18 @@ } }, "@truffle/debug-utils": { - "version": "5.1.18", - "resolved": "https://registry.npmjs.org/@truffle/debug-utils/-/debug-utils-5.1.18.tgz", - "integrity": "sha512-QBq1vA/YozksQZGjyA7o482AuT8KW5gvO8VmYM/PIDllCIqDruEZuz4DZ+zpVUPXyVoJycFo+RKnM/TLE1AZRQ==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@truffle/debug-utils/-/debug-utils-6.0.2.tgz", + "integrity": "sha512-gMZ2IHPS9cvWGinUwVMoZedOYJz4sSekUXGC5FQkBnR0XDVriPmuja4rdgXhkA9EFSqZdXu4JAL8IiEHp/1YIw==", "dev": true, "optional": true, "requires": { - "@truffle/codec": "^0.11.17", + "@truffle/codec": "^0.11.21", "@trufflesuite/chromafi": "^2.2.2", "bn.js": "^5.1.3", "chalk": "^2.4.2", "debug": "^4.3.1", - "highlightjs-solidity": "^2.0.1" + "highlightjs-solidity": "^2.0.2" } }, "@truffle/error": { @@ -31336,9 +31447,9 @@ } }, "@types/node": { - "version": "12.20.33", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.33.tgz", - "integrity": "sha512-5XmYX2GECSa+CxMYaFsr2mrql71Q4EvHjKS+ox/SiwSdaASMoBIWE6UmZqFO+VX1jIcsYLStI4FFoB6V7FeIYw==", + "version": "12.20.37", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.37.tgz", + "integrity": "sha512-i1KGxqcvJaLQali+WuypQnXwcplhtNtjs66eNsZpp2P2FL/trJJxx/VWsM0YCL2iMoIJrbXje48lvIQAQ4p2ZA==", "dev": true, "optional": true }, @@ -31409,9 +31520,9 @@ } }, "highlightjs-solidity": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/highlightjs-solidity/-/highlightjs-solidity-2.0.1.tgz", - "integrity": "sha512-9YY+HQpXMTrF8HgRByjeQhd21GXAz2ktMPTcs6oWSj5HJR52fgsNoelMOmgigwcpt9j4tu4IVSaWaJB2n2TbvQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/highlightjs-solidity/-/highlightjs-solidity-2.0.2.tgz", + "integrity": "sha512-q0aYUKiZ9MPQg41qx/KpXKaCpqql50qTvmwGYyLFfcjt9AE/+C9CwjVIdJZc7EYj6NGgJuFJ4im1gfgrzUU1fQ==", "dev": true, "optional": true }, @@ -31508,9 +31619,9 @@ }, "dependencies": { "bignumber.js": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", - "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", + "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", "dev": true, "optional": true } @@ -31808,9 +31919,9 @@ } }, "@truffle/contract-schema": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/@truffle/contract-schema/-/contract-schema-3.4.3.tgz", - "integrity": "sha512-pgaTgF4CKIpkqVYZVr2qGTxZZQOkNCWOXW9VQpKvLd4G0SNF2Y1gyhrFbBhoOUtYlbbSty+IEFFHsoAqpqlvpQ==", + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@truffle/contract-schema/-/contract-schema-3.4.4.tgz", + "integrity": "sha512-xWgrm6WRM2jmT04w7dP7aVbS2qyP9XPmH/mybQtFXMjJ/8BZlp0yltC8QOs8sGl6q8Ws7acp19YtRkLdK6SsmQ==", "dev": true, "requires": { "ajv": "^6.10.0", @@ -31875,15 +31986,15 @@ } }, "@types/node": { - "version": "12.20.33", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.33.tgz", - "integrity": "sha512-5XmYX2GECSa+CxMYaFsr2mrql71Q4EvHjKS+ox/SiwSdaASMoBIWE6UmZqFO+VX1jIcsYLStI4FFoB6V7FeIYw==", + "version": "12.20.37", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.37.tgz", + "integrity": "sha512-i1KGxqcvJaLQali+WuypQnXwcplhtNtjs66eNsZpp2P2FL/trJJxx/VWsM0YCL2iMoIJrbXje48lvIQAQ4p2ZA==", "dev": true }, "bignumber.js": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", - "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", + "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", "dev": true }, "bn.js": { @@ -32345,15 +32456,15 @@ } }, "@types/node": { - "version": "12.20.33", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.33.tgz", - "integrity": "sha512-5XmYX2GECSa+CxMYaFsr2mrql71Q4EvHjKS+ox/SiwSdaASMoBIWE6UmZqFO+VX1jIcsYLStI4FFoB6V7FeIYw==", + "version": "12.20.37", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.37.tgz", + "integrity": "sha512-i1KGxqcvJaLQali+WuypQnXwcplhtNtjs66eNsZpp2P2FL/trJJxx/VWsM0YCL2iMoIJrbXje48lvIQAQ4p2ZA==", "dev": true }, "bignumber.js": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", - "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", + "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", "dev": true }, "bn.js": { @@ -32797,9 +32908,9 @@ } }, "@types/chai": { - "version": "4.2.22", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.22.tgz", - "integrity": "sha512-tFfcE+DSTzWAgifkjik9AySNqIyNoYwmR+uecPwwD/XRNfvOjmC/FjCxpiUGDkDVDphPfCUecSQVFw+lN3M3kQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.0.tgz", + "integrity": "sha512-/ceqdqeRraGolFTcfoXNiqjyQhZzbINDngeoAq9GoHa8PPK1yNzTaxWjA6BFWp5Ua9JpXEMSS4s5i9tS0hOJtw==", "dev": true }, "@types/concat-stream": { @@ -32866,9 +32977,9 @@ "dev": true }, "@types/node": { - "version": "16.11.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.1.tgz", - "integrity": "sha512-PYGcJHL9mwl1Ek3PLiYgyEKtwTMmkMw4vbiyz/ps3pfdRYLVv+SN7qHVAImrjdAXxgluDEw6Ph4lyv+m9UpRmA==" + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.0.tgz", + "integrity": "sha512-eMhwJXc931Ihh4tkU+Y7GiLzT/y/DBNpNtr4yU9O2w3SYBsr9NaOPhQlLKRmoWtI54uNwuo0IOUFQjVOTZYRvw==" }, "@types/parse-json": { "version": "4.0.0", @@ -32899,9 +33010,9 @@ } }, "@uniswap/token-lists": { - "version": "1.0.0-beta.26", - "resolved": "https://registry.npmjs.org/@uniswap/token-lists/-/token-lists-1.0.0-beta.26.tgz", - "integrity": "sha512-lDeB81CVds2ISqTbANyxgProFtoux4WRJFv9OoFV3NRnn10SYr0kVjgSOuBmbqa8gJorqomQYqOSGksIDQqthw==", + "version": "1.0.0-beta.27", + "resolved": "https://registry.npmjs.org/@uniswap/token-lists/-/token-lists-1.0.0-beta.27.tgz", + "integrity": "sha512-x5hmIniQ9TGqOBCRqfWcmZi/U5kB0qrHMDQ9igs3nMbK0wwmYLraL4owbIwXFGR/co6/lJYJC4K/Gjn4wZY5mQ==", "dev": true }, "@webassemblyjs/ast": { @@ -33091,6 +33202,12 @@ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", "dev": true }, + "abbrev": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", + "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", + "dev": true + }, "abi-decoder": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/abi-decoder/-/abi-decoder-2.3.0.tgz", @@ -33448,9 +33565,9 @@ "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" @@ -33640,9 +33757,9 @@ "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" } @@ -33736,21 +33853,21 @@ "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" }, "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.19.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.1.tgz", + "integrity": "sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA==", "dev": true, "requires": { - "bytes": "3.1.0", + "bytes": "3.1.1", "content-type": "~1.0.4", "debug": "2.6.9", "depd": "~1.1.2", - "http-errors": "1.7.2", + "http-errors": "1.8.1", "iconv-lite": "0.4.24", "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" + "qs": "6.9.6", + "raw-body": "2.4.2", + "type-is": "~1.6.18" }, "dependencies": { "debug": { @@ -33762,25 +33879,6 @@ "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", @@ -33788,22 +33886,10 @@ "dev": true }, "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "version": "6.9.6", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz", + "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==", "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==", - "dev": true, - "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } } } }, @@ -33828,9 +33914,9 @@ }, "dependencies": { "bignumber.js": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", - "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", + "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", "dev": true }, "commander": { @@ -34030,9 +34116,9 @@ "dev": true }, "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz", + "integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==", "dev": true }, "cacache": { @@ -34056,14 +34142,6 @@ "ssri": "^6.0.1", "unique-filename": "^1.1.1", "y18n": "^4.0.0" - }, - "dependencies": { - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - } } }, "cache-base": { @@ -34193,9 +34271,9 @@ }, "dependencies": { "bignumber.js": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", - "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", + "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", "dev": true, "optional": true } @@ -34334,6 +34412,12 @@ "readdirp": "~3.6.0" } }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, "chrome-trace-event": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", @@ -34481,9 +34565,9 @@ } }, "cli-table": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.6.tgz", - "integrity": "sha512-ZkNZbnZjKERTY5NwC2SeMeLeifSPq/pubeRoTpdr3WchLlnZg6hEgvHkK5zL7KNFdd9PmHN8lxrENUwI3cE8vQ==", + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.11.tgz", + "integrity": "sha512-IqLQi4lO0nIB4tcdTpN4LCB9FI3uqrJZK7RC515EnhZ6qBaglkIgICb1wjeAqpdoOabm1+SuQtkXIPdYC93jhQ==", "dev": true, "requires": { "colors": "1.0.3" @@ -34513,6 +34597,51 @@ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==" }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.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 + }, + "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 + }, + "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" + } + } + } + }, "clone-response": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", @@ -34669,98 +34798,6 @@ "yargs": "^13.3.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 - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "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 - }, - "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 - }, - "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" - } - }, "supports-color": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", @@ -34769,41 +34806,6 @@ "requires": { "has-flag": "^3.0.0" } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "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" - } - }, - "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" - } } } }, @@ -34909,9 +34911,9 @@ "dev": true }, "core-js-pure": { - "version": "3.18.3", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.18.3.tgz", - "integrity": "sha512-qfskyO/KjtbYn09bn1IPkuhHl5PlJ6IzJ9s9sraJ1EqcuGyLGKzhSM1cY0zgyL9hx42eulQLZ6WaeK5ycJCkqw==", + "version": "3.20.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.20.0.tgz", + "integrity": "sha512-qsrbIwWSEEYOM7z616jAVgwhuDDtPLwZSpUsU3vyUkHYqKTf/uwOJBZg2V7lMurYWkpVlaVOxBrfX0Q3ppvjfg==", "dev": true }, "core-util-is": { @@ -35041,15 +35043,15 @@ } }, "css-select": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.1.3.tgz", - "integrity": "sha512-gT3wBNd9Nj49rAbmtFHj1cljIAOLYSX1nZ8CB7TBO3INYckygm5B7LISU/szY//YmdiSLbJvDLOx9VnMVpMBxA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.2.0.tgz", + "integrity": "sha512-6YVG6hsH9yIb/si3Th/is8Pex7qnVHO6t7q7U6TIUnkQASGbS8tnUDBftnPynLNnuUl/r2+PTd0ekiiq7R0zJw==", "requires": { "boolbase": "^1.0.0", - "css-what": "^5.0.0", - "domhandler": "^4.2.0", - "domutils": "^2.6.0", - "nth-check": "^2.0.0" + "css-what": "^5.1.0", + "domhandler": "^4.3.0", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" } }, "css-what": { @@ -35083,9 +35085,9 @@ } }, "date-fns": { - "version": "2.25.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.25.0.tgz", - "integrity": "sha512-ovYRFnTrbGPD4nqaEqescPEv1mNwvt+UTqI3Ay9SzNtey9NZnYu6E2qCcBBgJ6/2VF1zGGygpyTDITqpQQ5e+w==", + "version": "2.27.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.27.0.tgz", + "integrity": "sha512-sj+J0Mo2p2X1e306MHq282WS4/A8Pz/95GIFcsPNMPMZVI3EUrAdSv90al1k+p74WGLCruMXk23bfEDZa71X9Q==", "dev": true }, "death": { @@ -35095,9 +35097,9 @@ "dev": true }, "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "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" @@ -35330,9 +35332,9 @@ "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==" }, "domhandler": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.2.tgz", - "integrity": "sha512-PzE9aBMsdZO8TK4BnuJwH0QT41wgMbRzuZrHUcpYncEjmQazq8QEaBWgLG7ZyC/DAZKEgglpIA6j4Qn/HmxS3w==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.0.tgz", + "integrity": "sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==", "requires": { "domelementtype": "^2.2.0" } @@ -36103,9 +36105,9 @@ }, "dependencies": { "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.9.tgz", + "integrity": "sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ==", "dev": true }, "semver": { @@ -36191,9 +36193,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 } } @@ -36208,9 +36210,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 } } @@ -36252,13 +36254,13 @@ } }, "eth-gas-reporter": { - "version": "0.2.22", - "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.22.tgz", - "integrity": "sha512-L1FlC792aTf3j/j+gGzSNlGrXKSxNPXQNk6TnV5NNZ2w3jnQCRyJjDl0zUo25Cq2t90IS5vGdbkwqFQK7Ce+kw==", + "version": "0.2.23", + "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.23.tgz", + "integrity": "sha512-T8KsVakDEupvQxW3MfFfHDfJ7y8zl2+XhyEQk4hZ3qQsAh/FE27BfFHM9UhqNQvrJLz8zVWnPZWNcARwLT/lsA==", "dev": true, "requires": { "@ethersproject/abi": "^5.0.0-beta.146", - "@solidity-parser/parser": "^0.12.0", + "@solidity-parser/parser": "^0.14.0", "cli-table3": "^0.5.0", "colors": "^1.1.2", "ethereumjs-util": "6.2.0", @@ -36275,10 +36277,13 @@ }, "dependencies": { "@solidity-parser/parser": { - "version": "0.12.2", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.12.2.tgz", - "integrity": "sha512-d7VS7PxgMosm5NyaiyDJRNID5pK4AWj1l64Dbz0147hJgy5k2C0/ZiKK/9u5c5K+HRUVHmp+RMvGEjGh84oA5Q==", - "dev": true + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.0.tgz", + "integrity": "sha512-cX0JJRcmPtNUJpzD2K7FdA7qQsTOk1UZnFx2k7qAg9ZRvuaH5NBe5IEdBMXGlmf2+FmjhqbygJ26H8l2SV7aKQ==", + "dev": true, + "requires": { + "antlr4ts": "^0.5.0-alpha.4" + } }, "@types/bn.js": { "version": "4.11.6", @@ -36295,12 +36300,6 @@ "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", "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==", - "dev": true - }, "bn.js": { "version": "4.12.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", @@ -36323,17 +36322,6 @@ "readdirp": "~3.2.0" } }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, "debug": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", @@ -36349,12 +36337,6 @@ "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 - }, "ethereumjs-util": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.0.tgz", @@ -36557,12 +36539,6 @@ "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", @@ -36591,26 +36567,6 @@ "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=", "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" - } - }, "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", @@ -36641,41 +36597,6 @@ "isexe": "^2.0.0" } }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "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" - } - }, - "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" - } - }, "yargs-unparser": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", @@ -37405,6 +37326,13 @@ "dev": true, "optional": 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=", + "dev": true, + "optional": true + }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", @@ -37555,13 +37483,6 @@ "isexe": "^2.0.0" } }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true, - "optional": true - }, "window-size": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", @@ -38238,6 +38159,30 @@ "vary": "~1.1.2" }, "dependencies": { + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "dev": true, + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + } + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true + }, "cookie": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", @@ -38253,6 +38198,25 @@ "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", @@ -38265,11 +38229,35 @@ "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==", + "dev": true, + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "dev": true + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "dev": true } } }, @@ -38382,9 +38370,9 @@ "optional": true }, "fast-check": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-2.18.0.tgz", - "integrity": "sha512-7KKUw0wtAJOVrJ1DgmFILd9EmeqMLGtfe5HoEtkYZfYIxohm6Zy7zPq1Zl8t6tPL8A3e86YZrheyGg2m5j8cLA==", + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-2.20.0.tgz", + "integrity": "sha512-tFNjLyPnOUg6iimVxOtoWMJOIyybCo7B8gUGm1yv43jDCQ0hlPUn0fmna/XO/n1yPxn/dxQw3+IygPSbMDiiog==", "dev": true, "optional": true, "requires": { @@ -38801,9 +38789,9 @@ } }, "follow-redirects": { - "version": "1.14.4", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.4.tgz", - "integrity": "sha512-zwGkiSXC1MUJG/qmeIFH2HBJx9u0V46QGUe3YR1fXG8bXQxq7fLj0RjLZQ5nubr9qNJUZrH+xUcwXEoXNpfS+g==", + "version": "1.14.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.6.tgz", + "integrity": "sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A==", "dev": true }, "for-each": { @@ -38811,6 +38799,7 @@ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", "dev": true, + "peer": true, "requires": { "is-callable": "^1.1.3" } @@ -38931,6 +38920,15 @@ "universalify": "^1.0.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", @@ -39955,9 +39953,9 @@ }, "dependencies": { "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.9.tgz", + "integrity": "sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ==", "dev": true } } @@ -40115,23 +40113,6 @@ "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", "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==", - "dev": true - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, "commander": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", @@ -40169,12 +40150,6 @@ "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 - }, "encoding-down": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-6.3.0.tgz", @@ -40475,12 +40450,6 @@ "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 - }, "resolve": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", @@ -40543,26 +40512,6 @@ } } }, - "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" - } - }, "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", @@ -40593,52 +40542,6 @@ "isexe": "^2.0.0" } }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "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" - } - }, - "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": { - "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" - } - } - } - }, "yargs-unparser": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", @@ -40653,15 +40556,298 @@ } }, "hardhat-gas-reporter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.4.tgz", - "integrity": "sha512-G376zKh81G3K9WtDA+SoTLWsoygikH++tD1E7llx+X7J+GbIqfwhDKKgvJjcnEesMrtR9UqQHK02lJuXY1RTxw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.6.tgz", + "integrity": "sha512-LlCEmSx1dZpnxKmODb2hmP5eJ1IAM5It3NnBNTUpBTxn9g9qPPI3JQTxj8AbGEiNc3r6V+w/mXYCmiC8pWvnoQ==", "dev": true, "requires": { - "eth-gas-reporter": "^0.2.20", + "array-uniq": "1.0.3", + "eth-gas-reporter": "^0.2.23", "sha1": "^1.1.1" } }, + "hardhat-interact": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/hardhat-interact/-/hardhat-interact-0.2.0.tgz", + "integrity": "sha512-MiqTv3r2zYwdhOdZE9uKprw8Ig/nO5Ww69jhPzFG2wsd7A9CAuSfUYDUUQEi+u6FeosXYkqpgcj1Vj9T49k/zA==", + "dev": true, + "requires": { + "@synthetixio/wei": "^2.53.0-alpha2", + "axios": "^0.24.0", + "chalk": "^4.0.0", + "ethers": "^5.5.1", + "lodash": "^4.17.21", + "prompts": "^2.4.2" + }, + "dependencies": { + "@ethersproject/basex": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.5.0.tgz", + "integrity": "sha512-ZIodwhHpVJ0Y3hUCfUucmxKsWQA5TMnavp5j/UOuDdzZWzJlRmuOjcTMIGgHCYuZmHt36BfiSyQPSRskPxbfaQ==", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/properties": "^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==", + "dev": true, + "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==", + "dev": true, + "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/pbkdf2": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.5.0.tgz", + "integrity": "sha512-SaDvQFvXPnz1QGpzr6/HToLifftSXGoXrbpZ6BvoZhmx4bNLHrxDe8MZisuecyOziP1aVEwzC2Hasj+86TgWVg==", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/sha2": "^5.5.0" + } + }, + "@ethersproject/providers": { + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.5.1.tgz", + "integrity": "sha512-2zdD5sltACDWhjUE12Kucg2PcgM6V2q9JMyVvObtVGnzJu+QSmibbP+BHQyLWZUBfLApx2942+7DC5D+n4wBQQ==", + "dev": true, + "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.0", + "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.5.0.tgz", + "integrity": "sha512-egGYZwZ/YIFKMHcoBUo8t3a8Hb/TKYX8BCBoLjudVCZh892welR3jOxgOmb48xznc9bTcMm7Tpwc1gHC1PFNFQ==", + "dev": true, + "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==", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "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==", + "dev": true, + "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/units": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.5.0.tgz", + "integrity": "sha512-7+DpjiZk4v6wrikj+TCyWWa9dXLNU73tSTa7n0TSJDxkYbV3Yf1eRh9ToMLlZtuctNYu9RDNNy2USq3AdqSbag==", + "dev": true, + "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==", + "dev": true, + "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/wordlists": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.5.0.tgz", + "integrity": "sha512-bL0UTReWDiaQJJYOC9sh/XcRu/9i2jMrzf8VLRmPKx58ckSlOJiohODkECCO50dtLZHcGU6MLXQ4OOrgBwP77Q==", + "dev": true, + "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" + } + }, + "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" + } + }, + "axios": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz", + "integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==", + "dev": true, + "requires": { + "follow-redirects": "^1.14.4" + } + }, + "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 + }, + "ethers": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.5.2.tgz", + "integrity": "sha512-EF5W+6Wwcu6BqVwpgmyR5U2+L4c1FQzlM/02dkZOugN3KF0cG9bzHZP+TDJglmPm2/IzCEJDT7KBxzayk7SAHw==", + "dev": true, + "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.1", + "@ethersproject/pbkdf2": "5.5.0", + "@ethersproject/properties": "5.5.0", + "@ethersproject/providers": "5.5.1", + "@ethersproject/random": "5.5.0", + "@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" + } + }, + "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" + } + } + } + }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -40873,16 +41059,16 @@ "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": "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.1.1", + "setprototypeof": "1.2.0", "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" + "toidentifier": "1.0.1" } }, "http-https": { @@ -41525,9 +41711,9 @@ "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": { @@ -41655,12 +41841,12 @@ "optional": true }, "is-weakref": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.1.tgz", - "integrity": "sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", "dev": true, "requires": { - "call-bind": "^1.0.0" + "call-bind": "^1.0.2" } }, "is-windows": { @@ -41795,9 +41981,9 @@ "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": { @@ -41861,14 +42047,14 @@ "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" } }, @@ -41906,6 +42092,12 @@ "graceful-fs": "^4.1.9" } }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true + }, "lazy-cache": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", @@ -42110,9 +42302,9 @@ } }, "lines-and-columns": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, "load-json-file": { @@ -42647,18 +42839,18 @@ "dev": true }, "mime-db": { - "version": "1.50.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz", - "integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==", + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", "dev": true }, "mime-types": { - "version": "2.1.33", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz", - "integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==", + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", "dev": true, "requires": { - "mime-db": "1.50.0" + "mime-db": "1.51.0" } }, "mimic-fn": { @@ -42711,6 +42903,25 @@ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, + "minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "dev": true, + "requires": { + "minipass": "^2.9.0" + } + }, "mississippi": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", @@ -42758,12 +42969,12 @@ } }, "mnemonist": { - "version": "0.38.4", - "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.4.tgz", - "integrity": "sha512-mflgW0gEWmVLbDDE2gJbOh3+RltTN7CgV9jV25qyCnyLN9FtoltWr7ZtAEDeD9u8W4oFAoolR6fBWieXdn3u8Q==", + "version": "0.38.5", + "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz", + "integrity": "sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==", "dev": true, "requires": { - "obliterator": "^1.6.1" + "obliterator": "^2.0.0" } }, "mocha": { @@ -42799,12 +43010,6 @@ "yargs-unparser": "1.6.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==", - "dev": true - }, "chokidar": { "version": "3.4.2", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.2.tgz", @@ -42821,17 +43026,6 @@ "readdirp": "~3.4.0" } }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", @@ -42841,12 +43035,6 @@ "ms": "^2.1.1" } }, - "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 - }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -42945,12 +43133,6 @@ "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==", - "dev": true - }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -42966,32 +43148,6 @@ "picomatch": "^2.2.1" } }, - "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 - }, - "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" - } - }, "strip-json-comments": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", @@ -43006,86 +43162,6 @@ "requires": { "has-flag": "^4.0.0" } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "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" - } - }, - "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": { - "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" - } - }, - "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 - } - } } } }, @@ -43382,9 +43458,9 @@ } }, "node-fetch": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz", - "integrity": "sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==", + "version": "2.6.6", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.6.tgz", + "integrity": "sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA==", "dev": true, "requires": { "whatwg-url": "^5.0.0" @@ -43503,6 +43579,15 @@ "dev": true, "optional": true }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true, + "requires": { + "abbrev": "1" + } + }, "normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -43661,9 +43746,9 @@ } }, "object-inspect": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", - "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.1.tgz", + "integrity": "sha512-If7BjFlpkzzBeV1cqgT3OSWT3azyoxDGajR+iGnFBfVV2EWyDyWaZZW2ERDjUaY2QM8i5jI3Sj7mhsM4DDAqWA==", "dev": true }, "object-keys": { @@ -43725,9 +43810,9 @@ } }, "obliterator": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-1.6.1.tgz", - "integrity": "sha512-9WXswnqINnnhOG/5SLimUlzuU1hFJUc8zkwyD59Sd+dPOMf05PmnYG/d6Q7HZ+KmgkZJa1PxRso6QdM3sTNHig==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.1.tgz", + "integrity": "sha512-XnkiCrrBcIZQitJPAI36mrrpEUvatbte8hLcTcQwKA1v9NkCKasSi+UAguLsLDs/out7MoRzAlmz7VXvY6ph6w==", "dev": true }, "oboe": { @@ -44221,9 +44306,9 @@ } }, "prettier": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.4.1.tgz", - "integrity": "sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz", + "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==", "dev": true }, "semver": { @@ -44322,9 +44407,9 @@ } }, "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.9.tgz", + "integrity": "sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ==", "dev": true }, "locate-path": { @@ -44434,6 +44519,16 @@ "iterate-value": "^1.0.0" } }, + "prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + } + }, "proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -44524,9 +44619,9 @@ "optional": true }, "qs": { - "version": "6.10.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", - "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.2.tgz", + "integrity": "sha512-mSIdjzqznWgfd4pMii7sHtaYF8rx8861hBO80SraY5GT0XQibWZWJSid0avzHGkDIZLImux2S5mXO0Hfct2QCw==", "dev": true, "requires": { "side-channel": "^1.0.4" @@ -44585,13 +44680,13 @@ "dev": true }, "raw-body": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.1.tgz", - "integrity": "sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz", + "integrity": "sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==", "dev": true, "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.3", + "bytes": "3.1.1", + "http-errors": "1.8.1", "iconv-lite": "0.4.24", "unpipe": "1.0.0" } @@ -44917,11 +45012,10 @@ "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=", - "dev": true, - "optional": true + "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 }, "resolve": { "version": "1.20.0", @@ -45187,12 +45281,6 @@ "wordwrap": "^1.0.0" }, "dependencies": { - "abbrev": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", - "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", - "dev": true - }, "async": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", @@ -45224,15 +45312,6 @@ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", "dev": true }, - "nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", - "dev": true, - "requires": { - "abbrev": "1" - } - }, "resolve": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", @@ -45354,11 +45433,36 @@ } } }, + "http-errors": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", + "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "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==", "dev": true + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "dev": true + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "dev": true } } }, @@ -45448,9 +45552,9 @@ "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" }, "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": { @@ -45533,9 +45637,9 @@ } }, "signal-exit": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", - "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==" + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", + "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==" }, "simple-concat": { "version": "1.0.1", @@ -45552,6 +45656,12 @@ "simple-concat": "^1.0.0" } }, + "sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -46203,9 +46313,9 @@ "dev": true }, "web3-utils": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.6.0.tgz", - "integrity": "sha512-bgCAWAeQnJF035YTFxrcHJ5mGEfTi/McsjqldZiXRwlHK7L1PyOqvXiQLE053dlzvy1kdAxWl/sSSfLMyNUAXg==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.6.1.tgz", + "integrity": "sha512-RidGKv5kOkcerI6jQqDFDoTllQQqV+rPhTzZHhmbqtFObbYpU93uc+yG1LHivRTQhA6llIx67iudc/vzisgO+w==", "dev": true, "requires": { "bn.js": "^4.11.9", @@ -46260,9 +46370,9 @@ } }, "source-map-support": { - "version": "0.5.20", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", - "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, "requires": { "buffer-from": "^1.0.0", @@ -46316,9 +46426,9 @@ } }, "spdx-license-ids": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz", - "integrity": "sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==", + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", + "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==", "dev": true }, "split-string": { @@ -46748,12 +46858,6 @@ "xhr-request": "^1.0.1" }, "dependencies": { - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, "fs-extra": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", @@ -46765,15 +46869,6 @@ "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" - } - }, "get-stream": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", @@ -46817,25 +46912,6 @@ "graceful-fs": "^4.1.6" } }, - "minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", - "dev": true, - "requires": { - "minipass": "^2.9.0" - } - }, "p-cancelable": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", @@ -46848,21 +46924,6 @@ "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", "dev": true }, - "tar": { - "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" - } - }, "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -46952,6 +47013,21 @@ "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", "dev": true }, + "tar": { + "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" + } + }, "terser": { "version": "4.8.0", "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz", @@ -47188,9 +47264,9 @@ } }, "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": { @@ -47249,9 +47325,9 @@ } }, "tsconfig-paths": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz", - "integrity": "sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz", + "integrity": "sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==", "dev": true, "requires": { "@types/json5": "^0.0.29", @@ -47363,16 +47439,16 @@ } }, "typescript": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", - "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==", + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz", + "integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==", "dev": true, "peer": true }, "uglify-js": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.14.2.tgz", - "integrity": "sha512-rtPMlmcO4agTUfz10CbgJ1k6UAoXM2gWb3GoMPPZB/+/Ackf8lNWk11K4rYi2D0apgoFRLtQOZhb+/iGNJq26A==", + "version": "3.14.5", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.14.5.tgz", + "integrity": "sha512-qZukoSxOG0urUTvjc2ERMTcAy+BiFh3weWAkeurLwjrCba73poHmG3E36XEjd/JGukMzwTL7uCxZiAexj8ppvQ==", "dev": true, "optional": true }, @@ -47402,9 +47478,9 @@ } }, "underscore": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.1.tgz", - "integrity": "sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.2.tgz", + "integrity": "sha512-ekY1NhRzq0B08g4bGuX4wd2jZx5GnKz6mKSqFL4nqBlfyMGiG10gDFhDTMEfYmDL6Jy0FUIZp7wiRB+0BP7J2g==", "dev": true }, "union-value": { @@ -47630,6 +47706,7 @@ "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.1.1.tgz", "integrity": "sha512-/s3UsZUrIfa6xDhr7zZhnE9SLQ5RIXyYfiVnMMyMDzOc8WhWN4Nbh36H842OyurKbCDAesZOJaVyvmSl6fhGQw==", "dev": true, + "peer": true, "requires": { "call-bind": "^1.0.0", "define-properties": "^1.1.3", @@ -48084,9 +48161,9 @@ }, "dependencies": { "@types/node": { - "version": "12.20.33", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.33.tgz", - "integrity": "sha512-5XmYX2GECSa+CxMYaFsr2mrql71Q4EvHjKS+ox/SiwSdaASMoBIWE6UmZqFO+VX1jIcsYLStI4FFoB6V7FeIYw==", + "version": "12.20.37", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.37.tgz", + "integrity": "sha512-i1KGxqcvJaLQali+WuypQnXwcplhtNtjs66eNsZpp2P2FL/trJJxx/VWsM0YCL2iMoIJrbXje48lvIQAQ4p2ZA==", "dev": true }, "underscore": { @@ -48122,15 +48199,15 @@ } }, "@types/node": { - "version": "12.20.33", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.33.tgz", - "integrity": "sha512-5XmYX2GECSa+CxMYaFsr2mrql71Q4EvHjKS+ox/SiwSdaASMoBIWE6UmZqFO+VX1jIcsYLStI4FFoB6V7FeIYw==", + "version": "12.20.37", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.37.tgz", + "integrity": "sha512-i1KGxqcvJaLQali+WuypQnXwcplhtNtjs66eNsZpp2P2FL/trJJxx/VWsM0YCL2iMoIJrbXje48lvIQAQ4p2ZA==", "dev": true }, "bignumber.js": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", - "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", + "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", "dev": true }, "bn.js": { @@ -48196,14 +48273,14 @@ } }, "web3-core-helpers": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.6.0.tgz", - "integrity": "sha512-H/IAH/0mrgvad/oxVKiAMC7qDzMrPPe/nRKmJOoIsupRg9/frvL62kZZiHhqVD1HMyyswbQFC69QRl7JqWzvxg==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.6.1.tgz", + "integrity": "sha512-om2PZvK1uoWcgMq6JfcSx3241LEIVF6qi2JuHz2SLKiKEW5UsBUaVx0mNCmcZaiuYQCyOsLS3r33q5AdM+v8ng==", "dev": true, "peer": true, "requires": { - "web3-eth-iban": "1.6.0", - "web3-utils": "1.6.0" + "web3-eth-iban": "1.6.1", + "web3-utils": "1.6.1" }, "dependencies": { "bn.js": { @@ -48214,9 +48291,9 @@ "peer": true }, "web3-utils": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.6.0.tgz", - "integrity": "sha512-bgCAWAeQnJF035YTFxrcHJ5mGEfTi/McsjqldZiXRwlHK7L1PyOqvXiQLE053dlzvy1kdAxWl/sSSfLMyNUAXg==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.6.1.tgz", + "integrity": "sha512-RidGKv5kOkcerI6jQqDFDoTllQQqV+rPhTzZHhmbqtFObbYpU93uc+yG1LHivRTQhA6llIx67iudc/vzisgO+w==", "dev": true, "peer": true, "requires": { @@ -48317,9 +48394,9 @@ } }, "web3-core-promievent": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.6.0.tgz", - "integrity": "sha512-ZzsevjMXWkhqW9dnVfTfb1OUcK7jKcKPvPIbQ4boJccNgvNZPZKlo8xB4pkAX38n4c59O5mC7Lt/z2QL/M5CeQ==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.6.1.tgz", + "integrity": "sha512-byJ5s2MQxrWdXd27pWFmujfzsTZK4ik8rDgIV1RFDFc+rHZ2nZhq+VWk7t/Nkrj7EaVXncEgTdPEHc18nx+ocQ==", "dev": true, "peer": true, "requires": { @@ -48587,12 +48664,12 @@ } }, "web3-eth-abi": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.6.0.tgz", - "integrity": "sha512-fImomGE9McuTMJLwK8Tp0lTUzXqCkWeMm00qPVIwpJ/h7lCw9UFYV9+4m29wSqW6FF+FIZKwc6UBEf9dlx3orA==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.6.1.tgz", + "integrity": "sha512-svhYrAlXP9XQtV7poWKydwDJq2CaNLMtmKydNXoOBLcQec6yGMP+v20pgrxF2H6wyTK+Qy0E3/5ciPOqC/VuoQ==", "requires": { "@ethersproject/abi": "5.0.7", - "web3-utils": "1.6.0" + "web3-utils": "1.6.1" }, "dependencies": { "@ethersproject/abi": { @@ -48617,9 +48694,9 @@ "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" }, "web3-utils": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.6.0.tgz", - "integrity": "sha512-bgCAWAeQnJF035YTFxrcHJ5mGEfTi/McsjqldZiXRwlHK7L1PyOqvXiQLE053dlzvy1kdAxWl/sSSfLMyNUAXg==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.6.1.tgz", + "integrity": "sha512-RidGKv5kOkcerI6jQqDFDoTllQQqV+rPhTzZHhmbqtFObbYpU93uc+yG1LHivRTQhA6llIx67iudc/vzisgO+w==", "requires": { "bn.js": "^4.11.9", "ethereum-bloom-filters": "^1.0.6", @@ -48961,14 +49038,14 @@ } }, "web3-eth-iban": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.6.0.tgz", - "integrity": "sha512-HM/bKBS/e8qg0+Eh7B8C/JVG+GkR4AJty17DKRuwMtrh78YsonPj7GKt99zS4n5sDLFww1Imu/ZIk3+K5uJCjw==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.6.1.tgz", + "integrity": "sha512-91H0jXZnWlOoXmc13O9NuQzcjThnWyAHyDn5Yf7u6mmKOhpJSGF/OHlkbpXt1Y4v2eJdEPaVFa+6i8aRyagE7Q==", "dev": true, "peer": true, "requires": { "bn.js": "^4.11.9", - "web3-utils": "1.6.0" + "web3-utils": "1.6.1" }, "dependencies": { "bn.js": { @@ -48979,9 +49056,9 @@ "peer": true }, "web3-utils": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.6.0.tgz", - "integrity": "sha512-bgCAWAeQnJF035YTFxrcHJ5mGEfTi/McsjqldZiXRwlHK7L1PyOqvXiQLE053dlzvy1kdAxWl/sSSfLMyNUAXg==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.6.1.tgz", + "integrity": "sha512-RidGKv5kOkcerI6jQqDFDoTllQQqV+rPhTzZHhmbqtFObbYpU93uc+yG1LHivRTQhA6llIx67iudc/vzisgO+w==", "dev": true, "peer": true, "requires": { @@ -49011,9 +49088,9 @@ }, "dependencies": { "@types/node": { - "version": "12.20.33", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.33.tgz", - "integrity": "sha512-5XmYX2GECSa+CxMYaFsr2mrql71Q4EvHjKS+ox/SiwSdaASMoBIWE6UmZqFO+VX1jIcsYLStI4FFoB6V7FeIYw==", + "version": "12.20.37", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.37.tgz", + "integrity": "sha512-i1KGxqcvJaLQali+WuypQnXwcplhtNtjs66eNsZpp2P2FL/trJJxx/VWsM0YCL2iMoIJrbXje48lvIQAQ4p2ZA==", "dev": true }, "bn.js": { @@ -49582,23 +49659,6 @@ "yargs": "^13.3.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 - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -49612,67 +49672,12 @@ "which": "^1.2.9" } }, - "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 - }, - "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 - }, "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", "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==", - "dev": true - }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", @@ -49694,26 +49699,6 @@ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", "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" - } - }, "supports-color": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", @@ -49731,41 +49716,6 @@ "requires": { "isexe": "^2.0.0" } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "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" - } - }, - "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" - } } } }, @@ -49851,11 +49801,10 @@ } }, "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, - "optional": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true }, "which-pm-runs": { "version": "1.0.0", @@ -49920,6 +49869,51 @@ "integrity": "sha512-fU2OcNA/GVAJLLyKUoHkAgIhKb0JoCpSjLC/G2vYKxUjVmQwGbRVeoPJ1a8U4pnVofz4AQV5Y/NEw8oKqxEBtA==", "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==", + "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 + }, + "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 + }, + "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" + } + } + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -52649,6 +52643,101 @@ } } }, + "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.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "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 + }, + "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" + } + } + } + }, "yargs-parser": { "version": "13.1.2", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", @@ -52692,17 +52781,6 @@ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", @@ -52752,12 +52830,6 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "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==", - "dev": true - }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", @@ -52778,23 +52850,6 @@ "ansi-regex": "^4.1.0" } }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "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" - } - }, "yargs": { "version": "14.2.3", "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.3.tgz", diff --git a/package.json b/package.json index aa01c63629..cc71dfa29d 100644 --- a/package.json +++ b/package.json @@ -106,6 +106,7 @@ "fs-extra": "9.0.1", "hardhat": "2.6.4", "hardhat-gas-reporter": "~1.0.4", + "hardhat-interact": "^0.2.0", "husky": "^4.3.0", "is-ci": "^2.0.0", "lodash.clonedeep": "^4.5.0", diff --git a/publish/deployed/kovan-ovm/deployment.json b/publish/deployed/kovan-ovm/deployment.json index bf603e0ecf..6bcabf630e 100644 --- a/publish/deployed/kovan-ovm/deployment.json +++ b/publish/deployed/kovan-ovm/deployment.json @@ -164,11 +164,11 @@ }, "FeePool": { "name": "FeePool", - "address": "0x2F737bf6a32bf3AcBef4d5148DA507569204Fb61", + "address": "0x129fd2f3a799bD156e8c00599760AfC2f0f953dA", "source": "FeePool", - "link": "https://kovan-explorer.optimism.io/address/0x2F737bf6a32bf3AcBef4d5148DA507569204Fb61", - "timestamp": "2021-10-27T22:52:55.212Z", - "txn": "", + "link": "https://kovan-explorer.optimism.io/address/0x129fd2f3a799bD156e8c00599760AfC2f0f953dA", + "timestamp": "2022-01-14T22:42:00.000Z", + "txn": "https://kovan-explorer.optimism.io/tx/0x55afbfcde0349a562421f00fc4a583508b063931289e3f1e968ad0e1965a3701", "network": "kovan" }, "FeePoolState": { @@ -12355,7 +12355,7 @@ } }, "FeePool": { - "bytecode": "6080604052631cd554d160e21b6007553480156200001c57600080fd5b506040516200472c3803806200472c8339810160408190526200003f9162000221565b8080621baf8085856001600160a01b038116620000795760405162461bcd60e51b8152600401620000709062000343565b60405180910390fd5b600080546001600160a01b0319166001600160a01b0383161781556040517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c91620000c69184906200030b565b60405180910390a1506000546001600160a01b0316620000fa5760405162461bcd60e51b8152600401620000709062000331565b600280546001600160a01b0319166001600160a01b0383161790556040517ffc80377ca9c49cc11ae6982f390a42db976d5530af7c43889264b13fbbd7c57e9062000147908390620002fb565b60405180910390a1504201600455600580546001600160a01b0319166001600160a01b0392909216919091179055506001620001846000620001e2565b80546001600160401b0319166001600160401b039290921691909117905542620001af6000620001e2565b80546001600160401b0392909216600160801b02600160801b600160c01b0319909216919091179055506200039e915050565b60006008600260ff16836012540181620001f857fe5b06600281106200020457fe5b6005020192915050565b80516200021b8162000384565b92915050565b6000806000606084860312156200023757600080fd5b60006200024586866200020e565b935050602062000258868287016200020e565b92505060406200026b868287016200020e565b9150509250925092565b620002808162000370565b82525050565b62000280816200035e565b6000620002a060118362000355565b7013dddb995c881b5d5cdd081899481cd95d607a1b815260200192915050565b6000620002cf60198362000355565b7f4f776e657220616464726573732063616e6e6f74206265203000000000000000815260200192915050565b602081016200021b828462000275565b604081016200031b828562000275565b6200032a602083018462000286565b9392505050565b602080825281016200021b8162000291565b602080825281016200021b81620002c0565b90815260200190565b60006001600160a01b0382166200021b565b60006200021b8260006200021b826200035e565b6200038f816200035e565b81146200039b57600080fd5b50565b61437e80620003ae6000396000f3fe608060405234801561001057600080fd5b50600436106102415760003560e01c80636de813f111610145578063b410a034116100bd578063d67bdd251161008c578063eb1edd6111610071578063eb1edd611461045c578063ec55688914610464578063fd1f498d1461046c57610241565b8063d67bdd251461044c578063e0e6393d1461045457610241565b8063b410a03414610414578063bc67f8321461041c578063cff2ddad1461042f578063d294f0931461044457610241565b8063899ffef41161011457806397107d6d116100f957806397107d6d146103e6578063ac834193146103f9578063b10090b81461040157610241565b8063899ffef4146103c95780638da5cb5b146103de57610241565b80636de813f11461039e57806374185360146103a657806379ba5097146103ae57806386645274146103b657610241565b806333140016116101d857806353a47bb7116101a757806359a2f19f1161018c57806359a2f19f14610370578063614d08f8146103835780636466f45e1461038b57610241565b806353a47bb714610353578063569249d01461036857610241565b806333140016146102fd5780633ebc457a1461031d5780633fcd22401461032557806346ba2d901461034b57610241565b80631627540c116102145780631627540c146102b857806322425fa4146102cd57806322bf55ef146102d55780632af64bd3146102e857610241565b806304f3bcec1461024657806307ea50cd146102645780630813071c146102845780630de5861514610297575b600080fd5b61024e61047f565b60405161025b9190614023565b60405180910390f35b610277610272366004613262565b61048e565b60405161025b9190613f40565b6102776102923660046132a6565b610563565b6102aa6102a5366004613262565b6106af565b60405161025b929190613f5c565b6102cb6102c6366004613262565b610731565b005b61027761078f565b6102cb6102e3366004613387565b61079f565b6102f0610978565b60405161025b9190613f32565b61031061030b366004613262565b610aa8565b60405161025b9190613f13565b6102cb610d0c565b610338610333366004613387565b611112565b60405161025b97969594939291906141c0565b6102776111bb565b61035b6111c1565b60405161025b9190613e40565b6102776111d0565b6102f061037e366004613262565b61122b565b61027761123d565b6102f0610399366004613262565b611261565b61027761138d565b6102cb6113e2565b6102cb611534565b6102cb6103c43660046132e0565b6115d0565b6103d1611710565b60405161025b9190613f21565b61035b611a30565b6102cb6103f4366004613262565b611a3f565b610277611a92565b6102cb61040f366004613405565b611b32565b610277611d2c565b6102cb61042a366004613262565b611d36565b610437611d60565b60405161025b9190614228565b6102f0611d65565b61035b611ddc565b610277611deb565b61035b611df5565b61024e611e0d565b6102cb61047a366004613387565b611e1c565b6005546001600160a01b031681565b6000610498611e99565b6001600160a01b031663bdc963d87f6c6173745f6665655f7769746864726177616c00000000000000000000000000846040516020016104d9929190613dce565b604051602081830303815290604052805190602001206040518263ffffffff1660e01b815260040161050b9190613f40565b60206040518083038186803b15801561052357600080fd5b505afa158015610537573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061055b919081019061334b565b90505b919050565b60008161058b5760405162461bcd60e51b815260040161058290614192565b60405180910390fd5b600282106105ab5760405162461bcd60e51b815260040161058290614142565b6105b760018303611ec4565b5468010000000000000000900467ffffffffffffffff166105da575060006106a9565b600061060a60016105ed60018603611ec4565b5468010000000000000000900467ffffffffffffffff1690611eee565b9050600080610617611f16565b6001600160a01b031663d29c000a87856040518363ffffffff1660e01b8152600401610644929190613e92565b604080518083038186803b15801561065b57600080fd5b505afa15801561066f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061069391908101906133d5565b90925090506106a3838383611f41565b93505050505b92915050565b6000806106ba61317a565b6106c384610aa8565b905060008060015b6002811015610724576106f08482600281106106e357fe5b602002015151849061208c565b925061071a84826002811061070157fe5b602002015160016020020151839063ffffffff61208c16565b91506001016106cb565b509093509150505b915091565b6107396120b1565b600180546001600160a01b0319166001600160a01b0383161790556040517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce2290610784908390613e40565b60405180910390a150565b60006107996120dd565b90505b90565b60006107a96121a4565b6001600160a01b0316331490506000806107c16121cf565b6001600160a01b03166316b2213f336040518263ffffffff1660e01b81526004016107ec9190613e4e565b60206040518083038186803b15801561080457600080fd5b505afa158015610818573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061083c919081019061334b565b14159050600061084a6121e3565b6001600160a01b031663b38988f7336040518263ffffffff1660e01b81526004016108759190613e4e565b60206040518083038186803b15801561088d57600080fd5b505afa1580156108a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506108c5919081019061332d565b905060006108d161220e565b6001600160a01b0316336001600160a01b031614905060006108f1612239565b6001600160a01b0316336001600160a01b031614905084806109105750835b806109185750825b806109205750815b806109285750805b6109445760405162461bcd60e51b815260040161058290614042565b610962866109526000611ec4565b600101549063ffffffff61208c16565b61096c6000611ec4565b60010155505050505050565b60006060610984611710565b905060005b8151811015610a9f5760008282815181106109a057fe5b602090810291909101810151600081815260069092526040918290205460055492517f21f8a7210000000000000000000000000000000000000000000000000000000081529193506001600160a01b039081169216906321f8a72190610a0a908590600401613f40565b60206040518083038186803b158015610a2257600080fd5b505afa158015610a36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610a5a9190810190613288565b6001600160a01b0316141580610a8557506000818152600660205260409020546001600160a01b0316155b15610a96576000935050505061079c565b50600101610989565b50600191505090565b610ab061317a565b6000806000610abd611f16565b6040517fb326f84e0000000000000000000000000000000000000000000000000000000081529091506001600160a01b0382169063b326f84e90610b08908890600090600401613e77565b604080518083038186803b158015610b1f57600080fd5b505afa158015610b33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610b5791908101906133d5565b909350915081158015610b68575082155b15610b8057610b7561317a565b935061055e92505050565b600080610b8f60008686612264565b8751829052875160200181905290925090506000610bac8861048e565b905060015b8015610d005760001981016000610bc782611ec4565b5468010000000000000000900467ffffffffffffffff1690508015801590610c015750610bf383611ec4565b5467ffffffffffffffff1684105b15610cf5576000610c1982600163ffffffff611eee16565b6040517fd29c000a0000000000000000000000000000000000000000000000000000000081529091506001600160a01b0389169063d29c000a90610c63908f908590600401613e92565b604080518083038186803b158015610c7a57600080fd5b505afa158015610c8e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610cb291908101906133d5565b909a509850610cc2848b8b612264565b9097509550868b8560028110610cd457fe5b602002015152858b8560028110610ce757fe5b602002015160016020020152505b505060001901610bb1565b50505050505050919050565b610d14612306565b6001600160a01b0316637c3125416040518163ffffffff1660e01b815260040160006040518083038186803b158015610d4c57600080fd5b505afa158015610d60573d6000803e3d6000fd5b505050506000610d6e6120dd565b11610d8b5760405162461bcd60e51b8152600401610582906141a2565b610d936120dd565b4203610d9f6000611ec4565b54600160801b900467ffffffffffffffff161115610dcf5760405162461bcd60e51b815260040161058290614062565b610dd761220e565b6001600160a01b031663bb57ad206040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610e1157600080fd5b505af1158015610e25573d6000803e3d6000fd5b50505050610e31612239565b6001600160a01b031663bb57ad206040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610e6b57600080fd5b505af1158015610e7f573d6000803e3d6000fd5b5060009250610e919150829050611ec4565b90506000610e9f6001611ec4565b9050610ed08260010154610ec483600201548460010154611eee90919063ffffffff16565b9063ffffffff61208c16565b610eda6000611ec4565b60010155600380830154600483015491830154610f0192610ec4919063ffffffff611eee16565b610f0b6000611ec4565b60030155601254610f4890600290610f3c90600190610f30908463ffffffff61208c16565b9063ffffffff611eee16565b9063ffffffff61233116565b601281905560089060028110610f5a57fe5b6005020180547fffffffffffffffff000000000000000000000000000000000000000000000000168155600060018083018290556002830182905560038301829055600490920155610fc690610faf81611ec4565b5467ffffffffffffffff169063ffffffff61208c16565b610fd06000611ec4565b805467ffffffffffffffff191667ffffffffffffffff92909216919091179055610ff8612361565b6001600160a01b031663cd92eba96040518163ffffffff1660e01b815260040160206040518083038186803b15801561103057600080fd5b505afa158015611044573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611068919081019061334b565b6110726000611ec4565b805467ffffffffffffffff9290921668010000000000000000026fffffffffffffffff000000000000000019909216919091179055426110b26000611ec4565b805467ffffffffffffffff92909216600160801b027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff90921691909117905561110e6110fe6001611ec4565b5467ffffffffffffffff1661238c565b5050565b60008060008060008060006111256131a7565b61112e89611ec4565b6040805160e081018252825467ffffffffffffffff808216808452680100000000000000008304821660208501819052600160801b909304909116938301849052600185015460608401819052600286015460808501819052600387015460a0860181905260049097015460c0909501859052919f929e50939c50929a5091985091965090945092505050565b60045481565b6001546001600160a01b031681565b60008060015b6002811015611225576111fc6111eb82611ec4565b60010154839063ffffffff61208c16565b915061121b61120a82611ec4565b60020154839063ffffffff611eee16565b91506001016111d6565b50905090565b600061123682612444565b5092915050565b7f466565506f6f6c0000000000000000000000000000000000000000000000000081565b600061126b612306565b6001600160a01b0316637c3125416040518163ffffffff1660e01b815260040160006040518083038186803b1580156112a357600080fd5b505afa1580156112b7573d6000803e3d6000fd5b505050506112c3612538565b6112cb612577565b6003546040517f21f4ae570000000000000000000000000000000000000000000000000000000081526001600160a01b03928316926321f4ae579261131892879290911690600401613e5c565b60206040518083038186803b15801561133057600080fd5b505afa158015611344573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611368919081019061332d565b6113845760405162461bcd60e51b8152600401610582906140e2565b61055b826125a2565b60008060015b6002811015611225576113b96113a882611ec4565b60030154839063ffffffff61208c16565b91506113d86113c782611ec4565b60040154839063ffffffff611eee16565b9150600101611393565b60606113ec611710565b905060005b815181101561110e57600082828151811061140857fe5b602002602001015190506000600560009054906101000a90046001600160a01b03166001600160a01b031663dacb2d01838460405160200161144a9190613e2a565b6040516020818303038152906040526040518363ffffffff1660e01b8152600401611476929190613f6a565b60206040518083038186803b15801561148e57600080fd5b505afa1580156114a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506114c69190810190613288565b6000838152600660205260409081902080546001600160a01b0319166001600160a01b038416179055519091507f88a93678a3692f6789d9546fc621bf7234b101ddb7d4fe479455112831b8aa68906115229084908490613f4e565b60405180910390a150506001016113f1565b6001546001600160a01b0316331461155e5760405162461bcd60e51b815260040161058290614052565b6000546001546040517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c926115a1926001600160a01b0391821692911690613e5c565b60405180910390a160018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b60006115da6121cf565b6001600160a01b0316336001600160a01b031614905060006115fa612361565b6001600160a01b0316336001600160a01b031614905081806116195750805b6116355760405162461bcd60e51b815260040161058290614182565b61163d611f16565b6001600160a01b03166394e1a4488686866116586000611ec4565b5460405160e086901b7fffffffff000000000000000000000000000000000000000000000000000000001681526116ab9493929168010000000000000000900467ffffffffffffffff1690600401613ed5565b600060405180830381600087803b1580156116c557600080fd5b505af11580156116d9573d6000803e3d6000fd5b505050506117098585856116ed6000611ec4565b5468010000000000000000900467ffffffffffffffff16612697565b5050505050565b60608061171b612766565b60408051600d8082526101c0820190925291925060609190602082016101a0803883390190505090507f53797374656d53746174757300000000000000000000000000000000000000008160008151811061177257fe5b6020026020010181815250507f53796e7468657469780000000000000000000000000000000000000000000000816001815181106117ac57fe5b6020026020010181815250507f466565506f6f6c53746174650000000000000000000000000000000000000000816002815181106117e657fe5b6020026020010181815250507f466565506f6f6c457465726e616c53746f7261676500000000000000000000008160038151811061182057fe5b6020026020010181815250507f45786368616e67657200000000000000000000000000000000000000000000008160048151811061185a57fe5b6020026020010181815250506524b9b9bab2b960d11b8160058151811061187d57fe5b6020026020010181815250507f53796e7468657469785374617465000000000000000000000000000000000000816006815181106118b757fe5b6020026020010181815250507f526577617264457363726f775632000000000000000000000000000000000000816007815181106118f157fe5b6020026020010181815250507f44656c6567617465417070726f76616c730000000000000000000000000000008160088151811061192b57fe5b6020026020010181815250507f52657761726473446973747269627574696f6e000000000000000000000000008160098151811061196557fe5b6020026020010181815250507f436f6c6c61746572616c4d616e6167657200000000000000000000000000000081600a8151811061199f57fe5b6020026020010181815250507f57726170706572466163746f727900000000000000000000000000000000000081600b815181106119d957fe5b6020026020010181815250507f457468657257726170706572000000000000000000000000000000000000000081600c81518110611a1357fe5b602002602001018181525050611a2982826127c5565b9250505090565b6000546001600160a01b031681565b611a476120b1565b600280546001600160a01b0319166001600160a01b0383161790556040517ffc80377ca9c49cc11ae6982f390a42db976d5530af7c43889264b13fbbd7c57e90610784908390613e4e565b6000610799611b1e611aa261287a565b7387a479d8433121e4583d45d37b4a349b4350b79f63907af6c06040518163ffffffff1660e01b815260040160206040518083038186803b158015611ae657600080fd5b505af4158015611afa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ec4919081019061334b565b611b266128f1565b9063ffffffff61296816565b611b3a612992565b6004544210611b5b5760405162461bcd60e51b815260040161058290614152565b611b63612361565b6001600160a01b031663cd92eba96040518163ffffffff1660e01b815260040160206040518083038186803b158015611b9b57600080fd5b505afa158015611baf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611bd3919081019061334b565b861115611bf25760405162461bcd60e51b815260040161058290614132565b6040518060e001604052808867ffffffffffffffff1681526020018767ffffffffffffffff1681526020018667ffffffffffffffff168152602001858152602001848152602001838152602001828152506008611c62600260ff16610f3c8c60125461208c90919063ffffffff16565b60028110611c6c57fe5b82516005919091029190910180546020840151604085015167ffffffffffffffff1990921667ffffffffffffffff948516176fffffffffffffffff000000000000000019166801000000000000000091851691909102177fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff16600160801b9390911692909202919091178155606082015160018201556080820151600282015560a0820151600382015560c0909101516004909101555050505050505050565b60006107996128f1565b611d3e612a00565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b600281565b6000611d6f612306565b6001600160a01b0316637c3125416040518163ffffffff1660e01b815260040160006040518083038186803b158015611da757600080fd5b505afa158015611dbb573d6000803e3d6000fd5b50505050611dc7612538565b600354610799906001600160a01b03166125a2565b6003546001600160a01b031681565b600061079961287a565b73feefeefeefeefeefeefeefeefeefeefeefeefeef81565b6002546001600160a01b031681565b6000611e26612a2a565b6003549091506001600160a01b0380831691161480611e4d5750336001600160a01b038216145b611e695760405162461bcd60e51b8152600401610582906140f2565b611e8782611e776000611ec4565b600301549063ffffffff61208c16565b611e916000611ec4565b600301555050565b60006107997f466565506f6f6c457465726e616c53746f726167650000000000000000000000612a51565b60006008600260ff16836012540181611ed957fe5b0660028110611ee457fe5b6005020192915050565b600082821115611f105760405162461bcd60e51b815260040161058290614092565b50900390565b60006107997f466565506f6f6c53746174650000000000000000000000000000000000000000612a51565b600080611f4c612361565b9050600061208085612074846001600160a01b03166308d95cd5886040518263ffffffff1660e01b8152600401611f839190613f40565b60206040518083038186803b158015611f9b57600080fd5b505afa158015611faf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611fd3919081019061334b565b6040517f08d95cd50000000000000000000000000000000000000000000000000000000081526001600160a01b038716906308d95cd590612018908d90600401613f40565b60206040518083038186803b15801561203057600080fd5b505afa158015612044573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612068919081019061334b565b9063ffffffff612aae16565b9063ffffffff612ac716565b925050505b9392505050565b6000828201838110156120855760405162461bcd60e51b815260040161058290614082565b6000546001600160a01b031633146120db5760405162461bcd60e51b815260040161058290614102565b565b60006120e7612ae0565b6001600160a01b03166323257c2b7f53797374656d53657474696e67730000000000000000000000000000000000007f666565506572696f644475726174696f6e0000000000000000000000000000006040518363ffffffff1660e01b8152600401612154929190613f5c565b60206040518083038186803b15801561216c57600080fd5b505afa158015612180573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610799919081019061334b565b60006107997f45786368616e6765720000000000000000000000000000000000000000000000612a51565b60006107996524b9b9bab2b960d11b612a51565b60006107997f436f6c6c61746572616c4d616e61676572000000000000000000000000000000612a51565b60006107997f4574686572577261707065720000000000000000000000000000000000000000612a51565b60006107997f57726170706572466163746f7279000000000000000000000000000000000000612a51565b60008083612277575060009050806122fe565b8385156122a257600061229160016105ed60018a03611ec4565b905061229e818787611f41565b9150505b60006122c1826122b189611ec4565b600101549063ffffffff61296816565b905060006122e2836122d28a611ec4565b600301549063ffffffff61296816565b90506122ed82612b0b565b6122f682612b0b565b945094505050505b935093915050565b60006107997f53797374656d5374617475730000000000000000000000000000000000000000612a51565b6000816123505760405162461bcd60e51b8152600401610582906140d2565b81838161235957fe5b069392505050565b60006107997f53796e7468657469785374617465000000000000000000000000000000000000612a51565b6002546040516001600160a01b039091169063907dff97906123b2908490602001613f40565b60405160208183030381529060405260016040516123cf90613e35565b6040519081900381207fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16825261241693929160009081908190600401613f8a565b600060405180830381600087803b15801561243057600080fd5b505af1158015611709573d6000803e3d6000fd5b6000806000806124526121cf565b6001600160a01b031663ae3bbbbb866040518263ffffffff1660e01b815260040161247d9190613e40565b604080518083038186803b15801561249457600080fd5b505afa1580156124a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506124cc91908101906133a5565b9150915060006124da6128f1565b9050808310156124f2575060019350915061072c9050565b600061250f612502611aa261287a565b839063ffffffff61296816565b90508084111561252957600083955095505050505061072c565b50600194509092505050915091565b6002546001600160a01b0316331480159061255e57506003546001600160a01b03163314155b156120db57600380546001600160a01b03191633179055565b60006107997f44656c6567617465417070726f76616c73000000000000000000000000000000612a51565b60008080808080806125b388612444565b91509150816125d45760405162461bcd60e51b815260040161058290614112565b80156125f25760405162461bcd60e51b8152600401610582906140c2565b6125fb886106af565b90945092508315158061260e5750600083115b61262a5760405162461bcd60e51b8152600401610582906140b2565b612648886126386001611ec4565b5467ffffffffffffffff16612b2d565b83156126635761265784612be0565b94506126638886612cbc565b821561267e5761267283612e58565b955061267e8887612f32565b612689888688612fac565b506001979650505050505050565b6002546040516001600160a01b039091169063907dff97906126c1908690869086906020016141b2565b60405160208183030381529060405260026040516126de90613dff565b6040519081900381207fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16825261272e9392916001600160a01b038b16906000908190600401613fe9565b600060405180830381600087803b15801561274857600080fd5b505af115801561275c573d6000803e3d6000fd5b5050505050505050565b604080516001808252818301909252606091602080830190803883390190505090507f466c657869626c6553746f726167650000000000000000000000000000000000816000815181106127b657fe5b60200260200101818152505090565b606081518351016040519080825280602002602001820160405280156127f5578160200160208202803883390190505b50905060005b83518110156128375783818151811061281057fe5b602002602001015182828151811061282457fe5b60209081029190910101526001016127fb565b5060005b82518110156112365782818151811061285057fe5b602002602001015182828651018151811061286757fe5b602090810291909101015260010161283b565b6000612884612ae0565b6001600160a01b03166323257c2b7f53797374656d53657474696e67730000000000000000000000000000000000007f7461726765745468726573686f6c6400000000000000000000000000000000006040518363ffffffff1660e01b8152600401612154929190613f5c565b60006128fb612ae0565b6001600160a01b03166323257c2b7f53797374656d53657474696e67730000000000000000000000000000000000007f69737375616e6365526174696f000000000000000000000000000000000000006040518363ffffffff1660e01b8152600401612154929190613f5c565b6000670de0b6b3a7640000612983848463ffffffff61307116565b8161298a57fe5b049392505050565b6002546001600160a01b031633148015906129b857506003546001600160a01b03163314155b156129d057600380546001600160a01b031916331790555b6000546003546001600160a01b039081169116146120db5760405162461bcd60e51b815260040161058290614072565b6002546001600160a01b031633146120db5760405162461bcd60e51b815260040161058290614172565b60006107997f52657761726473446973747269627574696f6e000000000000000000000000005b60008181526006602090815260408083205490516001600160a01b039091169182151591612a8191869101613e0a565b604051602081830303815290604052906112365760405162461bcd60e51b81526004016105829190614031565b600061208583836b033b2e3c9fd0803ce80000006130ab565b600061208583836b033b2e3c9fd0803ce80000006130ef565b60006107997f466c657869626c6553746f726167650000000000000000000000000000000000612a51565b60006305f5e10082046005600a820610612b2357600a015b600a900492915050565b612b35611e99565b6001600160a01b0316633562fd207f6c6173745f6665655f7769746864726177616c0000000000000000000000000084604051602001612b76929190613dce565b60405160208183030381529060405280519060200120836040518363ffffffff1660e01b8152600401612baa929190613f5c565b600060405180830381600087803b158015612bc457600080fd5b505af1158015612bd8573d6000803e3d6000fd5b505050505050565b6000818160015b6002811015612cb4576000612bfb82611ec4565b6002015490506000612c2082612c1085611ec4565b600101549063ffffffff611eee16565b90508015612ca9576000858210612c375785612c39565b815b9050612c4b838263ffffffff61208c16565b612c5485611ec4565b60020155612c68868263ffffffff611eee16565b9550612c7a858263ffffffff61208c16565b945085612c8f5784965050505050505061055e565b83158015612c9d5750600086115b15612ca757600095505b505b505060001901612be7565b509392505050565b816001600160a01b03811673feefeefeefeefeefeefeefeefeefeefeefeefeef1415612cfa5760405162461bcd60e51b815260040161058290614162565b6000612d046121cf565b6001600160a01b031663326080396007546040518263ffffffff1660e01b8152600401612d319190613f40565b60206040518083038186803b158015612d4957600080fd5b505afa158015612d5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612d819190810190613369565b6040517f9dc29fac0000000000000000000000000000000000000000000000000000000081529091506001600160a01b03821690639dc29fac90612ddf9073feefeefeefeefeefeefeefeefeefeefeefeefeef908790600401613e92565b600060405180830381600087803b158015612df957600080fd5b505af1158015612e0d573d6000803e3d6000fd5b50506040517f867904b40000000000000000000000000000000000000000000000000000000081526001600160a01b038416925063867904b4915061272e9087908790600401613e92565b6000818160015b6002811015612cb4576000612e93612e7683611ec4565b60040154612e8384611ec4565b600301549063ffffffff611eee16565b90508015612f28576000848210612eaa5784612eac565b815b9050612ecb81612ebb85611ec4565b600401549063ffffffff61208c16565b612ed484611ec4565b60040155612ee8858263ffffffff611eee16565b9450612efa848263ffffffff61208c16565b935084612f0e57839550505050505061055e565b82158015612f1c5750600085115b15612f2657600094505b505b5060001901612e5f565b816001600160a01b03811673feefeefeefeefeefeefeefeefeefeefeefeefeef1415612f705760405162461bcd60e51b815260040161058290614162565b6301dfe200612f7d61311a565b6001600160a01b0316631bb47b448585846040518463ffffffff1660e01b815260040161272e93929190613ead565b6002546040516001600160a01b039091169063907dff9790612fd690869086908690602001613ead565b6040516020818303038152906040526001604051612ff390613df4565b6040519081900381207fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16825261303a93929160009081908190600401613f8a565b600060405180830381600087803b15801561305457600080fd5b505af1158015613068573d6000803e3d6000fd5b50505050505050565b600082613080575060006106a9565b8282028284828161308d57fe5b04146120855760405162461bcd60e51b815260040161058290614122565b6000806130d1846130c587600a870263ffffffff61307116565b9063ffffffff61314516565b90506005600a825b06106130e357600a015b600a9004949350505050565b600080600a8304613106868663ffffffff61307116565b8161310d57fe5b0490506005600a826130d9565b60006107997f526577617264457363726f775632000000000000000000000000000000000000612a51565b60008082116131665760405162461bcd60e51b8152600401610582906140a2565b600082848161317157fe5b04949350505050565b60405180604001604052806002905b613191613202565b8152602001906001900390816131895790505090565b6040518060e00160405280600067ffffffffffffffff168152602001600067ffffffffffffffff168152602001600067ffffffffffffffff168152602001600081526020016000815260200160008152602001600081525090565b60405180604001604052806002906020820280388339509192915050565b80356106a981614309565b80516106a981614309565b80516106a981614320565b80516106a981614329565b80516106a981614332565b80356106a981614329565b60006020828403121561327457600080fd5b60006132808484613220565b949350505050565b60006020828403121561329a57600080fd5b6000613280848461322b565b600080604083850312156132b957600080fd5b60006132c58585613220565b92505060206132d685828601613257565b9150509250929050565b6000806000606084860312156132f557600080fd5b60006133018686613220565b935050602061331286828701613257565b925050604061332386828701613257565b9150509250925092565b60006020828403121561333f57600080fd5b60006132808484613236565b60006020828403121561335d57600080fd5b60006132808484613241565b60006020828403121561337b57600080fd5b6000613280848461324c565b60006020828403121561339957600080fd5b60006132808484613257565b600080604083850312156133b857600080fd5b60006133c48585613241565b92505060206132d685828601613236565b600080604083850312156133e857600080fd5b60006133f48585613241565b92505060206132d685828601613241565b600080600080600080600080610100898b03121561342257600080fd5b600061342e8b8b613257565b985050602061343f8b828c01613257565b97505060406134508b828c01613257565b96505060606134618b828c01613257565b95505060806134728b828c01613257565b94505060a06134838b828c01613257565b93505060c06134948b828c01613257565b92505060e06134a58b828c01613257565b9150509295985092959890939650565b60006134c183836135ab565b505060400190565b60006134d58383613600565b505060200190565b6134e681614289565b82525050565b6134e68161424f565b6134e66135018261424f565b6142e8565b61350f8161423c565b613519818461055e565b92506135248261079c565b8060005b83811015612bd857815161353c87826134b5565b965061354783614236565b925050600101613528565b600061355d82614242565b6135678185614246565b935061357283614236565b8060005b838110156135a057815161358a88826134c9565b975061359583614236565b925050600101613576565b509495945050505050565b6135b48161423c565b6135be818461055e565b92506135c98261079c565b8060005b83811015612bd85781516135e187826134c9565b96506135ec83614236565b9250506001016135cd565b6134e68161425a565b6134e68161079c565b6134e66136158261079c565b61079c565b600061362582614242565b61362f8185614246565b935061363f8185602086016142b8565b613648816142f9565b9093019392505050565b6134e68161425f565b6134e681614294565b6134e6816142a2565b600061367a601783614246565b7f4f6e6c7920496e7465726e616c20436f6e747261637473000000000000000000815260200192915050565b60006136b3603583614246565b7f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7581527f2063616e20616363657074206f776e6572736869700000000000000000000000602082015260400192915050565b6000613712601d83614246565b7f546f6f206561726c7920746f20636c6f73652066656520706572696f64000000815260200192915050565b600061374b601383614246565b7f4f776e6572206f6e6c792066756e6374696f6e00000000000000000000000000815260200192915050565b600061378460248361055e565b7f46656573436c61696d656428616464726573732c75696e743235362c75696e7481527f3235362900000000000000000000000000000000000000000000000000000000602082015260240192915050565b60006137e360378361055e565b7f49737375616e636544656274526174696f456e74727928616464726573732c7581527f696e743235362c75696e743235362c75696e7432353629000000000000000000602082015260370192915050565b6000613842601b83614246565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815260200192915050565b600061387b601e83614246565b7f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815260200192915050565b60006138b4601a83614246565b7f536166654d6174683a206469766973696f6e206279207a65726f000000000000815260200192915050565b60006138ed604083614246565b7f4e6f2066656573206f72207265776172647320617661696c61626c6520666f7281527f20706572696f642c206f72206665657320616c726561647920636c61696d6564602082015260400192915050565b600061394c60118361055e565b7f4d697373696e6720616464726573733a20000000000000000000000000000000815260110192915050565b6000613985601e83614246565b7f412073796e7468206f7220534e58207261746520697320696e76616c69640000815260200192915050565b60006139be601883614246565b7f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000815260200192915050565b60006139f7601f83614246565b7f4e6f7420617070726f76656420746f20636c61696d206f6e20626568616c6600815260200192915050565b6000613a30601e83614246565b7f43616c6c6572206973206e6f742072657761726473417574686f726974790000815260200192915050565b6000613a69602f83614246565b7f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726681527f6f726d207468697320616374696f6e0000000000000000000000000000000000602082015260400192915050565b6000613ac8601f83614246565b7f432d526174696f2062656c6f772070656e616c7479207468726573686f6c6400815260200192915050565b6000613b01602183614246565b7f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f81527f7700000000000000000000000000000000000000000000000000000000000000602082015260400192915050565b6000613b60601683614246565b7f43616e6e6f7420696d706f727420626164206461746100000000000000000000815260200192915050565b6000613b99601d83614246565b7f4578636565647320746865204645455f504552494f445f4c454e475448000000815260200192915050565b6000613bd2602983614246565b7f43616e206f6e6c7920706572666f726d207468697320616374696f6e2064757281527f696e672073657475700000000000000000000000000000000000000000000000602082015260400192915050565b6000613c3160198361055e565b7f5265736f6c766572206d697373696e67207461726765743a2000000000000000815260190192915050565b6000613c6a601783614246565b7f4665652061646472657373206e6f7420616c6c6f776564000000000000000000815260200192915050565b6000613ca360188361055e565b7f466565506572696f64436c6f7365642875696e74323536290000000000000000815260180192915050565b6000613cdc601783614246565b7f4f6e6c79207468652070726f78792063616e2063616c6c000000000000000000815260200192915050565b6000613d15601e83614246565b7f49737375657220616e642053796e7468657469785374617465206f6e6c790000815260200192915050565b6000613d4e602083614246565b7f43757272656e7420706572696f64206973206e6f7420636c6f73656420796574815260200192915050565b6000613d87601b83614246565b7f46656520506572696f64204475726174696f6e206e6f74207365740000000000815260200192915050565b6134e6816142ad565b6134e681614276565b6134e681614283565b6000613dda8285613609565b602082019150613dea82846134f5565b5060140192915050565b60006106a982613777565b60006106a9826137d6565b6000613e158261393f565b9150613e218284613609565b50602001919050565b6000613e1582613c24565b60006106a982613c96565b602081016106a982846134ec565b602081016106a982846134dd565b60408101613e6a82856134ec565b61208560208301846134ec565b60408101613e8582856134ec565b6120856020830184613664565b60408101613ea082856134ec565b6120856020830184613600565b60608101613ebb82866134ec565b613ec86020830185613600565b6132806040830184613600565b60808101613ee382876134ec565b613ef06020830186613600565b613efd6040830185613600565b613f0a6060830184613db3565b95945050505050565b608081016106a98284613506565b602080825281016120858184613552565b602081016106a982846135f7565b602081016106a98284613600565b60408101613e6a8285613600565b60408101613ea08285613600565b60408101613f788285613600565b8181036020830152613280818461361a565b60c08082528101613f9b818961361a565b9050613faa6020830188613664565b613fb76040830187613600565b613fc4606083018661365b565b613fd1608083018561365b565b613fde60a083018461365b565b979650505050505050565b60c08082528101613ffa818961361a565b90506140096020830188613664565b6140166040830187613600565b613fc46060830186613600565b602081016106a98284613652565b60208082528101612085818461361a565b6020808252810161055b8161366d565b6020808252810161055b816136a6565b6020808252810161055b81613705565b6020808252810161055b8161373e565b6020808252810161055b81613835565b6020808252810161055b8161386e565b6020808252810161055b816138a7565b6020808252810161055b816138e0565b6020808252810161055b81613978565b6020808252810161055b816139b1565b6020808252810161055b816139ea565b6020808252810161055b81613a23565b6020808252810161055b81613a5c565b6020808252810161055b81613abb565b6020808252810161055b81613af4565b6020808252810161055b81613b53565b6020808252810161055b81613b8c565b6020808252810161055b81613bc5565b6020808252810161055b81613c5d565b6020808252810161055b81613ccf565b6020808252810161055b81613d08565b6020808252810161055b81613d41565b6020808252810161055b81613d7a565b60608101613ebb8286613600565b60e081016141ce828a613dbc565b6141db6020830189613dbc565b6141e86040830188613dbc565b6141f56060830187613600565b6142026080830186613600565b61420f60a0830185613600565b61421c60c0830184613600565b98975050505050505050565b602081016106a98284613dc5565b60200190565b50600290565b5190565b90815260200190565b600061055b8261426a565b151590565b600061055b8261424f565b6001600160a01b031690565b67ffffffffffffffff1690565b60ff1690565b600061055b8261425f565b600061055b6136158361079c565b600061055b8261079c565b600061055b82614276565b60005b838110156142d35781810151838201526020016142bb565b838111156142e2576000848401525b50505050565b600061055b82600061055b82614303565b601f01601f191690565b60601b90565b6143128161424f565b811461431d57600080fd5b50565b6143128161425a565b6143128161079c565b6143128161425f56fea365627a7a7231582027c6d550873108a7d60713319b7fa5e4bbba69ffb8ed82ee57ccd2f3d0e2330a6c6578706572696d656e74616cf564736f6c63430005100040", + "bytecode": "6080604052631cd554d160e21b6007553480156200001c57600080fd5b506040516200471b3803806200471b8339810160408190526200003f9162000221565b8080621baf8085856001600160a01b038116620000795760405162461bcd60e51b8152600401620000709062000343565b60405180910390fd5b600080546001600160a01b0319166001600160a01b0383161781556040517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c91620000c69184906200030b565b60405180910390a1506000546001600160a01b0316620000fa5760405162461bcd60e51b8152600401620000709062000331565b600280546001600160a01b0319166001600160a01b0383161790556040517ffc80377ca9c49cc11ae6982f390a42db976d5530af7c43889264b13fbbd7c57e9062000147908390620002fb565b60405180910390a1504201600455600580546001600160a01b0319166001600160a01b0392909216919091179055506001620001846000620001e2565b80546001600160401b0319166001600160401b039290921691909117905542620001af6000620001e2565b80546001600160401b0392909216600160801b02600160801b600160c01b0319909216919091179055506200039e915050565b60006008600260ff16836012540181620001f857fe5b06600281106200020457fe5b6005020192915050565b80516200021b8162000384565b92915050565b6000806000606084860312156200023757600080fd5b60006200024586866200020e565b935050602062000258868287016200020e565b92505060406200026b868287016200020e565b9150509250925092565b620002808162000370565b82525050565b62000280816200035e565b6000620002a060118362000355565b7013dddb995c881b5d5cdd081899481cd95d607a1b815260200192915050565b6000620002cf60198362000355565b7f4f776e657220616464726573732063616e6e6f74206265203000000000000000815260200192915050565b602081016200021b828462000275565b604081016200031b828562000275565b6200032a602083018462000286565b9392505050565b602080825281016200021b8162000291565b602080825281016200021b81620002c0565b90815260200190565b60006001600160a01b0382166200021b565b60006200021b8260006200021b826200035e565b6200038f816200035e565b81146200039b57600080fd5b50565b61436d80620003ae6000396000f3fe608060405234801561001057600080fd5b50600436106102415760003560e01c80636de813f111610145578063b410a034116100bd578063d67bdd251161008c578063eb1edd6111610071578063eb1edd611461045c578063ec55688914610464578063fd1f498d1461046c57610241565b8063d67bdd251461044c578063e0e6393d1461045457610241565b8063b410a03414610414578063bc67f8321461041c578063cff2ddad1461042f578063d294f0931461044457610241565b8063899ffef41161011457806397107d6d116100f957806397107d6d146103e6578063ac834193146103f9578063b10090b81461040157610241565b8063899ffef4146103c95780638da5cb5b146103de57610241565b80636de813f11461039e57806374185360146103a657806379ba5097146103ae57806386645274146103b657610241565b806333140016116101d857806353a47bb7116101a757806359a2f19f1161018c57806359a2f19f14610370578063614d08f8146103835780636466f45e1461038b57610241565b806353a47bb714610353578063569249d01461036857610241565b806333140016146102fd5780633ebc457a1461031d5780633fcd22401461032557806346ba2d901461034b57610241565b80631627540c116102145780631627540c146102b857806322425fa4146102cd57806322bf55ef146102d55780632af64bd3146102e857610241565b806304f3bcec1461024657806307ea50cd146102645780630813071c146102845780630de5861514610297575b600080fd5b61024e61047f565b60405161025b9190614012565b60405180910390f35b610277610272366004613251565b61048e565b60405161025b9190613f2f565b610277610292366004613295565b610563565b6102aa6102a5366004613251565b6106af565b60405161025b929190613f4b565b6102cb6102c6366004613251565b610731565b005b61027761078f565b6102cb6102e3366004613376565b61079f565b6102f0610978565b60405161025b9190613f21565b61031061030b366004613251565b610aa8565b60405161025b9190613f02565b6102cb610d0c565b610338610333366004613376565b611112565b60405161025b97969594939291906141af565b6102776111bb565b61035b6111c1565b60405161025b9190613e2f565b6102776111d0565b6102f061037e366004613251565b61122b565b61027761123d565b6102f0610399366004613251565b611261565b61027761138d565b6102cb6113e2565b6102cb611534565b6102cb6103c43660046132cf565b6115d0565b6103d1611710565b60405161025b9190613f10565b61035b611a30565b6102cb6103f4366004613251565b611a3f565b610277611a92565b6102cb61040f3660046133f4565b611b32565b610277611d2c565b6102cb61042a366004613251565b611d36565b610437611d60565b60405161025b9190614217565b6102f0611d65565b61035b611ddc565b610277611deb565b61035b611df5565b61024e611e0d565b6102cb61047a366004613376565b611e1c565b6005546001600160a01b031681565b6000610498611e88565b6001600160a01b031663bdc963d87f6c6173745f6665655f7769746864726177616c00000000000000000000000000846040516020016104d9929190613dbd565b604051602081830303815290604052805190602001206040518263ffffffff1660e01b815260040161050b9190613f2f565b60206040518083038186803b15801561052357600080fd5b505afa158015610537573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061055b919081019061333a565b90505b919050565b60008161058b5760405162461bcd60e51b815260040161058290614181565b60405180910390fd5b600282106105ab5760405162461bcd60e51b815260040161058290614131565b6105b760018303611eb3565b5468010000000000000000900467ffffffffffffffff166105da575060006106a9565b600061060a60016105ed60018603611eb3565b5468010000000000000000900467ffffffffffffffff1690611edd565b9050600080610617611f05565b6001600160a01b031663d29c000a87856040518363ffffffff1660e01b8152600401610644929190613e81565b604080518083038186803b15801561065b57600080fd5b505afa15801561066f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061069391908101906133c4565b90925090506106a3838383611f30565b93505050505b92915050565b6000806106ba613169565b6106c384610aa8565b905060008060015b6002811015610724576106f08482600281106106e357fe5b602002015151849061207b565b925061071a84826002811061070157fe5b602002015160016020020151839063ffffffff61207b16565b91506001016106cb565b509093509150505b915091565b6107396120a0565b600180546001600160a01b0319166001600160a01b0383161790556040517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce2290610784908390613e2f565b60405180910390a150565b60006107996120cc565b90505b90565b60006107a9612193565b6001600160a01b0316331490506000806107c16121be565b6001600160a01b03166316b2213f336040518263ffffffff1660e01b81526004016107ec9190613e3d565b60206040518083038186803b15801561080457600080fd5b505afa158015610818573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061083c919081019061333a565b14159050600061084a6121d2565b6001600160a01b031663b38988f7336040518263ffffffff1660e01b81526004016108759190613e3d565b60206040518083038186803b15801561088d57600080fd5b505afa1580156108a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506108c5919081019061331c565b905060006108d16121fd565b6001600160a01b0316336001600160a01b031614905060006108f1612228565b6001600160a01b0316336001600160a01b031614905084806109105750835b806109185750825b806109205750815b806109285750805b6109445760405162461bcd60e51b815260040161058290614031565b610962866109526000611eb3565b600101549063ffffffff61207b16565b61096c6000611eb3565b60010155505050505050565b60006060610984611710565b905060005b8151811015610a9f5760008282815181106109a057fe5b602090810291909101810151600081815260069092526040918290205460055492517f21f8a7210000000000000000000000000000000000000000000000000000000081529193506001600160a01b039081169216906321f8a72190610a0a908590600401613f2f565b60206040518083038186803b158015610a2257600080fd5b505afa158015610a36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610a5a9190810190613277565b6001600160a01b0316141580610a8557506000818152600660205260409020546001600160a01b0316155b15610a96576000935050505061079c565b50600101610989565b50600191505090565b610ab0613169565b6000806000610abd611f05565b6040517fb326f84e0000000000000000000000000000000000000000000000000000000081529091506001600160a01b0382169063b326f84e90610b08908890600090600401613e66565b604080518083038186803b158015610b1f57600080fd5b505afa158015610b33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610b5791908101906133c4565b909350915081158015610b68575082155b15610b8057610b75613169565b935061055e92505050565b600080610b8f60008686612253565b8751829052875160200181905290925090506000610bac8861048e565b905060015b8015610d005760001981016000610bc782611eb3565b5468010000000000000000900467ffffffffffffffff1690508015801590610c015750610bf383611eb3565b5467ffffffffffffffff1684105b15610cf5576000610c1982600163ffffffff611edd16565b6040517fd29c000a0000000000000000000000000000000000000000000000000000000081529091506001600160a01b0389169063d29c000a90610c63908f908590600401613e81565b604080518083038186803b158015610c7a57600080fd5b505afa158015610c8e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610cb291908101906133c4565b909a509850610cc2848b8b612253565b9097509550868b8560028110610cd457fe5b602002015152858b8560028110610ce757fe5b602002015160016020020152505b505060001901610bb1565b50505050505050919050565b610d146122f5565b6001600160a01b0316637c3125416040518163ffffffff1660e01b815260040160006040518083038186803b158015610d4c57600080fd5b505afa158015610d60573d6000803e3d6000fd5b505050506000610d6e6120cc565b11610d8b5760405162461bcd60e51b815260040161058290614191565b610d936120cc565b4203610d9f6000611eb3565b54600160801b900467ffffffffffffffff161115610dcf5760405162461bcd60e51b815260040161058290614051565b610dd76121fd565b6001600160a01b031663bb57ad206040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610e1157600080fd5b505af1158015610e25573d6000803e3d6000fd5b50505050610e31612228565b6001600160a01b031663bb57ad206040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610e6b57600080fd5b505af1158015610e7f573d6000803e3d6000fd5b5060009250610e919150829050611eb3565b90506000610e9f6001611eb3565b9050610ed08260010154610ec483600201548460010154611edd90919063ffffffff16565b9063ffffffff61207b16565b610eda6000611eb3565b60010155600380830154600483015491830154610f0192610ec4919063ffffffff611edd16565b610f0b6000611eb3565b60030155601254610f4890600290610f3c90600190610f30908463ffffffff61207b16565b9063ffffffff611edd16565b9063ffffffff61232016565b601281905560089060028110610f5a57fe5b6005020180547fffffffffffffffff000000000000000000000000000000000000000000000000168155600060018083018290556002830182905560038301829055600490920155610fc690610faf81611eb3565b5467ffffffffffffffff169063ffffffff61207b16565b610fd06000611eb3565b805467ffffffffffffffff191667ffffffffffffffff92909216919091179055610ff8612350565b6001600160a01b031663cd92eba96040518163ffffffff1660e01b815260040160206040518083038186803b15801561103057600080fd5b505afa158015611044573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611068919081019061333a565b6110726000611eb3565b805467ffffffffffffffff9290921668010000000000000000026fffffffffffffffff000000000000000019909216919091179055426110b26000611eb3565b805467ffffffffffffffff92909216600160801b027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff90921691909117905561110e6110fe6001611eb3565b5467ffffffffffffffff1661237b565b5050565b6000806000806000806000611125613196565b61112e89611eb3565b6040805160e081018252825467ffffffffffffffff808216808452680100000000000000008304821660208501819052600160801b909304909116938301849052600185015460608401819052600286015460808501819052600387015460a0860181905260049097015460c0909501859052919f929e50939c50929a5091985091965090945092505050565b60045481565b6001546001600160a01b031681565b60008060015b6002811015611225576111fc6111eb82611eb3565b60010154839063ffffffff61207b16565b915061121b61120a82611eb3565b60020154839063ffffffff611edd16565b91506001016111d6565b50905090565b600061123682612433565b5092915050565b7f466565506f6f6c0000000000000000000000000000000000000000000000000081565b600061126b6122f5565b6001600160a01b0316637c3125416040518163ffffffff1660e01b815260040160006040518083038186803b1580156112a357600080fd5b505afa1580156112b7573d6000803e3d6000fd5b505050506112c3612527565b6112cb612566565b6003546040517f21f4ae570000000000000000000000000000000000000000000000000000000081526001600160a01b03928316926321f4ae579261131892879290911690600401613e4b565b60206040518083038186803b15801561133057600080fd5b505afa158015611344573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611368919081019061331c565b6113845760405162461bcd60e51b8152600401610582906140e1565b61055b82612591565b60008060015b6002811015611225576113b96113a882611eb3565b60030154839063ffffffff61207b16565b91506113d86113c782611eb3565b60040154839063ffffffff611edd16565b9150600101611393565b60606113ec611710565b905060005b815181101561110e57600082828151811061140857fe5b602002602001015190506000600560009054906101000a90046001600160a01b03166001600160a01b031663dacb2d01838460405160200161144a9190613e19565b6040516020818303038152906040526040518363ffffffff1660e01b8152600401611476929190613f59565b60206040518083038186803b15801561148e57600080fd5b505afa1580156114a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506114c69190810190613277565b6000838152600660205260409081902080546001600160a01b0319166001600160a01b038416179055519091507f88a93678a3692f6789d9546fc621bf7234b101ddb7d4fe479455112831b8aa68906115229084908490613f3d565b60405180910390a150506001016113f1565b6001546001600160a01b0316331461155e5760405162461bcd60e51b815260040161058290614041565b6000546001546040517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c926115a1926001600160a01b0391821692911690613e4b565b60405180910390a160018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b60006115da6121be565b6001600160a01b0316336001600160a01b031614905060006115fa612350565b6001600160a01b0316336001600160a01b031614905081806116195750805b6116355760405162461bcd60e51b815260040161058290614171565b61163d611f05565b6001600160a01b03166394e1a4488686866116586000611eb3565b5460405160e086901b7fffffffff000000000000000000000000000000000000000000000000000000001681526116ab9493929168010000000000000000900467ffffffffffffffff1690600401613ec4565b600060405180830381600087803b1580156116c557600080fd5b505af11580156116d9573d6000803e3d6000fd5b505050506117098585856116ed6000611eb3565b5468010000000000000000900467ffffffffffffffff16612686565b5050505050565b60608061171b612755565b60408051600d8082526101c0820190925291925060609190602082016101a0803883390190505090507f53797374656d53746174757300000000000000000000000000000000000000008160008151811061177257fe5b6020026020010181815250507f53796e7468657469780000000000000000000000000000000000000000000000816001815181106117ac57fe5b6020026020010181815250507f466565506f6f6c53746174650000000000000000000000000000000000000000816002815181106117e657fe5b6020026020010181815250507f466565506f6f6c457465726e616c53746f7261676500000000000000000000008160038151811061182057fe5b6020026020010181815250507f45786368616e67657200000000000000000000000000000000000000000000008160048151811061185a57fe5b6020026020010181815250506524b9b9bab2b960d11b8160058151811061187d57fe5b6020026020010181815250507f53796e7468657469785374617465000000000000000000000000000000000000816006815181106118b757fe5b6020026020010181815250507f526577617264457363726f775632000000000000000000000000000000000000816007815181106118f157fe5b6020026020010181815250507f44656c6567617465417070726f76616c730000000000000000000000000000008160088151811061192b57fe5b6020026020010181815250507f52657761726473446973747269627574696f6e000000000000000000000000008160098151811061196557fe5b6020026020010181815250507f436f6c6c61746572616c4d616e6167657200000000000000000000000000000081600a8151811061199f57fe5b6020026020010181815250507f57726170706572466163746f727900000000000000000000000000000000000081600b815181106119d957fe5b6020026020010181815250507f457468657257726170706572000000000000000000000000000000000000000081600c81518110611a1357fe5b602002602001018181525050611a2982826127b4565b9250505090565b6000546001600160a01b031681565b611a476120a0565b600280546001600160a01b0319166001600160a01b0383161790556040517ffc80377ca9c49cc11ae6982f390a42db976d5530af7c43889264b13fbbd7c57e90610784908390613e3d565b6000610799611b1e611aa2612869565b73__$f9217daff40bcb29719cec84f7ab900933$__63907af6c06040518163ffffffff1660e01b815260040160206040518083038186803b158015611ae657600080fd5b505af4158015611afa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ec4919081019061333a565b611b266128e0565b9063ffffffff61295716565b611b3a612981565b6004544210611b5b5760405162461bcd60e51b815260040161058290614141565b611b63612350565b6001600160a01b031663cd92eba96040518163ffffffff1660e01b815260040160206040518083038186803b158015611b9b57600080fd5b505afa158015611baf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611bd3919081019061333a565b861115611bf25760405162461bcd60e51b815260040161058290614121565b6040518060e001604052808867ffffffffffffffff1681526020018767ffffffffffffffff1681526020018667ffffffffffffffff168152602001858152602001848152602001838152602001828152506008611c62600260ff16610f3c8c60125461207b90919063ffffffff16565b60028110611c6c57fe5b82516005919091029190910180546020840151604085015167ffffffffffffffff1990921667ffffffffffffffff948516176fffffffffffffffff000000000000000019166801000000000000000091851691909102177fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff16600160801b9390911692909202919091178155606082015160018201556080820151600282015560a0820151600382015560c0909101516004909101555050505050505050565b60006107996128e0565b611d3e6129ef565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b600281565b6000611d6f6122f5565b6001600160a01b0316637c3125416040518163ffffffff1660e01b815260040160006040518083038186803b158015611da757600080fd5b505afa158015611dbb573d6000803e3d6000fd5b50505050611dc7612527565b600354610799906001600160a01b0316612591565b6003546001600160a01b031681565b6000610799612869565b73feefeefeefeefeefeefeefeefeefeefeefeefeef81565b6002546001600160a01b031681565b611e24612527565b611e2c612a19565b6003546001600160a01b03908116911614611e595760405162461bcd60e51b8152600401610582906140b1565b611e7781611e676000611eb3565b600301549063ffffffff61207b16565b611e816000611eb3565b6003015550565b60006107997f466565506f6f6c457465726e616c53746f726167650000000000000000000000612a40565b60006008600260ff16836012540181611ec857fe5b0660028110611ed357fe5b6005020192915050565b600082821115611eff5760405162461bcd60e51b815260040161058290614081565b50900390565b60006107997f466565506f6f6c53746174650000000000000000000000000000000000000000612a40565b600080611f3b612350565b9050600061206f85612063846001600160a01b03166308d95cd5886040518263ffffffff1660e01b8152600401611f729190613f2f565b60206040518083038186803b158015611f8a57600080fd5b505afa158015611f9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611fc2919081019061333a565b6040517f08d95cd50000000000000000000000000000000000000000000000000000000081526001600160a01b038716906308d95cd590612007908d90600401613f2f565b60206040518083038186803b15801561201f57600080fd5b505afa158015612033573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612057919081019061333a565b9063ffffffff612a9d16565b9063ffffffff612ab616565b925050505b9392505050565b6000828201838110156120745760405162461bcd60e51b815260040161058290614071565b6000546001600160a01b031633146120ca5760405162461bcd60e51b8152600401610582906140f1565b565b60006120d6612acf565b6001600160a01b03166323257c2b7f53797374656d53657474696e67730000000000000000000000000000000000007f666565506572696f644475726174696f6e0000000000000000000000000000006040518363ffffffff1660e01b8152600401612143929190613f4b565b60206040518083038186803b15801561215b57600080fd5b505afa15801561216f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610799919081019061333a565b60006107997f45786368616e6765720000000000000000000000000000000000000000000000612a40565b60006107996524b9b9bab2b960d11b612a40565b60006107997f436f6c6c61746572616c4d616e61676572000000000000000000000000000000612a40565b60006107997f4574686572577261707065720000000000000000000000000000000000000000612a40565b60006107997f57726170706572466163746f7279000000000000000000000000000000000000612a40565b60008083612266575060009050806122ed565b83851561229157600061228060016105ed60018a03611eb3565b905061228d818787611f30565b9150505b60006122b0826122a089611eb3565b600101549063ffffffff61295716565b905060006122d1836122c18a611eb3565b600301549063ffffffff61295716565b90506122dc82612afa565b6122e582612afa565b945094505050505b935093915050565b60006107997f53797374656d5374617475730000000000000000000000000000000000000000612a40565b60008161233f5760405162461bcd60e51b8152600401610582906140d1565b81838161234857fe5b069392505050565b60006107997f53796e7468657469785374617465000000000000000000000000000000000000612a40565b6002546040516001600160a01b039091169063907dff97906123a1908490602001613f2f565b60405160208183030381529060405260016040516123be90613e24565b6040519081900381207fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16825261240593929160009081908190600401613f79565b600060405180830381600087803b15801561241f57600080fd5b505af1158015611709573d6000803e3d6000fd5b6000806000806124416121be565b6001600160a01b031663ae3bbbbb866040518263ffffffff1660e01b815260040161246c9190613e2f565b604080518083038186803b15801561248357600080fd5b505afa158015612497573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506124bb9190810190613394565b9150915060006124c96128e0565b9050808310156124e1575060019350915061072c9050565b60006124fe6124f1611aa2612869565b839063ffffffff61295716565b90508084111561251857600083955095505050505061072c565b50600194509092505050915091565b6002546001600160a01b0316331480159061254d57506003546001600160a01b03163314155b156120ca57600380546001600160a01b03191633179055565b60006107997f44656c6567617465417070726f76616c73000000000000000000000000000000612a40565b60008080808080806125a288612433565b91509150816125c35760405162461bcd60e51b815260040161058290614101565b80156125e15760405162461bcd60e51b8152600401610582906140c1565b6125ea886106af565b9094509250831515806125fd5750600083115b6126195760405162461bcd60e51b8152600401610582906140a1565b612637886126276001611eb3565b5467ffffffffffffffff16612b1c565b83156126525761264684612bcf565b94506126528886612cab565b821561266d5761266183612e47565b955061266d8887612f21565b612678888688612f9b565b506001979650505050505050565b6002546040516001600160a01b039091169063907dff97906126b0908690869086906020016141a1565b60405160208183030381529060405260026040516126cd90613dee565b6040519081900381207fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16825261271d9392916001600160a01b038b16906000908190600401613fd8565b600060405180830381600087803b15801561273757600080fd5b505af115801561274b573d6000803e3d6000fd5b5050505050505050565b604080516001808252818301909252606091602080830190803883390190505090507f466c657869626c6553746f726167650000000000000000000000000000000000816000815181106127a557fe5b60200260200101818152505090565b606081518351016040519080825280602002602001820160405280156127e4578160200160208202803883390190505b50905060005b8351811015612826578381815181106127ff57fe5b602002602001015182828151811061281357fe5b60209081029190910101526001016127ea565b5060005b82518110156112365782818151811061283f57fe5b602002602001015182828651018151811061285657fe5b602090810291909101015260010161282a565b6000612873612acf565b6001600160a01b03166323257c2b7f53797374656d53657474696e67730000000000000000000000000000000000007f7461726765745468726573686f6c6400000000000000000000000000000000006040518363ffffffff1660e01b8152600401612143929190613f4b565b60006128ea612acf565b6001600160a01b03166323257c2b7f53797374656d53657474696e67730000000000000000000000000000000000007f69737375616e6365526174696f000000000000000000000000000000000000006040518363ffffffff1660e01b8152600401612143929190613f4b565b6000670de0b6b3a7640000612972848463ffffffff61306016565b8161297957fe5b049392505050565b6002546001600160a01b031633148015906129a757506003546001600160a01b03163314155b156129bf57600380546001600160a01b031916331790555b6000546003546001600160a01b039081169116146120ca5760405162461bcd60e51b815260040161058290614061565b6002546001600160a01b031633146120ca5760405162461bcd60e51b815260040161058290614161565b60006107997f52657761726473446973747269627574696f6e000000000000000000000000005b60008181526006602090815260408083205490516001600160a01b039091169182151591612a7091869101613df9565b604051602081830303815290604052906112365760405162461bcd60e51b81526004016105829190614020565b600061207483836b033b2e3c9fd0803ce800000061309a565b600061207483836b033b2e3c9fd0803ce80000006130de565b60006107997f466c657869626c6553746f726167650000000000000000000000000000000000612a40565b60006305f5e10082046005600a820610612b1257600a015b600a900492915050565b612b24611e88565b6001600160a01b0316633562fd207f6c6173745f6665655f7769746864726177616c0000000000000000000000000084604051602001612b65929190613dbd565b60405160208183030381529060405280519060200120836040518363ffffffff1660e01b8152600401612b99929190613f4b565b600060405180830381600087803b158015612bb357600080fd5b505af1158015612bc7573d6000803e3d6000fd5b505050505050565b6000818160015b6002811015612ca3576000612bea82611eb3565b6002015490506000612c0f82612bff85611eb3565b600101549063ffffffff611edd16565b90508015612c98576000858210612c265785612c28565b815b9050612c3a838263ffffffff61207b16565b612c4385611eb3565b60020155612c57868263ffffffff611edd16565b9550612c69858263ffffffff61207b16565b945085612c7e5784965050505050505061055e565b83158015612c8c5750600086115b15612c9657600095505b505b505060001901612bd6565b509392505050565b816001600160a01b03811673feefeefeefeefeefeefeefeefeefeefeefeefeef1415612ce95760405162461bcd60e51b815260040161058290614151565b6000612cf36121be565b6001600160a01b031663326080396007546040518263ffffffff1660e01b8152600401612d209190613f2f565b60206040518083038186803b158015612d3857600080fd5b505afa158015612d4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612d709190810190613358565b6040517f9dc29fac0000000000000000000000000000000000000000000000000000000081529091506001600160a01b03821690639dc29fac90612dce9073feefeefeefeefeefeefeefeefeefeefeefeefeef908790600401613e81565b600060405180830381600087803b158015612de857600080fd5b505af1158015612dfc573d6000803e3d6000fd5b50506040517f867904b40000000000000000000000000000000000000000000000000000000081526001600160a01b038416925063867904b4915061271d9087908790600401613e81565b6000818160015b6002811015612ca3576000612e82612e6583611eb3565b60040154612e7284611eb3565b600301549063ffffffff611edd16565b90508015612f17576000848210612e995784612e9b565b815b9050612eba81612eaa85611eb3565b600401549063ffffffff61207b16565b612ec384611eb3565b60040155612ed7858263ffffffff611edd16565b9450612ee9848263ffffffff61207b16565b935084612efd57839550505050505061055e565b82158015612f0b5750600085115b15612f1557600094505b505b5060001901612e4e565b816001600160a01b03811673feefeefeefeefeefeefeefeefeefeefeefeefeef1415612f5f5760405162461bcd60e51b815260040161058290614151565b6301dfe200612f6c613109565b6001600160a01b0316631bb47b448585846040518463ffffffff1660e01b815260040161271d93929190613e9c565b6002546040516001600160a01b039091169063907dff9790612fc590869086908690602001613e9c565b6040516020818303038152906040526001604051612fe290613de3565b6040519081900381207fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16825261302993929160009081908190600401613f79565b600060405180830381600087803b15801561304357600080fd5b505af1158015613057573d6000803e3d6000fd5b50505050505050565b60008261306f575060006106a9565b8282028284828161307c57fe5b04146120745760405162461bcd60e51b815260040161058290614111565b6000806130c0846130b487600a870263ffffffff61306016565b9063ffffffff61313416565b90506005600a825b06106130d257600a015b600a9004949350505050565b600080600a83046130f5868663ffffffff61306016565b816130fc57fe5b0490506005600a826130c8565b60006107997f526577617264457363726f775632000000000000000000000000000000000000612a40565b60008082116131555760405162461bcd60e51b815260040161058290614091565b600082848161316057fe5b04949350505050565b60405180604001604052806002905b6131806131f1565b8152602001906001900390816131785790505090565b6040518060e00160405280600067ffffffffffffffff168152602001600067ffffffffffffffff168152602001600067ffffffffffffffff168152602001600081526020016000815260200160008152602001600081525090565b60405180604001604052806002906020820280388339509192915050565b80356106a9816142f8565b80516106a9816142f8565b80516106a98161430f565b80516106a981614318565b80516106a981614321565b80356106a981614318565b60006020828403121561326357600080fd5b600061326f848461320f565b949350505050565b60006020828403121561328957600080fd5b600061326f848461321a565b600080604083850312156132a857600080fd5b60006132b4858561320f565b92505060206132c585828601613246565b9150509250929050565b6000806000606084860312156132e457600080fd5b60006132f0868661320f565b935050602061330186828701613246565b925050604061331286828701613246565b9150509250925092565b60006020828403121561332e57600080fd5b600061326f8484613225565b60006020828403121561334c57600080fd5b600061326f8484613230565b60006020828403121561336a57600080fd5b600061326f848461323b565b60006020828403121561338857600080fd5b600061326f8484613246565b600080604083850312156133a757600080fd5b60006133b38585613230565b92505060206132c585828601613225565b600080604083850312156133d757600080fd5b60006133e38585613230565b92505060206132c585828601613230565b600080600080600080600080610100898b03121561341157600080fd5b600061341d8b8b613246565b985050602061342e8b828c01613246565b975050604061343f8b828c01613246565b96505060606134508b828c01613246565b95505060806134618b828c01613246565b94505060a06134728b828c01613246565b93505060c06134838b828c01613246565b92505060e06134948b828c01613246565b9150509295985092959890939650565b60006134b0838361359a565b505060400190565b60006134c483836135ef565b505060200190565b6134d581614278565b82525050565b6134d58161423e565b6134d56134f08261423e565b6142d7565b6134fe8161422b565b613508818461055e565b92506135138261079c565b8060005b83811015612bc757815161352b87826134a4565b965061353683614225565b925050600101613517565b600061354c82614231565b6135568185614235565b935061356183614225565b8060005b8381101561358f57815161357988826134b8565b975061358483614225565b925050600101613565565b509495945050505050565b6135a38161422b565b6135ad818461055e565b92506135b88261079c565b8060005b83811015612bc75781516135d087826134b8565b96506135db83614225565b9250506001016135bc565b6134d581614249565b6134d58161079c565b6134d56136048261079c565b61079c565b600061361482614231565b61361e8185614235565b935061362e8185602086016142a7565b613637816142e8565b9093019392505050565b6134d58161424e565b6134d581614283565b6134d581614291565b6000613669601783614235565b7f4f6e6c7920496e7465726e616c20436f6e747261637473000000000000000000815260200192915050565b60006136a2603583614235565b7f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7581527f2063616e20616363657074206f776e6572736869700000000000000000000000602082015260400192915050565b6000613701601d83614235565b7f546f6f206561726c7920746f20636c6f73652066656520706572696f64000000815260200192915050565b600061373a601383614235565b7f4f776e6572206f6e6c792066756e6374696f6e00000000000000000000000000815260200192915050565b600061377360248361055e565b7f46656573436c61696d656428616464726573732c75696e743235362c75696e7481527f3235362900000000000000000000000000000000000000000000000000000000602082015260240192915050565b60006137d260378361055e565b7f49737375616e636544656274526174696f456e74727928616464726573732c7581527f696e743235362c75696e743235362c75696e7432353629000000000000000000602082015260370192915050565b6000613831601b83614235565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815260200192915050565b600061386a601e83614235565b7f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815260200192915050565b60006138a3601a83614235565b7f536166654d6174683a206469766973696f6e206279207a65726f000000000000815260200192915050565b60006138dc604083614235565b7f4e6f2066656573206f72207265776172647320617661696c61626c6520666f7281527f20706572696f642c206f72206665657320616c726561647920636c61696d6564602082015260400192915050565b600061393b60118361055e565b7f4d697373696e6720616464726573733a20000000000000000000000000000000815260110192915050565b6000613974601883614235565b7f52657761726473446973747269627574696f6e206f6e6c790000000000000000815260200192915050565b60006139ad601e83614235565b7f412073796e7468206f7220534e58207261746520697320696e76616c69640000815260200192915050565b60006139e6601883614235565b7f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000815260200192915050565b6000613a1f601f83614235565b7f4e6f7420617070726f76656420746f20636c61696d206f6e20626568616c6600815260200192915050565b6000613a58602f83614235565b7f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726681527f6f726d207468697320616374696f6e0000000000000000000000000000000000602082015260400192915050565b6000613ab7601f83614235565b7f432d526174696f2062656c6f772070656e616c7479207468726573686f6c6400815260200192915050565b6000613af0602183614235565b7f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f81527f7700000000000000000000000000000000000000000000000000000000000000602082015260400192915050565b6000613b4f601683614235565b7f43616e6e6f7420696d706f727420626164206461746100000000000000000000815260200192915050565b6000613b88601d83614235565b7f4578636565647320746865204645455f504552494f445f4c454e475448000000815260200192915050565b6000613bc1602983614235565b7f43616e206f6e6c7920706572666f726d207468697320616374696f6e2064757281527f696e672073657475700000000000000000000000000000000000000000000000602082015260400192915050565b6000613c2060198361055e565b7f5265736f6c766572206d697373696e67207461726765743a2000000000000000815260190192915050565b6000613c59601783614235565b7f4665652061646472657373206e6f7420616c6c6f776564000000000000000000815260200192915050565b6000613c9260188361055e565b7f466565506572696f64436c6f7365642875696e74323536290000000000000000815260180192915050565b6000613ccb601783614235565b7f4f6e6c79207468652070726f78792063616e2063616c6c000000000000000000815260200192915050565b6000613d04601e83614235565b7f49737375657220616e642053796e7468657469785374617465206f6e6c790000815260200192915050565b6000613d3d602083614235565b7f43757272656e7420706572696f64206973206e6f7420636c6f73656420796574815260200192915050565b6000613d76601b83614235565b7f46656520506572696f64204475726174696f6e206e6f74207365740000000000815260200192915050565b6134d58161429c565b6134d581614265565b6134d581614272565b6000613dc982856135f8565b602082019150613dd982846134e4565b5060140192915050565b60006106a982613766565b60006106a9826137c5565b6000613e048261392e565b9150613e1082846135f8565b50602001919050565b6000613e0482613c13565b60006106a982613c85565b602081016106a982846134db565b602081016106a982846134cc565b60408101613e5982856134db565b61207460208301846134db565b60408101613e7482856134db565b6120746020830184613653565b60408101613e8f82856134db565b61207460208301846135ef565b60608101613eaa82866134db565b613eb760208301856135ef565b61326f60408301846135ef565b60808101613ed282876134db565b613edf60208301866135ef565b613eec60408301856135ef565b613ef96060830184613da2565b95945050505050565b608081016106a982846134f5565b602080825281016120748184613541565b602081016106a982846135e6565b602081016106a982846135ef565b60408101613e5982856135ef565b60408101613e8f82856135ef565b60408101613f6782856135ef565b818103602083015261326f8184613609565b60c08082528101613f8a8189613609565b9050613f996020830188613653565b613fa660408301876135ef565b613fb3606083018661364a565b613fc0608083018561364a565b613fcd60a083018461364a565b979650505050505050565b60c08082528101613fe98189613609565b9050613ff86020830188613653565b61400560408301876135ef565b613fb360608301866135ef565b602081016106a98284613641565b602080825281016120748184613609565b6020808252810161055b8161365c565b6020808252810161055b81613695565b6020808252810161055b816136f4565b6020808252810161055b8161372d565b6020808252810161055b81613824565b6020808252810161055b8161385d565b6020808252810161055b81613896565b6020808252810161055b816138cf565b6020808252810161055b81613967565b6020808252810161055b816139a0565b6020808252810161055b816139d9565b6020808252810161055b81613a12565b6020808252810161055b81613a4b565b6020808252810161055b81613aaa565b6020808252810161055b81613ae3565b6020808252810161055b81613b42565b6020808252810161055b81613b7b565b6020808252810161055b81613bb4565b6020808252810161055b81613c4c565b6020808252810161055b81613cbe565b6020808252810161055b81613cf7565b6020808252810161055b81613d30565b6020808252810161055b81613d69565b60608101613eaa82866135ef565b60e081016141bd828a613dab565b6141ca6020830189613dab565b6141d76040830188613dab565b6141e460608301876135ef565b6141f160808301866135ef565b6141fe60a08301856135ef565b61420b60c08301846135ef565b98975050505050505050565b602081016106a98284613db4565b60200190565b50600290565b5190565b90815260200190565b600061055b82614259565b151590565b600061055b8261423e565b6001600160a01b031690565b67ffffffffffffffff1690565b60ff1690565b600061055b8261424e565b600061055b6136048361079c565b600061055b8261079c565b600061055b82614265565b60005b838110156142c25781810151838201526020016142aa565b838111156142d1576000848401525b50505050565b600061055b82600061055b826142f2565b601f01601f191690565b60601b90565b6143018161423e565b811461430c57600080fd5b50565b61430181614249565b6143018161079c565b6143018161424e56fea365627a7a72315820311ca67b066d8aa30c5fc3e5d4e569051e36efc62ebf3c8ccc4f5172288bdb2b6c6578706572696d656e74616cf564736f6c63430005100040", "abi": [ { "inputs": [ @@ -13148,10 +13148,10 @@ } ], "source": { - "keccak256": "0x8a65c401cfedc5e54b3544097f5873fff54bed8a0facdd2db530c816e53a93e0", + "keccak256": "0xdb500335962961757d10ccbded7e9de457824b4c2d428c8c9aa63f18a5ca3914", "urls": [ - "bzz-raw://b6de3d5f4f3f6e81c55d6d688ee1160c9c6a8377d554cf9498d439e6251bef07", - "dweb:/ipfs/QmPKF1vLdUUkLm49hUdULnrdBHMX6oqfpgHzGSSKAH7fab" + "bzz-raw://d45068f4b97b8568117b6c095694b7270cad2b0337ea0c2b8b24550dfa93fdbc", + "dweb:/ipfs/QmWYtWcqTszbsZ6tJTg6GcDWdWdGcnNkALBgzRpYPL3EH7" ] }, "metadata": { @@ -13173,10 +13173,10 @@ }, "sources": { "FeePool.sol": { - "keccak256": "0x8a65c401cfedc5e54b3544097f5873fff54bed8a0facdd2db530c816e53a93e0", + "keccak256": "0xdb500335962961757d10ccbded7e9de457824b4c2d428c8c9aa63f18a5ca3914", "urls": [ - "bzz-raw://b6de3d5f4f3f6e81c55d6d688ee1160c9c6a8377d554cf9498d439e6251bef07", - "dweb:/ipfs/QmPKF1vLdUUkLm49hUdULnrdBHMX6oqfpgHzGSSKAH7fab" + "bzz-raw://d45068f4b97b8568117b6c095694b7270cad2b0337ea0c2b8b24550dfa93fdbc", + "dweb:/ipfs/QmWYtWcqTszbsZ6tJTg6GcDWdWdGcnNkALBgzRpYPL3EH7" ] } }, diff --git a/publish/deployed/kovan/deployment.json b/publish/deployed/kovan/deployment.json index 418c14ca41..6d76708700 100644 --- a/publish/deployed/kovan/deployment.json +++ b/publish/deployed/kovan/deployment.json @@ -29,11 +29,11 @@ }, "FeePool": { "name": "FeePool", - "address": "0xE532C9336934DA37aacc0143D07314d7F9D2a8c0", + "address": "0x288cA161F9382d54dD27803AbF45C78Da95D19b0", "source": "FeePool", - "link": "https://kovan.etherscan.io/address/0xE532C9336934DA37aacc0143D07314d7F9D2a8c0", - "timestamp": "2021-11-16T16:15:24.000Z", - "txn": "https://kovan.etherscan.io/tx/0xdd26aec35a24cac358d35b7b3ffdb5b05ed9b497468063585740b14440f09037", + "link": "https://kovan.etherscan.io/address/0x288cA161F9382d54dD27803AbF45C78Da95D19b0", + "timestamp": "2022-01-14T21:51:36.000Z", + "txn": "https://kovan.etherscan.io/tx/0x67b804188bf9a74bb12abe605b8efab8b11c5c298d67118aa8cb38728f312790", "network": "kovan" }, "ProxyFeePool": { @@ -2488,7 +2488,7 @@ ] }, "FeePool": { - "bytecode": "6080604052631cd554d160e21b6007553480156200001c57600080fd5b506040516200472c3803806200472c8339810160408190526200003f9162000221565b8080621baf8085856001600160a01b038116620000795760405162461bcd60e51b8152600401620000709062000343565b60405180910390fd5b600080546001600160a01b0319166001600160a01b0383161781556040517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c91620000c69184906200030b565b60405180910390a1506000546001600160a01b0316620000fa5760405162461bcd60e51b8152600401620000709062000331565b600280546001600160a01b0319166001600160a01b0383161790556040517ffc80377ca9c49cc11ae6982f390a42db976d5530af7c43889264b13fbbd7c57e9062000147908390620002fb565b60405180910390a1504201600455600580546001600160a01b0319166001600160a01b0392909216919091179055506001620001846000620001e2565b80546001600160401b0319166001600160401b039290921691909117905542620001af6000620001e2565b80546001600160401b0392909216600160801b02600160801b600160c01b0319909216919091179055506200039e915050565b60006008600260ff16836012540181620001f857fe5b06600281106200020457fe5b6005020192915050565b80516200021b8162000384565b92915050565b6000806000606084860312156200023757600080fd5b60006200024586866200020e565b935050602062000258868287016200020e565b92505060406200026b868287016200020e565b9150509250925092565b620002808162000370565b82525050565b62000280816200035e565b6000620002a060118362000355565b7013dddb995c881b5d5cdd081899481cd95d607a1b815260200192915050565b6000620002cf60198362000355565b7f4f776e657220616464726573732063616e6e6f74206265203000000000000000815260200192915050565b602081016200021b828462000275565b604081016200031b828562000275565b6200032a602083018462000286565b9392505050565b602080825281016200021b8162000291565b602080825281016200021b81620002c0565b90815260200190565b60006001600160a01b0382166200021b565b60006200021b8260006200021b826200035e565b6200038f816200035e565b81146200039b57600080fd5b50565b61437e80620003ae6000396000f3fe608060405234801561001057600080fd5b50600436106102415760003560e01c80636de813f111610145578063b410a034116100bd578063d67bdd251161008c578063eb1edd6111610071578063eb1edd611461045c578063ec55688914610464578063fd1f498d1461046c57610241565b8063d67bdd251461044c578063e0e6393d1461045457610241565b8063b410a03414610414578063bc67f8321461041c578063cff2ddad1461042f578063d294f0931461044457610241565b8063899ffef41161011457806397107d6d116100f957806397107d6d146103e6578063ac834193146103f9578063b10090b81461040157610241565b8063899ffef4146103c95780638da5cb5b146103de57610241565b80636de813f11461039e57806374185360146103a657806379ba5097146103ae57806386645274146103b657610241565b806333140016116101d857806353a47bb7116101a757806359a2f19f1161018c57806359a2f19f14610370578063614d08f8146103835780636466f45e1461038b57610241565b806353a47bb714610353578063569249d01461036857610241565b806333140016146102fd5780633ebc457a1461031d5780633fcd22401461032557806346ba2d901461034b57610241565b80631627540c116102145780631627540c146102b857806322425fa4146102cd57806322bf55ef146102d55780632af64bd3146102e857610241565b806304f3bcec1461024657806307ea50cd146102645780630813071c146102845780630de5861514610297575b600080fd5b61024e61047f565b60405161025b9190614023565b60405180910390f35b610277610272366004613262565b61048e565b60405161025b9190613f40565b6102776102923660046132a6565b610563565b6102aa6102a5366004613262565b6106af565b60405161025b929190613f5c565b6102cb6102c6366004613262565b610731565b005b61027761078f565b6102cb6102e3366004613387565b61079f565b6102f0610978565b60405161025b9190613f32565b61031061030b366004613262565b610aa8565b60405161025b9190613f13565b6102cb610d0c565b610338610333366004613387565b611112565b60405161025b97969594939291906141c0565b6102776111bb565b61035b6111c1565b60405161025b9190613e40565b6102776111d0565b6102f061037e366004613262565b61122b565b61027761123d565b6102f0610399366004613262565b611261565b61027761138d565b6102cb6113e2565b6102cb611534565b6102cb6103c43660046132e0565b6115d0565b6103d1611710565b60405161025b9190613f21565b61035b611a30565b6102cb6103f4366004613262565b611a3f565b610277611a92565b6102cb61040f366004613405565b611b32565b610277611d2c565b6102cb61042a366004613262565b611d36565b610437611d60565b60405161025b9190614228565b6102f0611d65565b61035b611ddc565b610277611deb565b61035b611df5565b61024e611e0d565b6102cb61047a366004613387565b611e1c565b6005546001600160a01b031681565b6000610498611e99565b6001600160a01b031663bdc963d87f6c6173745f6665655f7769746864726177616c00000000000000000000000000846040516020016104d9929190613dce565b604051602081830303815290604052805190602001206040518263ffffffff1660e01b815260040161050b9190613f40565b60206040518083038186803b15801561052357600080fd5b505afa158015610537573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061055b919081019061334b565b90505b919050565b60008161058b5760405162461bcd60e51b815260040161058290614192565b60405180910390fd5b600282106105ab5760405162461bcd60e51b815260040161058290614142565b6105b760018303611ec4565b5468010000000000000000900467ffffffffffffffff166105da575060006106a9565b600061060a60016105ed60018603611ec4565b5468010000000000000000900467ffffffffffffffff1690611eee565b9050600080610617611f16565b6001600160a01b031663d29c000a87856040518363ffffffff1660e01b8152600401610644929190613e92565b604080518083038186803b15801561065b57600080fd5b505afa15801561066f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061069391908101906133d5565b90925090506106a3838383611f41565b93505050505b92915050565b6000806106ba61317a565b6106c384610aa8565b905060008060015b6002811015610724576106f08482600281106106e357fe5b602002015151849061208c565b925061071a84826002811061070157fe5b602002015160016020020151839063ffffffff61208c16565b91506001016106cb565b509093509150505b915091565b6107396120b1565b600180546001600160a01b0319166001600160a01b0383161790556040517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce2290610784908390613e40565b60405180910390a150565b60006107996120dd565b90505b90565b60006107a96121a4565b6001600160a01b0316331490506000806107c16121cf565b6001600160a01b03166316b2213f336040518263ffffffff1660e01b81526004016107ec9190613e4e565b60206040518083038186803b15801561080457600080fd5b505afa158015610818573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061083c919081019061334b565b14159050600061084a6121e3565b6001600160a01b031663b38988f7336040518263ffffffff1660e01b81526004016108759190613e4e565b60206040518083038186803b15801561088d57600080fd5b505afa1580156108a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506108c5919081019061332d565b905060006108d161220e565b6001600160a01b0316336001600160a01b031614905060006108f1612239565b6001600160a01b0316336001600160a01b031614905084806109105750835b806109185750825b806109205750815b806109285750805b6109445760405162461bcd60e51b815260040161058290614042565b610962866109526000611ec4565b600101549063ffffffff61208c16565b61096c6000611ec4565b60010155505050505050565b60006060610984611710565b905060005b8151811015610a9f5760008282815181106109a057fe5b602090810291909101810151600081815260069092526040918290205460055492517f21f8a7210000000000000000000000000000000000000000000000000000000081529193506001600160a01b039081169216906321f8a72190610a0a908590600401613f40565b60206040518083038186803b158015610a2257600080fd5b505afa158015610a36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610a5a9190810190613288565b6001600160a01b0316141580610a8557506000818152600660205260409020546001600160a01b0316155b15610a96576000935050505061079c565b50600101610989565b50600191505090565b610ab061317a565b6000806000610abd611f16565b6040517fb326f84e0000000000000000000000000000000000000000000000000000000081529091506001600160a01b0382169063b326f84e90610b08908890600090600401613e77565b604080518083038186803b158015610b1f57600080fd5b505afa158015610b33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610b5791908101906133d5565b909350915081158015610b68575082155b15610b8057610b7561317a565b935061055e92505050565b600080610b8f60008686612264565b8751829052875160200181905290925090506000610bac8861048e565b905060015b8015610d005760001981016000610bc782611ec4565b5468010000000000000000900467ffffffffffffffff1690508015801590610c015750610bf383611ec4565b5467ffffffffffffffff1684105b15610cf5576000610c1982600163ffffffff611eee16565b6040517fd29c000a0000000000000000000000000000000000000000000000000000000081529091506001600160a01b0389169063d29c000a90610c63908f908590600401613e92565b604080518083038186803b158015610c7a57600080fd5b505afa158015610c8e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610cb291908101906133d5565b909a509850610cc2848b8b612264565b9097509550868b8560028110610cd457fe5b602002015152858b8560028110610ce757fe5b602002015160016020020152505b505060001901610bb1565b50505050505050919050565b610d14612306565b6001600160a01b0316637c3125416040518163ffffffff1660e01b815260040160006040518083038186803b158015610d4c57600080fd5b505afa158015610d60573d6000803e3d6000fd5b505050506000610d6e6120dd565b11610d8b5760405162461bcd60e51b8152600401610582906141a2565b610d936120dd565b4203610d9f6000611ec4565b54600160801b900467ffffffffffffffff161115610dcf5760405162461bcd60e51b815260040161058290614062565b610dd761220e565b6001600160a01b031663bb57ad206040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610e1157600080fd5b505af1158015610e25573d6000803e3d6000fd5b50505050610e31612239565b6001600160a01b031663bb57ad206040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610e6b57600080fd5b505af1158015610e7f573d6000803e3d6000fd5b5060009250610e919150829050611ec4565b90506000610e9f6001611ec4565b9050610ed08260010154610ec483600201548460010154611eee90919063ffffffff16565b9063ffffffff61208c16565b610eda6000611ec4565b60010155600380830154600483015491830154610f0192610ec4919063ffffffff611eee16565b610f0b6000611ec4565b60030155601254610f4890600290610f3c90600190610f30908463ffffffff61208c16565b9063ffffffff611eee16565b9063ffffffff61233116565b601281905560089060028110610f5a57fe5b6005020180547fffffffffffffffff000000000000000000000000000000000000000000000000168155600060018083018290556002830182905560038301829055600490920155610fc690610faf81611ec4565b5467ffffffffffffffff169063ffffffff61208c16565b610fd06000611ec4565b805467ffffffffffffffff191667ffffffffffffffff92909216919091179055610ff8612361565b6001600160a01b031663cd92eba96040518163ffffffff1660e01b815260040160206040518083038186803b15801561103057600080fd5b505afa158015611044573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611068919081019061334b565b6110726000611ec4565b805467ffffffffffffffff9290921668010000000000000000026fffffffffffffffff000000000000000019909216919091179055426110b26000611ec4565b805467ffffffffffffffff92909216600160801b027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff90921691909117905561110e6110fe6001611ec4565b5467ffffffffffffffff1661238c565b5050565b60008060008060008060006111256131a7565b61112e89611ec4565b6040805160e081018252825467ffffffffffffffff808216808452680100000000000000008304821660208501819052600160801b909304909116938301849052600185015460608401819052600286015460808501819052600387015460a0860181905260049097015460c0909501859052919f929e50939c50929a5091985091965090945092505050565b60045481565b6001546001600160a01b031681565b60008060015b6002811015611225576111fc6111eb82611ec4565b60010154839063ffffffff61208c16565b915061121b61120a82611ec4565b60020154839063ffffffff611eee16565b91506001016111d6565b50905090565b600061123682612444565b5092915050565b7f466565506f6f6c0000000000000000000000000000000000000000000000000081565b600061126b612306565b6001600160a01b0316637c3125416040518163ffffffff1660e01b815260040160006040518083038186803b1580156112a357600080fd5b505afa1580156112b7573d6000803e3d6000fd5b505050506112c3612538565b6112cb612577565b6003546040517f21f4ae570000000000000000000000000000000000000000000000000000000081526001600160a01b03928316926321f4ae579261131892879290911690600401613e5c565b60206040518083038186803b15801561133057600080fd5b505afa158015611344573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611368919081019061332d565b6113845760405162461bcd60e51b8152600401610582906140e2565b61055b826125a2565b60008060015b6002811015611225576113b96113a882611ec4565b60030154839063ffffffff61208c16565b91506113d86113c782611ec4565b60040154839063ffffffff611eee16565b9150600101611393565b60606113ec611710565b905060005b815181101561110e57600082828151811061140857fe5b602002602001015190506000600560009054906101000a90046001600160a01b03166001600160a01b031663dacb2d01838460405160200161144a9190613e2a565b6040516020818303038152906040526040518363ffffffff1660e01b8152600401611476929190613f6a565b60206040518083038186803b15801561148e57600080fd5b505afa1580156114a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506114c69190810190613288565b6000838152600660205260409081902080546001600160a01b0319166001600160a01b038416179055519091507f88a93678a3692f6789d9546fc621bf7234b101ddb7d4fe479455112831b8aa68906115229084908490613f4e565b60405180910390a150506001016113f1565b6001546001600160a01b0316331461155e5760405162461bcd60e51b815260040161058290614052565b6000546001546040517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c926115a1926001600160a01b0391821692911690613e5c565b60405180910390a160018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b60006115da6121cf565b6001600160a01b0316336001600160a01b031614905060006115fa612361565b6001600160a01b0316336001600160a01b031614905081806116195750805b6116355760405162461bcd60e51b815260040161058290614182565b61163d611f16565b6001600160a01b03166394e1a4488686866116586000611ec4565b5460405160e086901b7fffffffff000000000000000000000000000000000000000000000000000000001681526116ab9493929168010000000000000000900467ffffffffffffffff1690600401613ed5565b600060405180830381600087803b1580156116c557600080fd5b505af11580156116d9573d6000803e3d6000fd5b505050506117098585856116ed6000611ec4565b5468010000000000000000900467ffffffffffffffff16612697565b5050505050565b60608061171b612766565b60408051600d8082526101c0820190925291925060609190602082016101a0803883390190505090507f53797374656d53746174757300000000000000000000000000000000000000008160008151811061177257fe5b6020026020010181815250507f53796e7468657469780000000000000000000000000000000000000000000000816001815181106117ac57fe5b6020026020010181815250507f466565506f6f6c53746174650000000000000000000000000000000000000000816002815181106117e657fe5b6020026020010181815250507f466565506f6f6c457465726e616c53746f7261676500000000000000000000008160038151811061182057fe5b6020026020010181815250507f45786368616e67657200000000000000000000000000000000000000000000008160048151811061185a57fe5b6020026020010181815250506524b9b9bab2b960d11b8160058151811061187d57fe5b6020026020010181815250507f53796e7468657469785374617465000000000000000000000000000000000000816006815181106118b757fe5b6020026020010181815250507f526577617264457363726f775632000000000000000000000000000000000000816007815181106118f157fe5b6020026020010181815250507f44656c6567617465417070726f76616c730000000000000000000000000000008160088151811061192b57fe5b6020026020010181815250507f52657761726473446973747269627574696f6e000000000000000000000000008160098151811061196557fe5b6020026020010181815250507f436f6c6c61746572616c4d616e6167657200000000000000000000000000000081600a8151811061199f57fe5b6020026020010181815250507f57726170706572466163746f727900000000000000000000000000000000000081600b815181106119d957fe5b6020026020010181815250507f457468657257726170706572000000000000000000000000000000000000000081600c81518110611a1357fe5b602002602001018181525050611a2982826127c5565b9250505090565b6000546001600160a01b031681565b611a476120b1565b600280546001600160a01b0319166001600160a01b0383161790556040517ffc80377ca9c49cc11ae6982f390a42db976d5530af7c43889264b13fbbd7c57e90610784908390613e4e565b6000610799611b1e611aa261287a565b73__$f9217daff40bcb29719cec84f7ab900933$__63907af6c06040518163ffffffff1660e01b815260040160206040518083038186803b158015611ae657600080fd5b505af4158015611afa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ec4919081019061334b565b611b266128f1565b9063ffffffff61296816565b611b3a612992565b6004544210611b5b5760405162461bcd60e51b815260040161058290614152565b611b63612361565b6001600160a01b031663cd92eba96040518163ffffffff1660e01b815260040160206040518083038186803b158015611b9b57600080fd5b505afa158015611baf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611bd3919081019061334b565b861115611bf25760405162461bcd60e51b815260040161058290614132565b6040518060e001604052808867ffffffffffffffff1681526020018767ffffffffffffffff1681526020018667ffffffffffffffff168152602001858152602001848152602001838152602001828152506008611c62600260ff16610f3c8c60125461208c90919063ffffffff16565b60028110611c6c57fe5b82516005919091029190910180546020840151604085015167ffffffffffffffff1990921667ffffffffffffffff948516176fffffffffffffffff000000000000000019166801000000000000000091851691909102177fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff16600160801b9390911692909202919091178155606082015160018201556080820151600282015560a0820151600382015560c0909101516004909101555050505050505050565b60006107996128f1565b611d3e612a00565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b600281565b6000611d6f612306565b6001600160a01b0316637c3125416040518163ffffffff1660e01b815260040160006040518083038186803b158015611da757600080fd5b505afa158015611dbb573d6000803e3d6000fd5b50505050611dc7612538565b600354610799906001600160a01b03166125a2565b6003546001600160a01b031681565b600061079961287a565b73feefeefeefeefeefeefeefeefeefeefeefeefeef81565b6002546001600160a01b031681565b6000611e26612a2a565b6003549091506001600160a01b0380831691161480611e4d5750336001600160a01b038216145b611e695760405162461bcd60e51b8152600401610582906140f2565b611e8782611e776000611ec4565b600301549063ffffffff61208c16565b611e916000611ec4565b600301555050565b60006107997f466565506f6f6c457465726e616c53746f726167650000000000000000000000612a51565b60006008600260ff16836012540181611ed957fe5b0660028110611ee457fe5b6005020192915050565b600082821115611f105760405162461bcd60e51b815260040161058290614092565b50900390565b60006107997f466565506f6f6c53746174650000000000000000000000000000000000000000612a51565b600080611f4c612361565b9050600061208085612074846001600160a01b03166308d95cd5886040518263ffffffff1660e01b8152600401611f839190613f40565b60206040518083038186803b158015611f9b57600080fd5b505afa158015611faf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611fd3919081019061334b565b6040517f08d95cd50000000000000000000000000000000000000000000000000000000081526001600160a01b038716906308d95cd590612018908d90600401613f40565b60206040518083038186803b15801561203057600080fd5b505afa158015612044573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612068919081019061334b565b9063ffffffff612aae16565b9063ffffffff612ac716565b925050505b9392505050565b6000828201838110156120855760405162461bcd60e51b815260040161058290614082565b6000546001600160a01b031633146120db5760405162461bcd60e51b815260040161058290614102565b565b60006120e7612ae0565b6001600160a01b03166323257c2b7f53797374656d53657474696e67730000000000000000000000000000000000007f666565506572696f644475726174696f6e0000000000000000000000000000006040518363ffffffff1660e01b8152600401612154929190613f5c565b60206040518083038186803b15801561216c57600080fd5b505afa158015612180573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610799919081019061334b565b60006107997f45786368616e6765720000000000000000000000000000000000000000000000612a51565b60006107996524b9b9bab2b960d11b612a51565b60006107997f436f6c6c61746572616c4d616e61676572000000000000000000000000000000612a51565b60006107997f4574686572577261707065720000000000000000000000000000000000000000612a51565b60006107997f57726170706572466163746f7279000000000000000000000000000000000000612a51565b60008083612277575060009050806122fe565b8385156122a257600061229160016105ed60018a03611ec4565b905061229e818787611f41565b9150505b60006122c1826122b189611ec4565b600101549063ffffffff61296816565b905060006122e2836122d28a611ec4565b600301549063ffffffff61296816565b90506122ed82612b0b565b6122f682612b0b565b945094505050505b935093915050565b60006107997f53797374656d5374617475730000000000000000000000000000000000000000612a51565b6000816123505760405162461bcd60e51b8152600401610582906140d2565b81838161235957fe5b069392505050565b60006107997f53796e7468657469785374617465000000000000000000000000000000000000612a51565b6002546040516001600160a01b039091169063907dff97906123b2908490602001613f40565b60405160208183030381529060405260016040516123cf90613e35565b6040519081900381207fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16825261241693929160009081908190600401613f8a565b600060405180830381600087803b15801561243057600080fd5b505af1158015611709573d6000803e3d6000fd5b6000806000806124526121cf565b6001600160a01b031663ae3bbbbb866040518263ffffffff1660e01b815260040161247d9190613e40565b604080518083038186803b15801561249457600080fd5b505afa1580156124a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506124cc91908101906133a5565b9150915060006124da6128f1565b9050808310156124f2575060019350915061072c9050565b600061250f612502611aa261287a565b839063ffffffff61296816565b90508084111561252957600083955095505050505061072c565b50600194509092505050915091565b6002546001600160a01b0316331480159061255e57506003546001600160a01b03163314155b156120db57600380546001600160a01b03191633179055565b60006107997f44656c6567617465417070726f76616c73000000000000000000000000000000612a51565b60008080808080806125b388612444565b91509150816125d45760405162461bcd60e51b815260040161058290614112565b80156125f25760405162461bcd60e51b8152600401610582906140c2565b6125fb886106af565b90945092508315158061260e5750600083115b61262a5760405162461bcd60e51b8152600401610582906140b2565b612648886126386001611ec4565b5467ffffffffffffffff16612b2d565b83156126635761265784612be0565b94506126638886612cbc565b821561267e5761267283612e58565b955061267e8887612f32565b612689888688612fac565b506001979650505050505050565b6002546040516001600160a01b039091169063907dff97906126c1908690869086906020016141b2565b60405160208183030381529060405260026040516126de90613dff565b6040519081900381207fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16825261272e9392916001600160a01b038b16906000908190600401613fe9565b600060405180830381600087803b15801561274857600080fd5b505af115801561275c573d6000803e3d6000fd5b5050505050505050565b604080516001808252818301909252606091602080830190803883390190505090507f466c657869626c6553746f726167650000000000000000000000000000000000816000815181106127b657fe5b60200260200101818152505090565b606081518351016040519080825280602002602001820160405280156127f5578160200160208202803883390190505b50905060005b83518110156128375783818151811061281057fe5b602002602001015182828151811061282457fe5b60209081029190910101526001016127fb565b5060005b82518110156112365782818151811061285057fe5b602002602001015182828651018151811061286757fe5b602090810291909101015260010161283b565b6000612884612ae0565b6001600160a01b03166323257c2b7f53797374656d53657474696e67730000000000000000000000000000000000007f7461726765745468726573686f6c6400000000000000000000000000000000006040518363ffffffff1660e01b8152600401612154929190613f5c565b60006128fb612ae0565b6001600160a01b03166323257c2b7f53797374656d53657474696e67730000000000000000000000000000000000007f69737375616e6365526174696f000000000000000000000000000000000000006040518363ffffffff1660e01b8152600401612154929190613f5c565b6000670de0b6b3a7640000612983848463ffffffff61307116565b8161298a57fe5b049392505050565b6002546001600160a01b031633148015906129b857506003546001600160a01b03163314155b156129d057600380546001600160a01b031916331790555b6000546003546001600160a01b039081169116146120db5760405162461bcd60e51b815260040161058290614072565b6002546001600160a01b031633146120db5760405162461bcd60e51b815260040161058290614172565b60006107997f52657761726473446973747269627574696f6e000000000000000000000000005b60008181526006602090815260408083205490516001600160a01b039091169182151591612a8191869101613e0a565b604051602081830303815290604052906112365760405162461bcd60e51b81526004016105829190614031565b600061208583836b033b2e3c9fd0803ce80000006130ab565b600061208583836b033b2e3c9fd0803ce80000006130ef565b60006107997f466c657869626c6553746f726167650000000000000000000000000000000000612a51565b60006305f5e10082046005600a820610612b2357600a015b600a900492915050565b612b35611e99565b6001600160a01b0316633562fd207f6c6173745f6665655f7769746864726177616c0000000000000000000000000084604051602001612b76929190613dce565b60405160208183030381529060405280519060200120836040518363ffffffff1660e01b8152600401612baa929190613f5c565b600060405180830381600087803b158015612bc457600080fd5b505af1158015612bd8573d6000803e3d6000fd5b505050505050565b6000818160015b6002811015612cb4576000612bfb82611ec4565b6002015490506000612c2082612c1085611ec4565b600101549063ffffffff611eee16565b90508015612ca9576000858210612c375785612c39565b815b9050612c4b838263ffffffff61208c16565b612c5485611ec4565b60020155612c68868263ffffffff611eee16565b9550612c7a858263ffffffff61208c16565b945085612c8f5784965050505050505061055e565b83158015612c9d5750600086115b15612ca757600095505b505b505060001901612be7565b509392505050565b816001600160a01b03811673feefeefeefeefeefeefeefeefeefeefeefeefeef1415612cfa5760405162461bcd60e51b815260040161058290614162565b6000612d046121cf565b6001600160a01b031663326080396007546040518263ffffffff1660e01b8152600401612d319190613f40565b60206040518083038186803b158015612d4957600080fd5b505afa158015612d5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612d819190810190613369565b6040517f9dc29fac0000000000000000000000000000000000000000000000000000000081529091506001600160a01b03821690639dc29fac90612ddf9073feefeefeefeefeefeefeefeefeefeefeefeefeef908790600401613e92565b600060405180830381600087803b158015612df957600080fd5b505af1158015612e0d573d6000803e3d6000fd5b50506040517f867904b40000000000000000000000000000000000000000000000000000000081526001600160a01b038416925063867904b4915061272e9087908790600401613e92565b6000818160015b6002811015612cb4576000612e93612e7683611ec4565b60040154612e8384611ec4565b600301549063ffffffff611eee16565b90508015612f28576000848210612eaa5784612eac565b815b9050612ecb81612ebb85611ec4565b600401549063ffffffff61208c16565b612ed484611ec4565b60040155612ee8858263ffffffff611eee16565b9450612efa848263ffffffff61208c16565b935084612f0e57839550505050505061055e565b82158015612f1c5750600085115b15612f2657600094505b505b5060001901612e5f565b816001600160a01b03811673feefeefeefeefeefeefeefeefeefeefeefeefeef1415612f705760405162461bcd60e51b815260040161058290614162565b6301dfe200612f7d61311a565b6001600160a01b0316631bb47b448585846040518463ffffffff1660e01b815260040161272e93929190613ead565b6002546040516001600160a01b039091169063907dff9790612fd690869086908690602001613ead565b6040516020818303038152906040526001604051612ff390613df4565b6040519081900381207fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16825261303a93929160009081908190600401613f8a565b600060405180830381600087803b15801561305457600080fd5b505af1158015613068573d6000803e3d6000fd5b50505050505050565b600082613080575060006106a9565b8282028284828161308d57fe5b04146120855760405162461bcd60e51b815260040161058290614122565b6000806130d1846130c587600a870263ffffffff61307116565b9063ffffffff61314516565b90506005600a825b06106130e357600a015b600a9004949350505050565b600080600a8304613106868663ffffffff61307116565b8161310d57fe5b0490506005600a826130d9565b60006107997f526577617264457363726f775632000000000000000000000000000000000000612a51565b60008082116131665760405162461bcd60e51b8152600401610582906140a2565b600082848161317157fe5b04949350505050565b60405180604001604052806002905b613191613202565b8152602001906001900390816131895790505090565b6040518060e00160405280600067ffffffffffffffff168152602001600067ffffffffffffffff168152602001600067ffffffffffffffff168152602001600081526020016000815260200160008152602001600081525090565b60405180604001604052806002906020820280388339509192915050565b80356106a981614309565b80516106a981614309565b80516106a981614320565b80516106a981614329565b80516106a981614332565b80356106a981614329565b60006020828403121561327457600080fd5b60006132808484613220565b949350505050565b60006020828403121561329a57600080fd5b6000613280848461322b565b600080604083850312156132b957600080fd5b60006132c58585613220565b92505060206132d685828601613257565b9150509250929050565b6000806000606084860312156132f557600080fd5b60006133018686613220565b935050602061331286828701613257565b925050604061332386828701613257565b9150509250925092565b60006020828403121561333f57600080fd5b60006132808484613236565b60006020828403121561335d57600080fd5b60006132808484613241565b60006020828403121561337b57600080fd5b6000613280848461324c565b60006020828403121561339957600080fd5b60006132808484613257565b600080604083850312156133b857600080fd5b60006133c48585613241565b92505060206132d685828601613236565b600080604083850312156133e857600080fd5b60006133f48585613241565b92505060206132d685828601613241565b600080600080600080600080610100898b03121561342257600080fd5b600061342e8b8b613257565b985050602061343f8b828c01613257565b97505060406134508b828c01613257565b96505060606134618b828c01613257565b95505060806134728b828c01613257565b94505060a06134838b828c01613257565b93505060c06134948b828c01613257565b92505060e06134a58b828c01613257565b9150509295985092959890939650565b60006134c183836135ab565b505060400190565b60006134d58383613600565b505060200190565b6134e681614289565b82525050565b6134e68161424f565b6134e66135018261424f565b6142e8565b61350f8161423c565b613519818461055e565b92506135248261079c565b8060005b83811015612bd857815161353c87826134b5565b965061354783614236565b925050600101613528565b600061355d82614242565b6135678185614246565b935061357283614236565b8060005b838110156135a057815161358a88826134c9565b975061359583614236565b925050600101613576565b509495945050505050565b6135b48161423c565b6135be818461055e565b92506135c98261079c565b8060005b83811015612bd85781516135e187826134c9565b96506135ec83614236565b9250506001016135cd565b6134e68161425a565b6134e68161079c565b6134e66136158261079c565b61079c565b600061362582614242565b61362f8185614246565b935061363f8185602086016142b8565b613648816142f9565b9093019392505050565b6134e68161425f565b6134e681614294565b6134e6816142a2565b600061367a601783614246565b7f4f6e6c7920496e7465726e616c20436f6e747261637473000000000000000000815260200192915050565b60006136b3603583614246565b7f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7581527f2063616e20616363657074206f776e6572736869700000000000000000000000602082015260400192915050565b6000613712601d83614246565b7f546f6f206561726c7920746f20636c6f73652066656520706572696f64000000815260200192915050565b600061374b601383614246565b7f4f776e6572206f6e6c792066756e6374696f6e00000000000000000000000000815260200192915050565b600061378460248361055e565b7f46656573436c61696d656428616464726573732c75696e743235362c75696e7481527f3235362900000000000000000000000000000000000000000000000000000000602082015260240192915050565b60006137e360378361055e565b7f49737375616e636544656274526174696f456e74727928616464726573732c7581527f696e743235362c75696e743235362c75696e7432353629000000000000000000602082015260370192915050565b6000613842601b83614246565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815260200192915050565b600061387b601e83614246565b7f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815260200192915050565b60006138b4601a83614246565b7f536166654d6174683a206469766973696f6e206279207a65726f000000000000815260200192915050565b60006138ed604083614246565b7f4e6f2066656573206f72207265776172647320617661696c61626c6520666f7281527f20706572696f642c206f72206665657320616c726561647920636c61696d6564602082015260400192915050565b600061394c60118361055e565b7f4d697373696e6720616464726573733a20000000000000000000000000000000815260110192915050565b6000613985601e83614246565b7f412073796e7468206f7220534e58207261746520697320696e76616c69640000815260200192915050565b60006139be601883614246565b7f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000815260200192915050565b60006139f7601f83614246565b7f4e6f7420617070726f76656420746f20636c61696d206f6e20626568616c6600815260200192915050565b6000613a30601e83614246565b7f43616c6c6572206973206e6f742072657761726473417574686f726974790000815260200192915050565b6000613a69602f83614246565b7f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726681527f6f726d207468697320616374696f6e0000000000000000000000000000000000602082015260400192915050565b6000613ac8601f83614246565b7f432d526174696f2062656c6f772070656e616c7479207468726573686f6c6400815260200192915050565b6000613b01602183614246565b7f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f81527f7700000000000000000000000000000000000000000000000000000000000000602082015260400192915050565b6000613b60601683614246565b7f43616e6e6f7420696d706f727420626164206461746100000000000000000000815260200192915050565b6000613b99601d83614246565b7f4578636565647320746865204645455f504552494f445f4c454e475448000000815260200192915050565b6000613bd2602983614246565b7f43616e206f6e6c7920706572666f726d207468697320616374696f6e2064757281527f696e672073657475700000000000000000000000000000000000000000000000602082015260400192915050565b6000613c3160198361055e565b7f5265736f6c766572206d697373696e67207461726765743a2000000000000000815260190192915050565b6000613c6a601783614246565b7f4665652061646472657373206e6f7420616c6c6f776564000000000000000000815260200192915050565b6000613ca360188361055e565b7f466565506572696f64436c6f7365642875696e74323536290000000000000000815260180192915050565b6000613cdc601783614246565b7f4f6e6c79207468652070726f78792063616e2063616c6c000000000000000000815260200192915050565b6000613d15601e83614246565b7f49737375657220616e642053796e7468657469785374617465206f6e6c790000815260200192915050565b6000613d4e602083614246565b7f43757272656e7420706572696f64206973206e6f7420636c6f73656420796574815260200192915050565b6000613d87601b83614246565b7f46656520506572696f64204475726174696f6e206e6f74207365740000000000815260200192915050565b6134e6816142ad565b6134e681614276565b6134e681614283565b6000613dda8285613609565b602082019150613dea82846134f5565b5060140192915050565b60006106a982613777565b60006106a9826137d6565b6000613e158261393f565b9150613e218284613609565b50602001919050565b6000613e1582613c24565b60006106a982613c96565b602081016106a982846134ec565b602081016106a982846134dd565b60408101613e6a82856134ec565b61208560208301846134ec565b60408101613e8582856134ec565b6120856020830184613664565b60408101613ea082856134ec565b6120856020830184613600565b60608101613ebb82866134ec565b613ec86020830185613600565b6132806040830184613600565b60808101613ee382876134ec565b613ef06020830186613600565b613efd6040830185613600565b613f0a6060830184613db3565b95945050505050565b608081016106a98284613506565b602080825281016120858184613552565b602081016106a982846135f7565b602081016106a98284613600565b60408101613e6a8285613600565b60408101613ea08285613600565b60408101613f788285613600565b8181036020830152613280818461361a565b60c08082528101613f9b818961361a565b9050613faa6020830188613664565b613fb76040830187613600565b613fc4606083018661365b565b613fd1608083018561365b565b613fde60a083018461365b565b979650505050505050565b60c08082528101613ffa818961361a565b90506140096020830188613664565b6140166040830187613600565b613fc46060830186613600565b602081016106a98284613652565b60208082528101612085818461361a565b6020808252810161055b8161366d565b6020808252810161055b816136a6565b6020808252810161055b81613705565b6020808252810161055b8161373e565b6020808252810161055b81613835565b6020808252810161055b8161386e565b6020808252810161055b816138a7565b6020808252810161055b816138e0565b6020808252810161055b81613978565b6020808252810161055b816139b1565b6020808252810161055b816139ea565b6020808252810161055b81613a23565b6020808252810161055b81613a5c565b6020808252810161055b81613abb565b6020808252810161055b81613af4565b6020808252810161055b81613b53565b6020808252810161055b81613b8c565b6020808252810161055b81613bc5565b6020808252810161055b81613c5d565b6020808252810161055b81613ccf565b6020808252810161055b81613d08565b6020808252810161055b81613d41565b6020808252810161055b81613d7a565b60608101613ebb8286613600565b60e081016141ce828a613dbc565b6141db6020830189613dbc565b6141e86040830188613dbc565b6141f56060830187613600565b6142026080830186613600565b61420f60a0830185613600565b61421c60c0830184613600565b98975050505050505050565b602081016106a98284613dc5565b60200190565b50600290565b5190565b90815260200190565b600061055b8261426a565b151590565b600061055b8261424f565b6001600160a01b031690565b67ffffffffffffffff1690565b60ff1690565b600061055b8261425f565b600061055b6136158361079c565b600061055b8261079c565b600061055b82614276565b60005b838110156142d35781810151838201526020016142bb565b838111156142e2576000848401525b50505050565b600061055b82600061055b82614303565b601f01601f191690565b60601b90565b6143128161424f565b811461431d57600080fd5b50565b6143128161425a565b6143128161079c565b6143128161425f56fea365627a7a7231582023fb25e610f0e82a8e13a44599008ec503839a1c5669bf3ffe153f41941fe4c36c6578706572696d656e74616cf564736f6c63430005100040", + "bytecode": "6080604052631cd554d160e21b6007553480156200001c57600080fd5b506040516200471b3803806200471b8339810160408190526200003f9162000221565b8080621baf8085856001600160a01b038116620000795760405162461bcd60e51b8152600401620000709062000343565b60405180910390fd5b600080546001600160a01b0319166001600160a01b0383161781556040517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c91620000c69184906200030b565b60405180910390a1506000546001600160a01b0316620000fa5760405162461bcd60e51b8152600401620000709062000331565b600280546001600160a01b0319166001600160a01b0383161790556040517ffc80377ca9c49cc11ae6982f390a42db976d5530af7c43889264b13fbbd7c57e9062000147908390620002fb565b60405180910390a1504201600455600580546001600160a01b0319166001600160a01b0392909216919091179055506001620001846000620001e2565b80546001600160401b0319166001600160401b039290921691909117905542620001af6000620001e2565b80546001600160401b0392909216600160801b02600160801b600160c01b0319909216919091179055506200039e915050565b60006008600260ff16836012540181620001f857fe5b06600281106200020457fe5b6005020192915050565b80516200021b8162000384565b92915050565b6000806000606084860312156200023757600080fd5b60006200024586866200020e565b935050602062000258868287016200020e565b92505060406200026b868287016200020e565b9150509250925092565b620002808162000370565b82525050565b62000280816200035e565b6000620002a060118362000355565b7013dddb995c881b5d5cdd081899481cd95d607a1b815260200192915050565b6000620002cf60198362000355565b7f4f776e657220616464726573732063616e6e6f74206265203000000000000000815260200192915050565b602081016200021b828462000275565b604081016200031b828562000275565b6200032a602083018462000286565b9392505050565b602080825281016200021b8162000291565b602080825281016200021b81620002c0565b90815260200190565b60006001600160a01b0382166200021b565b60006200021b8260006200021b826200035e565b6200038f816200035e565b81146200039b57600080fd5b50565b61436d80620003ae6000396000f3fe608060405234801561001057600080fd5b50600436106102415760003560e01c80636de813f111610145578063b410a034116100bd578063d67bdd251161008c578063eb1edd6111610071578063eb1edd611461045c578063ec55688914610464578063fd1f498d1461046c57610241565b8063d67bdd251461044c578063e0e6393d1461045457610241565b8063b410a03414610414578063bc67f8321461041c578063cff2ddad1461042f578063d294f0931461044457610241565b8063899ffef41161011457806397107d6d116100f957806397107d6d146103e6578063ac834193146103f9578063b10090b81461040157610241565b8063899ffef4146103c95780638da5cb5b146103de57610241565b80636de813f11461039e57806374185360146103a657806379ba5097146103ae57806386645274146103b657610241565b806333140016116101d857806353a47bb7116101a757806359a2f19f1161018c57806359a2f19f14610370578063614d08f8146103835780636466f45e1461038b57610241565b806353a47bb714610353578063569249d01461036857610241565b806333140016146102fd5780633ebc457a1461031d5780633fcd22401461032557806346ba2d901461034b57610241565b80631627540c116102145780631627540c146102b857806322425fa4146102cd57806322bf55ef146102d55780632af64bd3146102e857610241565b806304f3bcec1461024657806307ea50cd146102645780630813071c146102845780630de5861514610297575b600080fd5b61024e61047f565b60405161025b9190614012565b60405180910390f35b610277610272366004613251565b61048e565b60405161025b9190613f2f565b610277610292366004613295565b610563565b6102aa6102a5366004613251565b6106af565b60405161025b929190613f4b565b6102cb6102c6366004613251565b610731565b005b61027761078f565b6102cb6102e3366004613376565b61079f565b6102f0610978565b60405161025b9190613f21565b61031061030b366004613251565b610aa8565b60405161025b9190613f02565b6102cb610d0c565b610338610333366004613376565b611112565b60405161025b97969594939291906141af565b6102776111bb565b61035b6111c1565b60405161025b9190613e2f565b6102776111d0565b6102f061037e366004613251565b61122b565b61027761123d565b6102f0610399366004613251565b611261565b61027761138d565b6102cb6113e2565b6102cb611534565b6102cb6103c43660046132cf565b6115d0565b6103d1611710565b60405161025b9190613f10565b61035b611a30565b6102cb6103f4366004613251565b611a3f565b610277611a92565b6102cb61040f3660046133f4565b611b32565b610277611d2c565b6102cb61042a366004613251565b611d36565b610437611d60565b60405161025b9190614217565b6102f0611d65565b61035b611ddc565b610277611deb565b61035b611df5565b61024e611e0d565b6102cb61047a366004613376565b611e1c565b6005546001600160a01b031681565b6000610498611e88565b6001600160a01b031663bdc963d87f6c6173745f6665655f7769746864726177616c00000000000000000000000000846040516020016104d9929190613dbd565b604051602081830303815290604052805190602001206040518263ffffffff1660e01b815260040161050b9190613f2f565b60206040518083038186803b15801561052357600080fd5b505afa158015610537573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061055b919081019061333a565b90505b919050565b60008161058b5760405162461bcd60e51b815260040161058290614181565b60405180910390fd5b600282106105ab5760405162461bcd60e51b815260040161058290614131565b6105b760018303611eb3565b5468010000000000000000900467ffffffffffffffff166105da575060006106a9565b600061060a60016105ed60018603611eb3565b5468010000000000000000900467ffffffffffffffff1690611edd565b9050600080610617611f05565b6001600160a01b031663d29c000a87856040518363ffffffff1660e01b8152600401610644929190613e81565b604080518083038186803b15801561065b57600080fd5b505afa15801561066f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061069391908101906133c4565b90925090506106a3838383611f30565b93505050505b92915050565b6000806106ba613169565b6106c384610aa8565b905060008060015b6002811015610724576106f08482600281106106e357fe5b602002015151849061207b565b925061071a84826002811061070157fe5b602002015160016020020151839063ffffffff61207b16565b91506001016106cb565b509093509150505b915091565b6107396120a0565b600180546001600160a01b0319166001600160a01b0383161790556040517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce2290610784908390613e2f565b60405180910390a150565b60006107996120cc565b90505b90565b60006107a9612193565b6001600160a01b0316331490506000806107c16121be565b6001600160a01b03166316b2213f336040518263ffffffff1660e01b81526004016107ec9190613e3d565b60206040518083038186803b15801561080457600080fd5b505afa158015610818573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061083c919081019061333a565b14159050600061084a6121d2565b6001600160a01b031663b38988f7336040518263ffffffff1660e01b81526004016108759190613e3d565b60206040518083038186803b15801561088d57600080fd5b505afa1580156108a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506108c5919081019061331c565b905060006108d16121fd565b6001600160a01b0316336001600160a01b031614905060006108f1612228565b6001600160a01b0316336001600160a01b031614905084806109105750835b806109185750825b806109205750815b806109285750805b6109445760405162461bcd60e51b815260040161058290614031565b610962866109526000611eb3565b600101549063ffffffff61207b16565b61096c6000611eb3565b60010155505050505050565b60006060610984611710565b905060005b8151811015610a9f5760008282815181106109a057fe5b602090810291909101810151600081815260069092526040918290205460055492517f21f8a7210000000000000000000000000000000000000000000000000000000081529193506001600160a01b039081169216906321f8a72190610a0a908590600401613f2f565b60206040518083038186803b158015610a2257600080fd5b505afa158015610a36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610a5a9190810190613277565b6001600160a01b0316141580610a8557506000818152600660205260409020546001600160a01b0316155b15610a96576000935050505061079c565b50600101610989565b50600191505090565b610ab0613169565b6000806000610abd611f05565b6040517fb326f84e0000000000000000000000000000000000000000000000000000000081529091506001600160a01b0382169063b326f84e90610b08908890600090600401613e66565b604080518083038186803b158015610b1f57600080fd5b505afa158015610b33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610b5791908101906133c4565b909350915081158015610b68575082155b15610b8057610b75613169565b935061055e92505050565b600080610b8f60008686612253565b8751829052875160200181905290925090506000610bac8861048e565b905060015b8015610d005760001981016000610bc782611eb3565b5468010000000000000000900467ffffffffffffffff1690508015801590610c015750610bf383611eb3565b5467ffffffffffffffff1684105b15610cf5576000610c1982600163ffffffff611edd16565b6040517fd29c000a0000000000000000000000000000000000000000000000000000000081529091506001600160a01b0389169063d29c000a90610c63908f908590600401613e81565b604080518083038186803b158015610c7a57600080fd5b505afa158015610c8e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610cb291908101906133c4565b909a509850610cc2848b8b612253565b9097509550868b8560028110610cd457fe5b602002015152858b8560028110610ce757fe5b602002015160016020020152505b505060001901610bb1565b50505050505050919050565b610d146122f5565b6001600160a01b0316637c3125416040518163ffffffff1660e01b815260040160006040518083038186803b158015610d4c57600080fd5b505afa158015610d60573d6000803e3d6000fd5b505050506000610d6e6120cc565b11610d8b5760405162461bcd60e51b815260040161058290614191565b610d936120cc565b4203610d9f6000611eb3565b54600160801b900467ffffffffffffffff161115610dcf5760405162461bcd60e51b815260040161058290614051565b610dd76121fd565b6001600160a01b031663bb57ad206040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610e1157600080fd5b505af1158015610e25573d6000803e3d6000fd5b50505050610e31612228565b6001600160a01b031663bb57ad206040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610e6b57600080fd5b505af1158015610e7f573d6000803e3d6000fd5b5060009250610e919150829050611eb3565b90506000610e9f6001611eb3565b9050610ed08260010154610ec483600201548460010154611edd90919063ffffffff16565b9063ffffffff61207b16565b610eda6000611eb3565b60010155600380830154600483015491830154610f0192610ec4919063ffffffff611edd16565b610f0b6000611eb3565b60030155601254610f4890600290610f3c90600190610f30908463ffffffff61207b16565b9063ffffffff611edd16565b9063ffffffff61232016565b601281905560089060028110610f5a57fe5b6005020180547fffffffffffffffff000000000000000000000000000000000000000000000000168155600060018083018290556002830182905560038301829055600490920155610fc690610faf81611eb3565b5467ffffffffffffffff169063ffffffff61207b16565b610fd06000611eb3565b805467ffffffffffffffff191667ffffffffffffffff92909216919091179055610ff8612350565b6001600160a01b031663cd92eba96040518163ffffffff1660e01b815260040160206040518083038186803b15801561103057600080fd5b505afa158015611044573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611068919081019061333a565b6110726000611eb3565b805467ffffffffffffffff9290921668010000000000000000026fffffffffffffffff000000000000000019909216919091179055426110b26000611eb3565b805467ffffffffffffffff92909216600160801b027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff90921691909117905561110e6110fe6001611eb3565b5467ffffffffffffffff1661237b565b5050565b6000806000806000806000611125613196565b61112e89611eb3565b6040805160e081018252825467ffffffffffffffff808216808452680100000000000000008304821660208501819052600160801b909304909116938301849052600185015460608401819052600286015460808501819052600387015460a0860181905260049097015460c0909501859052919f929e50939c50929a5091985091965090945092505050565b60045481565b6001546001600160a01b031681565b60008060015b6002811015611225576111fc6111eb82611eb3565b60010154839063ffffffff61207b16565b915061121b61120a82611eb3565b60020154839063ffffffff611edd16565b91506001016111d6565b50905090565b600061123682612433565b5092915050565b7f466565506f6f6c0000000000000000000000000000000000000000000000000081565b600061126b6122f5565b6001600160a01b0316637c3125416040518163ffffffff1660e01b815260040160006040518083038186803b1580156112a357600080fd5b505afa1580156112b7573d6000803e3d6000fd5b505050506112c3612527565b6112cb612566565b6003546040517f21f4ae570000000000000000000000000000000000000000000000000000000081526001600160a01b03928316926321f4ae579261131892879290911690600401613e4b565b60206040518083038186803b15801561133057600080fd5b505afa158015611344573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611368919081019061331c565b6113845760405162461bcd60e51b8152600401610582906140e1565b61055b82612591565b60008060015b6002811015611225576113b96113a882611eb3565b60030154839063ffffffff61207b16565b91506113d86113c782611eb3565b60040154839063ffffffff611edd16565b9150600101611393565b60606113ec611710565b905060005b815181101561110e57600082828151811061140857fe5b602002602001015190506000600560009054906101000a90046001600160a01b03166001600160a01b031663dacb2d01838460405160200161144a9190613e19565b6040516020818303038152906040526040518363ffffffff1660e01b8152600401611476929190613f59565b60206040518083038186803b15801561148e57600080fd5b505afa1580156114a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506114c69190810190613277565b6000838152600660205260409081902080546001600160a01b0319166001600160a01b038416179055519091507f88a93678a3692f6789d9546fc621bf7234b101ddb7d4fe479455112831b8aa68906115229084908490613f3d565b60405180910390a150506001016113f1565b6001546001600160a01b0316331461155e5760405162461bcd60e51b815260040161058290614041565b6000546001546040517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c926115a1926001600160a01b0391821692911690613e4b565b60405180910390a160018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b60006115da6121be565b6001600160a01b0316336001600160a01b031614905060006115fa612350565b6001600160a01b0316336001600160a01b031614905081806116195750805b6116355760405162461bcd60e51b815260040161058290614171565b61163d611f05565b6001600160a01b03166394e1a4488686866116586000611eb3565b5460405160e086901b7fffffffff000000000000000000000000000000000000000000000000000000001681526116ab9493929168010000000000000000900467ffffffffffffffff1690600401613ec4565b600060405180830381600087803b1580156116c557600080fd5b505af11580156116d9573d6000803e3d6000fd5b505050506117098585856116ed6000611eb3565b5468010000000000000000900467ffffffffffffffff16612686565b5050505050565b60608061171b612755565b60408051600d8082526101c0820190925291925060609190602082016101a0803883390190505090507f53797374656d53746174757300000000000000000000000000000000000000008160008151811061177257fe5b6020026020010181815250507f53796e7468657469780000000000000000000000000000000000000000000000816001815181106117ac57fe5b6020026020010181815250507f466565506f6f6c53746174650000000000000000000000000000000000000000816002815181106117e657fe5b6020026020010181815250507f466565506f6f6c457465726e616c53746f7261676500000000000000000000008160038151811061182057fe5b6020026020010181815250507f45786368616e67657200000000000000000000000000000000000000000000008160048151811061185a57fe5b6020026020010181815250506524b9b9bab2b960d11b8160058151811061187d57fe5b6020026020010181815250507f53796e7468657469785374617465000000000000000000000000000000000000816006815181106118b757fe5b6020026020010181815250507f526577617264457363726f775632000000000000000000000000000000000000816007815181106118f157fe5b6020026020010181815250507f44656c6567617465417070726f76616c730000000000000000000000000000008160088151811061192b57fe5b6020026020010181815250507f52657761726473446973747269627574696f6e000000000000000000000000008160098151811061196557fe5b6020026020010181815250507f436f6c6c61746572616c4d616e6167657200000000000000000000000000000081600a8151811061199f57fe5b6020026020010181815250507f57726170706572466163746f727900000000000000000000000000000000000081600b815181106119d957fe5b6020026020010181815250507f457468657257726170706572000000000000000000000000000000000000000081600c81518110611a1357fe5b602002602001018181525050611a2982826127b4565b9250505090565b6000546001600160a01b031681565b611a476120a0565b600280546001600160a01b0319166001600160a01b0383161790556040517ffc80377ca9c49cc11ae6982f390a42db976d5530af7c43889264b13fbbd7c57e90610784908390613e3d565b6000610799611b1e611aa2612869565b73__$f9217daff40bcb29719cec84f7ab900933$__63907af6c06040518163ffffffff1660e01b815260040160206040518083038186803b158015611ae657600080fd5b505af4158015611afa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ec4919081019061333a565b611b266128e0565b9063ffffffff61295716565b611b3a612981565b6004544210611b5b5760405162461bcd60e51b815260040161058290614141565b611b63612350565b6001600160a01b031663cd92eba96040518163ffffffff1660e01b815260040160206040518083038186803b158015611b9b57600080fd5b505afa158015611baf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611bd3919081019061333a565b861115611bf25760405162461bcd60e51b815260040161058290614121565b6040518060e001604052808867ffffffffffffffff1681526020018767ffffffffffffffff1681526020018667ffffffffffffffff168152602001858152602001848152602001838152602001828152506008611c62600260ff16610f3c8c60125461207b90919063ffffffff16565b60028110611c6c57fe5b82516005919091029190910180546020840151604085015167ffffffffffffffff1990921667ffffffffffffffff948516176fffffffffffffffff000000000000000019166801000000000000000091851691909102177fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff16600160801b9390911692909202919091178155606082015160018201556080820151600282015560a0820151600382015560c0909101516004909101555050505050505050565b60006107996128e0565b611d3e6129ef565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b600281565b6000611d6f6122f5565b6001600160a01b0316637c3125416040518163ffffffff1660e01b815260040160006040518083038186803b158015611da757600080fd5b505afa158015611dbb573d6000803e3d6000fd5b50505050611dc7612527565b600354610799906001600160a01b0316612591565b6003546001600160a01b031681565b6000610799612869565b73feefeefeefeefeefeefeefeefeefeefeefeefeef81565b6002546001600160a01b031681565b611e24612527565b611e2c612a19565b6003546001600160a01b03908116911614611e595760405162461bcd60e51b8152600401610582906140b1565b611e7781611e676000611eb3565b600301549063ffffffff61207b16565b611e816000611eb3565b6003015550565b60006107997f466565506f6f6c457465726e616c53746f726167650000000000000000000000612a40565b60006008600260ff16836012540181611ec857fe5b0660028110611ed357fe5b6005020192915050565b600082821115611eff5760405162461bcd60e51b815260040161058290614081565b50900390565b60006107997f466565506f6f6c53746174650000000000000000000000000000000000000000612a40565b600080611f3b612350565b9050600061206f85612063846001600160a01b03166308d95cd5886040518263ffffffff1660e01b8152600401611f729190613f2f565b60206040518083038186803b158015611f8a57600080fd5b505afa158015611f9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611fc2919081019061333a565b6040517f08d95cd50000000000000000000000000000000000000000000000000000000081526001600160a01b038716906308d95cd590612007908d90600401613f2f565b60206040518083038186803b15801561201f57600080fd5b505afa158015612033573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612057919081019061333a565b9063ffffffff612a9d16565b9063ffffffff612ab616565b925050505b9392505050565b6000828201838110156120745760405162461bcd60e51b815260040161058290614071565b6000546001600160a01b031633146120ca5760405162461bcd60e51b8152600401610582906140f1565b565b60006120d6612acf565b6001600160a01b03166323257c2b7f53797374656d53657474696e67730000000000000000000000000000000000007f666565506572696f644475726174696f6e0000000000000000000000000000006040518363ffffffff1660e01b8152600401612143929190613f4b565b60206040518083038186803b15801561215b57600080fd5b505afa15801561216f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610799919081019061333a565b60006107997f45786368616e6765720000000000000000000000000000000000000000000000612a40565b60006107996524b9b9bab2b960d11b612a40565b60006107997f436f6c6c61746572616c4d616e61676572000000000000000000000000000000612a40565b60006107997f4574686572577261707065720000000000000000000000000000000000000000612a40565b60006107997f57726170706572466163746f7279000000000000000000000000000000000000612a40565b60008083612266575060009050806122ed565b83851561229157600061228060016105ed60018a03611eb3565b905061228d818787611f30565b9150505b60006122b0826122a089611eb3565b600101549063ffffffff61295716565b905060006122d1836122c18a611eb3565b600301549063ffffffff61295716565b90506122dc82612afa565b6122e582612afa565b945094505050505b935093915050565b60006107997f53797374656d5374617475730000000000000000000000000000000000000000612a40565b60008161233f5760405162461bcd60e51b8152600401610582906140d1565b81838161234857fe5b069392505050565b60006107997f53796e7468657469785374617465000000000000000000000000000000000000612a40565b6002546040516001600160a01b039091169063907dff97906123a1908490602001613f2f565b60405160208183030381529060405260016040516123be90613e24565b6040519081900381207fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16825261240593929160009081908190600401613f79565b600060405180830381600087803b15801561241f57600080fd5b505af1158015611709573d6000803e3d6000fd5b6000806000806124416121be565b6001600160a01b031663ae3bbbbb866040518263ffffffff1660e01b815260040161246c9190613e2f565b604080518083038186803b15801561248357600080fd5b505afa158015612497573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506124bb9190810190613394565b9150915060006124c96128e0565b9050808310156124e1575060019350915061072c9050565b60006124fe6124f1611aa2612869565b839063ffffffff61295716565b90508084111561251857600083955095505050505061072c565b50600194509092505050915091565b6002546001600160a01b0316331480159061254d57506003546001600160a01b03163314155b156120ca57600380546001600160a01b03191633179055565b60006107997f44656c6567617465417070726f76616c73000000000000000000000000000000612a40565b60008080808080806125a288612433565b91509150816125c35760405162461bcd60e51b815260040161058290614101565b80156125e15760405162461bcd60e51b8152600401610582906140c1565b6125ea886106af565b9094509250831515806125fd5750600083115b6126195760405162461bcd60e51b8152600401610582906140a1565b612637886126276001611eb3565b5467ffffffffffffffff16612b1c565b83156126525761264684612bcf565b94506126528886612cab565b821561266d5761266183612e47565b955061266d8887612f21565b612678888688612f9b565b506001979650505050505050565b6002546040516001600160a01b039091169063907dff97906126b0908690869086906020016141a1565b60405160208183030381529060405260026040516126cd90613dee565b6040519081900381207fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16825261271d9392916001600160a01b038b16906000908190600401613fd8565b600060405180830381600087803b15801561273757600080fd5b505af115801561274b573d6000803e3d6000fd5b5050505050505050565b604080516001808252818301909252606091602080830190803883390190505090507f466c657869626c6553746f726167650000000000000000000000000000000000816000815181106127a557fe5b60200260200101818152505090565b606081518351016040519080825280602002602001820160405280156127e4578160200160208202803883390190505b50905060005b8351811015612826578381815181106127ff57fe5b602002602001015182828151811061281357fe5b60209081029190910101526001016127ea565b5060005b82518110156112365782818151811061283f57fe5b602002602001015182828651018151811061285657fe5b602090810291909101015260010161282a565b6000612873612acf565b6001600160a01b03166323257c2b7f53797374656d53657474696e67730000000000000000000000000000000000007f7461726765745468726573686f6c6400000000000000000000000000000000006040518363ffffffff1660e01b8152600401612143929190613f4b565b60006128ea612acf565b6001600160a01b03166323257c2b7f53797374656d53657474696e67730000000000000000000000000000000000007f69737375616e6365526174696f000000000000000000000000000000000000006040518363ffffffff1660e01b8152600401612143929190613f4b565b6000670de0b6b3a7640000612972848463ffffffff61306016565b8161297957fe5b049392505050565b6002546001600160a01b031633148015906129a757506003546001600160a01b03163314155b156129bf57600380546001600160a01b031916331790555b6000546003546001600160a01b039081169116146120ca5760405162461bcd60e51b815260040161058290614061565b6002546001600160a01b031633146120ca5760405162461bcd60e51b815260040161058290614161565b60006107997f52657761726473446973747269627574696f6e000000000000000000000000005b60008181526006602090815260408083205490516001600160a01b039091169182151591612a7091869101613df9565b604051602081830303815290604052906112365760405162461bcd60e51b81526004016105829190614020565b600061207483836b033b2e3c9fd0803ce800000061309a565b600061207483836b033b2e3c9fd0803ce80000006130de565b60006107997f466c657869626c6553746f726167650000000000000000000000000000000000612a40565b60006305f5e10082046005600a820610612b1257600a015b600a900492915050565b612b24611e88565b6001600160a01b0316633562fd207f6c6173745f6665655f7769746864726177616c0000000000000000000000000084604051602001612b65929190613dbd565b60405160208183030381529060405280519060200120836040518363ffffffff1660e01b8152600401612b99929190613f4b565b600060405180830381600087803b158015612bb357600080fd5b505af1158015612bc7573d6000803e3d6000fd5b505050505050565b6000818160015b6002811015612ca3576000612bea82611eb3565b6002015490506000612c0f82612bff85611eb3565b600101549063ffffffff611edd16565b90508015612c98576000858210612c265785612c28565b815b9050612c3a838263ffffffff61207b16565b612c4385611eb3565b60020155612c57868263ffffffff611edd16565b9550612c69858263ffffffff61207b16565b945085612c7e5784965050505050505061055e565b83158015612c8c5750600086115b15612c9657600095505b505b505060001901612bd6565b509392505050565b816001600160a01b03811673feefeefeefeefeefeefeefeefeefeefeefeefeef1415612ce95760405162461bcd60e51b815260040161058290614151565b6000612cf36121be565b6001600160a01b031663326080396007546040518263ffffffff1660e01b8152600401612d209190613f2f565b60206040518083038186803b158015612d3857600080fd5b505afa158015612d4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612d709190810190613358565b6040517f9dc29fac0000000000000000000000000000000000000000000000000000000081529091506001600160a01b03821690639dc29fac90612dce9073feefeefeefeefeefeefeefeefeefeefeefeefeef908790600401613e81565b600060405180830381600087803b158015612de857600080fd5b505af1158015612dfc573d6000803e3d6000fd5b50506040517f867904b40000000000000000000000000000000000000000000000000000000081526001600160a01b038416925063867904b4915061271d9087908790600401613e81565b6000818160015b6002811015612ca3576000612e82612e6583611eb3565b60040154612e7284611eb3565b600301549063ffffffff611edd16565b90508015612f17576000848210612e995784612e9b565b815b9050612eba81612eaa85611eb3565b600401549063ffffffff61207b16565b612ec384611eb3565b60040155612ed7858263ffffffff611edd16565b9450612ee9848263ffffffff61207b16565b935084612efd57839550505050505061055e565b82158015612f0b5750600085115b15612f1557600094505b505b5060001901612e4e565b816001600160a01b03811673feefeefeefeefeefeefeefeefeefeefeefeefeef1415612f5f5760405162461bcd60e51b815260040161058290614151565b6301dfe200612f6c613109565b6001600160a01b0316631bb47b448585846040518463ffffffff1660e01b815260040161271d93929190613e9c565b6002546040516001600160a01b039091169063907dff9790612fc590869086908690602001613e9c565b6040516020818303038152906040526001604051612fe290613de3565b6040519081900381207fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16825261302993929160009081908190600401613f79565b600060405180830381600087803b15801561304357600080fd5b505af1158015613057573d6000803e3d6000fd5b50505050505050565b60008261306f575060006106a9565b8282028284828161307c57fe5b04146120745760405162461bcd60e51b815260040161058290614111565b6000806130c0846130b487600a870263ffffffff61306016565b9063ffffffff61313416565b90506005600a825b06106130d257600a015b600a9004949350505050565b600080600a83046130f5868663ffffffff61306016565b816130fc57fe5b0490506005600a826130c8565b60006107997f526577617264457363726f775632000000000000000000000000000000000000612a40565b60008082116131555760405162461bcd60e51b815260040161058290614091565b600082848161316057fe5b04949350505050565b60405180604001604052806002905b6131806131f1565b8152602001906001900390816131785790505090565b6040518060e00160405280600067ffffffffffffffff168152602001600067ffffffffffffffff168152602001600067ffffffffffffffff168152602001600081526020016000815260200160008152602001600081525090565b60405180604001604052806002906020820280388339509192915050565b80356106a9816142f8565b80516106a9816142f8565b80516106a98161430f565b80516106a981614318565b80516106a981614321565b80356106a981614318565b60006020828403121561326357600080fd5b600061326f848461320f565b949350505050565b60006020828403121561328957600080fd5b600061326f848461321a565b600080604083850312156132a857600080fd5b60006132b4858561320f565b92505060206132c585828601613246565b9150509250929050565b6000806000606084860312156132e457600080fd5b60006132f0868661320f565b935050602061330186828701613246565b925050604061331286828701613246565b9150509250925092565b60006020828403121561332e57600080fd5b600061326f8484613225565b60006020828403121561334c57600080fd5b600061326f8484613230565b60006020828403121561336a57600080fd5b600061326f848461323b565b60006020828403121561338857600080fd5b600061326f8484613246565b600080604083850312156133a757600080fd5b60006133b38585613230565b92505060206132c585828601613225565b600080604083850312156133d757600080fd5b60006133e38585613230565b92505060206132c585828601613230565b600080600080600080600080610100898b03121561341157600080fd5b600061341d8b8b613246565b985050602061342e8b828c01613246565b975050604061343f8b828c01613246565b96505060606134508b828c01613246565b95505060806134618b828c01613246565b94505060a06134728b828c01613246565b93505060c06134838b828c01613246565b92505060e06134948b828c01613246565b9150509295985092959890939650565b60006134b0838361359a565b505060400190565b60006134c483836135ef565b505060200190565b6134d581614278565b82525050565b6134d58161423e565b6134d56134f08261423e565b6142d7565b6134fe8161422b565b613508818461055e565b92506135138261079c565b8060005b83811015612bc757815161352b87826134a4565b965061353683614225565b925050600101613517565b600061354c82614231565b6135568185614235565b935061356183614225565b8060005b8381101561358f57815161357988826134b8565b975061358483614225565b925050600101613565565b509495945050505050565b6135a38161422b565b6135ad818461055e565b92506135b88261079c565b8060005b83811015612bc75781516135d087826134b8565b96506135db83614225565b9250506001016135bc565b6134d581614249565b6134d58161079c565b6134d56136048261079c565b61079c565b600061361482614231565b61361e8185614235565b935061362e8185602086016142a7565b613637816142e8565b9093019392505050565b6134d58161424e565b6134d581614283565b6134d581614291565b6000613669601783614235565b7f4f6e6c7920496e7465726e616c20436f6e747261637473000000000000000000815260200192915050565b60006136a2603583614235565b7f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7581527f2063616e20616363657074206f776e6572736869700000000000000000000000602082015260400192915050565b6000613701601d83614235565b7f546f6f206561726c7920746f20636c6f73652066656520706572696f64000000815260200192915050565b600061373a601383614235565b7f4f776e6572206f6e6c792066756e6374696f6e00000000000000000000000000815260200192915050565b600061377360248361055e565b7f46656573436c61696d656428616464726573732c75696e743235362c75696e7481527f3235362900000000000000000000000000000000000000000000000000000000602082015260240192915050565b60006137d260378361055e565b7f49737375616e636544656274526174696f456e74727928616464726573732c7581527f696e743235362c75696e743235362c75696e7432353629000000000000000000602082015260370192915050565b6000613831601b83614235565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815260200192915050565b600061386a601e83614235565b7f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815260200192915050565b60006138a3601a83614235565b7f536166654d6174683a206469766973696f6e206279207a65726f000000000000815260200192915050565b60006138dc604083614235565b7f4e6f2066656573206f72207265776172647320617661696c61626c6520666f7281527f20706572696f642c206f72206665657320616c726561647920636c61696d6564602082015260400192915050565b600061393b60118361055e565b7f4d697373696e6720616464726573733a20000000000000000000000000000000815260110192915050565b6000613974601883614235565b7f52657761726473446973747269627574696f6e206f6e6c790000000000000000815260200192915050565b60006139ad601e83614235565b7f412073796e7468206f7220534e58207261746520697320696e76616c69640000815260200192915050565b60006139e6601883614235565b7f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000815260200192915050565b6000613a1f601f83614235565b7f4e6f7420617070726f76656420746f20636c61696d206f6e20626568616c6600815260200192915050565b6000613a58602f83614235565b7f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726681527f6f726d207468697320616374696f6e0000000000000000000000000000000000602082015260400192915050565b6000613ab7601f83614235565b7f432d526174696f2062656c6f772070656e616c7479207468726573686f6c6400815260200192915050565b6000613af0602183614235565b7f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f81527f7700000000000000000000000000000000000000000000000000000000000000602082015260400192915050565b6000613b4f601683614235565b7f43616e6e6f7420696d706f727420626164206461746100000000000000000000815260200192915050565b6000613b88601d83614235565b7f4578636565647320746865204645455f504552494f445f4c454e475448000000815260200192915050565b6000613bc1602983614235565b7f43616e206f6e6c7920706572666f726d207468697320616374696f6e2064757281527f696e672073657475700000000000000000000000000000000000000000000000602082015260400192915050565b6000613c2060198361055e565b7f5265736f6c766572206d697373696e67207461726765743a2000000000000000815260190192915050565b6000613c59601783614235565b7f4665652061646472657373206e6f7420616c6c6f776564000000000000000000815260200192915050565b6000613c9260188361055e565b7f466565506572696f64436c6f7365642875696e74323536290000000000000000815260180192915050565b6000613ccb601783614235565b7f4f6e6c79207468652070726f78792063616e2063616c6c000000000000000000815260200192915050565b6000613d04601e83614235565b7f49737375657220616e642053796e7468657469785374617465206f6e6c790000815260200192915050565b6000613d3d602083614235565b7f43757272656e7420706572696f64206973206e6f7420636c6f73656420796574815260200192915050565b6000613d76601b83614235565b7f46656520506572696f64204475726174696f6e206e6f74207365740000000000815260200192915050565b6134d58161429c565b6134d581614265565b6134d581614272565b6000613dc982856135f8565b602082019150613dd982846134e4565b5060140192915050565b60006106a982613766565b60006106a9826137c5565b6000613e048261392e565b9150613e1082846135f8565b50602001919050565b6000613e0482613c13565b60006106a982613c85565b602081016106a982846134db565b602081016106a982846134cc565b60408101613e5982856134db565b61207460208301846134db565b60408101613e7482856134db565b6120746020830184613653565b60408101613e8f82856134db565b61207460208301846135ef565b60608101613eaa82866134db565b613eb760208301856135ef565b61326f60408301846135ef565b60808101613ed282876134db565b613edf60208301866135ef565b613eec60408301856135ef565b613ef96060830184613da2565b95945050505050565b608081016106a982846134f5565b602080825281016120748184613541565b602081016106a982846135e6565b602081016106a982846135ef565b60408101613e5982856135ef565b60408101613e8f82856135ef565b60408101613f6782856135ef565b818103602083015261326f8184613609565b60c08082528101613f8a8189613609565b9050613f996020830188613653565b613fa660408301876135ef565b613fb3606083018661364a565b613fc0608083018561364a565b613fcd60a083018461364a565b979650505050505050565b60c08082528101613fe98189613609565b9050613ff86020830188613653565b61400560408301876135ef565b613fb360608301866135ef565b602081016106a98284613641565b602080825281016120748184613609565b6020808252810161055b8161365c565b6020808252810161055b81613695565b6020808252810161055b816136f4565b6020808252810161055b8161372d565b6020808252810161055b81613824565b6020808252810161055b8161385d565b6020808252810161055b81613896565b6020808252810161055b816138cf565b6020808252810161055b81613967565b6020808252810161055b816139a0565b6020808252810161055b816139d9565b6020808252810161055b81613a12565b6020808252810161055b81613a4b565b6020808252810161055b81613aaa565b6020808252810161055b81613ae3565b6020808252810161055b81613b42565b6020808252810161055b81613b7b565b6020808252810161055b81613bb4565b6020808252810161055b81613c4c565b6020808252810161055b81613cbe565b6020808252810161055b81613cf7565b6020808252810161055b81613d30565b6020808252810161055b81613d69565b60608101613eaa82866135ef565b60e081016141bd828a613dab565b6141ca6020830189613dab565b6141d76040830188613dab565b6141e460608301876135ef565b6141f160808301866135ef565b6141fe60a08301856135ef565b61420b60c08301846135ef565b98975050505050505050565b602081016106a98284613db4565b60200190565b50600290565b5190565b90815260200190565b600061055b82614259565b151590565b600061055b8261423e565b6001600160a01b031690565b67ffffffffffffffff1690565b60ff1690565b600061055b8261424e565b600061055b6136048361079c565b600061055b8261079c565b600061055b82614265565b60005b838110156142c25781810151838201526020016142aa565b838111156142d1576000848401525b50505050565b600061055b82600061055b826142f2565b601f01601f191690565b60601b90565b6143018161423e565b811461430c57600080fd5b50565b61430181614249565b6143018161079c565b6143018161424e56fea365627a7a72315820311ca67b066d8aa30c5fc3e5d4e569051e36efc62ebf3c8ccc4f5172288bdb2b6c6578706572696d656e74616cf564736f6c63430005100040", "abi": [ { "inputs": [ @@ -3281,10 +3281,10 @@ } ], "source": { - "keccak256": "0x9e381069cb34a10eb54ca9fb651d514a2cbcdcb328adfe943956b9d759c5ebac", + "keccak256": "0xdb500335962961757d10ccbded7e9de457824b4c2d428c8c9aa63f18a5ca3914", "urls": [ - "bzz-raw://c8d6ae1feaa83b97ed46b18a34b336e2014ebbe064b07276bd35c33f8000aa71", - "dweb:/ipfs/QmUECjHzMVyjue53V4xAvbmXThvvxChgJg5FkVSZfs8Zam" + "bzz-raw://d45068f4b97b8568117b6c095694b7270cad2b0337ea0c2b8b24550dfa93fdbc", + "dweb:/ipfs/QmWYtWcqTszbsZ6tJTg6GcDWdWdGcnNkALBgzRpYPL3EH7" ] }, "metadata": { @@ -3306,10 +3306,10 @@ }, "sources": { "FeePool.sol": { - "keccak256": "0x9e381069cb34a10eb54ca9fb651d514a2cbcdcb328adfe943956b9d759c5ebac", + "keccak256": "0xdb500335962961757d10ccbded7e9de457824b4c2d428c8c9aa63f18a5ca3914", "urls": [ - "bzz-raw://c8d6ae1feaa83b97ed46b18a34b336e2014ebbe064b07276bd35c33f8000aa71", - "dweb:/ipfs/QmUECjHzMVyjue53V4xAvbmXThvvxChgJg5FkVSZfs8Zam" + "bzz-raw://d45068f4b97b8568117b6c095694b7270cad2b0337ea0c2b8b24550dfa93fdbc", + "dweb:/ipfs/QmWYtWcqTszbsZ6tJTg6GcDWdWdGcnNkALBgzRpYPL3EH7" ] } }, diff --git a/publish/deployed/local-ovm/config.json b/publish/deployed/local-ovm/config.json index af2879baff..16cedd4427 100644 --- a/publish/deployed/local-ovm/config.json +++ b/publish/deployed/local-ovm/config.json @@ -160,5 +160,8 @@ }, "SynthRedeemer": { "deploy": true + }, + "SystemSettingsLib": { + "deploy": true } } diff --git a/publish/deployed/local/config.json b/publish/deployed/local/config.json index b3968b3ebe..9b492c6221 100644 --- a/publish/deployed/local/config.json +++ b/publish/deployed/local/config.json @@ -388,5 +388,8 @@ }, "SynthRedeemer": { "deploy": true + }, + "SystemSettingsLib": { + "deploy": true } } diff --git a/publish/index.js b/publish/index.js index 7465bd5c02..4414ad0cba 100644 --- a/publish/index.js +++ b/publish/index.js @@ -7,6 +7,7 @@ require('dotenv').config(); require('./src/commands/build').cmd(program); require('./src/commands/connect-bridge').cmd(program); +require('./src/commands/deploy-migration').cmd(program); require('./src/commands/deploy-shorting-rewards').cmd(program); require('./src/commands/deploy-staking-rewards').cmd(program); require('./src/commands/deploy').cmd(program); diff --git a/publish/releases.json b/publish/releases.json index 44892848bb..bf46830298 100644 --- a/publish/releases.json +++ b/publish/releases.json @@ -420,6 +420,11 @@ "sources": ["WrapperFactory"], "released": "both" }, + { + "sip": 193, + "layer": "both", + "sources": ["SystemSettings", "SystemSettingsLib"] + }, { "sip": 194, "layer": "ovm", @@ -431,6 +436,16 @@ "layer": "ovm", "sources": ["CollateralEth"], "released": "ovm" + }, + { + "sip": 196, + "layer": "both", + "sources": ["ExchangeRates"] + }, + { + "sip": 200, + "layer": "both", + "sources": ["FeePool"] } ], "releases": [ @@ -768,7 +783,7 @@ "major": 2, "minor": 57 }, - "sips": [] + "sips": [200] }, { "name": "Peacock (Optimism)", @@ -778,7 +793,7 @@ "major": 2, "minor": 57 }, - "sips": [] + "sips": [200] }, { "name": "Alsephina", diff --git a/publish/src/Deployer.js b/publish/src/Deployer.js index c29455712a..b98872cba6 100644 --- a/publish/src/Deployer.js +++ b/publish/src/Deployer.js @@ -184,7 +184,7 @@ class Deployer { // Any contract after SafeDecimalMath can automatically get linked. // Doing this with bytecode that doesn't require the library is a no-op. let bytecode = compiled.evm.bytecode.object; - ['SafeDecimalMath', 'Math'].forEach(contractName => { + ['SafeDecimalMath', 'Math', 'SystemSettingsLib'].forEach(contractName => { if (this.deployedContracts[contractName]) { bytecode = linker.linkBytecode(bytecode, { [source + '.sol']: { diff --git a/publish/src/commands/deploy-migration.js b/publish/src/commands/deploy-migration.js new file mode 100644 index 0000000000..4e872b610a --- /dev/null +++ b/publish/src/commands/deploy-migration.js @@ -0,0 +1,187 @@ +'use strict'; + +const fs = require('fs'); +const path = require('path'); +const ethers = require('ethers'); +const { gray, green, yellow } = require('chalk'); +const { getUsers } = require('../../..'); +const { loadCompiledFiles, getLatestSolTimestamp } = require('../solidity'); + +const { + ensureNetwork, + loadConnections, + confirmAction, + parameterNotice, + loadAndCheckRequiredSources, + appendOwnerActionGenerator, +} = require('../util'); + +const { + wrap, + constants: { BUILD_FOLDER, CONTRACTS_FOLDER }, +} = require('../../..'); + +const DEFAULTS = { + priorityGasPrice: '1', + network: 'kovan', + buildPath: path.join(__dirname, '..', '..', '..', BUILD_FOLDER), + rewardsToDeploy: [], +}; + +const deployMigration = async ({ + releaseName, + maxFeePerGas, + maxPriorityFeePerGas = DEFAULTS.priorityGasPrice, + network = DEFAULTS.network, + useOvm, + buildPath = DEFAULTS.buildPath, + privateKey, + yes, + dryRun = false, +} = {}) => { + ensureNetwork(network); + + console.log( + gray('Checking all contracts not flagged for deployment have addresses in this network...') + ); + + console.log(gray('Loading the compiled contracts locally...')); + const { earliestCompiledTimestamp, compiled } = loadCompiledFiles({ buildPath }); + + // now get the latest time a Solidity file was edited + const latestSolTimestamp = getLatestSolTimestamp(CONTRACTS_FOLDER); + + const { providerUrl, privateKey: envPrivateKey } = loadConnections({ + network, + useOvm, + }); + + // allow local deployments to use the private key passed as a CLI option + if (network !== 'local' || !privateKey) { + privateKey = envPrivateKey; + } + + const provider = new ethers.providers.JsonRpcProvider(providerUrl); + + const ownerAddress = getUsers({ network, useOvm, user: 'owner' }).address; + + let signer = null; + if (network === 'local' && !privateKey) { + signer = provider.getSigner(ownerAddress); + signer.address = ownerAddress; + } else { + signer = new ethers.Wallet(privateKey, provider); + } + + parameterNotice({ + 'Dry Run': dryRun ? green('true') : yellow('⚠ NO'), + Network: network, + 'Use OVM': useOvm, + Gas: `Base fee ${maxFeePerGas} GWEI, miner tip ${maxPriorityFeePerGas} GWEI`, + 'Local build last modified': `${new Date(earliestCompiledTimestamp)} ${yellow( + ((new Date().getTime() - earliestCompiledTimestamp) / 60000).toFixed(2) + ' mins ago' + )}`, + 'Last Solidity update': + new Date(latestSolTimestamp) + + (latestSolTimestamp > earliestCompiledTimestamp + ? yellow(' ⚠⚠⚠ this is later than the last build! Is this intentional?') + : green(' ✅')), + 'Release Name': releaseName, + 'Deployer account:': signer.address, + }); + + if (!yes) { + try { + await confirmAction( + yellow( + `⚠⚠⚠ WARNING: This action will deploy the following contracts to ${network}:\nMigration_${releaseName}\n` + ) + + gray('-'.repeat(50)) + + '\nDo you want to continue? (y/n) ' + ); + } catch (err) { + console.log(gray('Operation cancelled')); + return; + } + } + + console.log(gray(`Starting deployment to ${network.toUpperCase()}...`)); + + const migrationContract = new ethers.ContractFactory( + compiled['Migration_' + releaseName].abi, + compiled['Migration_' + releaseName].evm.bytecode.object, + signer + ); + + const deployedContract = await migrationContract.deploy(); + + console.log(green(`\nSuccessfully deployed: ${deployedContract.address}\n`)); + + // append owner action to run the actual migration + const { getPathToNetwork } = wrap({ + network, + useOvm, + fs, + path, + }); + + // always appending to mainnet owner actions now + const { ownerActions, ownerActionsFile } = loadAndCheckRequiredSources({ + deploymentPath: getPathToNetwork({ network, useOvm }), + network, + }); + + // append to owner actions if supplied + const appendOwnerAction = appendOwnerActionGenerator({ + ownerActions, + ownerActionsFile, + // 'https://', + }); + + const actionName = `Migration_${releaseName}.migrate(${ownerAddress})`; + const txn = await deployedContract.populateTransaction.migrate(ownerAddress); + + const ownerAction = { + key: actionName, + target: txn.to, + action: actionName, + data: txn.data, + }; + + appendOwnerAction(ownerAction); + + console.log(gray(`All contracts deployed on "${network}" network:`)); +}; + +module.exports = { + deployMigration, + DEFAULTS, + cmd: program => + program + .command('deploy-migration') + .description('Deploys a migration script') + .option('-r, --release-name ', `Deploys migration contract corresponding to thi name`) + .option('-g, --max-fee-per-gas ', 'Maximum base gas fee price in GWEI') + .option( + '--max-priority-fee-per-gas ', + 'Priority gas fee price in GWEI', + DEFAULTS.priorityGasPrice + ) + .option( + '-n, --network ', + 'The network to run off.', + x => x.toLowerCase(), + DEFAULTS.network + ) + .option('--use-ovm', 'Use OVM') + .option( + '-r, --dry-run', + 'If enabled, will not run any transactions but merely report on them.' + ) + .option( + '-v, --private-key [value]', + 'The private key to deploy with (only works in local mode, otherwise set in .env).' + ) + .option('-y, --yes', 'Dont prompt, just reply yes.') + .action(deployMigration), +}; diff --git a/publish/src/commands/deploy/configure-loans.js b/publish/src/commands/deploy/configure-loans.js index 998d2cd443..f6be8f8c69 100644 --- a/publish/src/commands/deploy/configure-loans.js +++ b/publish/src/commands/deploy/configure-loans.js @@ -2,6 +2,7 @@ const { gray } = require('chalk'); const { toBytes32 } = require('../../../..'); +const { allowZeroOrUpdateIfNonZero } = require('../../util.js'); module.exports = async ({ addressOf, @@ -80,13 +81,14 @@ module.exports = async ({ comment: 'Ensure the CollateralEth contract has all associated synths added', }); + const issueFeeRate = (await getDeployParameter('COLLATERAL_ETH'))['ISSUE_FEE_RATE']; await runStep({ contract: 'CollateralEth', target: CollateralEth, read: 'issueFeeRate', - expected: input => input !== '0', // only change if zero, + expected: allowZeroOrUpdateIfNonZero(issueFeeRate), write: 'setIssueFeeRate', - writeArg: [(await getDeployParameter('COLLATERAL_ETH'))['ISSUE_FEE_RATE']], + writeArg: [issueFeeRate], comment: 'Ensure the CollateralEth contract has its issue fee rate set', }); } @@ -121,13 +123,14 @@ module.exports = async ({ comment: 'Ensure the CollateralErc20 contract has all associated synths added', }); + const issueFeeRate = (await getDeployParameter('COLLATERAL_RENBTC'))['ISSUE_FEE_RATE']; await runStep({ contract: 'CollateralErc20', target: CollateralErc20, read: 'issueFeeRate', - expected: input => input !== '0', // only change if zero + expected: allowZeroOrUpdateIfNonZero(issueFeeRate), write: 'setIssueFeeRate', - writeArg: [(await getDeployParameter('COLLATERAL_RENBTC'))['ISSUE_FEE_RATE']], + writeArg: [issueFeeRate], comment: 'Ensure the CollateralErc20 contract has its issue fee rate set', }); } @@ -167,7 +170,7 @@ module.exports = async ({ contract: 'CollateralShort', target: CollateralShort, read: 'issueFeeRate', - expected: input => (issueFeeRate === '0' ? true : input !== '0'), + expected: allowZeroOrUpdateIfNonZero(issueFeeRate), write: 'setIssueFeeRate', writeArg: [issueFeeRate], comment: 'Ensure the CollateralShort contract has its issue fee rate set', @@ -175,59 +178,62 @@ module.exports = async ({ if (CollateralShort.interactionDelay) { const interactionDelay = (await getDeployParameter('COLLATERAL_SHORT'))['INTERACTION_DELAY']; - await runStep({ contract: 'CollateralShort', target: CollateralShort, read: 'interactionDelay', - expected: input => input !== '0', // only change if zero + expected: allowZeroOrUpdateIfNonZero(interactionDelay), write: 'setInteractionDelay', - writeArg: interactionDelay, + writeArg: [interactionDelay], comment: 'Ensure the CollateralShort contract has an interaction delay to prevent frontrunning', }); } } + const maxDebt = collateralManagerDefaults['MAX_DEBT']; await runStep({ contract: 'CollateralManager', target: CollateralManager, read: 'maxDebt', - expected: input => input !== '0', // only change if zero + expected: allowZeroOrUpdateIfNonZero(maxDebt), write: 'setMaxDebt', - writeArg: [collateralManagerDefaults['MAX_DEBT']], + writeArg: [maxDebt], comment: 'Set the max amount of debt in the CollateralManager', }); if (CollateralManager.maxSkewRate) { + const maxSkewRate = collateralManagerDefaults['MAX_SKEW_RATE']; await runStep({ contract: 'CollateralManager', target: CollateralManager, read: 'maxSkewRate', - expected: input => input !== '0', // only change if zero + expected: allowZeroOrUpdateIfNonZero(maxSkewRate), write: 'setMaxSkewRate', - writeArg: [collateralManagerDefaults['MAX_SKEW_RATE']], + writeArg: [maxSkewRate], comment: 'Set the max skew rate in the CollateralManager', }); } + const baseBorrowRate = collateralManagerDefaults['BASE_BORROW_RATE']; await runStep({ contract: 'CollateralManager', target: CollateralManager, read: 'baseBorrowRate', - expected: input => input !== '0', // only change if zero + expected: allowZeroOrUpdateIfNonZero(baseBorrowRate), write: 'setBaseBorrowRate', - writeArg: [collateralManagerDefaults['BASE_BORROW_RATE']], + writeArg: [baseBorrowRate], comment: 'Set the base borrow rate in the CollateralManager', }); + const baseShortRate = collateralManagerDefaults['BASE_SHORT_RATE']; await runStep({ contract: 'CollateralManager', target: CollateralManager, read: 'baseShortRate', - expected: input => input !== '0', // only change if zero + expected: allowZeroOrUpdateIfNonZero(baseShortRate), write: 'setBaseShortRate', - writeArg: [collateralManagerDefaults['BASE_SHORT_RATE']], + writeArg: [baseShortRate], comment: 'Set the base short rate in the CollateralManager', }); diff --git a/publish/src/commands/deploy/configure-system-settings.js b/publish/src/commands/deploy/configure-system-settings.js index 5fd089052c..78efa75de7 100644 --- a/publish/src/commands/deploy/configure-system-settings.js +++ b/publish/src/commands/deploy/configure-system-settings.js @@ -8,6 +8,7 @@ const { toBytes32, constants: { ZERO_ADDRESS }, } = require('../../../..'); +const { allowZeroOrUpdateIfNonZero } = require('../../util.js'); module.exports = async ({ addressOf, @@ -107,20 +108,23 @@ module.exports = async ({ target: SystemSettings, read: 'waitingPeriodSecs', readTarget: previousSystemSettings, - expected: input => waitingPeriodSecs === '0' || input !== '0', // only change if setting to non-zero from zero + expected: allowZeroOrUpdateIfNonZero(waitingPeriodSecs), write: 'setWaitingPeriodSecs', writeArg: waitingPeriodSecs, comment: 'Set the fee reclamation (SIP-37) waiting period', }); + const priceDeviationThresholdFactor = await getDeployParameter( + 'PRICE_DEVIATION_THRESHOLD_FACTOR' + ); await runStep({ contract: 'SystemSettings', target: SystemSettings, read: 'priceDeviationThresholdFactor', readTarget: previousSystemSettings, - expected: input => input !== '0', // only change if zero + expected: allowZeroOrUpdateIfNonZero(priceDeviationThresholdFactor), write: 'setPriceDeviationThresholdFactor', - writeArg: await getDeployParameter('PRICE_DEVIATION_THRESHOLD_FACTOR'), + writeArg: priceDeviationThresholdFactor, comment: 'Set the threshold for the circuit breaker (SIP-65)', }); @@ -136,163 +140,179 @@ module.exports = async ({ comment: 'Set the flag for trading rewards (SIP-63)', }); + const issuanceRatio = await getDeployParameter('ISSUANCE_RATIO'); await runStep({ contract: 'SystemSettings', target: SystemSettings, read: 'issuanceRatio', readTarget: previousSystemSettings, - expected: input => input !== '0', // only change if zero + expected: allowZeroOrUpdateIfNonZero(issuanceRatio), write: 'setIssuanceRatio', - writeArg: await getDeployParameter('ISSUANCE_RATIO'), + writeArg: issuanceRatio, comment: 'Set the issuance ratio - the c-ratio stored as an inverted decimal', }); + const feePeriodDuration = await getDeployParameter('FEE_PERIOD_DURATION'); await runStep({ contract: 'SystemSettings', target: SystemSettings, read: 'feePeriodDuration', readTarget: previousSystemSettings, - expected: input => input !== '0', // only change if zero + expected: allowZeroOrUpdateIfNonZero(feePeriodDuration), write: 'setFeePeriodDuration', - writeArg: await getDeployParameter('FEE_PERIOD_DURATION'), + writeArg: feePeriodDuration, comment: 'Set the fee period duration', }); + const targetThreshold = await getDeployParameter('TARGET_THRESHOLD'); await runStep({ contract: 'SystemSettings', target: SystemSettings, read: 'targetThreshold', readTarget: previousSystemSettings, - expected: input => input !== '0', // only change if zero + expected: allowZeroOrUpdateIfNonZero(targetThreshold), write: 'setTargetThreshold', - writeArg: await getDeployParameter('TARGET_THRESHOLD'), + writeArg: targetThreshold, comment: 'Set the target threshold - the threshold beyond the c-ratio that allows fees to be claimed', }); + const liquidationDelay = await getDeployParameter('LIQUIDATION_DELAY'); await runStep({ contract: 'SystemSettings', target: SystemSettings, read: 'liquidationDelay', readTarget: previousSystemSettings, - expected: input => input !== '0', // only change if zero + expected: allowZeroOrUpdateIfNonZero(liquidationDelay), write: 'setLiquidationDelay', - writeArg: await getDeployParameter('LIQUIDATION_DELAY'), + writeArg: liquidationDelay, comment: 'Set the delay from when an account is flagged till when it can be liquidated', }); + const liquidationRatio = await getDeployParameter('LIQUIDATION_RATIO'); await runStep({ contract: 'SystemSettings', target: SystemSettings, read: 'liquidationRatio', readTarget: previousSystemSettings, - expected: input => input !== '0', // only change if zero + expected: allowZeroOrUpdateIfNonZero(liquidationRatio), write: 'setLiquidationRatio', - writeArg: await getDeployParameter('LIQUIDATION_RATIO'), + writeArg: liquidationRatio, comment: 'Set the ratio below which an account can be flagged for liquidation', }); + const liquidationPenalty = await getDeployParameter('LIQUIDATION_PENALTY'); await runStep({ contract: 'SystemSettings', target: SystemSettings, read: 'liquidationPenalty', readTarget: previousSystemSettings, - expected: input => input !== '0', // only change if zero + expected: allowZeroOrUpdateIfNonZero(liquidationPenalty), write: 'setLiquidationPenalty', - writeArg: await getDeployParameter('LIQUIDATION_PENALTY'), + writeArg: liquidationPenalty, comment: 'Set the penalty amount a liquidator receives from a liquidated account', }); + const rateStalePeriod = await getDeployParameter('RATE_STALE_PERIOD'); await runStep({ contract: 'SystemSettings', target: SystemSettings, read: 'rateStalePeriod', readTarget: previousSystemSettings, - expected: input => input !== '0', // only change if zero + expected: allowZeroOrUpdateIfNonZero(rateStalePeriod), write: 'setRateStalePeriod', - writeArg: await getDeployParameter('RATE_STALE_PERIOD'), + writeArg: rateStalePeriod, comment: 'Set the maximum amount of time (in secs) that a rate can be used for', }); + const minimumStakeTime = await getDeployParameter('MINIMUM_STAKE_TIME'); await runStep({ contract: 'SystemSettings', target: SystemSettings, read: 'minimumStakeTime', readTarget: previousSystemSettings, - expected: input => input !== '0', // only change if zero + expected: allowZeroOrUpdateIfNonZero(minimumStakeTime), write: 'setMinimumStakeTime', - writeArg: await getDeployParameter('MINIMUM_STAKE_TIME'), + writeArg: minimumStakeTime, comment: 'Set the minimum amount of time SNX can be issued before any is burned (SIP-40)', }); + const debtSnapshotStaleTime = await getDeployParameter('DEBT_SNAPSHOT_STALE_TIME'); await runStep({ contract: 'SystemSettings', target: SystemSettings, read: 'debtSnapshotStaleTime', readTarget: previousSystemSettings, - expected: input => input !== '0', // only change if zero + expected: allowZeroOrUpdateIfNonZero(debtSnapshotStaleTime), write: 'setDebtSnapshotStaleTime', - writeArg: await getDeployParameter('DEBT_SNAPSHOT_STALE_TIME'), + writeArg: debtSnapshotStaleTime, comment: 'Set the length of time after which the DebtCache snapshot becomes stale (SIP-91)', }); + const crossDomainDepositGasLimit = await getDeployParameter('CROSS_DOMAIN_DEPOSIT_GAS_LIMIT'); await runStep({ contract: 'SystemSettings', target: SystemSettings, read: 'crossDomainMessageGasLimit', readArg: 0, readTarget: previousSystemSettings, - expected: input => input !== '0', // only change if zero + expected: allowZeroOrUpdateIfNonZero(crossDomainDepositGasLimit), write: 'setCrossDomainMessageGasLimit', - writeArg: [0, await getDeployParameter('CROSS_DOMAIN_DEPOSIT_GAS_LIMIT')], + writeArg: [0, crossDomainDepositGasLimit], comment: 'Set the gas limit for depositing onto L2', }); + const crossDomainEscrowGasLimit = await getDeployParameter('CROSS_DOMAIN_ESCROW_GAS_LIMIT'); await runStep({ contract: 'SystemSettings', target: SystemSettings, read: 'crossDomainMessageGasLimit', readArg: 1, readTarget: previousSystemSettings, - expected: input => input !== '0', // only change if zero + expected: allowZeroOrUpdateIfNonZero(crossDomainEscrowGasLimit), write: 'setCrossDomainMessageGasLimit', - writeArg: [1, await getDeployParameter('CROSS_DOMAIN_ESCROW_GAS_LIMIT')], + writeArg: [1, crossDomainEscrowGasLimit], comment: 'Set the gas limit for migrating escrowed SNX to L2', }); + const crossDomainRewardGasLimit = await getDeployParameter('CROSS_DOMAIN_REWARD_GAS_LIMIT'); await runStep({ contract: 'SystemSettings', target: SystemSettings, read: 'crossDomainMessageGasLimit', readArg: 2, readTarget: previousSystemSettings, - expected: input => input !== '0', // only change if zero + expected: allowZeroOrUpdateIfNonZero(crossDomainRewardGasLimit), write: 'setCrossDomainMessageGasLimit', - writeArg: [2, await getDeployParameter('CROSS_DOMAIN_REWARD_GAS_LIMIT')], + writeArg: [2, crossDomainRewardGasLimit], comment: 'Set the gas limit for depositing rewards to L2', }); + const crossDomainWithdrawalGasLimit = await getDeployParameter( + 'CROSS_DOMAIN_WITHDRAWAL_GAS_LIMIT' + ); await runStep({ contract: 'SystemSettings', target: SystemSettings, read: 'crossDomainMessageGasLimit', readArg: 3, readTarget: previousSystemSettings, - expected: input => input !== '0', // only change if zero + expected: allowZeroOrUpdateIfNonZero(crossDomainWithdrawalGasLimit), write: 'setCrossDomainMessageGasLimit', - writeArg: [3, await getDeployParameter('CROSS_DOMAIN_WITHDRAWAL_GAS_LIMIT')], + writeArg: [3, crossDomainWithdrawalGasLimit], comment: 'Set the gas limit for withdrawing from L2', }); + const crossDomainRelayGasLimit = await getDeployParameter('CROSS_DOMAIN_RELAY_GAS_LIMIT'); await runStep({ contract: 'SystemSettings', target: SystemSettings, read: 'crossDomainMessageGasLimit', readArg: 4, readTarget: previousSystemSettings, - expected: input => input !== '0', // only change if zero + expected: allowZeroOrUpdateIfNonZero(crossDomainRelayGasLimit), write: 'setCrossDomainMessageGasLimit', - writeArg: [4, await getDeployParameter('CROSS_DOMAIN_RELAY_GAS_LIMIT')], + writeArg: [4, crossDomainRelayGasLimit], comment: 'Set the gas limit for relaying owner actions to L2', }); @@ -311,24 +331,27 @@ module.exports = async ({ }); } + const etherWrapperMaxETH = await getDeployParameter('ETHER_WRAPPER_MAX_ETH'); await runStep({ contract: 'SystemSettings', target: SystemSettings, read: 'etherWrapperMaxETH', readTarget: previousSystemSettings, - expected: input => input !== '0', // only change if zero + expected: allowZeroOrUpdateIfNonZero(etherWrapperMaxETH), write: 'setEtherWrapperMaxETH', - writeArg: await getDeployParameter('ETHER_WRAPPER_MAX_ETH'), + writeArg: etherWrapperMaxETH, comment: 'Set the max amount of Ether allowed in the EtherWrapper (SIP-112)', }); + + const etherWrapperMintFeeRate = await getDeployParameter('ETHER_WRAPPER_MINT_FEE_RATE'); await runStep({ contract: 'SystemSettings', target: SystemSettings, read: 'etherWrapperMintFeeRate', readTarget: previousSystemSettings, - expected: input => input !== '0', // only change if zero + expected: allowZeroOrUpdateIfNonZero(etherWrapperMintFeeRate), write: 'setEtherWrapperMintFeeRate', - writeArg: await getDeployParameter('ETHER_WRAPPER_MINT_FEE_RATE'), + writeArg: etherWrapperMintFeeRate, comment: 'Set the fee rate for minting sETH from ETH in the EtherWrapper (SIP-112)', }); @@ -339,7 +362,7 @@ module.exports = async ({ target: SystemSettings, read: 'etherWrapperBurnFeeRate', readTarget: previousSystemSettings, - expected: input => etherWrapperBurnFeeRate === '0' || input !== '0', // only change if the value to set is above zero and the value onchain is 0 + expected: allowZeroOrUpdateIfNonZero(etherWrapperBurnFeeRate), write: 'setEtherWrapperBurnFeeRate', writeArg: etherWrapperBurnFeeRate, comment: 'Set the fee rate for burning sETH for ETH in the EtherWrapper (SIP-112)', @@ -354,7 +377,7 @@ module.exports = async ({ target: SystemSettings, read: 'atomicMaxVolumePerBlock', readTarget: previousSystemSettings, - expected: input => atomicMaxVolumePerBlock === '0' || input !== '0', // only change if setting to non-zero from zero + expected: allowZeroOrUpdateIfNonZero(atomicMaxVolumePerBlock), write: 'setAtomicMaxVolumePerBlock', writeArg: atomicMaxVolumePerBlock, comment: 'SIP-120 Set max atomic volume per block (in USD amounts)', @@ -362,14 +385,15 @@ module.exports = async ({ } if (SystemSettings.atomicTwapWindow) { + const atomicTwapWindow = await getDeployParameter('ATOMIC_TWAP_WINDOW'); await runStep({ contract: 'SystemSettings', target: SystemSettings, read: 'atomicTwapWindow', readTarget: previousSystemSettings, - expected: input => input !== '0', // only change if zero + expected: allowZeroOrUpdateIfNonZero(atomicTwapWindow), write: 'setAtomicTwapWindow', - writeArg: await getDeployParameter('ATOMIC_TWAP_WINDOW'), + writeArg: atomicTwapWindow, comment: 'SIP-120 Set the TWAP window for atomic swaps', }); } @@ -490,7 +514,7 @@ module.exports = async ({ read: 'interactionDelay', readArg: addressOf(CollateralShort), readTarget: previousSystemSettings, - expected: input => (interactionDelay === '0' ? true : input !== '0'), + expected: allowZeroOrUpdateIfNonZero(interactionDelay), write: 'setInteractionDelay', writeArg: [CollateralShort.address, interactionDelay], comment: 'Ensure the CollateralShort contract has an interaction delay of zero on the OVM', @@ -505,7 +529,7 @@ module.exports = async ({ read: 'collapseFeeRate', readArg: addressOf(CollateralShort), readTarget: previousSystemSettings, - expected: input => (collapseFeeRate === '0' ? true : input !== '0'), + expected: allowZeroOrUpdateIfNonZero(collapseFeeRate), write: 'setCollapseFeeRate', writeArg: [CollateralShort.address, collapseFeeRate], comment: diff --git a/publish/src/commands/deploy/deploy-core.js b/publish/src/commands/deploy/deploy-core.js index dfd6a6ce02..223bec3c57 100644 --- a/publish/src/commands/deploy/deploy-core.js +++ b/publish/src/commands/deploy/deploy-core.js @@ -14,7 +14,6 @@ module.exports = async ({ currentSynthetixSupply, currentWeekOfInflation, deployer, - oracleAddress, useOvm, }) => { console.log(gray(`\n------ DEPLOY LIBRARIES ------\n`)); @@ -27,6 +26,10 @@ module.exports = async ({ name: 'Math', }); + await deployer.deployContract({ + name: 'SystemSettingsLib', + }); + console.log(gray(`\n------ DEPLOY CORE PROTOCOL ------\n`)); await deployer.deployContract({ @@ -59,7 +62,7 @@ module.exports = async ({ await deployer.deployContract({ name: 'ExchangeRates', source: useOvm ? 'ExchangeRates' : 'ExchangeRatesWithDexPricing', - args: [account, oracleAddress, addressOf(readProxyForResolver), [], []], + args: [account, addressOf(readProxyForResolver)], }); await deployer.deployContract({ diff --git a/publish/src/commands/deploy/index.js b/publish/src/commands/deploy/index.js index 686982fa01..b24cd46e27 100644 --- a/publish/src/commands/deploy/index.js +++ b/publish/src/commands/deploy/index.js @@ -62,7 +62,6 @@ const deploy = async ({ ignoreSafetyChecks, manageNonces, network = DEFAULTS.network, - oracleExrates, privateKey, providerUrl, skipFeedChecks = false, @@ -212,7 +211,6 @@ const deploy = async ({ currentSynthetixSupply, currentLastMintEvent, currentWeekOfInflation, - oracleAddress, systemSuspended, } = await systemAndParameterCheck({ account, @@ -229,7 +227,6 @@ const deploy = async ({ maxPriorityFeePerGas, getDeployParameter, network, - oracleExrates, providerUrl, skipFeedChecks, standaloneFeeds, @@ -276,7 +273,6 @@ const deploy = async ({ currentSynthetixSupply, currentWeekOfInflation, deployer, - oracleAddress, useOvm, }); diff --git a/publish/src/commands/deploy/system-and-parameter-check.js b/publish/src/commands/deploy/system-and-parameter-check.js index ac835a43c2..c14394ab25 100644 --- a/publish/src/commands/deploy/system-and-parameter-check.js +++ b/publish/src/commands/deploy/system-and-parameter-check.js @@ -33,7 +33,6 @@ module.exports = async ({ maxPriorityFeePerGas, getDeployParameter, network, - oracleExrates, providerUrl, skipFeedChecks, standaloneFeeds, @@ -43,7 +42,6 @@ module.exports = async ({ yes, buildPath, }) => { - let oracleAddress; let currentSynthetixSupply; let oldExrates; let currentLastMintEvent; @@ -92,12 +90,8 @@ module.exports = async ({ try { oldExrates = deployer.getExistingContract({ contract: 'ExchangeRates' }); - if (!oracleExrates) { - oracleAddress = await oldExrates.oracle(); - } } catch (err) { if (freshDeploy) { - oracleAddress = oracleExrates || account; oldExrates = undefined; // unset to signify that a fresh one will be deployed } else { console.error( @@ -127,12 +121,10 @@ module.exports = async ({ } } - for (const address of [account, oracleAddress]) { - if (!isAddress(address)) { - console.error(red('Invalid address detected (please check your inputs):', address)); - process.exitCode = 1; - process.exit(); - } + if (!isAddress(account)) { + console.error(red('Invalid address detected (please check your inputs):', account)); + process.exitCode = 1; + process.exit(); } const newSynthsToAdd = synths @@ -206,7 +198,6 @@ module.exports = async ({ : yellow('⚠ NO'), 'Deployer account:': account, 'Synthetix totalSupply': `${Math.round(formatUnits(currentSynthetixSupply) / 1e6)}m`, - 'ExchangeRates Oracle': oracleAddress, 'Last Mint Event': `${currentLastMintEvent} (${new Date(currentLastMintEvent * 1000)})`, 'Current Weeks Of Inflation': currentWeekOfInflation, 'Aggregated Prices': aggregatedPriceResults, @@ -240,7 +231,6 @@ module.exports = async ({ currentLastMintEvent, currentWeekOfInflation, oldExrates, - oracleAddress, systemSuspended, }; }; diff --git a/publish/src/util.js b/publish/src/util.js index a56aa05012..695edb9fb5 100644 --- a/publish/src/util.js +++ b/publish/src/util.js @@ -46,6 +46,8 @@ const JSONreplacer = (key, value) => { }; const stringify = input => JSON.stringify(input, JSONreplacer, '\t') + '\n'; +const allowZeroOrUpdateIfNonZero = param => input => param === '0' || input !== '0'; + const ensureNetwork = network => { if (!networks.includes(network)) { throw Error( @@ -272,6 +274,7 @@ const assignGasOptions = async ({ tx, provider, maxFeePerGas, maxPriorityFeePerG }; module.exports = { + allowZeroOrUpdateIfNonZero, ensureNetwork, ensureDeploymentPath, getDeploymentPathForNetwork, diff --git a/slither.config.json b/slither.config.json index a4494acca6..a6c11e0779 100644 --- a/slither.config.json +++ b/slither.config.json @@ -1,4 +1,5 @@ { "buidler_cache_directory": "build/cache", - "hardhat_artifacts_directory": "build/artifacts" + "hardhat_artifacts_directory": "build/artifacts", + "detectors_to_exclude": "reentrancy-events" } diff --git a/test/contracts/BaseSynthetix.js b/test/contracts/BaseSynthetix.js index 0cfae0a64c..c9a78e39ca 100644 --- a/test/contracts/BaseSynthetix.js +++ b/test/contracts/BaseSynthetix.js @@ -10,11 +10,13 @@ require('./common'); // import common test scaffolding const { setupContract, setupAllContracts } = require('./setup'); -const { currentTime, fastForward, toUnit } = require('../utils')(); +const { fastForward, toUnit } = require('../utils')(); const { ensureOnlyExpectedMutativeFunctions, onlyGivenAddressCanInvoke, + setupPriceAggregators, + updateAggregatorRates, updateRatesWithDefaults, setStatus, } = require('./helpers'); @@ -33,8 +35,6 @@ contract('BaseSynthetix', async accounts => { exchangeRates, debtCache, escrow, - oracle, - timestamp, addressResolver, systemSettings, systemStatus; @@ -68,9 +68,7 @@ contract('BaseSynthetix', async accounts => { ], })); - // Send a price update to guarantee we're not stale. - oracle = account1; - timestamp = await currentTime(); + await setupPriceAggregators(exchangeRates, owner, [sAUD, sEUR, sETH]); }); addSnapshotBeforeRestoreAfterEach(); @@ -406,7 +404,7 @@ contract('BaseSynthetix', async accounts => { }); describe('when a user has exchanged into sETH', () => { beforeEach(async () => { - await updateRatesWithDefaults({ exchangeRates, oracle, debtCache }); + await updateRatesWithDefaults({ exchangeRates, owner, debtCache }); await baseSynthetix.issueSynths(toUnit('100'), { from: owner }); await baseSynthetix.exchange(sUSD, toUnit('10'), sETH, { from: owner }); @@ -434,13 +432,10 @@ contract('BaseSynthetix', async accounts => { // fast forward to get past initial SNX setting await fastForward((await exchangeRates.rateStalePeriod()).add(web3.utils.toBN('300'))); - timestamp = await currentTime(); - - await exchangeRates.updateRates( + await updateAggregatorRates( + exchangeRates, [sAUD, sEUR, sETH], - ['0.5', '1.25', '100'].map(toUnit), - timestamp, - { from: oracle } + ['0.5', '1.25', '100'].map(toUnit) ); await debtCache.takeDebtSnapshot(); }); @@ -449,9 +444,7 @@ contract('BaseSynthetix', async accounts => { }); describe('when SNX is also set', () => { beforeEach(async () => { - timestamp = await currentTime(); - - await exchangeRates.updateRates([SNX], ['1'].map(toUnit), timestamp, { from: oracle }); + await updateAggregatorRates(exchangeRates, [SNX], ['1'].map(toUnit)); }); it('then no stale rates', async () => { assert.equal(await baseSynthetix.anySynthOrSNXRateIsInvalid(), false); @@ -461,11 +454,7 @@ contract('BaseSynthetix', async accounts => { beforeEach(async () => { await fastForward((await exchangeRates.rateStalePeriod()).add(web3.utils.toBN('300'))); - timestamp = await currentTime(); - - await exchangeRates.updateRates([SNX, sAUD], ['0.1', '0.78'].map(toUnit), timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [SNX, sAUD], ['0.1', '0.78'].map(toUnit)); }); it('then anySynthOrSNXRateIsInvalid() returns true', async () => { @@ -522,7 +511,7 @@ contract('BaseSynthetix', async accounts => { beforeEach(async () => { // Ensure all synths have rates to allow issuance - await updateRatesWithDefaults({ exchangeRates, oracle, debtCache }); + await updateRatesWithDefaults({ exchangeRates, owner, debtCache }); }); it('should transfer using the ERC20 transfer function @gasprofile', async () => { @@ -707,28 +696,21 @@ contract('BaseSynthetix', async accounts => { it('should not allow transfer if the exchange rate for SNX is stale', async () => { await ensureTransferReverts(); - const timestamp = await currentTime(); - // now give some synth rates - await exchangeRates.updateRates([sAUD, sEUR], ['0.5', '1.25'].map(toUnit), timestamp, { - from: oracle, - }); + + await updateAggregatorRates(exchangeRates, [sAUD, sEUR], ['0.5', '1.25'].map(toUnit)); await debtCache.takeDebtSnapshot(); await ensureTransferReverts(); // the remainder of the synths have prices - await exchangeRates.updateRates([sETH], ['100'].map(toUnit), timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [sETH], ['100'].map(toUnit)); await debtCache.takeDebtSnapshot(); await ensureTransferReverts(); // now give SNX rate - await exchangeRates.updateRates([SNX], ['1'].map(toUnit), timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [SNX], ['1'].map(toUnit)); // now SNX transfer should work await baseSynthetix.transfer(account2, value, { from: account1 }); @@ -740,28 +722,20 @@ contract('BaseSynthetix', async accounts => { it('should not allow transfer if the exchange rate for any synth is stale', async () => { await ensureTransferReverts(); - const timestamp = await currentTime(); - // now give SNX rate - await exchangeRates.updateRates([SNX], ['1'].map(toUnit), timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [SNX], ['1'].map(toUnit)); await debtCache.takeDebtSnapshot(); await ensureTransferReverts(); // now give some synth rates - await exchangeRates.updateRates([sAUD, sEUR], ['0.5', '1.25'].map(toUnit), timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [sAUD, sEUR], ['0.5', '1.25'].map(toUnit)); await debtCache.takeDebtSnapshot(); await ensureTransferReverts(); // now give the remainder of synths rates - await exchangeRates.updateRates([sETH], ['100'].map(toUnit), timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [sETH], ['100'].map(toUnit)); await debtCache.takeDebtSnapshot(); // now SNX transfer should work @@ -847,8 +821,7 @@ contract('BaseSynthetix', async accounts => { it("should lock newly received synthetix if the user's collaterisation is too high", async () => { // Set sEUR for purposes of this test - const timestamp1 = await currentTime(); - await exchangeRates.updateRates([sEUR], [toUnit('0.75')], timestamp1, { from: oracle }); + await updateAggregatorRates(exchangeRates, [sEUR], [toUnit('0.75')]); await debtCache.takeDebtSnapshot(); const issuedSynthetixs = web3.utils.toBN('200000'); @@ -876,8 +849,7 @@ contract('BaseSynthetix', async accounts => { }); // Increase the value of sEUR relative to synthetix - const timestamp2 = await currentTime(); - await exchangeRates.updateRates([sEUR], [toUnit('2.10')], timestamp2, { from: oracle }); + await updateAggregatorRates(exchangeRates, [sEUR], [toUnit('2.10')]); await debtCache.takeDebtSnapshot(); // Ensure that the new synthetix account1 receives cannot be transferred out. @@ -892,10 +864,9 @@ contract('BaseSynthetix', async accounts => { await systemSettings.setPriceDeviationThresholdFactor(toUnit('5'), { from: owner }); // Set sAUD for purposes of this test - const timestamp1 = await currentTime(); const aud2usdrate = toUnit('2'); - await exchangeRates.updateRates([sAUD], [aud2usdrate], timestamp1, { from: oracle }); + await updateAggregatorRates(exchangeRates, [sAUD], [aud2usdrate]); await debtCache.takeDebtSnapshot(); const issuedSynthetixs = web3.utils.toBN('200000'); @@ -917,9 +888,8 @@ contract('BaseSynthetix', async accounts => { await baseSynthetix.exchange(sUSD, issuedSynths, sAUD, { from: account1 }); // Increase the value of sAUD relative to synthetix - const timestamp2 = await currentTime(); const newAUDExchangeRate = toUnit('1'); - await exchangeRates.updateRates([sAUD], [newAUDExchangeRate], timestamp2, { from: oracle }); + await updateAggregatorRates(exchangeRates, [sAUD], [newAUDExchangeRate]); await debtCache.takeDebtSnapshot(); const transferable2 = await baseSynthetix.transferableSynthetix(account1); diff --git a/test/contracts/CollateralErc20.js b/test/contracts/CollateralErc20.js index 6121bdacad..5e1b4146b6 100644 --- a/test/contracts/CollateralErc20.js +++ b/test/contracts/CollateralErc20.js @@ -8,11 +8,16 @@ const BN = require('bn.js'); const PublicEST8Decimals = artifacts.require('PublicEST8Decimals'); -const { fastForward, toUnit, currentTime } = require('../utils')(); +const { fastForward, toUnit } = require('../utils')(); const { setupAllContracts, setupContract } = require('./setup'); -const { ensureOnlyExpectedMutativeFunctions, setStatus } = require('./helpers'); +const { + ensureOnlyExpectedMutativeFunctions, + setStatus, + setupPriceAggregators, + updateAggregatorRates, +} = require('./helpers'); const { toBytes32, @@ -47,7 +52,7 @@ contract('CollateralErc20', async accounts => { let id; let proxy, tokenState; - const [deployerAccount, owner, oracle, , account1, account2] = accounts; + const [deployerAccount, owner, , , account1, account2] = accounts; let cerc20, managerState, @@ -85,17 +90,7 @@ contract('CollateralErc20', async accounts => { }; const updateRatesWithDefaults = async () => { - const timestamp = await currentTime(); - - await exchangeRates.updateRates([sETH], ['100'].map(toUnit), timestamp, { - from: oracle, - }); - - const sBTC = toBytes32('sBTC'); - - await exchangeRates.updateRates([sBTC], ['10000'].map(toUnit), timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [sETH, sBTC], [100, 10000].map(toUnit)); }; const fastForwardAndUpdateRates = async seconds => { @@ -147,6 +142,8 @@ contract('CollateralErc20', async accounts => { ], })); + await setupPriceAggregators(exchangeRates, owner, [sBTC, sETH]); + managerState = await CollateralManagerState.new(owner, ZERO_ADDRESS, { from: deployerAccount }); const maxDebt = toUnit(10000000); @@ -304,28 +301,20 @@ contract('CollateralErc20', async accounts => { }); it('when the price falls by 25% our c ratio is 150%', async () => { - await exchangeRates.updateRates([sBTC], ['7500'].map(toUnit), await currentTime(), { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [sBTC], [7500].map(toUnit)); const ratio = await cerc20.collateralRatio(id); assert.bnEqual(ratio, toUnit(1.5)); }); it('when the price increases by 100% our c ratio is 400%', async () => { - await exchangeRates.updateRates([sBTC], ['20000'].map(toUnit), await currentTime(), { - from: oracle, - }); - + await updateAggregatorRates(exchangeRates, [sBTC], [20000].map(toUnit)); const ratio = await cerc20.collateralRatio(id); assert.bnEqual(ratio, toUnit(4)); }); it('when the price fallsby 50% our cratio is 100%', async () => { - await exchangeRates.updateRates([sBTC], ['5000'].map(toUnit), await currentTime(), { - from: oracle, - }); - + await updateAggregatorRates(exchangeRates, [sBTC], [5000].map(toUnit)); const ratio = await cerc20.collateralRatio(id); assert.bnEqual(ratio, toUnit(1)); }); @@ -346,10 +335,7 @@ contract('CollateralErc20', async accounts => { }); it('price changes should not change the cratio', async () => { - await exchangeRates.updateRates([sBTC], ['75'].map(toUnit), await currentTime(), { - from: oracle, - }); - + await updateAggregatorRates(exchangeRates, [sBTC], [75].map(toUnit)); const ratio = await cerc20.collateralRatio(id); assert.bnEqual(ratio, toUnit(2)); }); @@ -909,10 +895,7 @@ contract('CollateralErc20', async accounts => { let liquidationAmount; beforeEach(async () => { - const timestamp = await currentTime(); - await exchangeRates.updateRates([sBTC], ['7000'].map(toUnit), timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [sBTC], [7000].map(toUnit)); await issuesUSDToAccount(toUnit(5000), account2); @@ -962,10 +945,7 @@ contract('CollateralErc20', async accounts => { describe('when a loan needs to be completely liquidated', async () => { beforeEach(async () => { - const timestamp = await currentTime(); - await exchangeRates.updateRates([sBTC], ['5000'].map(toUnit), timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [sBTC], [5000].map(toUnit)); loan = await cerc20.loans(id); diff --git a/test/contracts/CollateralEth.js b/test/contracts/CollateralEth.js index 122337bf79..99635dba55 100644 --- a/test/contracts/CollateralEth.js +++ b/test/contracts/CollateralEth.js @@ -6,11 +6,16 @@ const { assert, addSnapshotBeforeRestoreAfterEach } = require('./common'); const BN = require('bn.js'); -const { fastForward, getEthBalance, toUnit, fromUnit, currentTime } = require('../utils')(); +const { fastForward, getEthBalance, toUnit, fromUnit } = require('../utils')(); const { setupAllContracts } = require('./setup'); -const { ensureOnlyExpectedMutativeFunctions, setStatus } = require('./helpers'); +const { + ensureOnlyExpectedMutativeFunctions, + setStatus, + setupPriceAggregators, + updateAggregatorRates, +} = require('./helpers'); const { toBytes32 } = require('../..'); @@ -20,6 +25,7 @@ contract('CollateralEth', async accounts => { const sUSD = toBytes32('sUSD'); const sETH = toBytes32('sETH'); + const sBTC = toBytes32('sBTC'); const oneETH = toUnit(1); const twoETH = toUnit(2); @@ -36,7 +42,7 @@ contract('CollateralEth', async accounts => { let loan; let id; - const [, owner, oracle, account1, account2] = accounts; + const [, owner, , account1, account2] = accounts; let ceth, managerState, @@ -101,6 +107,8 @@ contract('CollateralEth', async accounts => { ], })); + await setupPriceAggregators(exchangeRates, owner, [sBTC, sETH]); + await managerState.setAssociatedContract(manager.address, { from: owner }); FEE_ADDRESS = await feePool.FEE_ADDRESS(); @@ -139,17 +147,7 @@ contract('CollateralEth', async accounts => { }; const updateRatesWithDefaults = async () => { - const timestamp = await currentTime(); - - await exchangeRates.updateRates([sETH], ['100'].map(toUnit), timestamp, { - from: oracle, - }); - - const sBTC = toBytes32('sBTC'); - - await exchangeRates.updateRates([sBTC], ['10000'].map(toUnit), timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [sETH, sBTC], [100, 10000].map(toUnit)); }; const fastForwardAndUpdateRates = async seconds => { @@ -219,28 +217,19 @@ contract('CollateralEth', async accounts => { }); it('when the price falls by 25% our c ratio is 150%', async () => { - await exchangeRates.updateRates([sETH], ['75'].map(toUnit), await currentTime(), { - from: oracle, - }); - + await updateAggregatorRates(exchangeRates, [sETH], [toUnit(75)]); const ratio = await ceth.collateralRatio(id); assert.bnEqual(ratio, toUnit(1.5)); }); it('when the price increases by 100% our c ratio is 400%', async () => { - await exchangeRates.updateRates([sETH], ['200'].map(toUnit), await currentTime(), { - from: oracle, - }); - + await updateAggregatorRates(exchangeRates, [sETH], [toUnit(200)]); const ratio = await ceth.collateralRatio(id); assert.bnEqual(ratio, toUnit(4)); }); it('when the price falls by 50% our cratio is 100%', async () => { - await exchangeRates.updateRates([sETH], ['50'].map(toUnit), await currentTime(), { - from: oracle, - }); - + await updateAggregatorRates(exchangeRates, [sETH], [toUnit(50)]); const ratio = await ceth.collateralRatio(id); assert.bnEqual(ratio, toUnit(1)); }); @@ -261,10 +250,7 @@ contract('CollateralEth', async accounts => { }); it('price changes should not change the cratio', async () => { - await exchangeRates.updateRates([sETH], ['75'].map(toUnit), await currentTime(), { - from: oracle, - }); - + await updateAggregatorRates(exchangeRates, [sETH], [toUnit(75)]); const ratio = await ceth.collateralRatio(id); assert.bnEqual(ratio, toUnit(2)); }); @@ -279,7 +265,7 @@ contract('CollateralEth', async accounts => { assert.bnClose(sUSDAmount, toUnit('200'), '100'); // $260 worth of eth should allow $200 (0.02) of sBTC to be issued. - const sBTCAmount = await ceth.maxLoan(toUnit('2.6'), toBytes32('sBTC')); + const sBTCAmount = await ceth.maxLoan(toUnit('2.6'), sBTC); assert.bnEqual(sBTCAmount, toUnit('0.02')); }); @@ -791,11 +777,7 @@ contract('CollateralEth', async accounts => { let liquidationAmount; beforeEach(async () => { - const timestamp = await currentTime(); - await exchangeRates.updateRates([sETH], ['90'].map(toUnit), timestamp, { - from: oracle, - }); - + await updateAggregatorRates(exchangeRates, [sETH], [toUnit(90)]); await issuesUSDToAccount(toUnit(1000), account2); liquidatorEthBalBefore = new BN(await getEthBalance(account2)); @@ -856,11 +838,7 @@ contract('CollateralEth', async accounts => { let liquidatorEthBalBefore; beforeEach(async () => { - const timestamp = await currentTime(); - await exchangeRates.updateRates([sETH], ['50'].map(toUnit), timestamp, { - from: oracle, - }); - + await updateAggregatorRates(exchangeRates, [sETH], [toUnit(50)]); loan = await ceth.loans(id); await issuesUSDToAccount(toUnit(1000), account2); diff --git a/test/contracts/CollateralManager.js b/test/contracts/CollateralManager.js index 9b6db8a531..ffa1634309 100644 --- a/test/contracts/CollateralManager.js +++ b/test/contracts/CollateralManager.js @@ -4,11 +4,16 @@ const { contract } = require('hardhat'); const { assert, addSnapshotBeforeRestoreAfterEach } = require('./common'); -const { toUnit, currentTime, fastForward } = require('../utils')(); +const { toUnit, fastForward } = require('../utils')(); const { setupAllContracts, setupContract, mockToken } = require('./setup'); -const { ensureOnlyExpectedMutativeFunctions, onlyGivenAddressCanInvoke } = require('./helpers'); +const { + ensureOnlyExpectedMutativeFunctions, + onlyGivenAddressCanInvoke, + setupPriceAggregators, + updateAggregatorRates, +} = require('./helpers'); const { toBytes32, @@ -16,7 +21,7 @@ const { } = require('../..'); contract('CollateralManager', async accounts => { - const [, owner, oracle, , account1] = accounts; + const [, owner, , , account1] = accounts; const sETH = toBytes32('sETH'); const sUSD = toBytes32('sUSD'); @@ -58,17 +63,7 @@ contract('CollateralManager', async accounts => { }; const updateRatesWithDefaults = async () => { - const timestamp = await currentTime(); - - await exchangeRates.updateRates([sETH], ['100'].map(toUnit), timestamp, { - from: oracle, - }); - - const sBTC = toBytes32('sBTC'); - - await exchangeRates.updateRates([sBTC], ['10000'].map(toUnit), timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [sETH, sBTC], [100, 10000].map(toUnit)); }; const fastForwardAndUpdateRates = async seconds => { @@ -127,6 +122,8 @@ contract('CollateralManager', async accounts => { ], })); + await setupPriceAggregators(exchangeRates, owner, [sBTC, sETH]); + maxDebt = toUnit(50000000); await managerState.setAssociatedContract(manager.address, { from: owner }); diff --git a/test/contracts/CollateralShort.js b/test/contracts/CollateralShort.js index 018893baad..3e9afb874a 100644 --- a/test/contracts/CollateralShort.js +++ b/test/contracts/CollateralShort.js @@ -4,11 +4,16 @@ const { contract } = require('hardhat'); const { assert, addSnapshotBeforeRestoreAfterEach } = require('./common'); -const { fastForward, toUnit, fromUnit, currentTime } = require('../utils')(); +const { fastForward, toUnit, fromUnit } = require('../utils')(); const { setupAllContracts } = require('./setup'); -const { ensureOnlyExpectedMutativeFunctions, setExchangeFeeRateForSynths } = require('./helpers'); +const { + ensureOnlyExpectedMutativeFunctions, + setExchangeFeeRateForSynths, + setupPriceAggregators, + updateAggregatorRates, +} = require('./helpers'); const { toBytes32 } = require('../..'); @@ -19,7 +24,7 @@ contract('CollateralShort', async accounts => { const sETH = toBytes32('sETH'); const sBTC = toBytes32('sBTC'); - const [, owner, oracle, , account1, account2] = accounts; + const [, owner, , , account1, account2] = accounts; let short, managerState, @@ -54,17 +59,7 @@ contract('CollateralShort', async accounts => { }; const updateRatesWithDefaults = async () => { - const timestamp = await currentTime(); - - await exchangeRates.updateRates([sETH], ['100'].map(toUnit), timestamp, { - from: oracle, - }); - - const sBTC = toBytes32('sBTC'); - - await exchangeRates.updateRates([sBTC], ['10000'].map(toUnit), timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [sETH, sBTC], [100, 10000].map(toUnit)); }; const setupShort = async () => { @@ -103,6 +98,8 @@ contract('CollateralShort', async accounts => { ], })); + await setupPriceAggregators(exchangeRates, owner, [sBTC, sETH]); + await managerState.setAssociatedContract(manager.address, { from: owner }); FEE_ADDRESS = await feePool.FEE_ADDRESS(); @@ -506,10 +503,7 @@ contract('CollateralShort', async accounts => { await fastForwardAndUpdateRates(3600); - const timestamp = await currentTime(); - await exchangeRates.updateRates([sETH], ['50'].map(toUnit), timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [sETH], [toUnit(50)]); // simulate buying sETH for 50 susd. await sUSDSynth.transfer(owner, toUnit(50), { from: account1 }); @@ -531,10 +525,7 @@ contract('CollateralShort', async accounts => { await fastForwardAndUpdateRates(3600); - const timestamp = await currentTime(); - await exchangeRates.updateRates([sETH], ['150'].map(toUnit), timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [sETH], [toUnit(150)]); // simulate buying sETH for 150 susd. await sUSDSynth.transfer(owner, toUnit(150), { from: account1 }); @@ -566,10 +557,7 @@ contract('CollateralShort', async accounts => { }); it('liquidation should be capped to only fix the c ratio', async () => { - const timestamp = await currentTime(); - await exchangeRates.updateRates([sETH], ['110'].map(toUnit), timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [sETH], [toUnit(110)]); // When the ETH price increases 10% to $110, the short // which started at 130% should allow 0.18 ETH @@ -620,11 +608,7 @@ contract('CollateralShort', async accounts => { await fastForwardAndUpdateRates(3600); - const timestamp = await currentTime(); - await exchangeRates.updateRates([sETH], ['150'].map(toUnit), timestamp, { - from: oracle, - }); - + await updateAggregatorRates(exchangeRates, [sETH], [toUnit(150)]); await debtCache.takeDebtSnapshot(); result = await debtCache.cachedDebt(); assert.bnEqual(result, toUnit(111100)); @@ -665,10 +649,7 @@ contract('CollateralShort', async accounts => { await fastForwardAndUpdateRates(3600); - const timestamp = await currentTime(); - await exchangeRates.updateRates([sETH], ['150'].map(toUnit), timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [sETH], [toUnit(150)]); // 111100 + 50 - (2 * 50) = 111,050 @@ -712,10 +693,7 @@ contract('CollateralShort', async accounts => { await fastForwardAndUpdateRates(3600); - const timestamp = await currentTime(); - await exchangeRates.updateRates([sETH], ['50'].map(toUnit), timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [sETH], [toUnit(50)]); // 111100 - 50 + (2 * 50) = 111,150 diff --git a/test/contracts/CollateralUtil.js b/test/contracts/CollateralUtil.js index b3c1c848a8..767d17a8a6 100644 --- a/test/contracts/CollateralUtil.js +++ b/test/contracts/CollateralUtil.js @@ -4,11 +4,15 @@ const { contract, web3 } = require('hardhat'); const { assert, addSnapshotBeforeRestoreAfterEach } = require('./common'); -const { toUnit, currentTime } = require('../utils')(); +const { toUnit } = require('../utils')(); const { setupAllContracts, setupContract, mockToken } = require('./setup'); -const { ensureOnlyExpectedMutativeFunctions } = require('./helpers'); +const { + ensureOnlyExpectedMutativeFunctions, + setupPriceAggregators, + updateAggregatorRates, +} = require('./helpers'); const { toBytes32 } = require('../..'); @@ -27,7 +31,7 @@ contract('CollateralUtil', async accounts => { const name = 'Some name'; const symbol = 'TOKEN'; - const [, owner, oracle, , account1] = accounts; + const [, owner, , , account1] = accounts; let cerc20, managerState, @@ -63,20 +67,6 @@ contract('CollateralUtil', async accounts => { await renBTC.transfer(receiver, issueAmount, { from: owner }); }; - const updateRatesWithDefaults = async () => { - const timestamp = await currentTime(); - - await exchangeRates.updateRates([sETH], ['100'].map(toUnit), timestamp, { - from: oracle, - }); - - const sBTC = toBytes32('sBTC'); - - await exchangeRates.updateRates([sBTC], ['10000'].map(toUnit), timestamp, { - from: oracle, - }); - }; - const deployCollateral = async ({ owner, manager, @@ -125,6 +115,8 @@ contract('CollateralUtil', async accounts => { ], })); + await setupPriceAggregators(exchangeRates, owner, [sBTC, sETH]); + await managerState.setAssociatedContract(manager.address, { from: owner }); ({ token: renBTC } = await mockToken({ @@ -186,7 +178,7 @@ contract('CollateralUtil', async accounts => { addSnapshotBeforeRestoreAfterEach(); beforeEach(async () => { - await updateRatesWithDefaults(); + await updateAggregatorRates(exchangeRates, [sETH, sBTC], [100, 10000].map(toUnit)); await issuesUSDToAccount(toUnit(1000), owner); await issuesBTCtoAccount(toUnit(10), owner); @@ -224,9 +216,7 @@ contract('CollateralUtil', async accounts => { }); it('when we start at 200%, we can take a 25% reduction in collateral prices', async () => { - await exchangeRates.updateRates([sBTC], ['7500'].map(toUnit), await currentTime(), { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [sBTC], [toUnit(7500)]); amountToLiquidate = await cerc20.liquidationAmount(id); @@ -234,9 +224,7 @@ contract('CollateralUtil', async accounts => { }); it('when we start at 200%, a price shock of 30% in the collateral requires 25% of the loan to be liquidated', async () => { - await exchangeRates.updateRates([sBTC], ['7000'].map(toUnit), await currentTime(), { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [sBTC], [toUnit(7000)]); amountToLiquidate = await cerc20.liquidationAmount(id); @@ -244,9 +232,7 @@ contract('CollateralUtil', async accounts => { }); it('when we start at 200%, a price shock of 40% in the collateral requires 75% of the loan to be liquidated', async () => { - await exchangeRates.updateRates([sBTC], ['6000'].map(toUnit), await currentTime(), { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [sBTC], [toUnit(6000)]); amountToLiquidate = await cerc20.liquidationAmount(id); @@ -254,10 +240,7 @@ contract('CollateralUtil', async accounts => { }); it('when we start at 200%, a price shock of 45% in the collateral requires 100% of the loan to be liquidated', async () => { - await exchangeRates.updateRates([sBTC], ['5500'].map(toUnit), await currentTime(), { - from: oracle, - }); - + await updateAggregatorRates(exchangeRates, [sBTC], [toUnit(5500)]); amountToLiquidate = await cerc20.liquidationAmount(id); assert.bnClose(amountToLiquidate, toUnit(5000), '10000'); @@ -279,9 +262,7 @@ contract('CollateralUtil', async accounts => { }); it('when BTC is @ $20000 and we are liquidating 1000 sUSD, then redeem 0.055 BTC', async () => { - await exchangeRates.updateRates([sBTC], ['20000'].map(toUnit), await currentTime(), { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [sBTC], [toUnit(20000)]); collateralRedeemed = await util.collateralRedeemed(sUSD, oneThousandsUSD, collateralKey); @@ -289,9 +270,7 @@ contract('CollateralUtil', async accounts => { }); it('when BTC is @ $7000 and we are liquidating 2500 sUSD, then redeem 0.36666 ETH', async () => { - await exchangeRates.updateRates([sBTC], ['7000'].map(toUnit), await currentTime(), { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [sBTC], [toUnit(7000)]); collateralRedeemed = await util.collateralRedeemed(sUSD, toUnit(2500), collateralKey); @@ -303,9 +282,7 @@ contract('CollateralUtil', async accounts => { assert.bnEqual(collateralRedeemed, toUnit(1.1)); - await exchangeRates.updateRates([sBTC], ['1000'].map(toUnit), await currentTime(), { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [sBTC], [toUnit(1000)]); collateralRedeemed = await util.collateralRedeemed(sBTC, toUnit(1), collateralKey); diff --git a/test/contracts/DebtCache.js b/test/contracts/DebtCache.js index 75de4c34fc..18949aeb36 100644 --- a/test/contracts/DebtCache.js +++ b/test/contracts/DebtCache.js @@ -15,6 +15,8 @@ const { onlyGivenAddressCanInvoke, ensureOnlyExpectedMutativeFunctions, setStatus, + setupPriceAggregators, + updateAggregatorRates, } = require('./helpers'); const { @@ -35,7 +37,7 @@ contract('DebtCache', async accounts => { ].map(toBytes32); const synthKeys = [sUSD, sAUD, sEUR, sETH, SNX]; - const [deployerAccount, owner, oracle, account1, account2] = accounts; + const [deployerAccount, owner, , account1, account2] = accounts; const oneETH = toUnit('1.0'); const twoETH = toUnit('2.0'); @@ -49,7 +51,6 @@ contract('DebtCache', async accounts => { sETHContract, sEURContract, sAUDContract, - timestamp, debtCache, issuer, synths, @@ -279,18 +280,17 @@ contract('DebtCache', async accounts => { 'WETH', ], })); + + await setupPriceAggregators(exchangeRates, owner, [sAUD, sEUR, sETH, ETH, iETH]); }); addSnapshotBeforeRestoreAfterEach(); beforeEach(async () => { - timestamp = await currentTime(); - - await exchangeRates.updateRates( + await updateAggregatorRates( + exchangeRates, [sAUD, sEUR, SNX, sETH, ETH, iETH], - ['0.5', '1.25', '10', '200', '200', '200'].map(toUnit), - timestamp, - { from: oracle } + ['0.5', '1.25', '10', '200', '200', '200'].map(toUnit) ); // set a 0.3% default exchange fee rate @@ -395,11 +395,10 @@ contract('DebtCache', async accounts => { // set default issuance ratio of 0.2 await systemSettings.setIssuanceRatio(toUnit('0.2'), { from: owner }); // set up initial prices - await exchangeRates.updateRates( + await updateAggregatorRates( + exchangeRates, [sAUD, sEUR, sETH], - ['0.5', '2', '100'].map(toUnit), - await currentTime(), - { from: oracle } + ['0.5', '2', '100'].map(toUnit) ); await debtCache.takeDebtSnapshot(); @@ -451,9 +450,7 @@ contract('DebtCache', async accounts => { assert.bnEqual(result[0], toUnit(550)); assert.isFalse(result[1]); - await exchangeRates.updateRates([sAUD, sEUR], ['1', '3'].map(toUnit), await currentTime(), { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [sAUD, sEUR], ['1', '3'].map(toUnit)); await debtCache.takeDebtSnapshot(); assert.bnEqual((await debtCache.cacheInfo()).debt, toUnit(700)); result = await debtCache.currentDebt(); @@ -475,13 +472,10 @@ contract('DebtCache', async accounts => { }); it('updates the cached values for all individual synths', async () => { - await exchangeRates.updateRates( + await updateAggregatorRates( + exchangeRates, [sAUD, sEUR, sETH], - ['1', '3', '200'].map(toUnit), - await currentTime(), - { - from: oracle, - } + ['1', '3', '200'].map(toUnit) ); await debtCache.takeDebtSnapshot(); let debts = await debtCache.currentSynthDebts([sUSD, sEUR, sAUD, sETH]); @@ -509,11 +503,10 @@ contract('DebtCache', async accounts => { assert.isTrue((await debtCache.cacheInfo()).isInvalid); // Revalidate the cache once rates are no longer stale - await exchangeRates.updateRates( + await updateAggregatorRates( + exchangeRates, [sAUD, sEUR, SNX, sETH, ETH, iETH], - ['0.5', '2', '100', '200', '200', '200'].map(toUnit), - await currentTime(), - { from: oracle } + ['0.5', '2', '100', '200', '200', '200'].map(toUnit) ); const tx2 = await debtCache.takeDebtSnapshot(); assert.isFalse((await debtCache.cacheInfo()).isInvalid); @@ -530,11 +523,10 @@ contract('DebtCache', async accounts => { await fastForward(snapshotStaleTime + 10); // ensure no actual rates are stale. - await exchangeRates.updateRates( + await updateAggregatorRates( + exchangeRates, [sAUD, sEUR, sETH, SNX], - ['0.5', '2', '100', '1'].map(toUnit), - await currentTime(), - { from: oracle } + ['0.5', '2', '100', '1'].map(toUnit) ); const info = await debtCache.cacheInfo(); @@ -598,13 +590,11 @@ contract('DebtCache', async accounts => { const snapshotStaleTime = await systemSettings.debtSnapshotStaleTime(); await fastForward(snapshotStaleTime + 10); // ensure no actual rates are stale. - await exchangeRates.updateRates( + await updateAggregatorRates( + exchangeRates, [sAUD, sEUR, sETH, SNX], - ['0.5', '2', '100', '1'].map(toUnit), - await currentTime(), - { from: oracle } + ['0.5', '2', '100', '1'].map(toUnit) ); - await assert.revert( synthetix.issueSynths(toUnit('10'), { from: account1 }), 'A synth or SNX rate is invalid' @@ -672,13 +662,10 @@ contract('DebtCache', async accounts => { it('allows resynchronisation of subsets of synths', async () => { await debtCache.takeDebtSnapshot(); - await exchangeRates.updateRates( + await updateAggregatorRates( + exchangeRates, [sAUD, sEUR, sETH], - ['1', '3', '200'].map(toUnit), - await currentTime(), - { - from: oracle, - } + ['1', '3', '200'].map(toUnit) ); // First try a single currency, ensuring that the others have not been altered. @@ -712,11 +699,10 @@ contract('DebtCache', async accounts => { assert.isTrue((await debtCache.cacheInfo()).isInvalid); // But even if we update all rates, we can't revalidate the cache using the partial update function - await exchangeRates.updateRates( + await updateAggregatorRates( + exchangeRates, [sAUD, sEUR, sETH], - ['0.5', '2', '100'].map(toUnit), - await currentTime(), - { from: oracle } + ['0.5', '2', '100'].map(toUnit) ); const tx2 = await debtCache.updateCachedSynthDebts([sAUD, sEUR, sETH]); assert.isTrue((await debtCache.cacheInfo()).isInvalid); @@ -727,13 +713,10 @@ contract('DebtCache', async accounts => { it('properly emits events', async () => { await debtCache.takeDebtSnapshot(); - await exchangeRates.updateRates( + await updateAggregatorRates( + exchangeRates, [sAUD, sEUR, sETH], - ['1', '3', '200'].map(toUnit), - await currentTime(), - { - from: oracle, - } + ['1', '3', '200'].map(toUnit) ); const tx = await debtCache.updateCachedSynthDebts([sAUD]); @@ -998,9 +981,7 @@ contract('DebtCache', async accounts => { const debts = await debtCache.cachedSynthDebts([sAUD, sEUR]); - await exchangeRates.updateRates([sAUD, sEUR], ['1', '1'].map(toUnit), await currentTime(), { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [sAUD, sEUR], ['1', '1'].map(toUnit)); await synthetix.exchange(sEUR, toUnit(10), sAUD, { from: account1 }); const postDebts = await debtCache.cachedSynthDebts([sAUD, sEUR]); @@ -1031,9 +1012,7 @@ contract('DebtCache', async accounts => { // set a high price deviation threshold factor to be sure it doesn't trigger here await systemSettings.setPriceDeviationThresholdFactor(toUnit('99'), { from: owner }); - await exchangeRates.updateRates([sAUD, sEUR], ['2', '1'].map(toUnit), await currentTime(), { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [sAUD, sEUR], ['2', '1'].map(toUnit)); await fastForward(100); @@ -1443,7 +1422,6 @@ contract('DebtCache', async accounts => { await sETHContract.issue(account1, amount, { from: owner }); await setupShort(); - await systemSettings.setMinCratio(short.address, toUnit(1.5), { from: owner }); await short.setIssueFeeRate(toUnit('0'), { from: owner }); await short.open(amount, oneETH, sETH, { from: account1 }); }); diff --git a/test/contracts/Depot.js b/test/contracts/Depot.js index 1fafcec800..00ce2420c8 100644 --- a/test/contracts/Depot.js +++ b/test/contracts/Depot.js @@ -5,7 +5,6 @@ const { contract, web3 } = require('hardhat'); const { assert, addSnapshotBeforeRestoreAfterEach } = require('./common'); const { - currentTime, fastForward, getEthBalance, toUnit, @@ -17,6 +16,8 @@ const { onlyGivenAddressCanInvoke, ensureOnlyExpectedMutativeFunctions, setStatus, + setupPriceAggregators, + updateAggregatorRates, } = require('./helpers'); const { mockToken, setupAllContracts } = require('./setup'); @@ -26,7 +27,7 @@ const { toBytes32 } = require('../..'); contract('Depot', async accounts => { let synthetix, synth, depot, addressResolver, systemStatus, exchangeRates, ethRate, snxRate; - const [, owner, oracle, fundsWallet, address1, address2, address3] = accounts; + const [, owner, , fundsWallet, address1, address2, address3] = accounts; const [SNX, ETH] = ['SNX', 'ETH'].map(toBytes32); @@ -71,19 +72,16 @@ contract('Depot', async accounts => { 'Issuer', ], })); + + await setupPriceAggregators(exchangeRates, owner, [ETH]); }); addSnapshotBeforeRestoreAfterEach(); beforeEach(async () => { - const timestamp = await currentTime(); - snxRate = toUnit('0.1'); ethRate = toUnit('172'); - - await exchangeRates.updateRates([SNX, ETH], [snxRate, ethRate], timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [SNX, ETH], [snxRate, ethRate]); }); it('should set constructor params on deployment', async () => { @@ -778,10 +776,7 @@ contract('Depot', async accounts => { ); }); it('when the purchaser supplies a rate and the rate is changed in by the oracle', async () => { - const timestamp = await currentTime(); - await exchangeRates.updateRates([SNX, ETH], ['0.1', '134'].map(toUnit), timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [SNX, ETH], ['0.1', '134'].map(toUnit)); await assert.revert( depot.exchangeEtherForSynthsAtRate(ethRate, payload), 'Guaranteed rate would not be received' @@ -830,10 +825,7 @@ contract('Depot', async accounts => { ); }); it('when the purchaser supplies a rate and the rate is changed in by the oracle', async () => { - const timestamp = await currentTime(); - await exchangeRates.updateRates([SNX, ETH], ['0.1', '134'].map(toUnit), timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [SNX, ETH], ['0.1', '134'].map(toUnit)); await assert.revert( depot.exchangeEtherForSNXAtRate(ethRate, snxRate, ethToSendFromPurchaser), 'Guaranteed ether rate would not be received' @@ -894,10 +886,7 @@ contract('Depot', async accounts => { ); }); it('when the purchaser supplies a rate and the rate is changed in by the oracle', async () => { - const timestamp = await currentTime(); - await exchangeRates.updateRates([SNX], ['0.05'].map(toUnit), timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [SNX], ['0.05'].map(toUnit)); await assert.revert( depot.exchangeSynthsForSNXAtRate(synthsToSend, snxRate, fromPurchaser), 'Guaranteed rate would not be received' diff --git a/test/contracts/EtherWrapper.js b/test/contracts/EtherWrapper.js index 70e1d612f0..c5b6b105a9 100644 --- a/test/contracts/EtherWrapper.js +++ b/test/contracts/EtherWrapper.js @@ -4,12 +4,14 @@ const { contract } = require('hardhat'); const { assert, addSnapshotBeforeRestoreAfterEach } = require('./common'); -const { currentTime, toUnit, multiplyDecimal } = require('../utils')(); +const { toUnit, multiplyDecimal } = require('../utils')(); const { ensureOnlyExpectedMutativeFunctions, getDecodedLogs, decodedEventEqual, + setupPriceAggregators, + updateAggregatorRates, } = require('./helpers'); const { setupAllContracts } = require('./setup'); @@ -23,7 +25,7 @@ contract('EtherWrapper', async accounts => { const ONE = toBN('1'); - const [, owner, oracle, , account1] = accounts; + const [, owner, , , account1] = accounts; let systemSettings, feePool, @@ -35,8 +37,7 @@ contract('EtherWrapper', async accounts => { sUSDSynth, sETHSynth, etherWrapper, - weth, - timestamp; + weth; const calculateETHToUSD = async feesInETH => { // Ask the Depot how many sUSD I will get for this ETH @@ -93,12 +94,10 @@ contract('EtherWrapper', async accounts => { await systemSettings.setEtherWrapperBurnFeeRate(toUnit('0.005'), { from: owner }); FEE_ADDRESS = await feePool.FEE_ADDRESS(); - timestamp = await currentTime(); + await setupPriceAggregators(exchangeRates, owner, [sETH, ETH]); // Depot requires ETH rates - await exchangeRates.updateRates([sETH, ETH], ['1500', '1500'].map(toUnit), timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [sETH, ETH], ['1500', '1500'].map(toUnit)); }); addSnapshotBeforeRestoreAfterEach(); diff --git a/test/contracts/ExchangeRates.js b/test/contracts/ExchangeRates.js index 15e7aae97d..c5a78a4cfb 100644 --- a/test/contracts/ExchangeRates.js +++ b/test/contracts/ExchangeRates.js @@ -17,9 +17,11 @@ const { ensureOnlyExpectedMutativeFunctions, onlyGivenAddressCanInvoke, convertToDecimals, + setupPriceAggregators, + updateAggregatorRates, } = require('./helpers'); -const { setupContract, setupAllContracts } = require('./setup'); +const { setupAllContracts } = require('./setup'); const { toBytes32, @@ -31,33 +33,9 @@ const { toBN } = require('web3-utils'); const MockAggregator = artifacts.require('MockAggregatorV2V3'); -const getRandomCurrencyKey = () => - Math.random() - .toString(36) - .substring(2, 6) - .toUpperCase(); - -const createRandomKeysAndRates = quantity => { - const uniqueCurrencyKeys = {}; - for (let i = 0; i < quantity; i++) { - const rate = Math.random() * 100; - const key = toBytes32(getRandomCurrencyKey()); - uniqueCurrencyKeys[key] = web3.utils.toWei(rate.toFixed(18), 'ether'); - } - - const rates = []; - const currencyKeys = []; - Object.entries(uniqueCurrencyKeys).forEach(([key, rate]) => { - currencyKeys.push(key); - rates.push(rate); - }); - - return { currencyKeys, rates }; -}; - contract('Exchange Rates', async accounts => { const [deployerAccount, owner, oracle, dexPriceAggregator, accountOne, accountTwo] = accounts; - const [SNX, sJPY, sETH, sXTZ, sBNB, sUSD, sEUR, sAUD, fastGasPrice] = [ + const [SNX, sJPY, sETH, sXTZ, sBNB, sUSD, sEUR, sAUD, GOLD, fastGasPrice] = [ 'SNX', 'sJPY', 'sETH', @@ -66,6 +44,7 @@ contract('Exchange Rates', async accounts => { 'sUSD', 'sEUR', 'sAUD', + 'GOLD', 'fastGasPrice', ].map(toBytes32); let instance; @@ -73,19 +52,10 @@ contract('Exchange Rates', async accounts => { let aggregatorJPY; let aggregatorXTZ; let aggregatorFastGasPrice; - let initialTime; - let timeSent; - let resolver; let mockFlagsInterface; const itIncludesCorrectMutativeFunctions = contract => { - const baseFunctions = [ - 'addAggregator', - 'deleteRate', - 'removeAggregator', - 'setOracle', - 'updateRates', - ]; + const baseFunctions = ['addAggregator', 'removeAggregator']; const withDexPricingFunctions = baseFunctions.concat(['setDexPriceAggregator']); it('only expected functions should be mutative', () => { @@ -102,497 +72,11 @@ contract('Exchange Rates', async accounts => { describe('constructor', () => { it('should set constructor params on deployment', async () => { assert.equal(await instance.owner(), owner); - assert.equal(await instance.oracle(), oracle); - - assert.etherEqual(await instance.rateForCurrency(sUSD), '1'); - assert.etherEqual(await instance.rateForCurrency(SNX), '0.2'); - - // Ensure that when the rate isn't found, 0 is returned as the exchange rate. - assert.etherEqual(await instance.rateForCurrency(toBytes32('OTHER')), '0'); - - const lastUpdatedTimeSUSD = await instance.lastRateUpdateTimes.call(sUSD); - assert.isAtLeast(lastUpdatedTimeSUSD.toNumber(), initialTime); - - const lastUpdatedTimeOTHER = await instance.lastRateUpdateTimes.call(toBytes32('OTHER')); - assert.equal(lastUpdatedTimeOTHER.toNumber(), 0); - - const lastUpdatedTimeSNX = await instance.lastRateUpdateTimes.call(SNX); - assert.isAtLeast(lastUpdatedTimeSNX.toNumber(), initialTime); - - const sUSDRate = await instance.rateForCurrency(sUSD); - assert.bnEqual(sUSDRate, toUnit('1')); - }); - - it('two different currencies in same array should mean that the second one overrides', async () => { - const creationTime = await currentTime(); - const firstAmount = '4.33'; - const secondAmount = firstAmount + 10; - const instance = await setupContract({ - accounts, - contract, - args: [ - owner, - oracle, - resolver.address, - [toBytes32('CARTER'), toBytes32('CARTOON')], - [web3.utils.toWei(firstAmount, 'ether'), web3.utils.toWei(secondAmount, 'ether')], - ], - }); - - assert.etherEqual(await instance.rateForCurrency(toBytes32('CARTER')), firstAmount); - assert.etherEqual(await instance.rateForCurrency(toBytes32('CARTOON')), secondAmount); - - const lastUpdatedTime = await instance.lastRateUpdateTimes.call(toBytes32('CARTER')); - assert.isAtLeast(lastUpdatedTime.toNumber(), creationTime); - }); - - it('should revert when number of currency keys > new rates length on create', async () => { - await assert.revert( - setupContract({ - accounts, - contract, - args: [ - owner, - oracle, - resolver.address, - [SNX, toBytes32('GOLD')], - [web3.utils.toWei('0.2', 'ether')], - ], - }), - 'Currency key length and rate length must match' - ); - }); - - it('should limit to 32 bytes if currency key > 32 bytes on create', async () => { - const creationTime = await currentTime(); - const amount = '4.33'; - const instance = await setupContract({ - accounts, - contract, - args: [ - owner, - oracle, - resolver.address, - [toBytes32('ABCDEFGHIJKLMNOPQRSTUVXYZ1234567')], - [web3.utils.toWei(amount, 'ether')], - ], - }); - - assert.etherEqual( - await instance.rateForCurrency(toBytes32('ABCDEFGHIJKLMNOPQRSTUVXYZ1234567')), - amount - ); - assert.etherNotEqual( - await instance.rateForCurrency(toBytes32('ABCDEFGHIJKLMNOPQRSTUVXYZ123456')), - amount - ); - - const lastUpdatedTime = await instance.lastRateUpdateTimes.call( - toBytes32('ABCDEFGHIJKLMNOPQRSTUVXYZ1234567') - ); - assert.isAtLeast(lastUpdatedTime.toNumber(), creationTime); - }); - - it("shouldn't be able to set exchange rate to 0 on create", async () => { - await assert.revert( - setupContract({ - accounts, - contract, - args: [owner, oracle, resolver.address, [SNX], ['0']], - }), - 'Zero is not a valid rate, please call deleteRate instead' - ); - }); - - it('should be able to handle lots of currencies on creation', async () => { - const creationTime = await currentTime(); - const numberOfCurrencies = 80; - const { currencyKeys, rates } = createRandomKeysAndRates(numberOfCurrencies); - - const instance = await setupContract({ - accounts, - contract, - args: [owner, oracle, resolver.address, currencyKeys, rates], - }); - - for (let i = 0; i < currencyKeys.length; i++) { - assert.bnEqual(await instance.rateForCurrency(currencyKeys[i]), rates[i]); - const lastUpdatedTime = await instance.lastRateUpdateTimes.call(currencyKeys[i]); - assert.isAtLeast(lastUpdatedTime.toNumber(), creationTime); - } - }); - }); - }; - - // Oracle rates - - const itUpdatesRates = () => { - describe('updateRates()', () => { - it('should be able to update rates of only one currency without affecting other rates', async () => { - await fastForward(1); - - await instance.updateRates( - [toBytes32('lABC'), toBytes32('lDEF'), toBytes32('lGHI')], - [ - web3.utils.toWei('1.3', 'ether'), - web3.utils.toWei('2.4', 'ether'), - web3.utils.toWei('3.5', 'ether'), - ], - timeSent, - { from: oracle } - ); - - await fastForward(10); - const updatedTime = timeSent + 10; - - const updatedRate = '64.33'; - await instance.updateRates( - [toBytes32('lABC')], - [web3.utils.toWei(updatedRate, 'ether')], - updatedTime, - { from: oracle } - ); - - const updatedTimelDEF = await instance.lastRateUpdateTimes.call(toBytes32('lDEF')); - const updatedTimelGHI = await instance.lastRateUpdateTimes.call(toBytes32('lGHI')); - - assert.etherEqual(await instance.rateForCurrency(toBytes32('lABC')), updatedRate); - assert.etherEqual(await instance.rateForCurrency(toBytes32('lDEF')), '2.4'); - assert.etherEqual(await instance.rateForCurrency(toBytes32('lGHI')), '3.5'); - - const lastUpdatedTimeLABC = await instance.lastRateUpdateTimes.call(toBytes32('lABC')); - assert.equal(lastUpdatedTimeLABC.toNumber(), updatedTime); - const lastUpdatedTimeLDEF = await instance.lastRateUpdateTimes.call(toBytes32('lDEF')); - assert.equal(lastUpdatedTimeLDEF.toNumber(), updatedTimelDEF.toNumber()); - const lastUpdatedTimeLGHI = await instance.lastRateUpdateTimes.call(toBytes32('lGHI')); - assert.equal(lastUpdatedTimeLGHI.toNumber(), updatedTimelGHI.toNumber()); - }); - - it('should be able to update rates of all currencies', async () => { - await fastForward(1); - - await instance.updateRates( - [toBytes32('lABC'), toBytes32('lDEF'), toBytes32('lGHI')], - [ - web3.utils.toWei('1.3', 'ether'), - web3.utils.toWei('2.4', 'ether'), - web3.utils.toWei('3.5', 'ether'), - ], - timeSent, - { from: oracle } - ); - - await fastForward(5); - const updatedTime = timeSent + 5; - - const updatedRate1 = '64.33'; - const updatedRate2 = '2.54'; - const updatedRate3 = '10.99'; - await instance.updateRates( - [toBytes32('lABC'), toBytes32('lDEF'), toBytes32('lGHI')], - [ - web3.utils.toWei(updatedRate1, 'ether'), - web3.utils.toWei(updatedRate2, 'ether'), - web3.utils.toWei(updatedRate3, 'ether'), - ], - updatedTime, - { from: oracle } - ); - - assert.etherEqual(await instance.rateForCurrency(toBytes32('lABC')), updatedRate1); - assert.etherEqual(await instance.rateForCurrency(toBytes32('lDEF')), updatedRate2); - assert.etherEqual(await instance.rateForCurrency(toBytes32('lGHI')), updatedRate3); - - const lastUpdatedTimeLABC = await instance.lastRateUpdateTimes.call(toBytes32('lABC')); - assert.equal(lastUpdatedTimeLABC.toNumber(), updatedTime); - const lastUpdatedTimeLDEF = await instance.lastRateUpdateTimes.call(toBytes32('lDEF')); - assert.equal(lastUpdatedTimeLDEF.toNumber(), updatedTime); - const lastUpdatedTimeLGHI = await instance.lastRateUpdateTimes.call(toBytes32('lGHI')); - assert.equal(lastUpdatedTimeLGHI.toNumber(), updatedTime); - }); - - it('should revert when trying to set sUSD price', async () => { - await fastForward(1); - - await assert.revert( - instance.updateRates([sUSD], [web3.utils.toWei('1.0', 'ether')], timeSent, { - from: oracle, - }), - "Rate of sUSD cannot be updated, it's always UNIT" - ); - }); - - it('should emit RatesUpdated event when rate updated', async () => { - const rates = [ - web3.utils.toWei('1.3', 'ether'), - web3.utils.toWei('2.4', 'ether'), - web3.utils.toWei('3.5', 'ether'), - ]; - - const keys = ['lABC', 'lDEF', 'lGHI']; - const currencyKeys = keys.map(toBytes32); - const txn = await instance.updateRates(currencyKeys, rates, await currentTime(), { - from: oracle, - }); - - assert.eventEqual(txn, 'RatesUpdated', { - currencyKeys, - newRates: rates, - }); - }); - - it('should be able to handle lots of currency updates', async () => { - const numberOfCurrencies = 150; - const { currencyKeys, rates } = createRandomKeysAndRates(numberOfCurrencies); - - const updatedTime = await currentTime(); - await instance.updateRates(currencyKeys, rates, updatedTime, { from: oracle }); - - for (let i = 0; i < currencyKeys.length; i++) { - assert.equal(await instance.rateForCurrency(currencyKeys[i]), rates[i]); - const lastUpdatedTime = await instance.lastRateUpdateTimes.call(currencyKeys[i]); - assert.equal(lastUpdatedTime.toNumber(), updatedTime); - } - }); - - it('should revert when currency keys length != new rates length on update', async () => { - await assert.revert( - instance.updateRates( - [sUSD, SNX, toBytes32('GOLD')], - [web3.utils.toWei('1', 'ether'), web3.utils.toWei('0.2', 'ether')], - await currentTime(), - { from: oracle } - ), - 'Currency key array length must match rates array length' - ); - }); - - it('should not be able to set exchange rate to 0 on update', async () => { - await assert.revert( - instance.updateRates( - [toBytes32('ZERO')], - [web3.utils.toWei('0', 'ether')], - await currentTime(), - { from: oracle } - ), - 'Zero is not a valid rate, please call deleteRate instead' - ); - }); - - it('only oracle can update exchange rates', async () => { - await onlyGivenAddressCanInvoke({ - fnc: instance.updateRates, - args: [ - [toBytes32('GOLD'), toBytes32('FOOL')], - [web3.utils.toWei('10', 'ether'), web3.utils.toWei('0.9', 'ether')], - timeSent, - ], - address: oracle, - accounts, - skipPassCheck: true, - reason: 'Only the oracle can perform this action', - }); - - assert.etherNotEqual(await instance.rateForCurrency(toBytes32('GOLD')), '10'); - assert.etherNotEqual(await instance.rateForCurrency(toBytes32('FOOL')), '0.9'); - - const updatedTime = await currentTime(); - - await instance.updateRates( - [toBytes32('GOLD'), toBytes32('FOOL')], - [web3.utils.toWei('10', 'ether'), web3.utils.toWei('0.9', 'ether')], - updatedTime, - { from: oracle } - ); - assert.etherEqual(await instance.rateForCurrency(toBytes32('GOLD')), '10'); - assert.etherEqual(await instance.rateForCurrency(toBytes32('FOOL')), '0.9'); - - const lastUpdatedTimeGOLD = await instance.lastRateUpdateTimes.call(toBytes32('GOLD')); - assert.equal(lastUpdatedTimeGOLD.toNumber(), updatedTime); - const lastUpdatedTimeFOOL = await instance.lastRateUpdateTimes.call(toBytes32('FOOL')); - assert.equal(lastUpdatedTimeFOOL.toNumber(), updatedTime); - }); - - it('should not be able to update rates if they are too far in the future', async () => { - const timeTooFarInFuture = (await currentTime()) + 10 * 61; - await assert.revert( - instance.updateRates( - [toBytes32('GOLD')], - [web3.utils.toWei('1', 'ether')], - timeTooFarInFuture, - { from: oracle } - ), - 'Time is too far into the future' - ); - }); - }); - }; - - const itSetsOracle = () => { - describe('setOracle()', () => { - it("only the owner should be able to change the oracle's address", async () => { - await onlyGivenAddressCanInvoke({ - fnc: instance.setOracle, - args: [oracle], - address: owner, - accounts, - skipPassCheck: true, - }); - - await instance.setOracle(accountOne, { from: owner }); - - assert.equal(await instance.oracle.call(), accountOne); - assert.notEqual(await instance.oracle.call(), oracle); - }); - - it('should emit event on successful oracle address update', async () => { - // Ensure oracle is set to oracle address originally - await instance.setOracle(oracle, { from: owner }); - assert.equal(await instance.oracle.call(), oracle); - - const txn = await instance.setOracle(accountOne, { from: owner }); - assert.eventEqual(txn, 'OracleUpdated', { - newOracle: accountOne, - }); - }); - }); - }; - - const itDeletesRates = () => { - describe('deleteRate()', () => { - it('should be able to remove specific rate', async () => { - const foolsRate = '0.002'; - const encodedRateGOLD = toBytes32('GOLD'); - - await instance.updateRates( - [encodedRateGOLD, toBytes32('FOOL')], - [web3.utils.toWei('10.123', 'ether'), web3.utils.toWei(foolsRate, 'ether')], - timeSent, - { from: oracle } - ); - - const beforeRate = await instance.rateForCurrency(encodedRateGOLD); - const beforeRateUpdatedTime = await instance.lastRateUpdateTimes.call(encodedRateGOLD); - - await instance.deleteRate(encodedRateGOLD, { from: oracle }); - - const afterRate = await instance.rateForCurrency(encodedRateGOLD); - const afterRateUpdatedTime = await instance.lastRateUpdateTimes.call(encodedRateGOLD); - assert.notEqual(afterRate, beforeRate); - assert.equal(afterRate, '0'); - assert.notEqual(afterRateUpdatedTime, beforeRateUpdatedTime); - assert.equal(afterRateUpdatedTime, '0'); - - // Other rates are unaffected - assert.etherEqual(await instance.rateForCurrency(toBytes32('FOOL')), foolsRate); - }); - - it('only oracle can delete a rate', async () => { - // Assume that the contract is already set up with a valid oracle account called 'oracle' - - const encodedRateName = toBytes32('COOL'); - await instance.updateRates( - [encodedRateName], - [web3.utils.toWei('10.123', 'ether')], - await currentTime(), - { from: oracle } - ); - - await onlyGivenAddressCanInvoke({ - fnc: instance.deleteRate, - args: [encodedRateName], - accounts, - address: oracle, - reason: 'Only the oracle can perform this action', - }); - }); - - it("deleting rate that doesn't exist causes revert", async () => { - // This key shouldn't exist but let's do the best we can to ensure that it doesn't - const encodedCurrencyKey = toBytes32('7NEQ'); - const currentRate = await instance.rateForCurrency(encodedCurrencyKey); - if (currentRate > 0) { - await instance.deleteRate(encodedCurrencyKey, { from: oracle }); - } - - // Ensure rate deletion attempt results in revert - await assert.revert( - instance.deleteRate(encodedCurrencyKey, { from: oracle }), - 'Rate is zero' - ); - assert.etherEqual(await instance.rateForCurrency(encodedCurrencyKey), '0'); }); - it('should emit RateDeleted event when rate deleted', async () => { - const updatedTime = await currentTime(); - const rate = 'GOLD'; - const encodedRate = toBytes32(rate); - await instance.updateRates( - [encodedRate], - [web3.utils.toWei('10.123', 'ether')], - updatedTime, - { - from: oracle, - } - ); - - const txn = await instance.deleteRate(encodedRate, { from: oracle }); - assert.eventEqual(txn, 'RateDeleted', { currencyKey: encodedRate }); - }); - }); - }; - - const itReturnsRates = () => { - describe('getting rates', () => { - it('should be able to get exchange rate with key', async () => { - const updatedTime = await currentTime(); - const encodedRate = toBytes32('GOLD'); - const rateValueEncodedStr = web3.utils.toWei('10.123', 'ether'); - await instance.updateRates([encodedRate], [rateValueEncodedStr], updatedTime, { - from: oracle, - }); - - const rate = await instance.rateForCurrency(encodedRate); - assert.equal(rate, rateValueEncodedStr); - }); - - it('all users should be able to get exchange rate with key', async () => { - const updatedTime = await currentTime(); - const encodedRate = toBytes32('FETC'); - const rateValueEncodedStr = web3.utils.toWei('910.6661293879', 'ether'); - await instance.updateRates([encodedRate], [rateValueEncodedStr], updatedTime, { - from: oracle, - }); - - await instance.rateForCurrency(encodedRate, { from: accountOne }); - await instance.rateForCurrency(encodedRate, { from: accountTwo }); - await instance.rateForCurrency(encodedRate, { from: oracle }); - await instance.rateForCurrency(encodedRate, { from: owner }); - await instance.rateForCurrency(encodedRate, { from: deployerAccount }); - }); - - it('Fetching non-existent rate returns 0', async () => { - const encodedRateKey = toBytes32('GOLD'); - const currentRate = await instance.rateForCurrency(encodedRateKey); - if (currentRate > 0) { - await instance.deleteRate(encodedRateKey, { from: oracle }); - } - - const rate = await instance.rateForCurrency(encodedRateKey); - assert.equal(rate.toString(), '0'); - }); - - it('should be able to get the latest exchange rate and updated time', async () => { - const updatedTime = await currentTime(); - const encodedRate = toBytes32('GOLD'); - const rateValueEncodedStr = web3.utils.toWei('10.123', 'ether'); - await instance.updateRates([encodedRate], [rateValueEncodedStr], updatedTime, { - from: oracle, - }); - - const rateAndTime = await instance.rateAndUpdatedTime(encodedRate); - assert.equal(rateAndTime.rate, rateValueEncodedStr); - assert.bnEqual(rateAndTime.time, updatedTime); + it('returns correct values for sUSD after deployment ', async () => { + assert.bnEqual(await instance.rateForCurrency(sUSD), toUnit('1')); + assert.equal(await instance.lastRateUpdateTimes(sUSD), 0); }); }); }; @@ -620,62 +104,18 @@ contract('Exchange Rates', async accounts => { assert.equal(rateIsStale, false); }); - it('check if a single rate is stale', async () => { - // Set up rates for test - await systemSettings.setRateStalePeriod(30, { from: owner }); - const updatedTime = await currentTime(); - await instance.updateRates( - [toBytes32('ABC')], - [web3.utils.toWei('2', 'ether')], - updatedTime, - { - from: oracle, - } - ); - await fastForward(31); - - const rateIsStale = await instance.rateIsStale(toBytes32('ABC')); - assert.equal(rateIsStale, true); - }); - - it('check if a single rate is not stale', async () => { - // Set up rates for test - await systemSettings.setRateStalePeriod(30, { from: owner }); - const updatedTime = await currentTime(); - await instance.updateRates( - [toBytes32('ABC')], - [web3.utils.toWei('2', 'ether')], - updatedTime, - { - from: oracle, - } - ); - await fastForward(28); - - const rateIsStale = await instance.rateIsStale(toBytes32('ABC')); - assert.equal(rateIsStale, false); - }); - - it('ensure rate is considered stale if not set', async () => { + it('ensure stale if not set', async () => { // Set up rates for test await systemSettings.setRateStalePeriod(30, { from: owner }); - const encodedRateKey = toBytes32('GOLD'); - const currentRate = await instance.rateForCurrency(encodedRateKey); - if (currentRate > 0) { - await instance.deleteRate(encodedRateKey, { from: oracle }); - } - - const rateIsStale = await instance.rateIsStale(encodedRateKey); - assert.equal(rateIsStale, true); + assert.equal(await instance.rateIsStale(toBytes32('GOLD')), true); }); it('make sure anyone can check if rate is stale', async () => { - const rateKey = toBytes32('ABC'); - await instance.rateIsStale(rateKey, { from: oracle }); - await instance.rateIsStale(rateKey, { from: owner }); - await instance.rateIsStale(rateKey, { from: deployerAccount }); - await instance.rateIsStale(rateKey, { from: accountOne }); - await instance.rateIsStale(rateKey, { from: accountTwo }); + await instance.rateIsStale(sUSD, { from: oracle }); + await instance.rateIsStale(sUSD, { from: owner }); + await instance.rateIsStale(sUSD, { from: deployerAccount }); + await instance.rateIsStale(sUSD, { from: accountOne }); + await instance.rateIsStale(sUSD, { from: accountTwo }); }); }); }; @@ -683,29 +123,18 @@ contract('Exchange Rates', async accounts => { const itCalculatesInvalidRates = () => { describe('anyRateIsInvalid()', () => { describe('stale scenarios', () => { - it('should never allow sUSD to go stale via anyRateIsInvalid', async () => { - const keysArray = [SNX, toBytes32('GOLD')]; - - await instance.updateRates( - keysArray, - [web3.utils.toWei('0.1', 'ether'), web3.utils.toWei('0.2', 'ether')], - await currentTime(), - { from: oracle } - ); - assert.equal(await instance.anyRateIsInvalid(keysArray), false); + it('anyRateIsInvalid conforms to rateStalePeriod', async () => { + await setupAggregators([SNX, GOLD]); - await fastForward(await instance.rateStalePeriod()); + await updateRates([SNX, GOLD], [toUnit(0.1), toUnit(0.2)]); - await instance.updateRates( - [SNX, toBytes32('GOLD')], - [web3.utils.toWei('0.1', 'ether'), web3.utils.toWei('0.2', 'ether')], - await currentTime(), - { from: oracle } - ); + assert.equal(await instance.anyRateIsInvalid([SNX, GOLD]), false); - // Even though sUSD hasn't been updated since the stale rate period has expired, - // we expect that sUSD remains "not stale" - assert.equal(await instance.anyRateIsInvalid(keysArray), false); + await fastForward(await instance.rateStalePeriod()); + assert.equal(await instance.anyRateIsInvalid([SNX, GOLD]), true); + + await updateRates([SNX, GOLD], [toUnit(0.1), toUnit(0.2)]); + assert.equal(await instance.anyRateIsInvalid([SNX, GOLD]), false); }); it('should be able to confirm no rates are stale from a subset', async () => { @@ -741,20 +170,19 @@ contract('Exchange Rates', async accounts => { web3.utils.toWei('10', 'ether'), web3.utils.toWei('11', 'ether'), ]; + + await setupAggregators([...encodedRateKeys1, ...encodedRateKeys2, ...encodedRateKeys3]); + const updatedTime1 = await currentTime(); - await instance.updateRates(encodedRateKeys1, encodedRateValues1, updatedTime1, { - from: oracle, - }); + await updateRates(encodedRateKeys1, encodedRateValues1, updatedTime1); + await fastForward(5); const updatedTime2 = await currentTime(); - await instance.updateRates(encodedRateKeys2, encodedRateValues2, updatedTime2, { - from: oracle, - }); + await updateRates(encodedRateKeys2, encodedRateValues2, updatedTime2); + await fastForward(5); const updatedTime3 = await currentTime(); - await instance.updateRates(encodedRateKeys3, encodedRateValues3, updatedTime3, { - from: oracle, - }); + await updateRates(encodedRateKeys3, encodedRateValues3, updatedTime3); await fastForward(12); const rateIsInvalid = await instance.anyRateIsInvalid([ @@ -788,21 +216,18 @@ contract('Exchange Rates', async accounts => { web3.utils.toWei('8', 'ether'), ]; + await setupAggregators([...encodedRateKeys1, ...encodedRateKeys2, ...encodedRateKeys3]); + const updatedTime2 = await currentTime(); - await instance.updateRates(encodedRateKeys2, encodedRateValues2, updatedTime2, { - from: oracle, - }); + await updateRates(encodedRateKeys2, encodedRateValues2, updatedTime2); await fastForward(20); const updatedTime1 = await currentTime(); - await instance.updateRates(encodedRateKeys1, encodedRateValues1, updatedTime1, { - from: oracle, - }); + await updateRates(encodedRateKeys1, encodedRateValues1, updatedTime1); await fastForward(15); + const updatedTime3 = await currentTime(); - await instance.updateRates(encodedRateKeys3, encodedRateValues3, updatedTime3, { - from: oracle, - }); + await updateRates(encodedRateKeys3, encodedRateValues3, updatedTime3); await fastForward(6); const rateIsInvalid = await instance.anyRateIsInvalid([ @@ -815,23 +240,18 @@ contract('Exchange Rates', async accounts => { it('should be able to confirm a single rate (from a set of 1) is stale', async () => { // Set up rates for test await systemSettings.setRateStalePeriod(40, { from: owner }); - const updatedTime = await currentTime(); - await instance.updateRates( - [toBytes32('ABC')], - [web3.utils.toWei('2', 'ether')], - updatedTime, - { - from: oracle, - } - ); + const key = toBytes32('ABC'); + await setupAggregators([key]); + await updateRates([key], [web3.utils.toWei('2', 'ether')]); await fastForward(41); - const rateIsInvalid = await instance.anyRateIsInvalid([toBytes32('ABC')]); + const rateIsInvalid = await instance.anyRateIsInvalid([key]); assert.equal(rateIsInvalid, true); }); it('make sure anyone can check if any rates are stale', async () => { const rateKey = toBytes32('ABC'); + await setupAggregators([rateKey]); await instance.anyRateIsInvalid([rateKey], { from: oracle }); await instance.anyRateIsInvalid([rateKey], { from: owner }); await instance.anyRateIsInvalid([rateKey], { from: deployerAccount }); @@ -855,14 +275,13 @@ contract('Exchange Rates', async accounts => { web3.utils.toWei('4', 'ether'), ]; - const updatedTime1 = await currentTime(); - await instance.updateRates(encodedRateKeys1, encodedRateValues1, updatedTime1, { - from: oracle, - }); - const rateIsInvalid = await instance.anyRateIsInvalid([ - ...encodedRateKeys1, - toBytes32('RST'), - ]); + const staleKey = toBytes32('RST'); + const allKeys = [...encodedRateKeys1, staleKey]; + + await setupAggregators(allKeys); + await updateRates(encodedRateKeys1, encodedRateValues1); + + const rateIsInvalid = await instance.anyRateIsInvalid(allKeys); assert.equal(rateIsInvalid, true); }); }); @@ -874,20 +293,13 @@ contract('Exchange Rates', async accounts => { from: owner, }); }); - describe('when a regular and aggregated synth have rates', () => { + describe('when aggregated synth has rates', () => { beforeEach(async () => { const timestamp = await currentTime(); - await instance.updateRates([toBytes32('sGOLD')], [web3.utils.toWei('1')], timestamp, { - from: oracle, - }); await aggregatorJPY.setLatestAnswer(convertToDecimals(100, 8), timestamp); }); - it('then rateIsInvalid for both is false', async () => { - const rateIsInvalid = await instance.anyRateIsInvalid([ - toBytes32('sGOLD'), - sJPY, - sUSD, - ]); + it('then rateIsInvalid is false', async () => { + const rateIsInvalid = await instance.anyRateIsInvalid([sJPY, sUSD]); assert.equal(rateIsInvalid, false); }); @@ -901,12 +313,8 @@ contract('Exchange Rates', async accounts => { }); }); - it('then rateIsInvalid for both is still false', async () => { - const rateIsInvalid = await instance.anyRateIsInvalid([ - toBytes32('sGOLD'), - sJPY, - sUSD, - ]); + it('then rateIsInvalid is still false', async () => { + const rateIsInvalid = await instance.anyRateIsInvalid([sJPY, sUSD]); assert.equal(rateIsInvalid, false); }); @@ -914,12 +322,8 @@ contract('Exchange Rates', async accounts => { beforeEach(async () => { await mockFlagsInterface.flagAggregator(aggregatorJPY.address); }); - it('then rateIsInvalid for both is true', async () => { - const rateIsInvalid = await instance.anyRateIsInvalid([ - toBytes32('sGOLD'), - sJPY, - sUSD, - ]); + it('then rateIsInvalid is true', async () => { + const rateIsInvalid = await instance.anyRateIsInvalid([sJPY, sUSD]); assert.equal(rateIsInvalid, true); }); }); @@ -936,21 +340,13 @@ contract('Exchange Rates', async accounts => { const abc = toBytes32('lABC'); const timeSent = await currentTime(); const listOfKeys = [abc, toBytes32('lDEF'), toBytes32('lGHI')]; - await instance.updateRates( - listOfKeys.slice(0, 2), - [web3.utils.toWei('1.3', 'ether'), web3.utils.toWei('2.4', 'ether')], - timeSent, - { from: oracle } - ); + await setupAggregators(listOfKeys); + + await updateRates(listOfKeys.slice(0, 2), [toUnit('1.3'), toUnit('2.4')], timeSent); await fastForward(100); const newTimeSent = await currentTime(); - await instance.updateRates( - listOfKeys.slice(2), - [web3.utils.toWei('3.5', 'ether')], - newTimeSent, - { from: oracle } - ); + await updateRates(listOfKeys.slice(2), [toUnit('3.5')], newTimeSent); const lastUpdateTimes = await instance.lastRateUpdateTimesForCurrencies(listOfKeys); assert.notEqual(timeSent, newTimeSent); @@ -964,18 +360,14 @@ contract('Exchange Rates', async accounts => { const abc = toBytes32('lABC'); const def = toBytes32('lDEF'); const ghi = toBytes32('lGHI'); + await setupAggregators([abc, def, ghi]); + const timeSent = await currentTime(); - await instance.updateRates( - [abc, def], - [web3.utils.toWei('1.3', 'ether'), web3.utils.toWei('2.4', 'ether')], - timeSent, - { from: oracle } - ); + await updateRates([abc, def], [toUnit('1.3'), toUnit('2.4')], timeSent); + await fastForward(10000); const timeSent2 = await currentTime(); - await instance.updateRates([ghi], [web3.utils.toWei('2.4', 'ether')], timeSent2, { - from: oracle, - }); + await updateRates([ghi], [toUnit('2.4')], timeSent2); const [firstTS, secondTS] = await Promise.all([ instance.lastRateUpdateTimes(abc), @@ -989,21 +381,14 @@ contract('Exchange Rates', async accounts => { const itCalculatesEffectiveValue = () => { describe('effectiveValue() and effectiveValueAndRates()', () => { - let timestamp; - beforeEach(async () => { - timestamp = await currentTime(); - }); - describe('when a price is sent to the oracle', () => { beforeEach(async () => { // Send a price update to guarantee we're not depending on values from outside this test. - await instance.updateRates( - ['sAUD', 'sEUR', 'SNX'].map(toBytes32), - ['0.5', '1.25', '0.1'].map(toUnit), - timestamp, - { from: oracle } - ); + const keys = [sAUD, sEUR, SNX]; + await setupAggregators(keys); + await updateRates(keys, ['0.5', '1.25', '0.1'].map(toUnit)); }); + it('should correctly calculate an exchange rate in effectiveValue()', async () => { // 1 sUSD should be worth 2 sAUD. assert.bnEqual(await instance.effectiveValue(sUSD, toUnit('1'), sAUD), toUnit('2')); @@ -1019,12 +404,8 @@ contract('Exchange Rates', async accounts => { // Add stale period to the time to ensure we go stale. await fastForward((await instance.rateStalePeriod()) + 1); - timestamp = await currentTime(); - // Update all rates except sUSD. - await instance.updateRates([sEUR, SNX], ['1.25', '0.1'].map(toUnit), timestamp, { - from: oracle, - }); + await updateRates([sEUR, SNX], ['1.25', '0.1'].map(toUnit)); const amountOfSynthetixs = toUnit('10'); const amountOfEur = toUnit('0.8'); @@ -1034,11 +415,11 @@ contract('Exchange Rates', async accounts => { }); it('should return 0 when relying on a non-existant dest exchange rate in effectiveValue()', async () => { - assert.equal(await instance.effectiveValue(SNX, toUnit('10'), toBytes32('XYZ')), '0'); + assert.equal(await instance.effectiveValue(SNX, toUnit('10'), toBytes32('XYZ')), 0); }); - it('should return 0 when relying on a non-existing src rate in effectiveValue', async () => { - assert.equal(await instance.effectiveValue(toBytes32('XYZ'), toUnit('10'), SNX), '0'); + it('should revert when relying on a non-existing src rate in effectiveValue', async () => { + assert.equal(await instance.effectiveValue(toBytes32('XYZ'), toUnit('10'), SNX), 0); }); it('effectiveValueAndRates() should return rates as well with sUSD on one side', async () => { @@ -1080,8 +461,6 @@ contract('Exchange Rates', async accounts => { }); }; - // Aggregator rates and flags - const itReadsFromAggregator = () => { describe('when the flags interface is set', () => { beforeEach(async () => { @@ -1410,45 +789,27 @@ contract('Exchange Rates', async accounts => { await assert.invalidOpcode(instance.aggregatorKeys(1)); }); }); - describe('when the ratesAndInvalidForCurrencies is queried', () => { - let response; - beforeEach(async () => { - response = await instance.ratesAndInvalidForCurrencies([sJPY, sXTZ, sUSD]); - }); - - it('then the rates are invalid again', () => { - assert.equal(response[1], true); - }); - - it('and JPY is 0 while the other is fine', () => { - assert.equal(response[0][0], '0'); - assert.bnEqual(response[0][1], toUnit(newRateXTZ.toString())); - }); + it('when the ratesAndInvalidForCurrencies is queried it returns 0', async () => { + assert.deepEqual( + await instance.ratesAndInvalidForCurrencies([sJPY, sXTZ, sUSD]), + [[0, toUnit(newRateXTZ), toUnit(1)], true] + ); }); describe('when rateAndInvalid is queried', () => { - let responseJPY; - let responseXTZ; - let responseUSD; - beforeEach(async () => { - responseJPY = await instance.rateAndInvalid(sJPY); - responseXTZ = await instance.rateAndInvalid(sXTZ); - responseUSD = await instance.rateAndInvalid(sUSD); + it('then JPY returns true', async () => { + assert.deepEqual(await instance.rateAndInvalid(sJPY), [0, true]); }); - it('then the rates are invalid again', () => { - assert.equal(responseJPY[1], true); + it('other rates are fine', async () => { + const responseXTZ = await instance.rateAndInvalid(sXTZ); + const responseUSD = await instance.rateAndInvalid(sUSD); + assert.equal(responseXTZ[1], false); assert.equal(responseUSD[1], false); - }); - - it('and JPY is 0 while the other is fine', () => { - assert.bnEqual(responseJPY[0], toUnit('0')); assert.bnEqual(responseXTZ[0], toUnit(newRateXTZ.toString())); assert.bnEqual(responseUSD[0], toUnit('1')); }); }); - - describe('when sJPY has a non-aggregated rate', () => {}); }); }); }); @@ -1511,295 +872,6 @@ contract('Exchange Rates', async accounts => { }); }); - describe('when a price already exists for sJPY', () => { - const oldPrice = 100; - let timeOldSent; - beforeEach(async () => { - timeOldSent = await currentTime(); - - await instance.updateRates( - [sJPY], - [web3.utils.toWei(oldPrice.toString())], - timeOldSent, - { - from: oracle, - } - ); - }); - describe('when the ratesAndInvalidForCurrencies is queried with sJPY', () => { - let response; - beforeEach(async () => { - response = await instance.ratesAndInvalidForCurrencies([sJPY, sUSD]); - }); - - it('then the rates are NOT invalid', () => { - assert.equal(response[1], false); - }); - - it('and equal to the value', () => { - assert.bnEqual(response[0][0], web3.utils.toWei(oldPrice.toString())); - }); - }); - describe('when rateAndInvalid is queried with sJPY', () => { - let response; - beforeEach(async () => { - response = await instance.rateAndInvalid(sJPY); - }); - - it('then the rate is NOT invalid', () => { - assert.equal(response[1], false); - }); - - it('and equal to the value', () => { - assert.bnEqual(response[0], web3.utils.toWei(oldPrice.toString())); - }); - }); - - describe('when the price is inspected for sJPY', () => { - it('then the price is returned as expected', async () => { - const result = await instance.rateForCurrency(sJPY, { - from: accountOne, - }); - assert.equal(result.toString(), toUnit(oldPrice)); - }); - it('then the timestamp is returned as expected', async () => { - const result = await instance.lastRateUpdateTimes(sJPY, { - from: accountOne, - }); - assert.equal(result.toNumber(), timeOldSent); - }); - }); - - describe('when sJPY added as an aggregator (replacing existing)', () => { - beforeEach(async () => { - await instance.addAggregator(sJPY, aggregatorJPY.address, { - from: owner, - }); - }); - describe('when the price is fetched for sJPY', () => { - it('0 is returned', async () => { - const result = await instance.rateForCurrency(sJPY, { - from: accountOne, - }); - assert.equal(result.toNumber(), 0); - }); - }); - describe('when the timestamp is fetched for sJPY', () => { - it('0 is returned', async () => { - const result = await instance.lastRateUpdateTimes(sJPY, { - from: accountOne, - }); - assert.equal(result.toNumber(), 0); - }); - }); - describe('when the ratesAndInvalidForCurrencies is queried with sJPY', () => { - let response; - beforeEach(async () => { - response = await instance.ratesAndInvalidForCurrencies([sJPY]); - }); - - it('then the rates are invalid', () => { - assert.equal(response[1], true); - }); - - it('with no value', () => { - assert.bnEqual(response[0][0], '0'); - }); - }); - describe('when the rateAndInvalid is queried with sJPY', () => { - let response; - beforeEach(async () => { - response = await instance.rateAndInvalid(sJPY); - }); - - it('then the rate is invalid', () => { - assert.equal(response[1], true); - }); - - it('with no value', () => { - assert.bnEqual(response[0], '0'); - }); - }); - - describe('when the aggregator price is set to set a specific number (with support for 8 decimals)', () => { - const newRate = 9.55; - let timestamp; - beforeEach(async () => { - await fastForward(50); - timestamp = await currentTime(); - await aggregatorJPY.setLatestAnswer(convertToDecimals(newRate, 8), timestamp); - }); - - describe('when the price is fetched for sJPY', () => { - it('the new aggregator rate is returned instead of the old price', async () => { - const result = await instance.rateForCurrency(sJPY, { - from: accountOne, - }); - assert.bnEqual(result, toUnit(newRate.toString())); - }); - it('and the timestamp is the new one', async () => { - const result = await instance.lastRateUpdateTimes(sJPY, { - from: accountOne, - }); - assert.bnEqual(result.toNumber(), timestamp); - }); - }); - - describe('when the ratesAndInvalidForCurrencies is queried with sJPY', () => { - let response; - beforeEach(async () => { - response = await instance.ratesAndInvalidForCurrencies([sJPY, sUSD]); - }); - - it('then the rates are NOT invalid', () => { - assert.equal(response[1], false); - }); - - it('and equal to the value', () => { - assert.bnEqual(response[0][0], toUnit(newRate.toString())); - }); - }); - - describe('when rateAndInvalid is queried with sJPY', () => { - let response; - beforeEach(async () => { - response = await instance.rateAndInvalid(sJPY); - }); - - it('then the rates are NOT invalid', () => { - assert.equal(response[1], false); - }); - - it('and equal to the value', () => { - assert.bnEqual(response[0], toUnit(newRate.toString())); - }); - }); - - describe('when the aggregator is removed for sJPY', () => { - beforeEach(async () => { - await instance.removeAggregator(sJPY, { - from: owner, - }); - }); - describe('when a user queries the first entry in aggregatorKeys', () => { - it('then they are empty', async () => { - await assert.invalidOpcode(instance.aggregatorKeys(0)); - }); - }); - describe('when the price is inspected for sJPY', () => { - it('then the old price is returned', async () => { - const result = await instance.rateForCurrency(sJPY, { - from: accountOne, - }); - assert.equal(result.toString(), toUnit(oldPrice)); - }); - it('and the timestamp is returned as expected', async () => { - const result = await instance.lastRateUpdateTimes(sJPY, { - from: accountOne, - }); - assert.equal(result.toNumber(), timeOldSent); - }); - }); - describe('when the ratesAndInvalidForCurrencies is queried with sJPY', () => { - let response; - beforeEach(async () => { - response = await instance.ratesAndInvalidForCurrencies([sJPY, sUSD]); - }); - - it('then the rates are NOT invalid', () => { - assert.equal(response[1], false); - }); - - it('and equal to the old value', () => { - assert.bnEqual(response[0][0], web3.utils.toWei(oldPrice.toString())); - }); - }); - - describe('when the rateAndInvalid is queried with sJPY', () => { - let response; - beforeEach(async () => { - response = await instance.rateAndInvalid(sJPY); - }); - - it('then the rates are NOT invalid', () => { - assert.equal(response[1], false); - }); - - it('and equal to the old value', () => { - assert.bnEqual(response[0], web3.utils.toWei(oldPrice.toString())); - }); - }); - }); - }); - }); - - describe('when sXTZ added as an aggregator', () => { - beforeEach(async () => { - await instance.addAggregator(sXTZ, aggregatorXTZ.address, { - from: owner, - }); - }); - describe('when the ratesAndInvalidForCurrencies is queried with sJPY and sXTZ', () => { - let response; - beforeEach(async () => { - response = await instance.ratesAndInvalidForCurrencies([sJPY, sXTZ, sUSD]); - }); - - it('then the rates are invalid', () => { - assert.equal(response[1], true); - }); - - it('with sXTZ having no value', () => { - assert.bnEqual(response[0][0], web3.utils.toWei(oldPrice.toString())); - assert.bnEqual(response[0][1], '0'); - }); - }); - describe('when the rateAndInvalid is queried with sJPY and sXTZ', () => { - let responseJPY; - let responseXTZ; - beforeEach(async () => { - responseJPY = await instance.rateAndInvalid(sJPY); - responseXTZ = await instance.rateAndInvalid(sXTZ); - }); - - it('then the XTZ rate is invalid', () => { - assert.equal(responseJPY[1], false); - assert.equal(responseXTZ[1], true); - }); - - it('with sXTZ having no value', () => { - assert.bnEqual(responseJPY[0], web3.utils.toWei(oldPrice.toString())); - assert.bnEqual(responseXTZ[0], '0'); - }); - }); - - describe('when the aggregator price is set to set for sXTZ', () => { - const newRate = 99; - let timestamp; - beforeEach(async () => { - await fastForward(50); - timestamp = await currentTime(); - await aggregatorXTZ.setLatestAnswer(convertToDecimals(newRate, 8), timestamp); - }); - - describe('when the ratesAndInvalidForCurrencies is queried with sJPY and sXTZ', () => { - let response; - beforeEach(async () => { - response = await instance.ratesAndInvalidForCurrencies([sJPY, sXTZ, sUSD]); - }); - - it('then the rates are NOT invalid', () => { - assert.equal(response[1], false); - }); - - it('and equal to the values', () => { - assert.bnEqual(response[0][0], toUnit(oldPrice.toString())); - assert.bnEqual(response[0][1], toUnit(newRate.toString())); - }); - }); - }); - }); - }); describe('warning flags and invalid rates', () => { it('sUSD is never flagged / invalid.', async () => { assert.isFalse(await instance.rateIsFlagged(sUSD)); @@ -1861,24 +933,31 @@ contract('Exchange Rates', async accounts => { }); describe('roundIds for historical rates', () => { - it('getCurrentRoundId() by default is 0 for all synths except sUSD which is 1', async () => { - // Note: rates that were set in the truffle migration will be at 1, so we need to check - // other synths - assert.equal(await instance.getCurrentRoundId(sJPY), '0'); - assert.equal(await instance.getCurrentRoundId(sBNB), '0'); - assert.equal(await instance.getCurrentRoundId(sUSD), '1'); + it('getCurrentRoundId() returns 0 for unknown currencies', async () => { + assert.equal(await instance.getCurrentRoundId(sJPY), 0); + assert.equal(await instance.getCurrentRoundId(sBNB), 0); + }); + + it('getCurrentRoundId() is 0 for currencies with no updates', async () => { + await setupAggregators([sJPY, sBNB]); + assert.equal(await instance.getCurrentRoundId(sJPY), 0); + assert.equal(await instance.getCurrentRoundId(sBNB), 0); + }); + + it('getCurrentRoundId() is 0 for sUSD', async () => { + assert.equal(await instance.getCurrentRoundId(sUSD), 0); }); it('ratesAndUpdatedTimeForCurrencyLastNRounds() shows first entry for sUSD', async () => { - const timeOfsUSDRateSetOnInit = await instance.lastRateUpdateTimes(sUSD); assert.deepEqual(await instance.ratesAndUpdatedTimeForCurrencyLastNRounds(sUSD, '3'), [ [toUnit('1'), '0', '0'], - [timeOfsUSDRateSetOnInit, '0', '0'], + [0, 0, 0], ]); }); - it('ratesAndUpdatedTimeForCurrencyLastNRounds() returns 0s for other currency keys', async () => { + it('ratesAndUpdatedTimeForCurrencyLastNRounds() returns 0s for other currencies without updates', async () => { const fiveZeros = new Array(5).fill('0'); - assert.deepEqual(await instance.ratesAndUpdatedTimeForCurrencyLastNRounds(sAUD, '5'), [ + await setupAggregators([sJPY]); + assert.deepEqual(await instance.ratesAndUpdatedTimeForCurrencyLastNRounds(sJPY, '5'), [ fiveZeros, fiveZeros, ]); @@ -1899,145 +978,83 @@ contract('Exchange Rates', async accounts => { } }); - describe('and the sBNB rate (non-aggregator) has been set three times directly also', () => { - let timestamp; - - beforeEach(async () => { - for (let i = 0; i < 3; i++) { - timestamp = 10000; - await instance.updateRates([sBNB], [toUnit((1000 + i).toString())], timestamp + i, { - from: oracle, - }); - } - }); - describe('getCurrentRoundId())', () => { - describe('when invoked for an aggregator', () => { - it('getCurrentRound() returns the last entry', async () => { - await assert.equal((await instance.getCurrentRoundId(sJPY)).toString(), '3'); - }); - }); - describe('when invoked for a regular price', () => { - it('getCurrentRound() returns the last entry', async () => { - await assert.equal((await instance.getCurrentRoundId(sBNB)).toString(), '3'); - }); + describe('getCurrentRoundId())', () => { + describe('when invoked for an aggregator', () => { + it('getCurrentRound() returns the last entry', async () => { + assert.equal((await instance.getCurrentRoundId(sJPY)).toString(), '3'); }); }); - describe('rateAndTimestampAtRound()', () => { - it('when invoked for no price, returns no rate and no tme', async () => { + }); + describe('rateAndTimestampAtRound()', () => { + it('when invoked for no price returns 0', async () => { + assert.deepEqual(await instance.rateAndTimestampAtRound(toBytes32('TEST'), '0'), [ + 0, + 0, + ]); + }); + it('when invoked for an aggregator', async () => { + const assertRound = async ({ roundId }) => { const { rate, time } = await instance.rateAndTimestampAtRound( - toBytes32('TEST'), - '0' + sJPY, + roundId.toString() + ); + assert.bnEqual(rate, toUnit((100 + roundId - 1).toString())); + assert.bnEqual(time, toBN(1000 + roundId - 1)); + }; + await assertRound({ roundId: 1 }); + await assertRound({ roundId: 2 }); + await assertRound({ roundId: 3 }); + }); + }); + + describe('ratesAndUpdatedTimeForCurrencyLastNRounds()', () => { + describe('when invoked for a non-existant currency', () => { + it('then it returns zeros', async () => { + const fiveZeros = new Array(5).fill('0'); + assert.deepEqual( + await instance.ratesAndUpdatedTimeForCurrencyLastNRounds(sAUD, '5'), + [fiveZeros, fiveZeros] ); - assert.equal(rate, '0'); - assert.equal(time, '0'); - }); - it('when invoked for an aggregator', async () => { - const assertRound = async ({ roundId }) => { - const { rate, time } = await instance.rateAndTimestampAtRound( - sJPY, - roundId.toString() - ); - assert.bnEqual(rate, toUnit((100 + roundId - 1).toString())); - assert.bnEqual(time, toBN(1000 + roundId - 1)); - }; - await assertRound({ roundId: 1 }); - await assertRound({ roundId: 2 }); - await assertRound({ roundId: 3 }); - }); - it('when invoked for a regular price', async () => { - const assertRound = async ({ roundId }) => { - const { rate, time } = await instance.rateAndTimestampAtRound( - sBNB, - roundId.toString() - ); - assert.bnEqual(rate, toUnit((1000 + roundId - 1).toString())); - assert.bnEqual(time, toBN(10000 + roundId - 1)); - }; - await assertRound({ roundId: 1 }); - await assertRound({ roundId: 2 }); - await assertRound({ roundId: 3 }); }); }); - - describe('ratesAndUpdatedTimeForCurrencyLastNRounds()', () => { - describe('when invoked for a non-existant currency', () => { - it('then it returns 0s', async () => { - const fiveZeros = new Array(5).fill('0'); - assert.deepEqual( - await instance.ratesAndUpdatedTimeForCurrencyLastNRounds(sAUD, '5'), - [fiveZeros, fiveZeros] - ); - }); - }); - describe('when invoked for an aggregated price', () => { - it('then it returns the rates as expected', async () => { - assert.deepEqual( - await instance.ratesAndUpdatedTimeForCurrencyLastNRounds(sJPY, '3'), - [ - [toUnit('102'), toUnit('101'), toUnit('100')], - ['1002', '1001', '1000'], - ] - ); - }); - - it('then it returns the rates as expected, even over the edge', async () => { - assert.deepEqual( - await instance.ratesAndUpdatedTimeForCurrencyLastNRounds(sJPY, '5'), - [ - [toUnit('102'), toUnit('101'), toUnit('100'), '0', '0'], - ['1002', '1001', '1000', '0', '0'], - ] - ); - }); + describe('when invoked for an aggregated price', () => { + it('then it returns the rates as expected', async () => { + assert.deepEqual( + await instance.ratesAndUpdatedTimeForCurrencyLastNRounds(sJPY, '3'), + [ + [toUnit('102'), toUnit('101'), toUnit('100')], + ['1002', '1001', '1000'], + ] + ); }); - describe('when invoked for a regular price', () => { - it('then it returns the rates as expected', async () => { - assert.deepEqual( - await instance.ratesAndUpdatedTimeForCurrencyLastNRounds(sBNB, '3'), - [ - [toUnit('1002'), toUnit('1001'), toUnit('1000')], - ['10002', '10001', '10000'], - ] - ); - }); - it('then it returns the rates as expected, even over the edge', async () => { - assert.deepEqual( - await instance.ratesAndUpdatedTimeForCurrencyLastNRounds(sBNB, '5'), - [ - [toUnit('1002'), toUnit('1001'), toUnit('1000'), '0', '0'], - ['10002', '10001', '10000', '0', '0'], - ] - ); - }); + it('then it returns the rates as expected, even over the edge', async () => { + assert.deepEqual( + await instance.ratesAndUpdatedTimeForCurrencyLastNRounds(sJPY, '5'), + [ + [toUnit('102'), toUnit('101'), toUnit('100'), '0', '0'], + ['1002', '1001', '1000', '0', '0'], + ] + ); }); }); }); }); - describe('and both the aggregator and regular prices have been given three rates, 30seconds apart', () => { + describe('and the aggregator has been given three rates, 30seconds apart', () => { beforeEach(async () => { await aggregatorJPY.setLatestAnswer(convertToDecimals(100, 8), 30); // round 1 for sJPY await aggregatorJPY.setLatestAnswer(convertToDecimals(200, 8), 60); // round 2 for sJPY await aggregatorJPY.setLatestAnswer(convertToDecimals(300, 8), 90); // round 3 for sJPY - - await instance.updateRates([sBNB], [toUnit('1000')], '30', { from: oracle }); // round 1 for sBNB - await instance.updateRates([sBNB], [toUnit('2000')], '60', { from: oracle }); // round 2 for sBNB - await instance.updateRates([sBNB], [toUnit('3000')], '90', { from: oracle }); // round 3 for sBNB }); describe('getLastRoundIdBeforeElapsedSecs()', () => { describe('when getLastRoundIdBeforeElapsedSecs() is invoked with the first round and a waiting time of less than 30s', () => { it('then it receives round 1 - no change ', async () => { - // assert both aggregated price and regular prices work as expected assert.equal( (await instance.getLastRoundIdBeforeElapsedSecs(sJPY, '1', 40, 10)).toString(), '1' ); - assert.equal( - (await instance.getLastRoundIdBeforeElapsedSecs(sBNB, '1', 40, 10)).toString(), - '1' - ); }); }); @@ -2047,10 +1064,6 @@ contract('Exchange Rates', async accounts => { (await instance.getLastRoundIdBeforeElapsedSecs(sJPY, '1', 40, 20)).toString(), '2' ); - assert.equal( - (await instance.getLastRoundIdBeforeElapsedSecs(sBNB, '1', 40, 20)).toString(), - '2' - ); }); }); @@ -2060,10 +1073,6 @@ contract('Exchange Rates', async accounts => { (await instance.getLastRoundIdBeforeElapsedSecs(sJPY, '2', 65, 25)).toString(), '3' ); - assert.equal( - (await instance.getLastRoundIdBeforeElapsedSecs(sBNB, '2', 65, 25)).toString(), - '3' - ); }); }); @@ -2073,10 +1082,6 @@ contract('Exchange Rates', async accounts => { (await instance.getLastRoundIdBeforeElapsedSecs(sJPY, '1', 40, 40)).toString(), '2' ); - assert.equal( - (await instance.getLastRoundIdBeforeElapsedSecs(sBNB, '1', 40, 40)).toString(), - '2' - ); }); }); describe('when getLastRoundIdBeforeElapsedSecs() is invoked with the first round and a waiting time of 60s exactly', () => { @@ -2085,10 +1090,6 @@ contract('Exchange Rates', async accounts => { (await instance.getLastRoundIdBeforeElapsedSecs(sJPY, '1', 50, 40)).toString(), '3' ); - assert.equal( - (await instance.getLastRoundIdBeforeElapsedSecs(sBNB, '1', 50, 40)).toString(), - '3' - ); }); }); describe('when getLastRoundIdBeforeElapsedSecs() is invoked with the first round and a waiting time beyond 60s', () => { @@ -2097,10 +1098,6 @@ contract('Exchange Rates', async accounts => { (await instance.getLastRoundIdBeforeElapsedSecs(sJPY, '1', 55, 6000)).toString(), '3' ); - assert.equal( - (await instance.getLastRoundIdBeforeElapsedSecs(sBNB, '1', 50, 40)).toString(), - '3' - ); }); }); describe('when getLastRoundIdBeforeElapsedSecs() is invoked with the third round and a waiting time beyond 60s', () => { @@ -2109,30 +1106,23 @@ contract('Exchange Rates', async accounts => { (await instance.getLastRoundIdBeforeElapsedSecs(sJPY, '3', 180, 9000)).toString(), '3' ); - assert.equal( - (await instance.getLastRoundIdBeforeElapsedSecs(sBNB, '1', 50, 40)).toString(), - '3' - ); }); }); }); }); + describe('effectiveValueAtRound()', () => { - describe('when both the aggregator and regular prices have been give three rates with current timestamps', () => { + describe('when both aggregated prices have been given three rates with current timestamps', () => { beforeEach(async () => { - let timestamp = await currentTime(); - await aggregatorJPY.setLatestAnswer(convertToDecimals(100, 8), timestamp); // round 1 for sJPY - await instance.updateRates([sBNB], [toUnit('1000')], timestamp, { from: oracle }); // round 1 for sBNB + await setupAggregators([sBNB]); + + await updateRates([sJPY, sBNB], [convertToDecimals(100, 8), toUnit('1000')]); await fastForward(120); - timestamp = await currentTime(); - await aggregatorJPY.setLatestAnswer(convertToDecimals(200, 8), timestamp); // round 2 for sJPY - await instance.updateRates([sBNB], [toUnit('2000')], timestamp, { from: oracle }); // round 2 for sBNB + await updateRates([sJPY, sBNB], [convertToDecimals(200, 8), toUnit('2000')]); await fastForward(120); - timestamp = await currentTime(); - await aggregatorJPY.setLatestAnswer(convertToDecimals(300, 8), timestamp); // round 3 for sJPY - await instance.updateRates([sBNB], [toUnit('4000')], timestamp, { from: oracle }); // round 3 for sBNB + await updateRates([sJPY, sBNB], [convertToDecimals(300, 8), toUnit('4000')]); }); it('accepts various changes to src roundId', async () => { assert.bnEqual( @@ -2990,20 +1980,28 @@ contract('Exchange Rates', async accounts => { }); }; + // utility function to setup price aggregators + async function setupAggregators(keys, decimalsArray = []) { + await setupPriceAggregators(instance, owner, keys, decimalsArray); + } + + // utility function update rates for aggregators that are already set up + async function updateRates(keys, rates, timestamp = undefined) { + await updateAggregatorRates(instance, keys, rates, timestamp); + } + describe('Using ExchangeRates', () => { const exchangeRatesContract = 'ExchangeRates'; before(async () => { - initialTime = await currentTime(); - ({ - ExchangeRates: instance, - SystemSettings: systemSettings, - AddressResolver: resolver, - } = await setupAllContracts({ + ({ ExchangeRates: instance, SystemSettings: systemSettings } = await setupAllContracts({ accounts, contracts: [exchangeRatesContract, 'SystemSettings', 'AddressResolver'], })); + // remove the pre-configured aggregator + await instance.removeAggregator(toBytes32('SNX'), { from: owner }); + aggregatorJPY = await MockAggregator.new({ from: owner }); aggregatorXTZ = await MockAggregator.new({ from: owner }); aggregatorFastGasPrice = await MockAggregator.new({ from: owner }); @@ -3018,22 +2016,10 @@ contract('Exchange Rates', async accounts => { addSnapshotBeforeRestoreAfterEach(); - beforeEach(async () => { - timeSent = await currentTime(); - }); - itIncludesCorrectMutativeFunctions(exchangeRatesContract); itIsConstructedCorrectly(exchangeRatesContract); - itUpdatesRates(); - - itSetsOracle(); - - itDeletesRates(); - - itReturnsRates(); - itCalculatesStaleRates(); itCalculatesInvalidRates(); @@ -3053,16 +2039,14 @@ contract('Exchange Rates', async accounts => { const exchangeRatesContract = 'ExchangeRatesWithDexPricing'; before(async () => { - initialTime = await currentTime(); - ({ - ExchangeRates: instance, - SystemSettings: systemSettings, - AddressResolver: resolver, - } = await setupAllContracts({ + ({ ExchangeRates: instance, SystemSettings: systemSettings } = await setupAllContracts({ accounts, contracts: [exchangeRatesContract, 'SystemSettings', 'AddressResolver'], })); + // remove the pre-configured aggregator + await instance.removeAggregator(toBytes32('SNX'), { from: owner }); + aggregatorJPY = await MockAggregator.new({ from: owner }); aggregatorXTZ = await MockAggregator.new({ from: owner }); aggregatorFastGasPrice = await MockAggregator.new({ from: owner }); @@ -3077,22 +2061,10 @@ contract('Exchange Rates', async accounts => { addSnapshotBeforeRestoreAfterEach(); - beforeEach(async () => { - timeSent = await currentTime(); - }); - itIncludesCorrectMutativeFunctions(exchangeRatesContract); itIsConstructedCorrectly(exchangeRatesContract); - itUpdatesRates(); - - itSetsOracle(); - - itDeletesRates(); - - itReturnsRates(); - itCalculatesStaleRates(); itCalculatesInvalidRates(); diff --git a/test/contracts/Exchanger.spec.js b/test/contracts/Exchanger.spec.js index 2ad3043ec2..5ca67e5e57 100644 --- a/test/contracts/Exchanger.spec.js +++ b/test/contracts/Exchanger.spec.js @@ -18,6 +18,8 @@ const { setStatus, convertToAggregatorPrice, updateRatesWithDefaults, + setupPriceAggregators, + updateAggregatorRates, } = require('./helpers'); const { @@ -58,8 +60,6 @@ contract('Exchanger (spec tests)', async accounts => { sEURContract, sBTCContract, sETHContract, - oracle, - timestamp, exchanger, exchangeState, exchangeFeeRate, @@ -139,7 +139,7 @@ contract('Exchanger (spec tests)', async accounts => { const amountOfSrcExchanged = toUnit('10'); beforeEach(async () => { - await updateRatesWithDefaults({ exchangeRates, oracle, debtCache }); + await updateRatesWithDefaults({ exchangeRates, owner, debtCache }); await sUSDContract.issue(owner, toUnit('100')); await synthetix.exchange(sUSD, toUnit('10'), sETH, { from: owner }); }); @@ -272,9 +272,7 @@ contract('Exchanger (spec tests)', async accounts => { beforeEach(async () => { await fastForward(10); // base rate of sETH is 100 from shared setup above - await exchangeRates.updateRates([sETH], [toUnit('300')], await currentTime(), { - from: oracle, - }); + await updateRates([sETH], [toUnit('300')]); await synthetix.exchange(sUSD, toUnit('1'), sETH, { from: account1 }); }); it('then the synth is suspended', async () => { @@ -287,9 +285,7 @@ contract('Exchanger (spec tests)', async accounts => { beforeEach(async () => { await fastForward(10); // base rate of sETH is 100 from shared setup above - await exchangeRates.updateRates([sETH], [toUnit('33')], await currentTime(), { - from: oracle, - }); + await updateRates([sETH], [toUnit('33')]); await synthetix.exchange(sUSD, toUnit('1'), sETH, { from: account1 }); }); it('then the synth is suspended', async () => { @@ -307,9 +303,7 @@ contract('Exchanger (spec tests)', async accounts => { beforeEach(async () => { await fastForward(10); // base rate of sETH is 100 from shared setup above - await exchangeRates.updateRates([sETH], [toUnit('300')], await currentTime(), { - from: oracle, - }); + await updateRates([sETH], [toUnit('300')]); await synthetix.exchange(sUSD, toUnit('1'), sETH, { from: account1 }); }); it('then the synth is not suspended', async () => { @@ -322,9 +316,7 @@ contract('Exchanger (spec tests)', async accounts => { beforeEach(async () => { await fastForward(10); // base rate of sETH is 100 from shared setup above - await exchangeRates.updateRates([sETH], [toUnit('33')], await currentTime(), { - from: oracle, - }); + await updateRates([sETH], [toUnit('33')]); await synthetix.exchange(sUSD, toUnit('1'), sETH, { from: account1 }); }); it('then the synth is not suspended', async () => { @@ -667,14 +659,7 @@ contract('Exchanger (spec tests)', async accounts => { describe('given the sEUR rate is 2, and sETH is 100, sBTC is 9000', () => { beforeEach(async () => { // set sUSD:sEUR as 2:1, sUSD:sETH at 100:1, sUSD:sBTC at 9000:1 - await exchangeRates.updateRates( - [sEUR, sETH, sBTC], - ['2', '100', '9000'].map(toUnit), - timestamp, - { - from: oracle, - } - ); + await updateRates([sEUR, sETH, sBTC], ['2', '100', '9000'].map(toUnit)); }); describe('and the exchange fee rate is 1% for easier human consumption', () => { beforeEach(async () => { @@ -858,11 +843,7 @@ contract('Exchanger (spec tests)', async accounts => { describe('when the price doubles for sUSD:sEUR to 4:1', () => { beforeEach(async () => { await fastForward(5); - timestamp = await currentTime(); - - await exchangeRates.updateRates([sEUR], ['4'].map(toUnit), timestamp, { - from: oracle, - }); + await updateRates([sEUR], ['4'].map(toUnit)); }); it('then settlement reclaimAmount shows a reclaim of half the entire balance of sEUR', async () => { const expected = calculateExpectedSettlementAmount({ @@ -1084,12 +1065,7 @@ contract('Exchanger (spec tests)', async accounts => { describe('when the price halves for sUSD:sEUR to 1:1', () => { beforeEach(async () => { await fastForward(5); - - timestamp = await currentTime(); - - await exchangeRates.updateRates([sEUR], ['1'].map(toUnit), timestamp, { - from: oracle, - }); + await updateRates([sEUR], ['1'].map(toUnit)); }); it('then settlement rebateAmount shows a rebate of half the entire balance of sEUR', async () => { const expected = calculateExpectedSettlementAmount({ @@ -1118,12 +1094,7 @@ contract('Exchanger (spec tests)', async accounts => { describe('and then the price increases for sUSD:sEUR to 2:1', () => { beforeEach(async () => { await fastForward(5); - - timestamp = await currentTime(); - - await exchangeRates.updateRates([sEUR], ['2'].map(toUnit), timestamp, { - from: oracle, - }); + await updateRates([sEUR], ['2'].map(toUnit)); }); describe('when settlement is invoked', () => { describe('when another minute passes', () => { @@ -1332,12 +1303,7 @@ contract('Exchanger (spec tests)', async accounts => { describe('when the price returns to sUSD:sEUR to 2:1', () => { beforeEach(async () => { await fastForward(12); - - timestamp = await currentTime(); - - await exchangeRates.updateRates([sEUR], ['2'].map(toUnit), timestamp, { - from: oracle, - }); + await updateRates([sEUR], ['2'].map(toUnit)); }); it('then settlement reclaimAmount shows 0 reclaim and 0 refund', async () => { const settlement = await exchanger.settlementOwing(account1, sEUR); @@ -1351,11 +1317,7 @@ contract('Exchanger (spec tests)', async accounts => { describe('when another minute elapses and the sETH price changes', () => { beforeEach(async () => { await fastForward(60); - timestamp = await currentTime(); - - await exchangeRates.updateRates([sEUR], ['3'].map(toUnit), timestamp, { - from: oracle, - }); + await updateRates([sEUR], ['3'].map(toUnit)); }); it('then settlement reclaimAmount still shows 0 reclaim and 0 refund as the timeout period ended', async () => { const settlement = await exchanger.settlementOwing(account1, sEUR); @@ -1411,11 +1373,7 @@ contract('Exchanger (spec tests)', async accounts => { describe('when the price doubles for sUSD:sEUR to 4:1', () => { beforeEach(async () => { await fastForward(5); - timestamp = await currentTime(); - - await exchangeRates.updateRates([sEUR], ['4'].map(toUnit), timestamp, { - from: oracle, - }); + await updateRates([sEUR], ['4'].map(toUnit)); }); it('then settlement shows a rebate rebateAmount', async () => { const { reclaimAmount, rebateAmount } = await exchanger.settlementOwing( @@ -1442,16 +1400,7 @@ contract('Exchanger (spec tests)', async accounts => { }); describe('when the price gains for sBTC more than the loss of the sEUR change', () => { beforeEach(async () => { - await fastForward(5); - timestamp = await currentTime(); - await exchangeRates.updateRates( - [sBTC], - ['20000'].map(toUnit), - timestamp, - { - from: oracle, - } - ); + await updateRates([sBTC], ['20000'].map(toUnit)); }); it('then the reclaimAmount is whats left when subtracting the rebate', async () => { const { reclaimAmount, rebateAmount } = await exchanger.settlementOwing( @@ -1506,16 +1455,8 @@ contract('Exchanger (spec tests)', async accounts => { let expectedFromSecond; beforeEach(async () => { await fastForward(5); - timestamp = await currentTime(); - - await exchangeRates.updateRates( - [sBTC], - ['10000'].map(toUnit), - timestamp, - { - from: oracle, - } - ); + + await updateRates([sBTC], ['10000'].map(toUnit)); expectedFromFirst = calculateExpectedSettlementAmount({ amount: amountOfSrcExchanged, @@ -1927,11 +1868,7 @@ contract('Exchanger (spec tests)', async accounts => { }); describe('when that synth has a fresh rate', () => { beforeEach(async () => { - const timestamp = await currentTime(); - - await exchangeRates.updateRates([sAUD], ['0.75'].map(toUnit), timestamp, { - from: oracle, - }); + await updateRates([sAUD], ['0.75'].map(toUnit)); }); describe(`when the user ${type} into that synth`, () => { beforeEach(async () => { @@ -2754,14 +2691,7 @@ contract('Exchanger (spec tests)', async accounts => { const updateRate = ({ target, rate }) => { beforeEach(async () => { await fastForward(10); - await exchangeRates.updateRates( - [target], - [toUnit(rate.toString())], - await currentTime(), - { - from: oracle, - } - ); + await updateRates([target], [toUnit(rate.toString())]); }); }; @@ -2846,13 +2776,10 @@ contract('Exchanger (spec tests)', async accounts => { beforeEach(async () => { // sETH over deviation and sEUR slight change await fastForward(10); - await exchangeRates.updateRates( + await updateAggregatorRates( + exchangeRates, [sETH, sEUR], - [toUnit(baseRate * 3).toString(), toUnit('1.9')], - await currentTime(), - { - from: oracle, - } + [toUnit(baseRate * 3).toString(), toUnit('1.9')] ); }); describe('and another user exchanges sETH to sEUR', () => { @@ -2875,13 +2802,10 @@ contract('Exchanger (spec tests)', async accounts => { beforeEach(async () => { // sEUR over deviation and sETH slight change await fastForward(10); - await exchangeRates.updateRates( + await updateAggregatorRates( + exchangeRates, [sETH, sEUR], - [toUnit(baseRate * 1.1).toString(), toUnit('10')], - await currentTime(), - { - from: oracle, - } + [toUnit(baseRate * 1.1).toString(), toUnit('10')] ); }); describe('and another user exchanges sEUR to sETH', () => { @@ -3073,21 +2997,12 @@ contract('Exchanger (spec tests)', async accounts => { describe('when a recent price rate is set way outside of the threshold', () => { beforeEach(async () => { await fastForward(10); - await exchangeRates.updateRates([sETH], [toUnit('1000')], await currentTime(), { - from: oracle, - }); + await updateRates([sETH], [toUnit('1000')]); }); describe('and then put back to normal', () => { beforeEach(async () => { await fastForward(10); - await exchangeRates.updateRates( - [sETH], - [baseRate.toString()], - await currentTime(), - { - from: oracle, - } - ); + await updateRates([sETH], [baseRate.toString()]); }); assertSpike({ from: sUSD, @@ -3500,9 +3415,14 @@ contract('Exchanger (spec tests)', async accounts => { }); }; + async function updateRates(keys, rates) { + await updateAggregatorRates(exchangeRates, keys, rates); + } + describe('With L1 configuration (Synthetix, ExchangerWithFeeRecAlternatives, ExchangeRatesWithDexPricing)', () => { before(async () => { const VirtualSynthMastercopy = artifacts.require('VirtualSynthMastercopy'); + const synths = ['sUSD', 'sETH', 'sEUR', 'sAUD', 'sBTC', 'iBTC', 'sTRX']; ({ Exchanger: exchanger, @@ -3524,7 +3444,7 @@ contract('Exchanger (spec tests)', async accounts => { FlexibleStorage: flexibleStorage, } = await setupAllContracts({ accounts, - synths: ['sUSD', 'sETH', 'sEUR', 'sAUD', 'sBTC', 'iBTC', 'sTRX'], + synths: synths, contracts: [ // L1 specific 'Synthetix', @@ -3548,8 +3468,7 @@ contract('Exchanger (spec tests)', async accounts => { }, })); - // Send a price update to guarantee we're not stale. - oracle = account1; + await setupPriceAggregators(exchangeRates, owner, synths.map(toBytes32)); amountIssued = toUnit('1000'); @@ -3561,15 +3480,10 @@ contract('Exchanger (spec tests)', async accounts => { addSnapshotBeforeRestoreAfterEach(); beforeEach(async () => { - timestamp = await currentTime(); - await exchangeRates.updateRates( - [sAUD, sEUR, SNX, sETH, sBTC, iBTC], - ['0.5', '2', '1', '100', '5000', '5000'].map(toUnit), - timestamp, - { - from: oracle, - } - ); + const keys = [sAUD, sEUR, SNX, sETH, sBTC, iBTC]; + const rates = ['0.5', '2', '1', '100', '5000', '5000'].map(toUnit); + await setupPriceAggregators(exchangeRates, owner, keys); + await updateRates(keys, rates); // set a 0.5% exchange fee rate (1/200) exchangeFeeRate = toUnit('0.005'); @@ -3610,6 +3524,7 @@ contract('Exchanger (spec tests)', async accounts => { describe('With L2 configuration (MintableSynthetix, Exchanger, ExchangeRates)', () => { before(async () => { + const synths = ['sUSD', 'sETH', 'sEUR', 'sAUD', 'sBTC', 'iBTC', 'sTRX']; ({ Exchanger: exchanger, Synthetix: synthetix, @@ -3630,7 +3545,7 @@ contract('Exchanger (spec tests)', async accounts => { FlexibleStorage: flexibleStorage, } = await setupAllContracts({ accounts, - synths: ['sUSD', 'sETH', 'sEUR', 'sAUD', 'sBTC', 'iBTC', 'sTRX'], + synths: synths, contracts: [ // L2 specific 'MintableSynthetix', @@ -3650,8 +3565,7 @@ contract('Exchanger (spec tests)', async accounts => { ], })); - // Send a price update to guarantee we're not stale. - oracle = account1; + await setupPriceAggregators(exchangeRates, owner, synths.map(toBytes32)); amountIssued = toUnit('1000'); @@ -3663,15 +3577,10 @@ contract('Exchanger (spec tests)', async accounts => { addSnapshotBeforeRestoreAfterEach(); beforeEach(async () => { - timestamp = await currentTime(); - await exchangeRates.updateRates( - [sAUD, sEUR, SNX, sETH, sBTC, iBTC], - ['0.5', '2', '1', '100', '5000', '5000'].map(toUnit), - timestamp, - { - from: oracle, - } - ); + const keys = [sAUD, sEUR, SNX, sETH, sBTC, iBTC]; + const rates = ['0.5', '2', '1', '100', '5000', '5000'].map(toUnit); + await setupPriceAggregators(exchangeRates, owner, keys); + await updateRates(keys, rates); // set a 0.5% exchange fee rate (1/200) exchangeFeeRate = toUnit('0.005'); diff --git a/test/contracts/FeePool.js b/test/contracts/FeePool.js index 3d88d071e8..f951ddc5c7 100644 --- a/test/contracts/FeePool.js +++ b/test/contracts/FeePool.js @@ -7,14 +7,7 @@ const { assert, addSnapshotBeforeRestoreAfterEach } = require('./common'); const FeePool = artifacts.require('FeePool'); const FlexibleStorage = artifacts.require('FlexibleStorage'); -const { - currentTime, - fastForward, - toUnit, - toPreciseUnit, - fromUnit, - multiplyDecimal, -} = require('../utils')(); +const { fastForward, toUnit, toPreciseUnit, fromUnit, multiplyDecimal } = require('../utils')(); const { ensureOnlyExpectedMutativeFunctions, @@ -24,6 +17,8 @@ const { decodedEventEqual, proxyThruTo, setExchangeFeeRateForSynths, + setupPriceAggregators, + updateAggregatorRates, } = require('./helpers'); const { setupAllContracts } = require('./setup'); @@ -34,15 +29,11 @@ const { } = require('../..'); contract('FeePool', async accounts => { - const [deployerAccount, owner, oracle, account1, account2] = accounts; + const [deployerAccount, owner, , account1, account2] = accounts; // Updates rates with defaults so they're not stale. const updateRatesWithDefaults = async () => { - const timestamp = await currentTime(); - - await exchangeRates.updateRates([sAUD, SNX], ['0.5', '0.1'].map(toUnit), timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [sAUD, SNX], ['0.5', '0.1'].map(toUnit)); await debtCache.takeDebtSnapshot(); }; @@ -75,6 +66,7 @@ contract('FeePool', async accounts => { systemSettings, exchangeRates, feePoolState, + rewardsDistribution, delegateApprovals, sUSDContract, addressResolver, @@ -91,6 +83,7 @@ contract('FeePool', async accounts => { FeePoolState: feePoolState, DebtCache: debtCache, ProxyFeePool: feePoolProxy, + RewardsDistribution: rewardsDistribution, Synthetix: synthetix, SystemSettings: systemSettings, SynthsUSD: sUSDContract, @@ -112,12 +105,15 @@ contract('FeePool', async accounts => { 'SystemSettings', 'SystemStatus', 'RewardEscrowV2', + 'RewardsDistribution', 'DelegateApprovals', 'CollateralManager', 'WrapperFactory', ], })); + await setupPriceAggregators(exchangeRates, owner, [sAUD]); + FEE_ADDRESS = await feePool.FEE_ADDRESS(); }); @@ -200,6 +196,23 @@ contract('FeePool', async accounts => { }); describe('restricted methods', () => { + before(async () => { + await proxyThruTo({ + proxy: feePoolProxy, + target: feePool, + fncName: 'setMessageSender', + from: account1, + args: [rewardsDistribution.address], + }); + }); + it('setRewardsToDistribute() cannot be called by an unauthorized account', async () => { + await onlyGivenAddressCanInvoke({ + fnc: feePool.setRewardsToDistribute, + accounts, + args: ['0'], + reason: 'RewardsDistribution only', + }); + }); it('appendAccountIssuanceRecord() cannot be invoked directly by any account', async () => { await onlyGivenAddressCanInvoke({ fnc: feePool.appendAccountIssuanceRecord, @@ -829,15 +842,10 @@ contract('FeePool', async accounts => { .concat(synths) .filter(key => key !== 'sUSD' && ![].concat(type).includes(key)); - const timestamp = await currentTime(); - - await exchangeRates.updateRates( + await updateAggregatorRates( + exchangeRates, ratesToUpdate.map(toBytes32), - ratesToUpdate.map(() => toUnit('1')), - timestamp, - { - from: oracle, - } + ratesToUpdate.map(() => toUnit('1')) ); await debtCache.takeDebtSnapshot(); }); @@ -1104,10 +1112,7 @@ contract('FeePool', async accounts => { // Increase the price so we start well and truly within our 20% ratio. const newRate = (await exchangeRates.rateForCurrency(SNX)).add(web3.utils.toBN('1')); - const timestamp = await currentTime(); - await exchangeRates.updateRates([SNX], [newRate], timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [SNX], [newRate]); await debtCache.takeDebtSnapshot(); assert.equal(await feePool.isFeesClaimable(owner), true); @@ -1121,10 +1126,7 @@ contract('FeePool', async accounts => { const newRate = (await exchangeRates.rateForCurrency(SNX)).add( step.mul(web3.utils.toBN('1')) ); - const timestamp = await currentTime(); - await exchangeRates.updateRates([SNX], [newRate], timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [SNX], [newRate]); await debtCache.takeDebtSnapshot(); const issuanceRatio = fromUnit(await feePool.issuanceRatio()); @@ -1146,10 +1148,7 @@ contract('FeePool', async accounts => { // Bump the rate down. const newRate = (await exchangeRates.rateForCurrency(SNX)).sub(step); - const timestamp = await currentTime(); - await exchangeRates.updateRates([SNX], [newRate], timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [SNX], [newRate]); await debtCache.takeDebtSnapshot(); } }); @@ -1181,10 +1180,7 @@ contract('FeePool', async accounts => { const currentRate = await exchangeRates.rateForCurrency(SNX); const newRate = currentRate.sub(multiplyDecimal(currentRate, toUnit('0.15'))); - const timestamp = await currentTime(); - await exchangeRates.updateRates([SNX], [newRate], timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [SNX], [newRate]); await debtCache.takeDebtSnapshot(); // fees available is unaffected but not claimable @@ -1224,10 +1220,7 @@ contract('FeePool', async accounts => { const currentRate = await exchangeRates.rateForCurrency(SNX); const newRate = currentRate.sub(multiplyDecimal(currentRate, toUnit('0.15'))); - const timestamp = await currentTime(); - await exchangeRates.updateRates([SNX], [newRate], timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [SNX], [newRate]); await debtCache.takeDebtSnapshot(); // fees available is unaffected but not claimable @@ -1328,15 +1321,10 @@ contract('FeePool', async accounts => { .concat(synths) .filter(key => key !== 'sUSD' && ![].concat(type).includes(key)); - const timestamp = await currentTime(); - - await exchangeRates.updateRates( + await updateAggregatorRates( + exchangeRates, ratesToUpdate.map(toBytes32), - ratesToUpdate.map(() => toUnit('1')), - timestamp, - { - from: oracle, - } + ratesToUpdate.map(() => toUnit('1')) ); await debtCache.takeDebtSnapshot(); }); diff --git a/test/contracts/FeePoolState.js b/test/contracts/FeePoolState.js index 19542e204a..e88cc83c16 100644 --- a/test/contracts/FeePoolState.js +++ b/test/contracts/FeePoolState.js @@ -360,14 +360,11 @@ contract('FeePoolState', async accounts => { // TODO checks SynthetixState debt entry is same as stored FeePoolState Entry // it.only('should allow an issuer to issue max synths and track debt issuance in feePool', async function() { // // Send a price update to guarantee we're not depending on values from outside this test. - // const oracle = await exchangeRates.oracle(); - // const timestamp = await currentTime(); - // await exchangeRates.updateRates( + // await updateAggregatorRates( + // exchangeRates, // [sAUD, sEUR, SNX], - // ['0.5', '1.25', '0.1'].map(toUnit), - // timestamp, - // { from: oracle } + // ['0.5', '1.25', '0.1'].map(toUnit) // ); // // Give some SNX to account1 @@ -397,14 +394,11 @@ contract('FeePoolState', async accounts => { // it('should allow an issuer to issue synths many times and track debt issuance in feePool', async function() { // // Send a price update to guarantee we're not depending on values from outside this test. - // const oracle = await exchangeRates.oracle(); - // const timestamp = await currentTime(); - // await exchangeRates.updateRates( + // await updateAggregatorRates( + // exchangeRates, // [sAUD, sEUR, SNX], // ['0.5', '1.25', '0.1'].map(toUnit), - // timestamp, - // { from: oracle } // ); // // Give some SNX to account1 diff --git a/test/contracts/Issuer.js b/test/contracts/Issuer.js index 5b1e034282..fdf8c432d2 100644 --- a/test/contracts/Issuer.js +++ b/test/contracts/Issuer.js @@ -25,6 +25,8 @@ const { onlyGivenAddressCanInvoke, ensureOnlyExpectedMutativeFunctions, setStatus, + setupPriceAggregators, + updateAggregatorRates, } = require('./helpers'); const { @@ -41,7 +43,7 @@ contract('Issuer (via Synthetix)', async accounts => { ); const synthKeys = [sUSD, sAUD, sEUR, sETH, SNX]; - const [, owner, oracle, account1, account2, account3, account6] = accounts; + const [, owner, , account1, account2, account3, account6] = accounts; let synthetix, systemStatus, @@ -56,7 +58,6 @@ contract('Issuer (via Synthetix)', async accounts => { sAUDContract, escrow, rewardEscrowV2, - timestamp, debtCache, issuer, synths, @@ -111,18 +112,17 @@ contract('Issuer (via Synthetix)', async accounts => { 'SynthRedeemer', ], })); + + await setupPriceAggregators(exchangeRates, owner, [sAUD, sEUR, sETH, ETH]); }); addSnapshotBeforeRestoreAfterEach(); beforeEach(async () => { - timestamp = await currentTime(); - - await exchangeRates.updateRates( + await updateAggregatorRates( + exchangeRates, [sAUD, sEUR, SNX, sETH], - ['0.5', '1.25', '0.1', '200'].map(toUnit), - timestamp, - { from: oracle } + ['0.5', '1.25', '0.1', '200'].map(toUnit) ); // set a 0.3% default exchange fee rate @@ -314,11 +314,10 @@ contract('Issuer (via Synthetix)', async accounts => { beforeEach(async () => { await fastForward(10); // Send a price update to give the synth rates - await exchangeRates.updateRates( + await updateAggregatorRates( + exchangeRates, [sAUD, sEUR, sETH, ETH, SNX], - ['0.5', '1.25', '100', '100', '2'].map(toUnit), - await currentTime(), - { from: oracle } + ['0.5', '1.25', '100', '100', '2'].map(toUnit) ); await debtCache.takeDebtSnapshot(); }); @@ -396,8 +395,7 @@ contract('Issuer (via Synthetix)', async accounts => { describe('debtBalance()', () => { it('should not change debt balance % if exchange rates change', async () => { let newAUDRate = toUnit('0.5'); - let timestamp = await currentTime(); - await exchangeRates.updateRates([sAUD], [newAUDRate], timestamp, { from: oracle }); + await updateAggregatorRates(exchangeRates, [sAUD], [newAUDRate]); await debtCache.takeDebtSnapshot(); await synthetix.transfer(account1, toUnit('20000'), { @@ -427,9 +425,8 @@ contract('Issuer (via Synthetix)', async accounts => { PRECISE_UNIT ); - timestamp = await currentTime(); newAUDRate = toUnit('1.85'); - await exchangeRates.updateRates([sAUD], [newAUDRate], timestamp, { from: oracle }); + await updateAggregatorRates(exchangeRates, [sAUD], [newAUDRate]); await debtCache.takeDebtSnapshot(); totalIssuedSynthsUSD = await synthetix.totalIssuedSynths(sUSD); @@ -669,6 +666,7 @@ contract('Issuer (via Synthetix)', async accounts => { })); await issuer.addSynth(synth.address, { from: owner }); + await setupPriceAggregators(exchangeRates, owner, [currencyKey]); }); it('should be able to query multiple synth addresses', async () => { @@ -719,9 +717,7 @@ contract('Issuer (via Synthetix)', async accounts => { }); describe('when the synth has a rate', () => { beforeEach(async () => { - await exchangeRates.updateRates([currencyKey], [toUnit('2')], timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [currencyKey], [toUnit('2')]); }); describe('when another user exchanges into the synth', () => { @@ -739,17 +735,6 @@ contract('Issuer (via Synthetix)', async accounts => { const { numEntries } = await exchanger.settlementOwing(owner, currencyKey); assert.equal(numEntries, '0'); }); - describe('when the rate is also removed', () => { - beforeEach(async () => { - await exchangeRates.deleteRate(currencyKey, { from: oracle }); - }); - it('then settling works as expected', async () => { - await synthetix.settle(currencyKey); - - const { numEntries } = await exchanger.settlementOwing(owner, currencyKey); - assert.equal(numEntries, '0'); - }); - }); }); describe('when the same user exchanges out of the synth', () => { beforeEach(async () => { @@ -773,22 +758,6 @@ contract('Issuer (via Synthetix)', async accounts => { const { numEntries } = await exchanger.settlementOwing(owner, currencyKey); assert.equal(numEntries, '0'); }); - describe('when the rate is also removed', () => { - beforeEach(async () => { - await exchangeRates.deleteRate(currencyKey, { from: oracle }); - }); - it('then settling works as expected', async () => { - await synthetix.settle(currencyKey); - - const { numEntries } = await exchanger.settlementOwing(owner, currencyKey); - assert.equal(numEntries, '0'); - }); - it('then settling from the original currency works too', async () => { - await synthetix.settle(currencyKey); - const { numEntries } = await exchanger.settlementOwing(owner, currencyKey); - assert.equal(numEntries, '0'); - }); - }); }); }); }); @@ -1040,15 +1009,10 @@ contract('Issuer (via Synthetix)', async accounts => { .concat(synths) .filter(key => key !== 'sUSD' && ![].concat(type).includes(key)); - const timestamp = await currentTime(); - - await exchangeRates.updateRates( + await updateAggregatorRates( + exchangeRates, ratesToUpdate.map(toBytes32), - ratesToUpdate.map(() => toUnit('1')), - timestamp, - { - from: oracle, - } + ratesToUpdate.map(() => toUnit('1')) ); await debtCache.takeDebtSnapshot(); }); @@ -1272,15 +1236,10 @@ contract('Issuer (via Synthetix)', async accounts => { .concat(synths) .filter(key => key !== 'sUSD' && ![].concat(type).includes(key)); - const timestamp = await currentTime(); - - await exchangeRates.updateRates( + await updateAggregatorRates( + exchangeRates, ratesToUpdate.map(toBytes32), - ratesToUpdate.map(rate => toUnit(rate === 'SNX' ? '0.1' : '1')), - timestamp, - { - from: oracle, - } + ratesToUpdate.map(rate => toUnit(rate === 'SNX' ? '0.1' : '1')) ); await debtCache.takeDebtSnapshot(); }); @@ -1606,9 +1565,7 @@ contract('Issuer (via Synthetix)', async accounts => { from: owner, }); // Set SNX price to 1 - await exchangeRates.updateRates([SNX], ['1'].map(toUnit), timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [SNX], ['1'].map(toUnit)); await debtCache.takeDebtSnapshot(); // Issue await synthetix.issueMaxSynths({ from: account1 }); @@ -1621,9 +1578,7 @@ contract('Issuer (via Synthetix)', async accounts => { describe('when the SNX price drops 50%', () => { let maxIssuableSynths; beforeEach(async () => { - await exchangeRates.updateRates([SNX], ['.5'].map(toUnit), timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [SNX], ['.5'].map(toUnit)); await debtCache.takeDebtSnapshot(); maxIssuableSynths = await synthetix.maxIssuableSynths(account1); assert.equal(await feePool.isFeesClaimable(account1), false); @@ -1645,9 +1600,7 @@ contract('Issuer (via Synthetix)', async accounts => { describe('when the SNX price drops 10%', () => { let maxIssuableSynths; beforeEach(async () => { - await exchangeRates.updateRates([SNX], ['.9'].map(toUnit), timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [SNX], ['.9'].map(toUnit)); await debtCache.takeDebtSnapshot(); maxIssuableSynths = await synthetix.maxIssuableSynths(account1); }); @@ -1668,9 +1621,7 @@ contract('Issuer (via Synthetix)', async accounts => { describe('when the SNX price drops 90%', () => { let maxIssuableSynths; beforeEach(async () => { - await exchangeRates.updateRates([SNX], ['.1'].map(toUnit), timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [SNX], ['.1'].map(toUnit)); await debtCache.takeDebtSnapshot(); maxIssuableSynths = await synthetix.maxIssuableSynths(account1); }); @@ -1691,9 +1642,7 @@ contract('Issuer (via Synthetix)', async accounts => { describe('when the SNX price increases 100%', () => { let maxIssuableSynths; beforeEach(async () => { - await exchangeRates.updateRates([SNX], ['2'].map(toUnit), timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [SNX], ['2'].map(toUnit)); await debtCache.takeDebtSnapshot(); maxIssuableSynths = await synthetix.maxIssuableSynths(account1); }); @@ -1780,9 +1729,7 @@ contract('Issuer (via Synthetix)', async accounts => { }); describe('and the sEUR price decreases by 20% to 1', () => { beforeEach(async () => { - await exchangeRates.updateRates([sEUR], ['1'].map(toUnit), timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [sEUR], ['1'].map(toUnit)); await debtCache.takeDebtSnapshot(); }); describe('and 60s elapses', () => { @@ -2105,8 +2052,7 @@ contract('Issuer (via Synthetix)', async accounts => { it("should prevent more issuance if the user's collaterisation changes to be insufficient", async () => { // Set sEUR for purposes of this test - const timestamp1 = await currentTime(); - await exchangeRates.updateRates([sEUR], [toUnit('0.75')], timestamp1, { from: oracle }); + await updateAggregatorRates(exchangeRates, [sEUR], [toUnit('0.75')]); await debtCache.takeDebtSnapshot(); const issuedSynthetixs = web3.utils.toBN('200000'); @@ -2125,8 +2071,7 @@ contract('Issuer (via Synthetix)', async accounts => { await synthetix.exchange(sUSD, issuedSynths, sEUR, { from: account1 }); // Increase the value of sEUR relative to synthetix - const timestamp2 = await currentTime(); - await exchangeRates.updateRates([sEUR], [toUnit('1.10')], timestamp2, { from: oracle }); + await updateAggregatorRates(exchangeRates, [sEUR], [toUnit('1.1')]); await debtCache.takeDebtSnapshot(); await assert.revert( @@ -2427,7 +2372,7 @@ contract('Issuer (via Synthetix)', async accounts => { await synthetix.transfer(authoriser, toUnit('20000'), { from: owner, }); - await exchangeRates.updateRates([SNX], ['1'].map(toUnit), timestamp, { from: oracle }); + await updateAggregatorRates(exchangeRates, [SNX], [toUnit('1')]); await debtCache.takeDebtSnapshot(); }); describe('when not approved it should revert on', async () => { @@ -2514,9 +2459,7 @@ contract('Issuer (via Synthetix)', async accounts => { }); it('and calling burnSynthsToTargetOnBehalf() succeeds', async () => { // need the user to be undercollaterized for this to succeed - await exchangeRates.updateRates([SNX], ['0.001'].map(toUnit), timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [SNX], [toUnit('0.001')]); await debtCache.takeDebtSnapshot(); await synthetix.burnSynthsToTargetOnBehalf(authoriser, { from: delegate }); }); @@ -2566,7 +2509,7 @@ contract('Issuer (via Synthetix)', async accounts => { }); it('should approveBurnOnBehalf and burnSynthsToTarget', async () => { await synthetix.issueMaxSynths({ from: authoriser }); - await exchangeRates.updateRates([SNX], ['0.01'].map(toUnit), timestamp, { from: oracle }); + await updateAggregatorRates(exchangeRates, [SNX], [toUnit('0.01')]); await debtCache.takeDebtSnapshot(); await delegateApprovals.approveBurnOnBehalf(delegate, { from: authoriser }); diff --git a/test/contracts/Liquidations.js b/test/contracts/Liquidations.js index 2f4bef7079..1255160b68 100644 --- a/test/contracts/Liquidations.js +++ b/test/contracts/Liquidations.js @@ -12,6 +12,7 @@ const { onlyGivenAddressCanInvoke, ensureOnlyExpectedMutativeFunctions, setStatus, + updateAggregatorRates, } = require('./helpers'); const { @@ -24,7 +25,7 @@ const FlexibleStorage = artifacts.require('FlexibleStorage'); contract('Liquidations', accounts => { const [sUSD, SNX] = ['sUSD', 'SNX'].map(toBytes32); - const [deployerAccount, owner, oracle, account1, alice, bob, carol, david] = accounts; + const [deployerAccount, owner, , account1, alice, bob, carol, david] = accounts; const week = 3600 * 24 * 7; const sUSD100 = toUnit('100'); @@ -38,8 +39,7 @@ contract('Liquidations', accounts => { systemStatus, feePoolState, debtCache, - issuer, - timestamp; + issuer; // run this once before all tests to prepare our environment, snapshots on beforeEach will take // care of resetting to this state @@ -86,16 +86,11 @@ contract('Liquidations', accounts => { }; const updateRatesWithDefaults = async () => { - timestamp = await currentTime(); - // SNX is 6 dolla await updateSNXPrice('6'); }; const updateSNXPrice = async rate => { - timestamp = await currentTime(); - await exchangeRates.updateRates([SNX], [rate].map(toUnit), timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [SNX], [rate].map(toUnit)); await debtCache.takeDebtSnapshot(); }; diff --git a/test/contracts/MultiCollateralSynth.js b/test/contracts/MultiCollateralSynth.js index 60e92c1c7c..165a13186a 100644 --- a/test/contracts/MultiCollateralSynth.js +++ b/test/contracts/MultiCollateralSynth.js @@ -6,8 +6,13 @@ const { assert, addSnapshotBeforeRestoreAfterEach } = require('./common'); let MultiCollateralSynth; -const { onlyGivenAddressCanInvoke, ensureOnlyExpectedMutativeFunctions } = require('./helpers'); -const { toUnit, currentTime, fastForward } = require('../utils')(); +const { + onlyGivenAddressCanInvoke, + ensureOnlyExpectedMutativeFunctions, + setupPriceAggregators, + updateAggregatorRates, +} = require('./helpers'); +const { toUnit, fastForward } = require('../utils')(); const { toBytes32, constants: { ZERO_ADDRESS }, @@ -16,9 +21,10 @@ const { const { setupAllContracts } = require('./setup'); contract('MultiCollateralSynth', accounts => { - const [deployerAccount, owner, oracle, , account1] = accounts; + const [deployerAccount, owner, , , account1] = accounts; const sETH = toBytes32('sETH'); + const sBTC = toBytes32('sBTC'); let issuer, resolver, @@ -43,20 +49,6 @@ contract('MultiCollateralSynth', accounts => { }); }; - const updateRatesWithDefaults = async () => { - const timestamp = await currentTime(); - - await exchangeRates.updateRates([sETH], ['100'].map(toUnit), timestamp, { - from: oracle, - }); - - const sBTC = toBytes32('sBTC'); - - await exchangeRates.updateRates([sBTC], ['10000'].map(toUnit), timestamp, { - from: oracle, - }); - }; - before(async () => { MultiCollateralSynth = artifacts.require('MultiCollateralSynth'); }); @@ -91,6 +83,9 @@ contract('MultiCollateralSynth', accounts => { ], })); + await setupPriceAggregators(exchangeRates, owner, [sETH, sBTC]); + await updateAggregatorRates(exchangeRates, [sETH, sBTC], [100, 10000].map(toUnit)); + await managerState.setAssociatedContract(manager.address, { from: owner }); await manager.rebuildCache(); @@ -99,8 +94,6 @@ contract('MultiCollateralSynth', accounts => { await manager.addCollaterals([ceth.address], { from: owner }); - await updateRatesWithDefaults(); - await issuesUSDToAccount(toUnit(1000), owner); await debtCache.takeDebtSnapshot(); }); @@ -199,11 +192,9 @@ contract('MultiCollateralSynth', accounts => { describe('when multiCollateral is set to the owner', () => { beforeEach(async () => { - const timestamp = await currentTime(); - - await exchangeRates.updateRates([toBytes32('sXYZ')], [toUnit(5)], timestamp, { - from: oracle, - }); + const sXYZ = toBytes32('sXYZ'); + await setupPriceAggregators(exchangeRates, owner, [sXYZ]); + await updateAggregatorRates(exchangeRates, [sXYZ], [toUnit(5)]); }); describe('when multiCollateral tries to issue', () => { it('then it can issue new synths', async () => { diff --git a/test/contracts/NativeEtherWrapper.js b/test/contracts/NativeEtherWrapper.js index 920891fcb2..c305cb4327 100644 --- a/test/contracts/NativeEtherWrapper.js +++ b/test/contracts/NativeEtherWrapper.js @@ -4,13 +4,15 @@ const { contract, web3 } = require('hardhat'); const { assert, addSnapshotBeforeRestoreAfterEach } = require('./common'); -const { currentTime, toUnit } = require('../utils')(); +const { toUnit } = require('../utils')(); const { GAS_PRICE } = require('../../hardhat.config'); const { ensureOnlyExpectedMutativeFunctions, getDecodedLogs, decodedEventEqual, + setupPriceAggregators, + updateAggregatorRates, } = require('./helpers'); const { setupAllContracts } = require('./setup'); @@ -22,7 +24,7 @@ contract('NativeEtherWrapper', async accounts => { const synths = ['sUSD', 'sETH', 'ETH', 'SNX']; const [sETH, ETH] = ['sETH', 'ETH'].map(toBytes32); - const [, owner, oracle, , account1] = accounts; + const [, owner, , , account1] = accounts; let systemSettings, exchangeRates, @@ -30,8 +32,7 @@ contract('NativeEtherWrapper', async accounts => { sETHSynth, etherWrapper, nativeEtherWrapper, - weth, - timestamp; + weth; before(async () => { ({ @@ -63,12 +64,10 @@ contract('NativeEtherWrapper', async accounts => { ], })); - timestamp = await currentTime(); + await setupPriceAggregators(exchangeRates, owner, [sETH, ETH]); // Depot requires ETH rates - await exchangeRates.updateRates([sETH, ETH], ['1500', '1500'].map(toUnit), timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [sETH, ETH], ['1500', '1500'].map(toUnit)); }); addSnapshotBeforeRestoreAfterEach(); diff --git a/test/contracts/PurgeableSynth.js b/test/contracts/PurgeableSynth.js index 812c1fcf0c..a66cb71a00 100644 --- a/test/contracts/PurgeableSynth.js +++ b/test/contracts/PurgeableSynth.js @@ -8,7 +8,7 @@ const TokenState = artifacts.require('TokenState'); const Proxy = artifacts.require('Proxy'); const PurgeableSynth = artifacts.require('PurgeableSynth'); -const { currentTime, fastForward, toUnit } = require('../utils')(); +const { fastForward, toUnit } = require('../utils')(); const { toBytes32, constants: { ZERO_ADDRESS }, @@ -20,6 +20,8 @@ const { onlyGivenAddressCanInvoke, ensureOnlyExpectedMutativeFunctions, setStatus, + setupPriceAggregators, + updateAggregatorRates, } = require('./helpers'); const { setupAllContracts } = require('./setup'); @@ -27,7 +29,7 @@ const { setupAllContracts } = require('./setup'); contract('PurgeableSynth', accounts => { const [sUSD, SNX, sAUD, iETH] = ['sUSD', 'SNX', 'sAUD', 'iETH'].map(toBytes32); const synthKeys = [sUSD, sAUD, iETH]; - const [deployerAccount, owner, oracle, , account1, account2] = accounts; + const [deployerAccount, owner, , , account1, account2] = accounts; let exchangeRates, exchanger, @@ -36,7 +38,6 @@ contract('PurgeableSynth', accounts => { sAUDContract, iETHContract, systemStatus, - timestamp, addressResolver, debtCache, issuer; @@ -71,7 +72,7 @@ contract('PurgeableSynth', accounts => { ], })); - timestamp = await currentTime(); + await setupPriceAggregators(exchangeRates, owner, [sAUD, iETH]); }); beforeEach(async () => { @@ -155,13 +156,10 @@ contract('PurgeableSynth', accounts => { describe("when there's a price for the purgeable synth", () => { beforeEach(async () => { - await exchangeRates.updateRates( + await updateAggregatorRates( + exchangeRates, [sAUD, SNX, iETH], - ['0.5', '1', '170'].map(toUnit), - timestamp, - { - from: oracle, - } + ['0.5', '1', '170'].map(toUnit) ); await debtCache.takeDebtSnapshot(); }); @@ -207,9 +205,7 @@ contract('PurgeableSynth', accounts => { }); describe('when rates are received', () => { beforeEach(async () => { - await exchangeRates.updateRates([iETH], ['170'].map(toUnit), await currentTime(), { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [iETH], ['170'].map(toUnit)); await debtCache.takeDebtSnapshot(); }); it('then purge() still works as expected', async () => { @@ -322,9 +318,7 @@ contract('PurgeableSynth', accounts => { describe('Replacing an existing Synth with a Purgeable one to purge and remove it', () => { describe('when sAUD has a price', () => { beforeEach(async () => { - await exchangeRates.updateRates([sAUD], ['0.776845993'].map(toUnit), timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [sAUD], ['0.776845993'].map(toUnit)); await debtCache.takeDebtSnapshot(); }); describe('when a user holds some sAUD', () => { diff --git a/test/contracts/RewardsIntegrationTests.js b/test/contracts/RewardsIntegrationTests.js index 64415c28dd..f50af7f70c 100644 --- a/test/contracts/RewardsIntegrationTests.js +++ b/test/contracts/RewardsIntegrationTests.js @@ -6,9 +6,14 @@ const { assert, addSnapshotBeforeRestoreAfterEach } = require('./common'); const { toBytes32 } = require('../..'); -const { currentTime, fastForward, toUnit, toPreciseUnit, multiplyDecimal } = require('../utils')(); +const { fastForward, toUnit, toPreciseUnit, multiplyDecimal } = require('../utils')(); -const { setExchangeFeeRateForSynths } = require('./helpers'); +const { + setExchangeFeeRateForSynths, + setupPriceAggregators, + updateRatesWithDefaults, + updateAggregatorRates, +} = require('./helpers'); const { setupAllContracts } = require('./setup'); @@ -60,22 +65,6 @@ contract('Rewards Integration Tests', accounts => { const synthKeys = [sUSD, sAUD, sEUR, sBTC, iBTC, sETH, ETH]; - // Updates rates with defaults so they're not stale. - const updateRatesWithDefaults = async () => { - const timestamp = await currentTime(); - - await exchangeRates.updateRates( - [sAUD, sEUR, SNX, sBTC, iBTC, sETH, ETH], - ['0.5', '1.25', '0.1', '5000', '4000', '172', '172'].map(toUnit), - timestamp, - { - from: oracle, - } - ); - - await debtCache.takeDebtSnapshot(); - }; - const fastForwardAndCloseFeePeriod = async () => { const feePeriodDuration = await feePool.feePeriodDuration(); // Note: add on a small addition of 10 seconds - this seems to have @@ -87,12 +76,12 @@ contract('Rewards Integration Tests', accounts => { // Fast forward another day after feePeriod closed before minting await fastForward(DAY + 10); - await updateRatesWithDefaults(); + await updateRatesWithDefaults({ exchangeRates, owner, debtCache }); }; const fastForwardAndUpdateRates = async seconds => { await fastForward(seconds); - await updateRatesWithDefaults(); + await updateRatesWithDefaults({ exchangeRates, owner, debtCache }); }; const exchangeFeeRate = toUnit('0.003'); // 30 bips @@ -130,7 +119,7 @@ contract('Rewards Integration Tests', accounts => { // const YEAR = 31556926; // ACCOUNTS - const [deployerAccount, owner, oracle, feeAuthority, account1, account2, account3] = accounts; + const [deployerAccount, owner, , feeAuthority, account1, account2, account3] = accounts; // VARIABLES let feePool, @@ -181,6 +170,8 @@ contract('Rewards Integration Tests', accounts => { ], })); + await setupPriceAggregators(exchangeRates, owner, [sAUD, sEUR, sBTC, iBTC, sETH, ETH]); + MINTER_SNX_REWARD = await supplySchedule.minterReward(); await setExchangeFeeRateForSynths({ @@ -627,10 +618,7 @@ contract('Rewards Integration Tests', accounts => { ); // Increase sBTC price by 100% - const timestamp = await currentTime(); - await exchangeRates.updateRates([sBTC], ['10000'].map(toUnit), timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [sBTC], ['10000'].map(toUnit)); await debtCache.takeDebtSnapshot(); // Account 3 (enters the system and) mints 10K sUSD (minus half of an exchange fee - to balance the fact @@ -928,10 +916,7 @@ contract('Rewards Integration Tests', accounts => { const currentRate = await exchangeRates.rateForCurrency(SNX); const newRate = currentRate.sub(multiplyDecimal(currentRate, toUnit('0.009'))); - const timestamp = await currentTime(); - await exchangeRates.updateRates([SNX], [newRate], timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [SNX], [newRate]); // we will be able to claim fees assert.equal(await feePool.isFeesClaimable(account1), true); @@ -953,11 +938,7 @@ contract('Rewards Integration Tests', accounts => { it('should block user from claiming fees and rewards when users claim rewards >10% threshold collateralisation ratio', async () => { // But if the price of SNX decreases a lot... const newRate = (await exchangeRates.rateForCurrency(SNX)).sub(toUnit('0.09')); - const timestamp = await currentTime(); - await exchangeRates.updateRates([SNX], [newRate], timestamp, { - from: oracle, - }); - + await updateAggregatorRates(exchangeRates, [SNX], [newRate]); // we will fall into the >100% bracket assert.equal(await feePool.isFeesClaimable(account1), false); diff --git a/test/contracts/ShortingRewards.js b/test/contracts/ShortingRewards.js index 4c6de47f63..4915282112 100644 --- a/test/contracts/ShortingRewards.js +++ b/test/contracts/ShortingRewards.js @@ -5,7 +5,12 @@ const { toBytes32, constants: { ZERO_ADDRESS }, } = require('../..'); -const { onlyGivenAddressCanInvoke, ensureOnlyExpectedMutativeFunctions } = require('./helpers'); +const { + onlyGivenAddressCanInvoke, + ensureOnlyExpectedMutativeFunctions, + setupPriceAggregators, + updateAggregatorRates, +} = require('./helpers'); const { assert, addSnapshotBeforeRestoreAfterEach } = require('./common'); const { setupAllContracts, setupContract } = require('./setup'); const { currentTime, toUnit, fastForward } = require('../utils')(); @@ -17,7 +22,7 @@ contract('ShortingRewards', accounts => { const [ deployerAccount, owner, - oracle, + , authority, rewardEscrowAddress, account1, @@ -27,7 +32,9 @@ contract('ShortingRewards', accounts => { const sUSD = toBytes32('sUSD'); const sETH = toBytes32('sETH'); + const iETH = toBytes32('iETH'); const sBTC = toBytes32('sBTC'); + const iBTC = toBytes32('iBTC'); // Synthetix is the rewardsToken let rewardsToken, @@ -57,33 +64,11 @@ contract('ShortingRewards', accounts => { return event.args.id; }; - const updateRatesWithDefaults = async () => { - const timestamp = await currentTime(); - - await exchangeRates.updateRates([sETH], ['100'].map(toUnit), timestamp, { - from: oracle, - }); - - const sBTC = toBytes32('sBTC'); - - await exchangeRates.updateRates([sBTC], ['10000'].map(toUnit), timestamp, { - from: oracle, - }); - }; - const setRewardsTokenExchangeRate = async ({ rateStaleDays } = { rateStaleDays: 7 }) => { const rewardsTokenIdentifier = await rewardsToken.symbol(); await systemSettings.setRateStalePeriod(DAY * rateStaleDays, { from: owner }); - const updatedTime = await currentTime(); - await exchangeRates.updateRates( - [toBytes32(rewardsTokenIdentifier)], - [toUnit('2')], - updatedTime, - { - from: oracle, - } - ); + await updateAggregatorRates(exchangeRates, [toBytes32(rewardsTokenIdentifier)], [toUnit('2')]); assert.equal(await exchangeRates.rateIsStale(toBytes32(rewardsTokenIdentifier)), false); }; @@ -150,6 +135,8 @@ contract('ShortingRewards', accounts => { ], })); + await setupPriceAggregators(exchangeRates, owner, [sBTC, iBTC, sETH, iETH]); + managerState = await CollateralManagerState.new(owner, ZERO_ADDRESS, { from: deployerAccount }); const maxDebt = toUnit(10000000); @@ -232,7 +219,7 @@ contract('ShortingRewards', accounts => { }); beforeEach(async () => { - await updateRatesWithDefaults(); + await updateAggregatorRates(exchangeRates, [sETH, sBTC], [100, 10000].map(toUnit)); await issuesUSDToAccount(toUnit(100000), owner); await issuesBTCtoAccount(toUnit(10), owner); @@ -443,10 +430,7 @@ contract('ShortingRewards', accounts => { await fastForward(DAY); // Make the short so underwater it must get closed. - const timestamp = await currentTime(); - await exchangeRates.updateRates([sBTC], ['20000'].map(toUnit), timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [sBTC], ['20000'].map(toUnit)); // close the loan via liquidation await issuesBTCtoAccount(toUnit(1), account2); @@ -465,10 +449,7 @@ contract('ShortingRewards', accounts => { await fastForward(DAY); // Make the short so underwater it must get closed. - const timestamp = await currentTime(); - await exchangeRates.updateRates([sBTC], ['20000'].map(toUnit), timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [sBTC], ['20000'].map(toUnit)); // close the loan via liquidation await issuesBTCtoAccount(toUnit(1), account2); diff --git a/test/contracts/StakingRewards.js b/test/contracts/StakingRewards.js index 59a94833ef..ae19180d18 100644 --- a/test/contracts/StakingRewards.js +++ b/test/contracts/StakingRewards.js @@ -2,7 +2,12 @@ const { contract } = require('hardhat'); const { toBN } = require('web3-utils'); const { toBytes32 } = require('../..'); -const { onlyGivenAddressCanInvoke, ensureOnlyExpectedMutativeFunctions } = require('./helpers'); +const { + onlyGivenAddressCanInvoke, + ensureOnlyExpectedMutativeFunctions, + setupPriceAggregators, + updateAggregatorRates, +} = require('./helpers'); const { assert, addSnapshotBeforeRestoreAfterEach } = require('./common'); const { mockToken, setupAllContracts, setupContract } = require('./setup'); const { currentTime, toUnit, fastForward } = require('../utils')(); @@ -11,7 +16,7 @@ contract('StakingRewards', accounts => { const [ , owner, - oracle, + , authority, rewardEscrowAddress, stakingAccount1, @@ -33,18 +38,12 @@ contract('StakingRewards', accounts => { const setRewardsTokenExchangeRate = async ({ rateStaleDays } = { rateStaleDays: 7 }) => { const rewardsTokenIdentifier = await rewardsToken.symbol(); + const tokenKey = toBytes32(rewardsTokenIdentifier); await systemSettings.setRateStalePeriod(DAY * rateStaleDays, { from: owner }); - const updatedTime = await currentTime(); - await exchangeRates.updateRates( - [toBytes32(rewardsTokenIdentifier)], - [toUnit('2')], - updatedTime, - { - from: oracle, - } - ); - assert.equal(await exchangeRates.rateIsStale(toBytes32(rewardsTokenIdentifier)), false); + await setupPriceAggregators(exchangeRates, owner, [tokenKey]); + await updateAggregatorRates(exchangeRates, [tokenKey], [toUnit('2')]); + assert.equal(await exchangeRates.rateIsStale(tokenKey), false); }; addSnapshotBeforeRestoreAfterEach(); diff --git a/test/contracts/Synth.js b/test/contracts/Synth.js index a0251a261e..73a95273fd 100644 --- a/test/contracts/Synth.js +++ b/test/contracts/Synth.js @@ -9,12 +9,14 @@ const Synth = artifacts.require('Synth'); const { setupAllContracts } = require('./setup'); -const { currentTime, toUnit, bytesToString } = require('../utils')(); +const { toUnit, bytesToString } = require('../utils')(); const { issueSynthsToUser, ensureOnlyExpectedMutativeFunctions, onlyGivenAddressCanInvoke, setStatus, + setupPriceAggregators, + updateAggregatorRates, } = require('./helpers'); const { @@ -25,7 +27,7 @@ const { contract('Synth', async accounts => { const [sUSD, SNX, sEUR] = ['sUSD', 'SNX', 'sEUR'].map(toBytes32); - const [deployerAccount, owner, oracle, , account1, account2] = accounts; + const [deployerAccount, owner, , , account1, account2] = accounts; let feePool, FEE_ADDRESS, @@ -71,18 +73,16 @@ contract('Synth', async accounts => { ], })); + await setupPriceAggregators(exchangeRates, owner, [sEUR]); + FEE_ADDRESS = await feePool.FEE_ADDRESS(); }); addSnapshotBeforeRestoreAfterEach(); beforeEach(async () => { - const timestamp = await currentTime(); - // Send a price update to guarantee we're not stale. - await exchangeRates.updateRates([SNX], ['0.1'].map(toUnit), timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [SNX], ['0.1'].map(toUnit)); await debtCache.takeDebtSnapshot(); // set default issuanceRatio to 0.2 @@ -733,12 +733,8 @@ contract('Synth', async accounts => { contracts: [{ contract: 'Synth', properties: { currencyKey: sEUR } }], })); - const timestamp = await currentTime(); - // Send a price update to guarantee we're not stale. - await exchangeRates.updateRates([sEUR], ['1'].map(toUnit), timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [sEUR], ['1'].map(toUnit)); await debtCache.takeDebtSnapshot(); }); diff --git a/test/contracts/SynthUtil.js b/test/contracts/SynthUtil.js index d2d7cc1ad7..9abd6f8360 100644 --- a/test/contracts/SynthUtil.js +++ b/test/contracts/SynthUtil.js @@ -3,16 +3,20 @@ const { contract } = require('hardhat'); const { assert, addSnapshotBeforeRestoreAfterEach } = require('./common'); const { toBytes32 } = require('../..'); -const { toUnit, currentTime } = require('../utils')(); -const { setExchangeFeeRateForSynths } = require('./helpers'); +const { toUnit } = require('../utils')(); +const { + setExchangeFeeRateForSynths, + setupPriceAggregators, + updateAggregatorRates, +} = require('./helpers'); const { setupAllContracts } = require('./setup'); contract('SynthUtil', accounts => { - const [, ownerAccount, oracle, account2] = accounts; - let synthUtil, sUSDContract, synthetix, exchangeRates, timestamp, systemSettings, debtCache; + const [, ownerAccount, , account2] = accounts; + let synthUtil, sUSDContract, synthetix, exchangeRates, systemSettings, debtCache; - const [sUSD, sBTC, iBTC] = ['sUSD', 'sBTC', 'iBTC'].map(toBytes32); + const [sUSD, sBTC, iBTC, SNX] = ['sUSD', 'sBTC', 'iBTC', 'SNX'].map(toBytes32); const synthKeys = [sUSD, sBTC, iBTC]; const synthPrices = [toUnit('1'), toUnit('5000'), toUnit('5000')]; @@ -42,15 +46,18 @@ contract('SynthUtil', accounts => { 'RewardEscrowV2', // required for issuer._collateral to read collateral ], })); + + await setupPriceAggregators(exchangeRates, ownerAccount, [sBTC, iBTC]); }); addSnapshotBeforeRestoreAfterEach(); beforeEach(async () => { - timestamp = await currentTime(); - await exchangeRates.updateRates([sBTC, iBTC], ['5000', '5000'].map(toUnit), timestamp, { - from: oracle, - }); + await updateAggregatorRates( + exchangeRates, + [sBTC, iBTC, SNX], + ['5000', '5000', '0.2'].map(toUnit) + ); await debtCache.takeDebtSnapshot(); // set a 0% default exchange fee rate for test purpose diff --git a/test/contracts/Synthetix.js b/test/contracts/Synthetix.js index a7a5159c6d..a7de48399f 100644 --- a/test/contracts/Synthetix.js +++ b/test/contracts/Synthetix.js @@ -15,6 +15,7 @@ const { fastForwardTo, toUnit, fromUnit } = require('../utils')(); const { ensureOnlyExpectedMutativeFunctions, updateRatesWithDefaults, + setupPriceAggregators, setStatus, } = require('./helpers'); @@ -34,7 +35,6 @@ contract('Synthetix', async accounts => { supplySchedule, rewardEscrow, rewardEscrowV2, - oracle, addressResolver, systemStatus, sUSDContract, @@ -72,8 +72,7 @@ contract('Synthetix', async accounts => { ], })); - // Send a price update to guarantee we're not stale. - oracle = account1; + await setupPriceAggregators(exchangeRates, owner, [sAUD, sEUR, sETH]); }); addSnapshotBeforeRestoreAfterEach(); @@ -187,7 +186,7 @@ contract('Synthetix', async accounts => { // ensure mint() can succeed by default const week234 = INFLATION_START_DATE + WEEK * 234; await fastForwardTo(new Date(week234 * 1000)); - await updateRatesWithDefaults({ exchangeRates, oracle, debtCache }); + await updateRatesWithDefaults({ exchangeRates, owner, debtCache }); }); ['System', 'Issuance'].forEach(section => { describe(`when ${section} is suspended`, () => { @@ -212,7 +211,7 @@ contract('Synthetix', async accounts => { // fast forward EVM to end of inflation supply decay at week 234 const week234 = INFLATION_START_DATE + WEEK * 234; await fastForwardTo(new Date(week234 * 1000)); - await updateRatesWithDefaults({ exchangeRates, oracle, debtCache }); + await updateRatesWithDefaults({ exchangeRates, owner, debtCache }); const existingSupply = await synthetix.totalSupply(); const mintableSupply = await supplySchedule.mintableSupply(); @@ -248,7 +247,7 @@ contract('Synthetix', async accounts => { // fast forward EVM to Week 3 in of the inflationary supply const weekThree = INFLATION_START_DATE + WEEK * 2 + DAY; await fastForwardTo(new Date(weekThree * 1000)); - await updateRatesWithDefaults({ exchangeRates, oracle, debtCache }); + await updateRatesWithDefaults({ exchangeRates, owner, debtCache }); const existingSupply = await synthetix.totalSupply(); const mintableSupply = await supplySchedule.mintableSupply(); @@ -285,7 +284,7 @@ contract('Synthetix', async accounts => { // fast forward EVM to Week 2 in Year 3 schedule starting at UNIX 1583971200+ const weekThirtyNine = INFLATION_START_DATE + WEEK * 39 + DAY; await fastForwardTo(new Date(weekThirtyNine * 1000)); - await updateRatesWithDefaults({ exchangeRates, oracle, debtCache }); + await updateRatesWithDefaults({ exchangeRates, owner, debtCache }); const existingTotalSupply = await synthetix.totalSupply(); const currentRewardEscrowBalance = await synthetix.balanceOf(rewardEscrow.address); @@ -312,7 +311,7 @@ contract('Synthetix', async accounts => { // fast forward EVM to week 236 const september142023 = INFLATION_START_DATE + 236 * WEEK + DAY; await fastForwardTo(new Date(september142023 * 1000)); - await updateRatesWithDefaults({ exchangeRates, oracle, debtCache }); + await updateRatesWithDefaults({ exchangeRates, owner, debtCache }); const existingTotalSupply = await synthetix.totalSupply(); const mintableSupply = await supplySchedule.mintableSupply(); @@ -334,7 +333,7 @@ contract('Synthetix', async accounts => { // fast forward EVM to week 236 const week573 = INFLATION_START_DATE + 572 * WEEK + DAY; await fastForwardTo(new Date(week573 * 1000)); - await updateRatesWithDefaults({ exchangeRates, oracle, debtCache }); + await updateRatesWithDefaults({ exchangeRates, owner, debtCache }); const existingTotalSupply = await synthetix.totalSupply(); const mintableSupply = await supplySchedule.mintableSupply(); @@ -356,7 +355,7 @@ contract('Synthetix', async accounts => { // fast forward EVM to Week 3 in Year 2 schedule starting at UNIX 1553040000+ const weekThree = INFLATION_START_DATE + 2 * WEEK + 1 * DAY; await fastForwardTo(new Date(weekThree * 1000)); - await updateRatesWithDefaults({ exchangeRates, oracle, debtCache }); + await updateRatesWithDefaults({ exchangeRates, owner, debtCache }); let existingTotalSupply = await synthetix.totalSupply(); let mintableSupply = await supplySchedule.mintableSupply(); @@ -370,7 +369,7 @@ contract('Synthetix', async accounts => { // fast forward EVM to Week 4 const weekFour = weekThree + 1 * WEEK + 1 * DAY; await fastForwardTo(new Date(weekFour * 1000)); - await updateRatesWithDefaults({ exchangeRates, oracle, debtCache }); + await updateRatesWithDefaults({ exchangeRates, owner, debtCache }); existingTotalSupply = await synthetix.totalSupply(); mintableSupply = await supplySchedule.mintableSupply(); @@ -386,7 +385,7 @@ contract('Synthetix', async accounts => { // fast forward EVM to Week 3 of inflation const weekThree = INFLATION_START_DATE + 2 * WEEK + DAY; await fastForwardTo(new Date(weekThree * 1000)); - await updateRatesWithDefaults({ exchangeRates, oracle, debtCache }); + await updateRatesWithDefaults({ exchangeRates, owner, debtCache }); const existingTotalSupply = await synthetix.totalSupply(); const mintableSupply = await supplySchedule.mintableSupply(); @@ -444,7 +443,7 @@ contract('Synthetix', async accounts => { contractExample = await MockThirdPartyExchangeContract.new(addressResolver.address); // ensure rates are set - await updateRatesWithDefaults({ exchangeRates, oracle, debtCache }); + await updateRatesWithDefaults({ exchangeRates, owner, debtCache }); // issue sUSD from the owner await synthetix.issueSynths(amountOfsUSD, { from: owner }); diff --git a/test/contracts/SystemSettings.js b/test/contracts/SystemSettings.js index 1d5c902163..a1ec5c00b8 100644 --- a/test/contracts/SystemSettings.js +++ b/test/contracts/SystemSettings.js @@ -64,7 +64,6 @@ contract('SystemSettings', async accounts => { 'setAtomicVolatilityConsiderationWindow', 'setAtomicVolatilityUpdateThreshold', 'setCollapseFeeRate', - 'setCollateralManager', 'setCrossDomainMessageGasLimit', 'setDebtSnapshotStaleTime', 'setEtherWrapperBurnFeeRate', @@ -77,7 +76,6 @@ contract('SystemSettings', async accounts => { 'setLiquidationDelay', 'setLiquidationPenalty', 'setLiquidationRatio', - 'setMinCratio', 'setMinimumStakeTime', 'setPriceDeviationThresholdFactor', 'setRateStalePeriod', @@ -91,6 +89,10 @@ contract('SystemSettings', async accounts => { }); }); + it('ensure contract name method using the library return correct value', async () => { + assert.equal(await systemSettings.CONTRACT_NAME(), toBytes32('SystemSettings')); + }); + describe('setCrossDomainMessageGasLimit()', () => { it('only owner can invoke', async () => { await onlyGivenAddressCanInvoke({ @@ -202,11 +204,9 @@ contract('SystemSettings', async accounts => { describe('setIssuanceRatio()', () => { it('should allow the owner to set the issuance ratio', async () => { const ratio = toUnit('0.2'); - const transaction = await systemSettings.setIssuanceRatio(ratio, { from: owner, }); - assert.eventEqual(transaction, 'IssuanceRatioUpdated', { newRatio: ratio }); }); @@ -279,7 +279,9 @@ contract('SystemSettings', async accounts => { }); it('reverts when setting the fee period duration below minimum', async () => { - const minimum = await systemSettings.MIN_FEE_PERIOD_DURATION(); + // Have to hardcode here due to public const not available in Solidity V5 + // https://ethereum.stackexchange.com/a/102633/33908 + const minimum = toBN('86400'); // 1 day // Owner should be able to set minimum const transaction = await systemSettings.setFeePeriodDuration(minimum, { @@ -301,7 +303,9 @@ contract('SystemSettings', async accounts => { }); it('should disallow the owner from setting the fee period duration above maximum', async () => { - const maximum = await systemSettings.MAX_FEE_PERIOD_DURATION(); + // Have to hardcode here due to public const not available in Solidity V5 + // https://ethereum.stackexchange.com/a/102633/33908 + const maximum = toBN('5184000'); // 60 days // Owner should be able to set maximum const transaction = await systemSettings.setFeePeriodDuration(maximum, { @@ -352,7 +356,9 @@ contract('SystemSettings', async accounts => { }); it('reverts when owner sets the Target threshold above the max allowed value', async () => { - const thresholdPercent = (await systemSettings.MAX_TARGET_THRESHOLD()).add(toBN('1')); + // Have to hardcode here due to public const not available in Solidity V5 + // https://ethereum.stackexchange.com/a/102633/33908 + const thresholdPercent = toBN('50').add(toBN('1')); await assert.revert( systemSettings.setTargetThreshold(thresholdPercent, { from: owner }), 'Threshold too high' @@ -360,31 +366,6 @@ contract('SystemSettings', async accounts => { }); }); - describe('setMinCratio', async () => { - describe('revert condtions', async () => { - it('should fail if not called by the owner', async () => { - await assert.revert( - systemSettings.setMinCratio(short.address, toUnit(1), { from: account1 }), - 'Only the contract owner may perform this action' - ); - }); - it('should fail if the minimum is less than 1', async () => { - await assert.revert( - systemSettings.setMinCratio(short.address, toUnit(0.99), { from: owner }), - 'Cratio must be above 1' - ); - }); - }); - describe('when it succeeds', async () => { - beforeEach(async () => { - await systemSettings.setMinCratio(short.address, toUnit(2), { from: owner }); - }); - it('should update the minCratio', async () => { - assert.bnEqual(await systemSettings.minCratio(short.address), toUnit(2)); - }); - }); - }); - describe('setCollapseFeeRate', async () => { describe('revert condtions', async () => { it('should fail if not called by the owner', async () => { @@ -433,25 +414,6 @@ contract('SystemSettings', async accounts => { }); }); - describe('setCollateralManager', async () => { - describe('revert condtions', async () => { - it('should fail if not called by the owner', async () => { - await assert.revert( - systemSettings.setCollateralManager(short.address, ZERO_ADDRESS, { from: account1 }), - 'Only the contract owner may perform this action' - ); - }); - }); - describe('when it succeeds', async () => { - beforeEach(async () => { - await systemSettings.setCollateralManager(short.address, ZERO_ADDRESS, { from: owner }); - }); - it('should update the manager', async () => { - assert.bnEqual(await systemSettings.collateralManager(short.address), ZERO_ADDRESS); - }); - }); - }); - describe('setLiquidationDelay()', () => { const day = 3600 * 24; @@ -551,7 +513,9 @@ contract('SystemSettings', async accounts => { issuanceRatio = await systemSettings.issuanceRatio(); - RATIO_FROM_TARGET_BUFFER = await systemSettings.RATIO_FROM_TARGET_BUFFER(); + // Have to hardcode here due to public const not available in Solidity V5 + // https://ethereum.stackexchange.com/a/102633/33908 + RATIO_FROM_TARGET_BUFFER = toUnit('2'); // min liquidation ratio is how much the collateral ratio can drop from the issuance ratio before liquidation's can be started. MIN_LIQUIDATION_RATIO = multiplyDecimal(RATIO_FROM_TARGET_BUFFER, issuanceRatio); @@ -564,7 +528,9 @@ contract('SystemSettings', async accounts => { }); it('when setLiquidationRatio is set above MAX_LIQUIDATION_RATIO then revert', async () => { - const MAX_LIQUIDATION_RATIO = await systemSettings.MAX_LIQUIDATION_RATIO(); + // Have to hardcode here due to public const not available in Solidity V5 + // https://ethereum.stackexchange.com/a/102633/33908 + const MAX_LIQUIDATION_RATIO = toUnit('1'); const newLiquidationRatio = MAX_LIQUIDATION_RATIO.add(toUnit('1')); await assert.revert( @@ -614,7 +580,9 @@ contract('SystemSettings', async accounts => { }); it('when setLiquidationPenalty is set above MAX_LIQUIDATION_PENALTY then revert', async () => { - const MAX_LIQUIDATION_PENALTY = await systemSettings.MAX_LIQUIDATION_PENALTY(); + // Have to hardcode here due to public const not available in Solidity V5 + // https://ethereum.stackexchange.com/a/102633/33908 + const MAX_LIQUIDATION_PENALTY = toUnit('0.25'); const newLiquidationPenalty = MAX_LIQUIDATION_PENALTY.add(toUnit('1')); await assert.revert( systemSettings.setLiquidationPenalty(newLiquidationPenalty, { @@ -640,11 +608,15 @@ contract('SystemSettings', async accounts => { describe('liquidations constants', () => { it('MAX_LIQUIDATION_RATIO is 100%', async () => { - const MAX_LIQUIDATION_RATIO = await systemSettings.MAX_LIQUIDATION_RATIO(); + // Have to hardcode here due to public const not available in Solidity V5 + // https://ethereum.stackexchange.com/a/102633/33908 + const MAX_LIQUIDATION_RATIO = toUnit('1'); assert.bnEqual(MAX_LIQUIDATION_RATIO, toUnit('1')); }); it('MAX_LIQUIDATION_PENALTY is 25%', async () => { - const MAX_LIQUIDATION_PENALTY = await systemSettings.MAX_LIQUIDATION_PENALTY(); + // Have to hardcode here due to public const not available in Solidity V5 + // https://ethereum.stackexchange.com/a/102633/33908 + const MAX_LIQUIDATION_PENALTY = toUnit('0.25'); assert.bnEqual(MAX_LIQUIDATION_PENALTY, toUnit('.25')); }); }); @@ -825,6 +797,7 @@ contract('SystemSettings', async accounts => { }); }); }); + describe('setMinimumStakeTime()', () => { const week = 604800; it('can only be invoked by owner', async () => { @@ -929,7 +902,9 @@ contract('SystemSettings', async accounts => { }); it('should revert if the rate exceeds MAX_WRAPPER_MINT_FEE_RATE', async () => { - const newValue = (await systemSettings.MAX_WRAPPER_MINT_FEE_RATE()).add(ONE); + // Have to hardcode here due to public const not available in Solidity V5 + // https://ethereum.stackexchange.com/a/102633/33908 + const newValue = toUnit('1').add(ONE); await assert.revert( systemSettings.setEtherWrapperMintFeeRate(newValue, { from: owner }), 'rate > MAX_WRAPPER_MINT_FEE_RATE' @@ -964,7 +939,9 @@ contract('SystemSettings', async accounts => { }); it('should revert if the rate exceeds MAX_WRAPPER_BURN_FEE_RATE', async () => { - const newValue = (await systemSettings.MAX_WRAPPER_BURN_FEE_RATE()).add(ONE); + // Have to hardcode here due to public const not available in Solidity V5 + // https://ethereum.stackexchange.com/a/102633/33908 + const newValue = toUnit('1').add(ONE); await assert.revert( systemSettings.setEtherWrapperBurnFeeRate(newValue, { from: owner }), 'rate > MAX_WRAPPER_BURN_FEE_RATE' @@ -1047,7 +1024,9 @@ contract('SystemSettings', async accounts => { }); it('should revert if window is below minimum', async () => { - const minimum = await systemSettings.MIN_ATOMIC_TWAP_WINDOW(); + // Have to hardcode here due to public const not available in Solidity V5 + // https://ethereum.stackexchange.com/a/102633/33908 + const minimum = toBN('60'); await assert.revert( systemSettings.setAtomicTwapWindow(minimum.sub(toBN('1')), { from: owner }), 'Atomic twap window under minimum 1 min' @@ -1055,7 +1034,9 @@ contract('SystemSettings', async accounts => { }); it('should revert if window is above maximum', async () => { - const maximum = await systemSettings.MAX_ATOMIC_TWAP_WINDOW(); + // Have to hardcode here due to public const not available in Solidity V5 + // https://ethereum.stackexchange.com/a/102633/33908 + const maximum = toBN('86400'); await assert.revert( systemSettings.setAtomicTwapWindow(maximum.add(toBN('1')), { from: owner }), 'Atomic twap window exceed maximum 1 day' @@ -1153,7 +1134,9 @@ contract('SystemSettings', async accounts => { }); it('should revert if fee is above maximum', async () => { - const maximum = await systemSettings.MAX_EXCHANGE_FEE_RATE(); + // Have to hardcode here due to public const not available in Solidity V5 + // https://ethereum.stackexchange.com/a/102633/33908 + const maximum = toUnit('0.1'); await assert.revert( systemSettings.setAtomicExchangeFeeRate(sETH, maximum.add(toBN('1')), { from: owner }), 'MAX_EXCHANGE_FEE_RATE exceeded' @@ -1244,7 +1227,9 @@ contract('SystemSettings', async accounts => { }); it('should revert if window is below minimum', async () => { - const minimum = await systemSettings.MIN_ATOMIC_VOLATILITY_CONSIDERATION_WINDOW(); + // Have to hardcode here due to public const not available in Solidity V5 + // https://ethereum.stackexchange.com/a/102633/33908 + const minimum = toBN('60'); await assert.revert( systemSettings.setAtomicVolatilityConsiderationWindow(sETH, minimum.sub(toBN('1')), { from: owner, @@ -1254,7 +1239,9 @@ contract('SystemSettings', async accounts => { }); it('should revert if window is above maximum', async () => { - const maximum = await systemSettings.MAX_ATOMIC_VOLATILITY_CONSIDERATION_WINDOW(); + // Have to hardcode here due to public const not available in Solidity V5 + // https://ethereum.stackexchange.com/a/102633/33908 + const maximum = toBN('86400'); await assert.revert( systemSettings.setAtomicVolatilityConsiderationWindow(sETH, maximum.add(toBN('1')), { from: owner, @@ -1396,7 +1383,9 @@ contract('SystemSettings', async accounts => { }); it('should revert if the rate exceeds MAX_WRAPPER_MINT_FEE_RATE', async () => { - const newValue = (await systemSettings.MAX_WRAPPER_MINT_FEE_RATE()).add(ONE); + // Have to hardcode here due to public const not available in Solidity V5 + // https://ethereum.stackexchange.com/a/102633/33908 + const newValue = toUnit('1').add(ONE); await assert.revert( systemSettings.setWrapperMintFeeRate(testWrapperAddress, newValue, { from: owner }), 'rate > MAX_WRAPPER_MINT_FEE_RATE' @@ -1449,9 +1438,10 @@ contract('SystemSettings', async accounts => { reason: 'Only the contract owner may perform this action', }); }); - it('should revert if the rate exceeds MAX_WRAPPER_BURN_FEE_RATE', async () => { - const newValue = (await systemSettings.MAX_WRAPPER_BURN_FEE_RATE()).add(ONE); + // Have to hardcode here due to public const not available in Solidity V5 + // https://ethereum.stackexchange.com/a/102633/33908 + const newValue = toUnit('1').add(ONE); await assert.revert( systemSettings.setWrapperBurnFeeRate(testWrapperAddress, newValue, { from: owner }), 'rate > MAX_WRAPPER_BURN_FEE_RATE' diff --git a/test/contracts/TradingRewards.spec.js b/test/contracts/TradingRewards.spec.js index cbb4b3aa68..97fc403a4c 100644 --- a/test/contracts/TradingRewards.spec.js +++ b/test/contracts/TradingRewards.spec.js @@ -2,8 +2,14 @@ const { contract, web3 } = require('hardhat'); const { toBN } = web3.utils; const { assert, addSnapshotBeforeRestoreAfter } = require('./common'); const { setupAllContracts } = require('./setup'); -const { currentTime, toUnit, multiplyDecimal } = require('../utils')(); -const { setExchangeFeeRateForSynths, getDecodedLogs, decodedEventEqual } = require('./helpers'); +const { toUnit, multiplyDecimal } = require('../utils')(); +const { + setExchangeFeeRateForSynths, + getDecodedLogs, + decodedEventEqual, + setupPriceAggregators, + updateAggregatorRates, +} = require('./helpers'); const { toBytes32 } = require('../..'); /* @@ -15,9 +21,9 @@ const { toBytes32 } = require('../..'); contract('TradingRewards', accounts => { const [, owner, account1] = accounts; - const synths = ['sUSD', 'sETH', 'sBTC']; + const synths = ['sUSD', 'sETH', 'sBTC', 'SNX']; const synthKeys = synths.map(toBytes32); - const [sUSD, sETH, sBTC] = synthKeys; + const [sUSD, sETH, sBTC, SNX] = synthKeys; let synthetix, exchanger, exchangeRates, rewards, resolver, systemSettings; let sUSDContract, sETHContract, sBTCContract; @@ -31,6 +37,7 @@ contract('TradingRewards', accounts => { const rates = { [sETH]: toUnit('100'), [sBTC]: toUnit('12000'), + [SNX]: toUnit('0.2'), }; let feesPaidUSD; @@ -91,6 +98,8 @@ contract('TradingRewards', accounts => { 'CollateralManager', ], })); + + await setupPriceAggregators(exchangeRates, owner, [sETH, sBTC]); }); before('BRRRRRR', async () => { @@ -100,12 +109,7 @@ contract('TradingRewards', accounts => { }); before('set exchange rates', async () => { - const oracle = account1; - const timestamp = await currentTime(); - - await exchangeRates.updateRates([sETH, sBTC], Object.values(rates), timestamp, { - from: oracle, - }); + await updateAggregatorRates(exchangeRates, [sETH, sBTC, SNX], Object.values(rates)); await setExchangeFeeRateForSynths({ owner, diff --git a/test/contracts/Wrapper.js b/test/contracts/Wrapper.js index 10ca44eb9d..4247835683 100644 --- a/test/contracts/Wrapper.js +++ b/test/contracts/Wrapper.js @@ -4,12 +4,14 @@ const { contract, artifacts, web3 } = require('hardhat'); const { assert, addSnapshotBeforeRestoreAfterEach } = require('./common'); -const { currentTime, toUnit } = require('../utils')(); +const { toUnit } = require('../utils')(); const { ensureOnlyExpectedMutativeFunctions, getDecodedLogs, decodedEventEqual, + setupPriceAggregators, + updateAggregatorRates, } = require('./helpers'); const { setupAllContracts } = require('./setup'); @@ -23,7 +25,7 @@ contract('Wrapper', async accounts => { const ONE = toBN('1'); - const [, owner, oracle, , account1] = accounts; + const [, owner, , , account1] = accounts; let systemSettings, feePool, @@ -35,8 +37,7 @@ contract('Wrapper', async accounts => { sETHSynth, wrapperFactory, etherWrapper, - weth, - timestamp; + weth; const calculateETHToUSD = async feesInETH => { // Ask the Depot how many sUSD I will get for this ETH @@ -112,12 +113,8 @@ contract('Wrapper', async accounts => { from: owner, }); - timestamp = await currentTime(); - - // Depot requires ETH rates - await exchangeRates.updateRates([sETH, ETH], ['1500', '1500'].map(toUnit), timestamp, { - from: oracle, - }); + await setupPriceAggregators(exchangeRates, owner, [sETH, ETH]); + await updateAggregatorRates(exchangeRates, [sETH, ETH], ['1500', '1500'].map(toUnit)); }); addSnapshotBeforeRestoreAfterEach(); diff --git a/test/contracts/WrapperFactory.js b/test/contracts/WrapperFactory.js index 5fd83537bc..8c0552ebee 100644 --- a/test/contracts/WrapperFactory.js +++ b/test/contracts/WrapperFactory.js @@ -4,13 +4,15 @@ const { contract, artifacts, web3 } = require('hardhat'); const { assert, addSnapshotBeforeRestoreAfterEach } = require('./common'); -const { currentTime, toUnit } = require('../utils')(); +const { toUnit } = require('../utils')(); const { ensureOnlyExpectedMutativeFunctions, onlyGivenAddressCanInvoke, getDecodedLogs, decodedEventEqual, + setupPriceAggregators, + updateAggregatorRates, } = require('./helpers'); const { setupAllContracts } = require('./setup'); @@ -22,7 +24,7 @@ contract('WrapperFactory', async accounts => { const synths = ['sUSD', 'sETH', 'ETH', 'SNX']; const [sETH, ETH] = ['sETH', 'ETH'].map(toBytes32); - const [, owner, oracle, , account1] = accounts; + const [, owner, , , account1] = accounts; let addressResolver, flexibleStorage, @@ -32,8 +34,7 @@ contract('WrapperFactory', async accounts => { FEE_ADDRESS, sUSDSynth, wrapperFactory, - weth, - timestamp; + weth; before(async () => { ({ @@ -66,12 +67,10 @@ contract('WrapperFactory', async accounts => { })); FEE_ADDRESS = await feePool.FEE_ADDRESS(); - timestamp = await currentTime(); // Depot requires ETH rates - await exchangeRates.updateRates([sETH, ETH], ['1500', '1500'].map(toUnit), timestamp, { - from: oracle, - }); + await setupPriceAggregators(exchangeRates, owner, [sETH, ETH]); + await updateAggregatorRates(exchangeRates, [sETH, ETH], ['1500', '1500'].map(toUnit)); }); addSnapshotBeforeRestoreAfterEach(); diff --git a/test/contracts/helpers.js b/test/contracts/helpers.js index b5e9c7d0da..37a83e09de 100644 --- a/test/contracts/helpers.js +++ b/test/contracts/helpers.js @@ -11,6 +11,48 @@ const { constants: { ZERO_ADDRESS, ZERO_BYTES32 }, } = require('../..'); +const MockAggregator = artifacts.require('MockAggregatorV2V3'); + +/// utility function to setup price aggregators +/// @param exchangeRates instance of ExchangeRates contract +/// @param owner owner account of exchangeRates contract for adding an aggregator +/// @param keys array of bytes32 currency keys +/// @param decimalsArray optional array of ints for each key, defaults to 18 decimals +async function setupPriceAggregators(exchangeRates, owner, keys, decimalsArray = []) { + let aggregator; + for (let i = 0; i < keys.length; i++) { + aggregator = await MockAggregator.new({ from: owner }); + await aggregator.setDecimals(decimalsArray.length > 0 ? decimalsArray[i] : 18); + await exchangeRates.addAggregator(keys[i], aggregator.address, { from: owner }); + } +} + +/// same as setupPriceAggregators, but checks if an aggregator for that currency is already setup up +async function setupMissingPriceAggregators(exchangeRates, owner, keys) { + const missingKeys = []; + for (let i = 0; i < keys.length; i++) { + if ((await exchangeRates.aggregators(keys[i])) === ZERO_ADDRESS) { + missingKeys.push(keys[i]); + } + } + await setupPriceAggregators(exchangeRates, owner, missingKeys); +} +// utility function update rates for aggregators that are already set up +/// @param exchangeRates instance of ExchangeRates contract +/// @param owner owner account of exchangeRates contract for adding an aggregator +/// @param keys array of bytes32 currency keys +/// @param rates array of BN rates +/// @param timestamp optional timestamp for the update, currentTime() is used by default +async function updateAggregatorRates(exchangeRates, keys, rates, timestamp = undefined) { + timestamp = timestamp || (await currentTime()); + for (let i = 0; i < keys.length; i++) { + const aggregatorAddress = await exchangeRates.aggregators(keys[i]); + const aggregator = await MockAggregator.at(aggregatorAddress); + // set the rate + await aggregator.setLatestAnswer(rates[i], timestamp); + } +} + module.exports = { /** * the truffle transaction does not return all events logged, only those from the invoked @@ -87,28 +129,17 @@ module.exports = { return web3.utils.hexToAscii(web3.utils.utf8ToHex(input)); }, - async updateRatesWithDefaults({ exchangeRates, oracle, debtCache }) { - const timestamp = await currentTime(); - - const [SNX, sAUD, sEUR, sBTC, iBTC, sETH, ETH] = [ - 'SNX', - 'sAUD', - 'sEUR', - 'sBTC', - 'iBTC', - 'sETH', - 'ETH', - ].map(toBytes32); - - await exchangeRates.updateRates( - [SNX, sAUD, sEUR, sBTC, iBTC, sETH, ETH], - ['0.1', '0.5', '1.25', '5000', '4000', '172', '172'].map(toUnit), - timestamp, - { - from: oracle, - } - ); + setupPriceAggregators, + + updateAggregatorRates, + + async updateRatesWithDefaults({ exchangeRates, owner, debtCache }) { + const keys = ['SNX', 'sAUD', 'sEUR', 'sBTC', 'iBTC', 'sETH', 'ETH'].map(toBytes32); + const rates = ['0.1', '0.5', '1.25', '5000', '4000', '172', '172'].map(toUnit); + // set up any missing aggregators + await setupMissingPriceAggregators(exchangeRates, owner, keys); + await updateAggregatorRates(exchangeRates, keys, rates); await debtCache.takeDebtSnapshot(); }, diff --git a/test/contracts/setup.js b/test/contracts/setup.js index 925d74f4ca..4ddbec7be1 100644 --- a/test/contracts/setup.js +++ b/test/contracts/setup.js @@ -4,6 +4,8 @@ const { artifacts, web3, log } = require('hardhat'); const { toWei } = web3.utils; const { toUnit } = require('../utils')(); +const { setupPriceAggregators, updateAggregatorRates } = require('./helpers'); + const { toBytes32, getUsers, @@ -108,7 +110,7 @@ const setupContract = async ({ skipPostDeploy = false, properties = {}, }) => { - const [deployerAccount, owner, oracle, fundsWallet] = accounts; + const [deployerAccount, owner, , fundsWallet] = accounts; const artifact = artifacts.require(contract); @@ -122,7 +124,14 @@ const setupContract = async ({ // if it needs library linking if (Object.keys((await artifacts.readArtifact(contract)).linkReferences).length > 0) { - await artifact.link(await artifacts.require('SafeDecimalMath').new()); + const safeDecimalMath = await artifacts.require('SafeDecimalMath').new(); + if (artifact._json.contractName === 'SystemSettings') { + const SystemSettingsLib = artifacts.require('SystemSettingsLib'); + SystemSettingsLib.link(safeDecimalMath); + artifact.link(await SystemSettingsLib.new()); + } else { + artifact.link(safeDecimalMath); + } } const tryGetAddressOf = name => (cache[name] ? cache[name].address : ZERO_ADDRESS); @@ -146,20 +155,8 @@ const setupContract = async ({ AddressResolver: [owner], SystemStatus: [owner], FlexibleStorage: [tryGetAddressOf('AddressResolver')], - ExchangeRates: [ - owner, - oracle, - tryGetAddressOf('AddressResolver'), - [toBytes32('SNX')], - [toWei('0.2', 'ether')], - ], - ExchangeRatesWithDexPricing: [ - owner, - oracle, - tryGetAddressOf('AddressResolver'), - [toBytes32('SNX')], - [toWei('0.2', 'ether')], - ], + ExchangeRates: [owner, tryGetAddressOf('AddressResolver')], + ExchangeRatesWithDexPricing: [owner, tryGetAddressOf('AddressResolver')], SynthetixState: [owner, ZERO_ADDRESS], SupplySchedule: [owner, 0, 0], Proxy: [owner], @@ -1132,6 +1129,13 @@ const setupAllContracts = async ({ .map(mock => mock.setAddressResolver(returnObj['AddressResolver'].address)) ); + if (returnObj['ExchangeRates']) { + // setup SNX price feed + const SNX = toBytes32('SNX'); + await setupPriceAggregators(returnObj['ExchangeRates'], owner, [SNX]); + await updateAggregatorRates(returnObj['ExchangeRates'], [SNX], [toUnit('0.2')]); + } + return returnObj; }; diff --git a/test/integration/behaviors/liquidations.behavior.js b/test/integration/behaviors/liquidations.behavior.js new file mode 100644 index 0000000000..55990c819b --- /dev/null +++ b/test/integration/behaviors/liquidations.behavior.js @@ -0,0 +1,132 @@ +const ethers = require('ethers'); +const { toBytes32 } = require('../../../index'); +const { assert } = require('../../contracts/common'); +const { getRate, setRate } = require('../utils/rates'); +const { ensureBalance } = require('../utils/balances'); +const { skipLiquidationDelay } = require('../utils/skip'); + +function itCanLiquidate({ ctx }) { + describe('liquidating', () => { + let owner; + let someUser; + let otherUser; + let exchangeRate; + let Synthetix, Liquidations, SystemSettings, SynthsUSD; + + before('target contracts and users', () => { + ({ Synthetix, Liquidations, SystemSettings, SynthsUSD } = ctx.contracts); + + ({ owner, someUser, otherUser } = ctx.users); + + SystemSettings = SystemSettings.connect(owner); + }); + + before('system settings are set', async () => { + await SystemSettings.setIssuanceRatio(ethers.utils.parseEther('0.25')); + await SystemSettings.setLiquidationRatio(ethers.utils.parseEther('0.5')); + }); + + before('ensure someUser has SNX', async () => { + await ensureBalance({ + ctx, + symbol: 'SNX', + user: someUser, + balance: ethers.utils.parseEther('100'), + }); + }); + + before('ensure otherUser has sUSD', async () => { + await ensureBalance({ + ctx, + symbol: 'sUSD', + user: otherUser, + balance: ethers.utils.parseEther('100'), + }); + }); + + before('exchange rate is set', async () => { + exchangeRate = await getRate({ ctx, symbol: 'SNX' }); + await setRate({ ctx, symbol: 'SNX', rate: '1000000000000000000' }); + }); + + before('someUser stakes their SNX', async () => { + await Synthetix.connect(someUser).issueMaxSynths(); + }); + + it('cannot be liquidated at this point', async () => { + assert.equal(await Liquidations.isOpenForLiquidation(someUser.address), false); + }); + + describe('getting marked', () => { + before('exchange rate changes to allow liquidation', async () => { + await setRate({ ctx, symbol: 'SNX', rate: '200000000000000000' }); + }); + + before('liquidation is marked', async () => { + await Liquidations.connect(otherUser).flagAccountForLiquidation(someUser.address); + }); + + after('restore exchange rate', async () => { + await setRate({ ctx, symbol: 'SNX', rate: exchangeRate.toString() }); + }); + + it('still not open for liquidation', async () => { + assert.equal(await Liquidations.isOpenForLiquidation(someUser.address), false); + }); + + it('deadline has not passed yet', async () => { + assert.equal(await Liquidations.isLiquidationDeadlinePassed(someUser.address), false); + }); + + describe('when the liquidation delay passes', () => { + before(async () => { + await skipLiquidationDelay({ ctx }); + }); + + describe('getting liquidated', () => { + let beforeDebt, beforeDebttedSnx; + let beforeBalance, beforeCredittedSnx; + + before('otherUser calls liquidateDelinquentAccount', async () => { + beforeDebt = ( + await Synthetix.debtBalanceOf(someUser.address, toBytes32('sUSD')) + ).toString(); + beforeDebttedSnx = await Synthetix.balanceOf(someUser.address); + beforeCredittedSnx = await Synthetix.balanceOf(otherUser.address); + beforeBalance = await SynthsUSD.balanceOf(otherUser.address); + + await Synthetix.connect(otherUser).liquidateDelinquentAccount( + someUser.address, + ethers.utils.parseEther('100') + ); + }); + + it('deducts sUSD debt from the liquidated', async () => { + assert.bnLt( + await Synthetix.debtBalanceOf(someUser.address, toBytes32('sUSD')), + beforeDebt + ); + }); + + it('burns sUSD from otherUser', async () => { + assert.bnLt(await SynthsUSD.balanceOf(otherUser.address), beforeBalance); + }); + + it('transfers SNX from otherUser', async () => { + const amountSent = beforeDebttedSnx.sub(await Synthetix.balanceOf(someUser.address)); + + assert.bnNotEqual(amountSent, '0'); + assert.bnEqual( + await Synthetix.balanceOf(otherUser.address), + beforeCredittedSnx.add(amountSent) + ); + }); + }); + }); + }); + }); +} + +module.exports = { + itCanLiquidate, +}; diff --git a/test/integration/behaviors/redeem.behavior.js b/test/integration/behaviors/redeem.behavior.js index 7b1d5f793b..4e855ce62c 100644 --- a/test/integration/behaviors/redeem.behavior.js +++ b/test/integration/behaviors/redeem.behavior.js @@ -6,7 +6,7 @@ const { } = require('../../../index'); const { ensureBalance } = require('../utils/balances'); const { skipWaitingPeriod } = require('../utils/skip'); -const { updateExchangeRatesIfNeeded } = require('../utils/rates'); +const { increaseStalePeriodAndCheckRatesAndCache } = require('../utils/rates'); function itCanRedeem({ ctx }) { describe('redemption of deprecated synths', () => { @@ -57,7 +57,7 @@ function itCanRedeem({ ctx }) { }); before('update rates and take snapshot if needed', async () => { - await updateExchangeRatesIfNeeded({ ctx }); + await increaseStalePeriodAndCheckRatesAndCache({ ctx }); }); before('record total system debt', async () => { diff --git a/test/integration/behaviors/stake.behavior.js b/test/integration/behaviors/stake.behavior.js index 4f0b608fe7..c76d319125 100644 --- a/test/integration/behaviors/stake.behavior.js +++ b/test/integration/behaviors/stake.behavior.js @@ -7,7 +7,7 @@ const { skipFeePeriod, skipMinimumStakeTime } = require('../utils/skip'); function itCanStake({ ctx }) { describe('staking and claiming', () => { - const SNXAmount = ethers.utils.parseEther('100'); + const SNXAmount = ethers.utils.parseEther('1000'); const amountToIssueAndBurnsUSD = ethers.utils.parseEther('1'); let user; diff --git a/test/integration/l1/Liquidations.l1.integrations.js b/test/integration/l1/Liquidations.l1.integrations.js new file mode 100644 index 0000000000..1027828391 --- /dev/null +++ b/test/integration/l1/Liquidations.l1.integrations.js @@ -0,0 +1,31 @@ +const { bootstrapL1 } = require('../utils/bootstrap'); +const { itCanLiquidate } = require('../behaviors/liquidations.behavior'); +const { ethers } = require('hardhat'); + +// Load Compiled +const path = require('path'); +const { + constants: { BUILD_FOLDER }, +} = require('../../..'); +const buildPath = path.join(__dirname, '..', '..', '..', `${BUILD_FOLDER}`); +const { loadCompiledFiles } = require('../../../publish/src/solidity'); +const { compiled } = loadCompiledFiles({ buildPath }); + +describe('Liquidations (L1)', () => { + const ctx = this; + bootstrapL1({ ctx }); + + before(async () => { + const { + abi, + evm: { + bytecode: { object: bytecode }, + }, + } = compiled.MockAggregatorV2V3; + const MockAggregatorFactory = new ethers.ContractFactory(abi, bytecode, ctx.users.owner); + const MockAggregator = await MockAggregatorFactory.deploy(); + ctx.contracts.MockAggregator = MockAggregator; + }); + + itCanLiquidate({ ctx }); +}); diff --git a/test/integration/l2/Liquidations.l2.integration.js b/test/integration/l2/Liquidations.l2.integration.js new file mode 100644 index 0000000000..34bb13634f --- /dev/null +++ b/test/integration/l2/Liquidations.l2.integration.js @@ -0,0 +1,31 @@ +const { bootstrapL2 } = require('../utils/bootstrap'); +const { itCanLiquidate } = require('../behaviors/liquidations.behavior'); +const { ethers } = require('hardhat'); + +// Load Compiled +const path = require('path'); +const { + constants: { BUILD_FOLDER }, +} = require('../../..'); +const buildPath = path.join(__dirname, '..', '..', '..', `${BUILD_FOLDER}`); +const { loadCompiledFiles } = require('../../../publish/src/solidity'); +const { compiled } = loadCompiledFiles({ buildPath }); + +describe('Liquidations (L2)', () => { + const ctx = this; + bootstrapL2({ ctx }); + + before(async () => { + const { + abi, + evm: { + bytecode: { object: bytecode }, + }, + } = compiled.MockAggregatorV2V3; + const MockAggregatorFactory = new ethers.ContractFactory(abi, bytecode, ctx.users.owner); + const MockAggregator = await MockAggregatorFactory.deploy(); + ctx.contracts.MockAggregator = MockAggregator; + }); + + itCanLiquidate({ ctx }); +}); diff --git a/test/integration/utils/bootstrap.js b/test/integration/utils/bootstrap.js index 0060f92781..c905e731e5 100644 --- a/test/integration/utils/bootstrap.js +++ b/test/integration/utils/bootstrap.js @@ -2,7 +2,7 @@ const hre = require('hardhat'); const ethers = require('ethers'); const { loadUsers } = require('./users'); const { connectContracts } = require('./contracts'); -const { updateExchangeRatesIfNeeded } = require('./rates'); +const { increaseStalePeriodAndCheckRatesAndCache } = require('./rates'); const { ensureBalance } = require('./balances'); const { setupOptimismWatchers, approveBridge } = require('./optimism'); const { startOpsHeartbeat } = require('./optimism-temp'); @@ -26,7 +26,7 @@ function bootstrapL1({ ctx }) { connectContracts({ ctx }); - await updateExchangeRatesIfNeeded({ ctx }); + await increaseStalePeriodAndCheckRatesAndCache({ ctx }); }); } @@ -57,7 +57,7 @@ function bootstrapL2({ ctx }) { connectContracts({ ctx }); - await updateExchangeRatesIfNeeded({ ctx }); + await increaseStalePeriodAndCheckRatesAndCache({ ctx }); await ensureBalance({ ctx, @@ -95,8 +95,8 @@ function bootstrapDual({ ctx }) { connectContracts({ ctx: ctx.l1 }); connectContracts({ ctx: ctx.l2 }); - await updateExchangeRatesIfNeeded({ ctx: ctx.l1 }); - await updateExchangeRatesIfNeeded({ ctx: ctx.l2 }); + await increaseStalePeriodAndCheckRatesAndCache({ ctx: ctx.l1 }); + await increaseStalePeriodAndCheckRatesAndCache({ ctx: ctx.l2 }); await approveBridge({ ctx: ctx.l1, amount: ethers.utils.parseEther('100000000') }); diff --git a/test/integration/utils/rates.js b/test/integration/utils/rates.js index a620cebcc0..7692b017d1 100644 --- a/test/integration/utils/rates.js +++ b/test/integration/utils/rates.js @@ -1,15 +1,18 @@ const ethers = require('ethers'); const { setSystemSetting } = require('./settings'); const { toBytes32 } = require('../../..'); +const { createMockAggregatorFactory } = require('../../utils')(); -async function updateExchangeRatesIfNeeded({ ctx }) { +async function increaseStalePeriodAndCheckRatesAndCache({ ctx }) { await setSystemSetting({ ctx, settingName: 'rateStalePeriod', newValue: '1000000000' }); if (await _areRatesInvalid({ ctx })) { - await _setNewRates({ ctx }); + // try to add the missing rates + await _setMissingRates({ ctx }); + // check again if (await _areRatesInvalid({ ctx })) { await _printRatesInfo({ ctx }); - throw new Error('Rates are still invalid after updating them.'); + throw new Error('Rates are still invalid after updating.'); } } @@ -71,35 +74,40 @@ async function _getAvailableCurrencyKeys({ ctx }) { .concat(['SNX', 'ETH'].map(toBytes32)); } -async function _getCurrentRates({ ctx, currencyKeys }) { - const { ExchangeRates } = ctx.contracts; - - const rates = []; - for (const currencyKey of currencyKeys) { - const rate = await ExchangeRates.rateForCurrency(currencyKey); - - // Simualte any exchange rates that are 0. - const newRate = rate.toString() === '0' ? ethers.utils.parseEther('1') : rate; - - rates.push(newRate); +async function _setMissingRates({ ctx }) { + let currencyKeys; + if (ctx.fork) { + // this adds a rate for only e.g. sREDEEMER in fork mode (which is not an existing synth + // but is added to test the redeeming functionality) + // All other synths should have feeds in fork mode + currencyKeys = (ctx.addedSynths || []).map(o => toBytes32(o.name)); + } else { + // set missing rates for all synths, since not in fork mode we don't have existing feeds + currencyKeys = await _getAvailableCurrencyKeys({ ctx }); } - return rates; -} + const owner = ctx.users.owner; + const ExchangeRates = ctx.contracts.ExchangeRates.connect(owner); -async function _setNewRates({ ctx }) { - let { ExchangeRates } = ctx.contracts; - const oracle = await ExchangeRates.oracle(); - const signer = ctx.fork ? ctx.provider.getSigner(oracle) : ctx.users.owner; - ExchangeRates = ExchangeRates.connect(signer); + // factory for price aggregators contracts + const MockAggregatorFactory = await createMockAggregatorFactory(owner); - const currencyKeys = await _getAvailableCurrencyKeys({ ctx }); + // got over all rates and add aggregators const { timestamp } = await ctx.provider.getBlock(); - - const rates = await _getCurrentRates({ ctx, currencyKeys }); - - const tx = await ExchangeRates.updateRates(currencyKeys, rates, timestamp); - await tx.wait(); + for (const currencyKey of currencyKeys) { + const rate = await ExchangeRates.rateForCurrency(currencyKey); + if (rate.toString() === '0') { + // deploy an aggregator + let aggregator = await MockAggregatorFactory.deploy(); + aggregator = aggregator.connect(owner); + // set decimals + await (await aggregator.setDecimals(18)).wait(); + // push the new price + await (await aggregator.setLatestAnswer(ethers.utils.parseEther('1'), timestamp)).wait(); + // set the aggregator in ExchangeRates + await (await ExchangeRates.addAggregator(currencyKey, aggregator.address)).wait(); + } + } } async function _updateCache({ ctx }) { @@ -121,8 +129,21 @@ async function getRate({ ctx, symbol }) { return ExchangeRates.rateForCurrency(toBytes32(symbol)); } +async function setRate({ ctx, symbol, rate }) { + const ExchangeRates = ctx.contracts.ExchangeRates.connect(ctx.users.owner); + const MockAggregator = ctx.contracts.MockAggregator.connect(ctx.users.owner); + + const { timestamp } = await ctx.provider.getBlock(); + + await (await MockAggregator.setDecimals(18)).wait(); + await (await MockAggregator.setLatestAnswer(ethers.utils.parseEther(rate), timestamp)).wait(); + await (await ExchangeRates.addAggregator(toBytes32(symbol), MockAggregator.address)).wait(); + await MockAggregator.setLatestAnswer(rate, timestamp); +} + module.exports = { - updateExchangeRatesIfNeeded, + increaseStalePeriodAndCheckRatesAndCache, getRate, + setRate, updateCache, }; diff --git a/test/integration/utils/skip.js b/test/integration/utils/skip.js index b32ce985ce..5122bd09d7 100644 --- a/test/integration/utils/skip.js +++ b/test/integration/utils/skip.js @@ -1,7 +1,7 @@ const { fastForward } = require('../../test-utils/rpc'); const { wait } = require('../../test-utils/wait'); const { getSystemSetting } = require('./settings'); -const { updateExchangeRatesIfNeeded } = require('./rates'); +const { increaseStalePeriodAndCheckRatesAndCache } = require('./rates'); async function skipWaitingPeriod({ ctx }) { await _dualFastForward({ @@ -24,6 +24,13 @@ async function skipMinimumStakeTime({ ctx }) { }); } +async function skipLiquidationDelay({ ctx }) { + await _dualFastForward({ + ctx, + seconds: await getSystemSetting({ ctx, settingName: 'liquidationDelay' }), + }); +} + /* * Fast forwards the L1 chain and waits for the * L2 chain to sync to the new timestamp. @@ -35,11 +42,12 @@ async function _dualFastForward({ ctx, seconds }) { await fastForward({ seconds: parseInt(seconds), provider: l1Ctx.provider }); await wait({ seconds: 6 }); - await updateExchangeRatesIfNeeded({ ctx }); + await increaseStalePeriodAndCheckRatesAndCache({ ctx }); } module.exports = { skipWaitingPeriod, skipFeePeriod, skipMinimumStakeTime, + skipLiquidationDelay, }; diff --git a/test/publish/index.js b/test/publish/index.js index b98bc6805e..46fa1250fd 100644 --- a/test/publish/index.js +++ b/test/publish/index.js @@ -6,14 +6,12 @@ const pLimit = require('p-limit'); const ethers = require('ethers'); const isCI = require('is-ci'); -const { loadCompiledFiles } = require('../../publish/src/solidity'); const { loadLocalWallets } = require('../test-utils/wallets'); const { fastForward } = require('../test-utils/rpc'); const deployStakingRewardsCmd = require('../../publish/src/commands/deploy-staking-rewards'); const deployShortingRewardsCmd = require('../../publish/src/commands/deploy-shorting-rewards'); const deployCmd = require('../../publish/src/commands/deploy'); -const { buildPath } = deployCmd.DEFAULTS; const testUtils = require('../utils'); const commands = { @@ -97,6 +95,7 @@ describe('publish scripts', () => { let sETH; let provider; let overrides; + let MockAggregatorFactory; const resetConfigAndSynthFiles = () => { // restore the synths and config files for this env (cause removal updated it) @@ -135,7 +134,7 @@ describe('publish scripts', () => { url: 'http://localhost:8545', }); - const { isCompileRequired } = testUtils(); + const { isCompileRequired, createMockAggregatorFactory } = testUtils(); // load accounts used by local EVM const wallets = loadLocalWallets({ provider }); @@ -154,6 +153,8 @@ describe('publish scripts', () => { console.log('Skipping build as everything up to date'); } + MockAggregatorFactory = await createMockAggregatorFactory(accounts.deployer); + [sUSD, sBTC, sETH] = ['sUSD', 'sBTC', 'sETH'].map(toBytes32); gasLimit = 8000000; @@ -195,15 +196,6 @@ describe('publish scripts', () => { ); const createMockAggregator = async () => { - // get last build - const { compiled } = loadCompiledFiles({ buildPath }); - const { - abi, - evm: { - bytecode: { object: bytecode }, - }, - } = compiled['MockAggregatorV2V3']; - const MockAggregatorFactory = new ethers.ContractFactory(abi, bytecode, accounts.deployer); const MockAggregator = await MockAggregatorFactory.deploy({ gasLimit, gasPrice }); const tx = await MockAggregator.setDecimals('8', { diff --git a/test/utils/index.js b/test/utils/index.js index 54f251eaa1..e49020edbe 100644 --- a/test/utils/index.js +++ b/test/utils/index.js @@ -528,6 +528,18 @@ module.exports = ({ web3 } = {}) => { return latestSolTimestamp > earliestCompiledTimestamp; }; + // create a factory to deploy mock price aggregators + const createMockAggregatorFactory = async account => { + const { compiled } = loadCompiledFiles({ buildPath }); + const { + abi, + evm: { + bytecode: { object: bytecode }, + }, + } = compiled['MockAggregatorV2V3']; + return new ethers.ContractFactory(abi, bytecode, account); + }; + const setupProvider = ({ providerUrl, privateKey, publicKey }) => { const provider = new ethers.providers.JsonRpcProvider(providerUrl); @@ -606,6 +618,7 @@ module.exports = ({ web3 } = {}) => { loadLocalUsers, isCompileRequired, + createMockAggregatorFactory, setupProvider, getContract,